monocart-coverage-reports
Advanced tools
Comparing version 2.0.8 to 2.0.9
@@ -33,7 +33,7 @@ const Util = require('../utils/util.js'); | ||
type, | ||
loc: { | ||
start: branchStart, | ||
// could be updated if multiple locations | ||
end: branchStart | ||
}, | ||
start: branchStart, | ||
// could be updated if multiple locations | ||
end: branchStart, | ||
locations: [], | ||
@@ -50,3 +50,3 @@ reverseParents, | ||
const branchStart = group.loc.start; | ||
const branchStart = group.start; | ||
@@ -71,3 +71,3 @@ // the block is not exact correct, if there is a block wrapped | ||
// update group end | ||
group.loc.end = end; | ||
group.end = end; | ||
@@ -230,3 +230,3 @@ locationMap.set(start, branchInfo); | ||
if (prevLocation) { | ||
const { loc, locations } = group; | ||
const { locations } = group; | ||
locations.sort((a, b) => { | ||
@@ -236,3 +236,3 @@ return a.start - b.start; | ||
// update group end after sorted | ||
loc.end = locations[locations.length - 1].end; | ||
group.end = locations[locations.length - 1].end; | ||
} | ||
@@ -280,3 +280,3 @@ }, | ||
} | ||
// console.log(parentCount, 'uncovered list', noBlockList.length, group.loc.start); | ||
// console.log(parentCount, 'uncovered list', noBlockList.length, group.start); | ||
let count = parentCount - blockCount; | ||
@@ -300,3 +300,3 @@ noBlockList.forEach((item) => { | ||
// const start = group.loc.start; | ||
// const start = group.start; | ||
// if (start > 7874 && start < 7922) { | ||
@@ -391,5 +391,15 @@ // console.log(group.type, parentCount, 'locations', group.locations); | ||
branchMap.forEach((group) => { | ||
// add start/end for none with group start/end | ||
group.locations.forEach((item) => { | ||
if (item.none) { | ||
item.start = group.start; | ||
item.end = group.end; | ||
} | ||
}); | ||
branches.push({ | ||
type: group.type, | ||
loc: group.loc, | ||
start: group.start, | ||
end: group.end, | ||
locations: group.locations | ||
@@ -401,3 +411,3 @@ }); | ||
branches.sort((a, b) => { | ||
return a.loc.start - b.loc.start; | ||
return a.start - b.start; | ||
}); | ||
@@ -404,0 +414,0 @@ |
@@ -8,5 +8,13 @@ // https://github.com/demurgos/v8-coverage | ||
* It detects skipped or repeated statements. The root range counts the number of function calls. | ||
* | ||
* @functionName can be an empty string. This is common for the FunctionCov representing the whole module. | ||
*/ | ||
// https://github.com/bcoe/v8-coverage | ||
/** | ||
* @ranges is always non-empty. The first range is called the "root range". | ||
* @isBlockCoverage indicates if the function has block coverage information. | ||
If this is false, it usually means that the functions was never called. | ||
It seems to be equivalent to ranges.length === 1 && ranges[0].count === 0. | ||
* @functionName can be an empty string. This is common for the FunctionCov representing the whole module. | ||
*/ | ||
// if you have a line of code that says `var x= 10; console.log(x);` that's one line and 2 statements. | ||
@@ -105,3 +113,2 @@ | ||
// console.log('===========================================', state.sourcePath); | ||
// console.log(coverageInfo.lines); | ||
// } | ||
@@ -214,17 +221,2 @@ | ||
// ======================================================================================================== | ||
const createEmptyCoverageInfo = () => { | ||
return { | ||
// v8 UI | ||
data: { | ||
bytes: [], | ||
functions: [], | ||
branches: [] | ||
}, | ||
// istanbul | ||
functions: [], | ||
branches: [] | ||
}; | ||
}; | ||
// istanbul coverage format | ||
@@ -243,21 +235,43 @@ /** | ||
const { sourcePath } = item; | ||
const { coverageInfo, locator } = state; | ||
const { | ||
data, | ||
bytes, | ||
functions, | ||
branches | ||
} = coverageInfo; | ||
branches, | ||
locator | ||
} = state; | ||
// ========================================== | ||
// v8 | ||
data.bytes = dedupeCountRanges(data.bytes); | ||
// v8 data | ||
const data = { | ||
bytes: dedupeCountRanges(bytes), | ||
functions: [], | ||
branches: [] | ||
}; | ||
// ========================================== | ||
// ignore | ||
const ignoredRanges = getIgnoredRanges(locator, options); | ||
if (ignoredRanges) { | ||
// data bytes is start/end/count object | ||
handleIgnoredRanges(data.bytes, ignoredRanges); | ||
handleIgnoredRanges(data.functions, ignoredRanges); | ||
handleIgnoredRanges(data.branches, ignoredRanges); | ||
// functions is InfoFunction start/end/count instance | ||
handleIgnoredRanges(functions, ignoredRanges); | ||
// branches is InfoBranch start/end/count instance | ||
handleIgnoredRanges(branches, ignoredRanges); | ||
// branch locations start/end/count object | ||
branches.forEach((group) => { | ||
if (group.ignored) { | ||
// all branch group ignored | ||
group.locations.forEach((it) => { | ||
it.ignored = true; | ||
}); | ||
} else { | ||
handleIgnoredRanges(group.locations, ignoredRanges); | ||
} | ||
}); | ||
// console.log(ignoredRanges); | ||
@@ -267,2 +281,13 @@ | ||
data.functions = functions.map((info) => { | ||
return info.getRange(); | ||
}); | ||
// branch group with locations to flat branches | ||
data.branches = branches.map((info) => { | ||
return info.getRanges(); | ||
}).flat(); | ||
// ========================================== | ||
// lines | ||
// after bytes with ignored, before calculateV8Lines | ||
@@ -273,2 +298,4 @@ const { | ||
// ========================================== | ||
// v8 data and summary | ||
item.data = data; | ||
@@ -295,3 +322,3 @@ item.summary = { | ||
lines.forEach((line, index) => { | ||
lines.filter((it) => !it.ignored).forEach((line, index) => { | ||
istanbulCoverage.statementMap[`${index}`] = line.generate(); | ||
@@ -301,10 +328,11 @@ istanbulCoverage.s[`${index}`] = line.count; | ||
functions.forEach((fn, index) => { | ||
istanbulCoverage.fnMap[`${index}`] = fn.generate(); | ||
functions.filter((it) => !it.ignored).forEach((fn, index) => { | ||
istanbulCoverage.fnMap[`${index}`] = fn.generate(locator); | ||
istanbulCoverage.f[`${index}`] = fn.count; | ||
}); | ||
branches.forEach((branch, index) => { | ||
istanbulCoverage.branchMap[`${index}`] = branch.generate(); | ||
istanbulCoverage.b[`${index}`] = branch.generateCounts(); | ||
branches.filter((it) => !it.ignored).forEach((branch, index) => { | ||
const { map, counts } = branch.generate(locator); | ||
istanbulCoverage.branchMap[`${index}`] = map; | ||
istanbulCoverage.b[`${index}`] = counts; | ||
}); | ||
@@ -320,4 +348,2 @@ | ||
const addJsBytesCoverage = (state, range) => { | ||
const { coverageInfo } = state; | ||
const { data } = coverageInfo; | ||
const { | ||
@@ -327,3 +353,3 @@ startOffset, endOffset, count | ||
// add bytes range | ||
data.bytes.push({ | ||
state.bytes.push({ | ||
start: startOffset, | ||
@@ -336,4 +362,2 @@ end: endOffset, | ||
const addCssBytesCoverage = (state, range) => { | ||
const { coverageInfo } = state; | ||
const { data } = coverageInfo; | ||
const { | ||
@@ -343,3 +367,3 @@ start, end, count | ||
// add css bytes range, already start, end | ||
data.bytes.push({ | ||
state.bytes.push({ | ||
start, | ||
@@ -351,15 +375,2 @@ end, | ||
const updateOffsetToLocation = (locator, loc) => { | ||
const sLoc = locator.offsetToLocation(loc.start); | ||
loc.start = { | ||
line: sLoc.line, | ||
column: sLoc.column | ||
}; | ||
const eLoc = locator.offsetToLocation(loc.end); | ||
loc.end = { | ||
line: eLoc.line, | ||
column: eLoc.column | ||
}; | ||
}; | ||
// ======================================================================================================== | ||
@@ -371,13 +382,6 @@ | ||
if (!state.js) { | ||
// use css rules data for functions | ||
return; | ||
} | ||
const { | ||
locator, coverageInfo, astInfo | ||
} = state; | ||
const v8Functions = coverageInfo.data.functions; | ||
const istanbulFunctions = coverageInfo.functions; | ||
const { functions, astInfo } = state; | ||
astInfo.functions.forEach((it) => { | ||
@@ -387,24 +391,6 @@ const { | ||
} = it; | ||
v8Functions.push({ | ||
start, | ||
end, | ||
count | ||
}); | ||
const loc = { | ||
start, | ||
end | ||
}; | ||
updateOffsetToLocation(locator, loc); | ||
const functionInfo = new InfoFunction(loc, count, functionName); | ||
istanbulFunctions.push(functionInfo); | ||
const functionInfo = new InfoFunction(start, end, count, functionName); | ||
functions.push(functionInfo); | ||
}); | ||
// if (state.sourcePath.endsWith('store.js')) { | ||
// console.log('=========================================================='); | ||
// console.log(astInfo.functions); | ||
// console.log(functions); | ||
// } | ||
}; | ||
@@ -419,48 +405,9 @@ | ||
const { | ||
locator, coverageInfo, astInfo | ||
} = state; | ||
const v8Branches = coverageInfo.data.branches; | ||
const isTanbulBranches = coverageInfo.branches; | ||
const { branches, astInfo } = state; | ||
astInfo.branches.forEach((it) => { | ||
const branchType = it.type; | ||
const branchLoc = { | ||
... it.loc | ||
}; | ||
updateOffsetToLocation(locator, branchLoc); | ||
// locations | ||
// [ { start:{line,column}, end:{line,column}, count }, ...] | ||
const locations = it.locations.map((oLoc) => { | ||
const newLoc = { | ||
... oLoc | ||
}; | ||
if (newLoc.none) { | ||
// the branch count is not very accurate | ||
v8Branches.push({ | ||
start: it.loc.start, | ||
end: it.loc.end, | ||
count: oLoc.count, | ||
none: true | ||
}); | ||
return newLoc; | ||
} | ||
// the branch count is not very accurate | ||
v8Branches.push({ | ||
start: oLoc.start, | ||
end: oLoc.end, | ||
count: oLoc.count | ||
}); | ||
updateOffsetToLocation(locator, newLoc); | ||
return newLoc; | ||
}); | ||
const branchInfo = new InfoBranch(branchLoc, locations, branchType); | ||
isTanbulBranches.push(branchInfo); | ||
const { | ||
start, end, locations, type | ||
} = it; | ||
const branchInfo = new InfoBranch(start, end, locations, type); | ||
branches.push(branchInfo); | ||
}); | ||
@@ -552,10 +499,8 @@ | ||
const { | ||
type, loc, locations | ||
} = it; | ||
const { type, locations } = it; | ||
// rename to startOffset and endOffset | ||
const bRange = { | ||
startOffset: loc.start, | ||
endOffset: loc.end | ||
startOffset: it.start, | ||
endOffset: it.end | ||
}; | ||
@@ -571,6 +516,4 @@ | ||
const newBranchLoc = { | ||
start: originalRange.startOffset, | ||
end: originalRange.endOffset | ||
}; | ||
const groupStart = originalRange.startOffset; | ||
const groupEnd = originalRange.endOffset; | ||
@@ -585,2 +528,4 @@ let hasError; | ||
if (newLoc.none) { | ||
newLoc.start = groupStart; | ||
newLoc.end = groupEnd; | ||
return newLoc; | ||
@@ -608,2 +553,3 @@ } | ||
// mapping to new range | ||
const oRage = res.originalRange; | ||
@@ -616,2 +562,3 @@ newLoc.start = oRage.startOffset; | ||
// ignored group when found error | ||
if (hasError) { | ||
@@ -624,3 +571,4 @@ return; | ||
type, | ||
loc: newBranchLoc, | ||
start: groupStart, | ||
end: groupEnd, | ||
locations: newLocations | ||
@@ -819,3 +767,6 @@ }); | ||
decodedMappings, | ||
coverageInfo: createEmptyCoverageInfo(), | ||
// coverage info | ||
bytes: [], | ||
functions: [], | ||
branches: [], | ||
astInfo: { | ||
@@ -840,2 +791,3 @@ functions: [], | ||
const sourceList = []; | ||
originalMap.forEach((originalState) => { | ||
@@ -849,3 +801,4 @@ | ||
const url = fileUrls[sourcePath] || sourcePath; | ||
const id = Util.calculateSha1(url + source); | ||
// add dist for id | ||
const id = Util.calculateSha1(distFile + url + source); | ||
@@ -862,3 +815,3 @@ const sourceItem = { | ||
// generate coverage, coverageInfo for current file, state for dist file | ||
// generate coverage for current file, state for dist file | ||
collectFileCoverage(sourceItem, originalState, state.coverageData, options); | ||
@@ -923,3 +876,2 @@ | ||
// console.log('=================================', originalState.sourcePath); | ||
// console.log(originalState.coverageInfo.lineMap); | ||
// } | ||
@@ -979,3 +931,3 @@ | ||
// global file sources and coverage data | ||
// global file sources and coverage | ||
const fileSources = {}; | ||
@@ -1010,5 +962,2 @@ const coverageData = {}; | ||
// ============================ | ||
const coverageInfo = createEmptyCoverageInfo(); | ||
// ============================ | ||
// move functions and ranges to coverageList | ||
@@ -1043,5 +992,8 @@ let coverageList = []; | ||
locator, | ||
coverageInfo, | ||
// coverage info | ||
bytes: [], | ||
functions: [], | ||
branches: [], | ||
astInfo, | ||
// for istanbul data | ||
// for istanbul | ||
fileSources: {}, | ||
@@ -1048,0 +1000,0 @@ coverageData: {} |
@@ -0,6 +1,6 @@ | ||
const Util = require('../utils/util.js'); | ||
module.exports = class InfoBranch { | ||
constructor(loc, locations, type) { | ||
this.loc = loc; | ||
this.line = loc.start.line; | ||
// [ { start:{line,column}, end:{line,column}, count }, ...] | ||
constructor(start, end, locations, type) { | ||
this.start = start; | ||
this.end = end; | ||
this.locations = locations; | ||
@@ -10,21 +10,66 @@ this.type = type || 'branch'; | ||
generate() { | ||
return { | ||
loc: this.loc, | ||
getRanges() { | ||
return this.locations.map((item) => { | ||
const range = { | ||
start: item.start, | ||
end: item.end, | ||
count: item.count | ||
}; | ||
if (item.none) { | ||
range.none = true; | ||
} | ||
if (item.ignored) { | ||
range.ignored = true; | ||
} | ||
return range; | ||
}); | ||
} | ||
generate(locator) { | ||
const groupLoc = { | ||
start: this.start, | ||
end: this.end | ||
}; | ||
Util.updateOffsetToLocation(locator, groupLoc); | ||
const line = groupLoc.start.line; | ||
// remove ignored | ||
const locations = this.locations.filter((it) => !it.ignored); | ||
// [ { start:{line,column}, end:{line,column}, count }, ...] | ||
locations.forEach((item) => { | ||
Util.updateOffsetToLocation(locator, item); | ||
}); | ||
const map = { | ||
loc: groupLoc, | ||
type: this.type, | ||
locations: this.locations.map((item) => { | ||
const { start, end } = item; | ||
locations: locations.map((item) => { | ||
const { | ||
start, end, none | ||
} = item; | ||
if (none) { | ||
// none with group start/end, should be empty for istanbul | ||
return { | ||
start: {}, | ||
end: {} | ||
}; | ||
} | ||
return { | ||
start: start || {}, | ||
end: end || {} | ||
start, | ||
end | ||
}; | ||
}), | ||
line: this.line | ||
line: line | ||
}; | ||
const counts = locations.map((item) => item.count); | ||
return { | ||
map, | ||
counts | ||
}; | ||
} | ||
generateCounts() { | ||
return this.locations.map((item) => item.count); | ||
} | ||
}; |
@@ -0,5 +1,6 @@ | ||
const Util = require('../utils/util.js'); | ||
module.exports = class InfoFunction { | ||
constructor(loc, count, name) { | ||
this.loc = loc; | ||
this.line = loc.start.line; | ||
constructor(start, end, count, name) { | ||
this.start = start; | ||
this.end = end; | ||
this.count = count; | ||
@@ -9,10 +10,32 @@ this.name = name || '(anonymous)'; | ||
generate() { | ||
getRange() { | ||
const range = { | ||
start: this.start, | ||
end: this.end, | ||
count: this.count | ||
}; | ||
if (this.ignored) { | ||
range.ignored = true; | ||
} | ||
return range; | ||
} | ||
generate(locator) { | ||
const loc = { | ||
start: this.start, | ||
end: this.end | ||
}; | ||
Util.updateOffsetToLocation(locator, loc); | ||
const line = loc.start.line; | ||
return { | ||
name: this.name, | ||
decl: this.loc, | ||
loc: this.loc, | ||
line: this.line | ||
decl: loc, | ||
loc: loc, | ||
line: line | ||
}; | ||
} | ||
}; |
@@ -246,2 +246,15 @@ const fs = require('fs'); | ||
updateOffsetToLocation: (locator, loc) => { | ||
const sLoc = locator.offsetToLocation(loc.start); | ||
loc.start = { | ||
line: sLoc.line, | ||
column: sLoc.column | ||
}; | ||
const eLoc = locator.offsetToLocation(loc.end); | ||
loc.end = { | ||
line: eLoc.line, | ||
column: eLoc.column | ||
}; | ||
}, | ||
forEachFile: function(dir, extList, callback) { | ||
@@ -248,0 +261,0 @@ if (!fs.existsSync(dir)) { |
{ | ||
"name": "monocart-coverage-reports", | ||
"version": "2.0.8", | ||
"version": "2.0.9", | ||
"description": "Monocart coverage reports", | ||
@@ -20,6 +20,7 @@ "main": "lib/index.js", | ||
"build": "sf lint && sf b -p && npm run build-test", | ||
"test-node": "npm run test-node-env && npm run test-node-ins && npm run test-node-api && npm run test-node-cdp", | ||
"test-node-env": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage node ./test/test-node-env.js && node ./test/generate-node-report.js", | ||
"test-node": "npm run test-node-env && npm run test-node-api && npm run test-node-fgc && npm run test-node-ins && npm run test-node-cdp", | ||
"test-node-env": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage-env node ./test/test-node-env.js && node ./test/generate-node-report.js", | ||
"test-node-api": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage-api node ./test/test-node-api.js", | ||
"test-node-fgc": "node ./test/test-node-fgc.js", | ||
"test-node-ins": "node ./test/test-node-ins.js", | ||
"test-node-api": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage node ./test/test-node-api.js", | ||
"test-node-cdp": "node --inspect=9229 ./test/test-node-cdp.js", | ||
@@ -26,0 +27,0 @@ "test-browser": "node ./test/test.js", |
116
README.md
@@ -13,2 +13,3 @@ # Monocart Coverage Reports | ||
* [Multiprocessing Support](#multiprocessing-support) | ||
* [onEnd Hook](#onend-hook) | ||
* [Compare Reports](#compare-reports) | ||
@@ -25,2 +26,3 @@ * [Compare Workflows](#compare-workflows) | ||
* [Chromium Coverage API](#chromium-coverage-api) | ||
* [V8 Coverage Data Format](#v8-coverage-data-format) | ||
* [Istanbul Introduction](#istanbul-introduction) | ||
@@ -134,7 +136,38 @@ * [Thanks](#thanks) | ||
## onEnd Hook | ||
For example, checking thresholds: | ||
```js | ||
const EC = require('eight-colors'); | ||
const coverageOptions = { | ||
name: 'My Coverage Report', | ||
outputDir: './coverage-reports', | ||
onEnd: (coverageResults) => { | ||
const thresholds = { | ||
bytes: 80, | ||
lines: 60 | ||
}; | ||
console.log('check thresholds ...', thresholds); | ||
const errors = []; | ||
const { summary } = coverageResults; | ||
Object.keys(thresholds).forEach((k) => { | ||
const pct = summary[k].pct; | ||
if (pct < thresholds[k]) { | ||
errors.push(`Coverage threshold for ${k} (${pct} %) not met: ${thresholds[k]} %`); | ||
} | ||
}); | ||
if (errors.length) { | ||
const errMsg = errors.join('\n'); | ||
console.log(EC.red(errMsg)); | ||
// throw new Error(errMsg); | ||
// process.exit(1); | ||
} | ||
} | ||
} | ||
``` | ||
## Compare Reports | ||
| | Istanbul | V8 | V8 to Istanbul | | ||
| :--------------| :------ | :------ | :---------------------- | | ||
| Coverage data | Istanbul (Object) | V8 (Array) | V8 (Array) | | ||
| Output | [Istanbul reports](#istanbul-reports) | [V8 reports](#v8-reports) | [Istanbul reports](#istanbul-reports) | | ||
| Coverage data | [Istanbul](https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md) (Object) | [V8](#v8-coverage-data-format) (Array) | [V8](#v8-coverage-data-format) (Array) | | ||
| Output | [Istanbul reports](#available-reports) | [V8 reports](#available-reports) | [Istanbul reports](#available-reports) | | ||
| - Bytes | ❌ | ✅ | ❌ | | ||
@@ -187,9 +220,12 @@ | - Statements | ✅ | ❌ | ☑️❔ | | ||
- example: | ||
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage` node [./test/test-node-env.js](./test/test-node-env.js) && node [./test/generate-node-report.js](./test/generate-node-report.js) | ||
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-env` node [./test/test-node-env.js](./test/test-node-env.js) && node [./test/generate-node-report.js](./test/generate-node-report.js) | ||
- Using [V8](https://nodejs.org/docs/latest/api/v8.html#v8takecoverage) API | ||
- Using [V8](https://nodejs.org/docs/latest/api/v8.html#v8takecoverage) API + NODE_V8_COVERAGE | ||
- Writing the coverage started by NODE_V8_COVERAGE to disk on demand with `v8.takeCoverage()` and stopping with `v8.stopCoverage()`. | ||
- example: | ||
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage` node [./test/test-node-api.js](./test/test-node-api.js) | ||
> cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-api` node [./test/test-node-api.js](./test/test-node-api.js) | ||
- Using [foreground-child](https://github.com/tapjs/foreground-child) + NODE_V8_COVERAGE | ||
- example: [./test/test-node-fgc.js](./test/test-node-fgc.js) | ||
- Using [Inspector](https://nodejs.org/docs/latest/api/inspector.html) API (or module [collect-v8-coverage](https://github.com/SimenB/collect-v8-coverage)) | ||
@@ -208,20 +244,20 @@ - Connecting to the V8 inspector and enable V8 coverage. | ||
``` | ||
1, dist/main.js | ||
2, dist/vendor.js | ||
3, dist/something-else.js | ||
dist/main.js | ||
dist/vendor.js | ||
dist/something-else.js | ||
``` | ||
We can use `entryFilter` to filter the entry files. For example, we should remove `vendor.js` and `something-else.js` if they are not in our coverage scope. | ||
``` | ||
1, dist/main.js | ||
dist/main.js | ||
``` | ||
When inline or linked sourcemap exists to the entry file, the source files will be extracted from the sourcemap for the entry file, and the entry file will be removed if `logging` is not `debug`. | ||
``` | ||
1, src/index.js | ||
2, src/components/app.js | ||
3, node_modules/dependency/dist/dependency.js | ||
> src/index.js | ||
> src/components/app.js | ||
> node_modules/dependency/dist/dependency.js | ||
``` | ||
We can use `sourceFilter` to filter the source files. For example, we should remove `dependency.js` if it is not in our coverage scope. | ||
``` | ||
1, src/index.js | ||
2, src/components/app.js | ||
> src/index.js | ||
> src/components/app.js | ||
``` | ||
@@ -253,9 +289,11 @@ Example: | ||
if (block.isBlockCoverage) { | ||
// v8-to-istanbul: count range as branch here. | ||
// v8-to-istanbul: new CovBranch() | ||
// Problem: not every block is branch, and the first block is actually function. | ||
if (block.functionName && i === 0) { | ||
// v8-to-istanbul: count range as function here. | ||
// v8-to-istanbul: new CovFunction() | ||
// Problem: no anonymous function | ||
} | ||
} else if (block.functionName) { | ||
// v8-to-istanbul: count range as function here. | ||
// v8-to-istanbul: new CovFunction() | ||
// Problem: no anonymous function | ||
} | ||
@@ -309,2 +347,46 @@ } | ||
## V8 Coverage Data Format | ||
```js | ||
// Coverage data for a source range. | ||
export interface CoverageRange { | ||
// JavaScript script source offset for the range start. | ||
startOffset: integer; | ||
// JavaScript script source offset for the range end. | ||
endOffset: integer; | ||
// Collected execution count of the source range. | ||
count: integer; | ||
} | ||
// Coverage data for a JavaScript function. | ||
/** | ||
* @functionName can be an empty string. | ||
* @ranges is always non-empty. The first range is called the "root range". | ||
* @isBlockCoverage indicates if the function has block coverage information. | ||
If this is false, it usually means that the functions was never called. | ||
It seems to be equivalent to ranges.length === 1 && ranges[0].count === 0. | ||
*/ | ||
export interface FunctionCoverage { | ||
// JavaScript function name. | ||
functionName: string; | ||
// Source ranges inside the function with coverage data. | ||
ranges: CoverageRange[]; | ||
// Whether coverage data for this function has block granularity. | ||
isBlockCoverage: boolean; | ||
} | ||
// Coverage data for a JavaScript script. | ||
export interface ScriptCoverage { | ||
// JavaScript script id. | ||
scriptId: Runtime.ScriptId; | ||
// JavaScript script name or url. | ||
url: string; | ||
// Functions contained in the script that has coverage data. | ||
functions: FunctionCoverage[]; | ||
} | ||
export type V8CoverageData = ScriptCoverage[]; | ||
``` | ||
see devtools-protocol [ScriptCoverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage) | ||
## Istanbul Introduction | ||
@@ -311,0 +393,0 @@ - [Istanbul coverage report](https://istanbul.js.org/) - Instrumenting source codes and generating coverage reports |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
810944
6091
392