monocart-coverage-reports 2.8.3 → 2.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -5
- package/README.zh-Hans.md +20 -4
- package/lib/converter/ast-visitor.js +25 -5
- package/lib/converter/ast.js +10 -7
- package/lib/converter/collect-source-maps.js +11 -4
- package/lib/converter/converter.js +88 -34
- package/lib/index.d.ts +12 -7
- package/lib/index.js +1 -0
- package/lib/index.mjs +1 -0
- package/lib/packages/monocart-coverage-app.js +1 -1
- package/lib/packages/monocart-coverage-cli.js +14 -14
- package/lib/packages/monocart-coverage-vendor.js +23 -23
- package/lib/platform/share.js +47 -26
- package/lib/register/register.js +4 -4
- package/lib/register/register.mjs +3 -3
- package/lib/utils/snapshot.js +388 -385
- package/lib/utils/util.js +10 -0
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* [Integration with Any Testing Framework](#integration-with-any-testing-framework)
|
|
40
40
|
* [Integration Examples](#integration-examples)
|
|
41
41
|
- [Playwright](#playwright)
|
|
42
|
+
- [c8](#c8)
|
|
42
43
|
- [CodeceptJS](#codeceptjs)
|
|
43
44
|
- [Jest](#jest)
|
|
44
45
|
- [Vitest](#vitest)
|
|
@@ -505,7 +506,7 @@ const coverageOptions = {
|
|
|
505
506
|
sourceFilter: "**/src/**"
|
|
506
507
|
};
|
|
507
508
|
```
|
|
508
|
-
|
|
509
|
+
Support multiple patterns:
|
|
509
510
|
```js
|
|
510
511
|
const coverageOptions = {
|
|
511
512
|
entryFilter: {
|
|
@@ -914,7 +915,6 @@ When `logging` is `debug`, the raw report data will be preserved in `[outputDir]
|
|
|
914
915
|
- [playwright-coverage](https://github.com/cenfun/playwright-coverage) - Example for Playwright coverage reports
|
|
915
916
|
- [playwright-bdd-coverage](https://github.com/cenfun/playwright-bdd-coverage) - Example for Playwright BDD coverage reports
|
|
916
917
|
- [monocart-reporter](https://github.com/cenfun/monocart-reporter) - Playwright custom reporter, supports generating [Code coverage report](https://github.com/cenfun/monocart-reporter?#code-coverage-report)
|
|
917
|
-
- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (unit + e2e shard)
|
|
918
918
|
- Coverage for component testing with `monocart-reporter`:
|
|
919
919
|
- [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue)
|
|
920
920
|
- [playwright-ct-react](https://github.com/cenfun/playwright-ct-react)
|
|
@@ -924,14 +924,22 @@ When `logging` is `debug`, the raw report data will be preserved in `[outputDir]
|
|
|
924
924
|
- [nextjs-with-playwright-istanbul](https://github.com/cenfun/nextjs-with-playwright-istanbul)
|
|
925
925
|
- see [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright)
|
|
926
926
|
|
|
927
|
+
### [c8](https://github.com/bcoe/c8)
|
|
928
|
+
- c8 has integrated `MCR` as an experimental feature since [v10.1.0](https://github.com/bcoe/c8/releases/tag/v10.1.0)
|
|
929
|
+
```sh
|
|
930
|
+
c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js
|
|
931
|
+
```
|
|
932
|
+
|
|
927
933
|
### [CodeceptJS](https://github.com/codeceptjs/CodeceptJS)
|
|
928
|
-
- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage)
|
|
934
|
+
- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage)
|
|
929
935
|
|
|
930
936
|
### [Jest](https://github.com/jestjs/jest/)
|
|
931
937
|
- [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) - Jest custom reporter for coverage reports
|
|
938
|
+
- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (Jest unit + Playwright e2e sharding)
|
|
932
939
|
|
|
933
940
|
### [Vitest](https://github.com/vitest-dev/vitest)
|
|
934
941
|
- [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports
|
|
942
|
+
- [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding)
|
|
935
943
|
|
|
936
944
|
### [Puppeteer](https://github.com/puppeteer/puppeteer/)
|
|
937
945
|
- [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage
|
|
@@ -1054,17 +1062,25 @@ const coverageOptions = {
|
|
|
1054
1062
|
- Node.js 20+
|
|
1055
1063
|
- VSCode (extensions: eslint/stylelint/vue)
|
|
1056
1064
|
```sh
|
|
1057
|
-
npm install starfall-cli -g
|
|
1058
1065
|
npm install
|
|
1066
|
+
npx playwright install --with-deps
|
|
1059
1067
|
|
|
1060
1068
|
npm run build
|
|
1061
1069
|
npm run test
|
|
1062
1070
|
|
|
1063
1071
|
npm run dev
|
|
1064
1072
|
```
|
|
1073
|
+
- Refreshing `eol=lf` for snapshot of test (Windows)
|
|
1074
|
+
```sh
|
|
1075
|
+
git add . -u
|
|
1076
|
+
git commit -m "Saving files before refreshing line endings"
|
|
1077
|
+
|
|
1078
|
+
npm run eol
|
|
1079
|
+
```
|
|
1065
1080
|
|
|
1066
1081
|
### VSCode Extension
|
|
1067
1082
|
- [Coverage Gutters](https://github.com/ryanluker/vscode-coverage-gutters) - Display test coverage generated by lcov or xml in VSCode editor.
|
|
1068
1083
|
|
|
1069
1084
|
## Thanks
|
|
1070
|
-
-
|
|
1085
|
+
- [@bcoe](https://github.com/bcoe)
|
|
1086
|
+
- [@edumserrano](https://github.com/edumserrano)
|
package/README.zh-Hans.md
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* [如何跟其他框架集成](#integration-with-any-testing-framework)
|
|
40
40
|
* [集成的例子](#integration-examples)
|
|
41
41
|
- [Playwright](#playwright)
|
|
42
|
+
- [c8](#c8)
|
|
42
43
|
- [CodeceptJS](#codeceptjs)
|
|
43
44
|
- [Jest](#jest)
|
|
44
45
|
- [Vitest](#vitest)
|
|
@@ -918,7 +919,6 @@ const coverageOptions = {
|
|
|
918
919
|
- [playwright-coverage](https://github.com/cenfun/playwright-coverage) - Example for Playwright coverage reports
|
|
919
920
|
- [playwright-bdd-coverage](https://github.com/cenfun/playwright-bdd-coverage) - Example for Playwright BDD coverage reports
|
|
920
921
|
- [monocart-reporter](https://github.com/cenfun/monocart-reporter) - Playwright custom reporter, supports generating [Code coverage report](https://github.com/cenfun/monocart-reporter?#code-coverage-report)
|
|
921
|
-
- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (unit + e2e shard)
|
|
922
922
|
- Coverage for component testing with `monocart-reporter`:
|
|
923
923
|
- [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue)
|
|
924
924
|
- [playwright-ct-react](https://github.com/cenfun/playwright-ct-react)
|
|
@@ -928,14 +928,22 @@ const coverageOptions = {
|
|
|
928
928
|
- [nextjs-with-playwright-istanbul](https://github.com/cenfun/nextjs-with-playwright-istanbul)
|
|
929
929
|
- see [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright)
|
|
930
930
|
|
|
931
|
+
### [c8](https://github.com/bcoe/c8)
|
|
932
|
+
- c8 has integrated `MCR` as an experimental feature since [v10.1.0](https://github.com/bcoe/c8/releases/tag/v10.1.0)
|
|
933
|
+
```sh
|
|
934
|
+
c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js
|
|
935
|
+
```
|
|
936
|
+
|
|
931
937
|
### [CodeceptJS](https://github.com/codeceptjs/CodeceptJS)
|
|
932
|
-
- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage)
|
|
938
|
+
- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage)
|
|
933
939
|
|
|
934
940
|
### [Jest](https://github.com/jestjs/jest/)
|
|
935
941
|
- [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) - Jest custom reporter for coverage reports
|
|
942
|
+
- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (Jest unit + Playwright e2e sharding)
|
|
936
943
|
|
|
937
944
|
### [Vitest](https://github.com/vitest-dev/vitest)
|
|
938
945
|
- [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports
|
|
946
|
+
- [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding)
|
|
939
947
|
|
|
940
948
|
### [Puppeteer](https://github.com/puppeteer/puppeteer/)
|
|
941
949
|
- [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage
|
|
@@ -1058,17 +1066,25 @@ const coverageOptions = {
|
|
|
1058
1066
|
- Node.js 20+
|
|
1059
1067
|
- VSCode (extensions: eslint/stylelint/vue)
|
|
1060
1068
|
```sh
|
|
1061
|
-
npm install starfall-cli -g
|
|
1062
1069
|
npm install
|
|
1070
|
+
npx playwright install --with-deps
|
|
1063
1071
|
|
|
1064
1072
|
npm run build
|
|
1065
1073
|
npm run test
|
|
1066
1074
|
|
|
1067
1075
|
npm run dev
|
|
1068
1076
|
```
|
|
1077
|
+
- Refreshing `eol=lf` for snapshot of test (Windows)
|
|
1078
|
+
```sh
|
|
1079
|
+
git add . -u
|
|
1080
|
+
git commit -m "Saving files before refreshing line endings"
|
|
1081
|
+
|
|
1082
|
+
npm run eol
|
|
1083
|
+
```
|
|
1069
1084
|
|
|
1070
1085
|
### VSCode Extension
|
|
1071
1086
|
- [Coverage Gutters](https://github.com/ryanluker/vscode-coverage-gutters) - Display test coverage generated by lcov or xml in VSCode editor.
|
|
1072
1087
|
|
|
1073
1088
|
## Thanks
|
|
1074
|
-
-
|
|
1089
|
+
- [@bcoe](https://github.com/bcoe)
|
|
1090
|
+
- [@edumserrano](https://github.com/edumserrano)
|
|
@@ -32,10 +32,10 @@ const getParentCount = (reverseParents, functionCount) => {
|
|
|
32
32
|
return functionCount;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
const getFunctionRange = (start, end, coverageInfo) => {
|
|
35
|
+
const getFunctionRange = (start, end, type, coverageInfo) => {
|
|
36
36
|
|
|
37
37
|
const {
|
|
38
|
-
functionMap, functionNameMap, functionUncoveredRanges
|
|
38
|
+
functionMap, functionNameMap, functionStaticRanges, functionUncoveredRanges
|
|
39
39
|
} = coverageInfo;
|
|
40
40
|
|
|
41
41
|
// exact matched in functionMap
|
|
@@ -49,6 +49,13 @@ const getFunctionRange = (start, end, coverageInfo) => {
|
|
|
49
49
|
return nameRange;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
if (type === 'StaticBlock' && functionStaticRanges.length) {
|
|
53
|
+
const staticRange = Util.findInRanges(start, end, functionStaticRanges, 'startOffset', 'endOffset');
|
|
54
|
+
if (staticRange) {
|
|
55
|
+
return staticRange;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
52
59
|
// find in uncoveredRanges
|
|
53
60
|
return Util.findInRanges(start, end, functionUncoveredRanges, 'startOffset', 'endOffset');
|
|
54
61
|
};
|
|
@@ -283,8 +290,10 @@ const updateBranchCount = (group) => {
|
|
|
283
290
|
if (none) {
|
|
284
291
|
return;
|
|
285
292
|
}
|
|
293
|
+
|
|
286
294
|
item.block = getFunctionBlock(start, end, functionState);
|
|
287
295
|
setGeneratedOnly(item.block, group.generatedOnly);
|
|
296
|
+
|
|
288
297
|
});
|
|
289
298
|
|
|
290
299
|
|
|
@@ -464,6 +473,15 @@ const collectNodes = (ast) => {
|
|
|
464
473
|
});
|
|
465
474
|
},
|
|
466
475
|
|
|
476
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
|
|
477
|
+
// as a function "functionName": "<static_initializer>",
|
|
478
|
+
StaticBlock: (node, parents) => {
|
|
479
|
+
const reverseParents = [].concat(parents).reverse();
|
|
480
|
+
functionNodes.push({
|
|
481
|
+
node,
|
|
482
|
+
reverseParents
|
|
483
|
+
});
|
|
484
|
+
},
|
|
467
485
|
|
|
468
486
|
// ===============================================================================
|
|
469
487
|
// functions
|
|
@@ -617,10 +635,12 @@ const getRootFunctionState = (ast, coverageInfo) => {
|
|
|
617
635
|
const findFunctionRange = (item, coverageInfo) => {
|
|
618
636
|
|
|
619
637
|
const { node, reverseParents } = item;
|
|
620
|
-
const {
|
|
638
|
+
const {
|
|
639
|
+
start, end, type
|
|
640
|
+
} = node;
|
|
621
641
|
|
|
622
642
|
// try function start/end
|
|
623
|
-
const functionRange = getFunctionRange(start, end, coverageInfo);
|
|
643
|
+
const functionRange = getFunctionRange(start, end, type, coverageInfo);
|
|
624
644
|
if (functionRange) {
|
|
625
645
|
return functionRange;
|
|
626
646
|
}
|
|
@@ -629,7 +649,7 @@ const findFunctionRange = (item, coverageInfo) => {
|
|
|
629
649
|
// 0 is function self
|
|
630
650
|
const parent = reverseParents[1];
|
|
631
651
|
if (parent && parent.type === 'MethodDefinition') {
|
|
632
|
-
return getFunctionRange(parent.start, parent.end, coverageInfo);
|
|
652
|
+
return getFunctionRange(parent.start, parent.end, parent.type, coverageInfo);
|
|
633
653
|
}
|
|
634
654
|
|
|
635
655
|
};
|
package/lib/converter/ast.js
CHANGED
|
@@ -8,7 +8,9 @@ const { collectAstInfo } = require('./ast-visitor.js');
|
|
|
8
8
|
const getCoverageInfo = (coverageList) => {
|
|
9
9
|
const functionMap = new Map();
|
|
10
10
|
const functionNameMap = new Map();
|
|
11
|
+
const functionStaticRanges = [];
|
|
11
12
|
const functionUncoveredRanges = [];
|
|
13
|
+
|
|
12
14
|
let rootRange;
|
|
13
15
|
coverageList.forEach((block) => {
|
|
14
16
|
const {
|
|
@@ -38,9 +40,7 @@ const getCoverageInfo = (coverageList) => {
|
|
|
38
40
|
functionRange.blockMap = blockMap;
|
|
39
41
|
// uncovered is unique
|
|
40
42
|
const blockUncoveredRanges = blockRanges.filter((it) => it.count === 0);
|
|
41
|
-
|
|
42
|
-
return a.startOffset - b.startOffset;
|
|
43
|
-
});
|
|
43
|
+
Util.sortOffsetRanges(blockUncoveredRanges);
|
|
44
44
|
functionRange.blockUncoveredRanges = blockUncoveredRanges;
|
|
45
45
|
functionRange.blockCoveredRanges = blockRanges.filter((it) => it.count > 0);
|
|
46
46
|
}
|
|
@@ -61,7 +61,11 @@ const getCoverageInfo = (coverageList) => {
|
|
|
61
61
|
functionNameMap.set(functionRange.startOffset + functionName.length, functionRange);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
if (functionName === '<static_initializer>') {
|
|
65
|
+
functionStaticRanges.push(functionRange);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// cache uncovered
|
|
65
69
|
if (functionRange.count === 0) {
|
|
66
70
|
functionUncoveredRanges.push(functionRange);
|
|
67
71
|
}
|
|
@@ -69,13 +73,12 @@ const getCoverageInfo = (coverageList) => {
|
|
|
69
73
|
});
|
|
70
74
|
|
|
71
75
|
// sort ranges
|
|
72
|
-
|
|
73
|
-
return a.startOffset - b.startOffset;
|
|
74
|
-
});
|
|
76
|
+
Util.sortOffsetRanges(functionUncoveredRanges);
|
|
75
77
|
|
|
76
78
|
return {
|
|
77
79
|
functionMap,
|
|
78
80
|
functionNameMap,
|
|
81
|
+
functionStaticRanges,
|
|
79
82
|
functionUncoveredRanges,
|
|
80
83
|
rootRange
|
|
81
84
|
};
|
|
@@ -63,9 +63,14 @@ const resolveSourcesContent = (data, url) => {
|
|
|
63
63
|
|
|
64
64
|
const { sources, sourcesContent } = data;
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
// sources [1,2,3]
|
|
67
|
+
// sourcesContent could be [null, null, "content"]
|
|
68
|
+
// some of contents could be missed
|
|
69
|
+
|
|
70
|
+
let hasSourceContent = false;
|
|
67
71
|
sources.forEach((file, i) => {
|
|
68
72
|
if (typeof sourcesContent[i] === 'string') {
|
|
73
|
+
hasSourceContent = true;
|
|
69
74
|
return;
|
|
70
75
|
}
|
|
71
76
|
|
|
@@ -79,16 +84,18 @@ const resolveSourcesContent = (data, url) => {
|
|
|
79
84
|
const content = Util.readFileSync(path.resolve(sourcePath));
|
|
80
85
|
if (typeof content === 'string') {
|
|
81
86
|
sourcesContent[i] = content;
|
|
87
|
+
hasSourceContent = true;
|
|
82
88
|
return;
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
failed
|
|
92
|
+
sourcesContent[i] = '';
|
|
93
|
+
Util.logDebug(EC.red(`failed to load source content: ${file}`));
|
|
94
|
+
|
|
88
95
|
});
|
|
89
96
|
|
|
90
97
|
|
|
91
|
-
if (
|
|
98
|
+
if (hasSourceContent) {
|
|
92
99
|
return data;
|
|
93
100
|
}
|
|
94
101
|
};
|
|
@@ -49,7 +49,7 @@ const logMappingErrors = (type, result) => {
|
|
|
49
49
|
|
|
50
50
|
const handleIgnoredRanges = (list, ignoredRanges) => {
|
|
51
51
|
list.forEach((item) => {
|
|
52
|
-
const range = Util.findInRanges(item.start, item.end, ignoredRanges
|
|
52
|
+
const range = Util.findInRanges(item.start, item.end, ignoredRanges);
|
|
53
53
|
if (range) {
|
|
54
54
|
// console.log(item, range);
|
|
55
55
|
item.ignored = true;
|
|
@@ -74,32 +74,7 @@ const applyBytesToLines = (bytes, locator, lineMap) => {
|
|
|
74
74
|
|
|
75
75
|
// update lines coverage
|
|
76
76
|
const lines = Util.getRangeLines(sLoc, eLoc);
|
|
77
|
-
|
|
78
|
-
lines.forEach((it) => {
|
|
79
|
-
const lineItem = lineMap.get(it.line);
|
|
80
|
-
if (!lineItem) {
|
|
81
|
-
// not found line, could be comment or blank line
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (lineItem.ignored) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
it.count = count;
|
|
89
|
-
|
|
90
|
-
// default is covered, so only focus on
|
|
91
|
-
// 1, biggest covered count
|
|
92
|
-
// 2, uncovered entire and pieces
|
|
93
|
-
if (count > 0) {
|
|
94
|
-
lineItem.coveredCount = Math.max(lineItem.coveredCount, count);
|
|
95
|
-
} else {
|
|
96
|
-
if (it.entire) {
|
|
97
|
-
lineItem.uncoveredEntire = it;
|
|
98
|
-
} else {
|
|
99
|
-
lineItem.uncoveredPieces.push(it);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
77
|
+
Util.updateLinesCoverage(lines, count, lineMap);
|
|
103
78
|
|
|
104
79
|
});
|
|
105
80
|
|
|
@@ -414,6 +389,13 @@ const checkOriginalRangeCode = (range, state, startEndMap, type) => {
|
|
|
414
389
|
return false;
|
|
415
390
|
}
|
|
416
391
|
|
|
392
|
+
// do not check text for `bytes`
|
|
393
|
+
// it could be `} ` uncovered in `try { } catch`
|
|
394
|
+
// instead, use `dedupeCountRanges` to accumulate count
|
|
395
|
+
if (type === 'bytes') {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
|
|
417
399
|
// invalid original code
|
|
418
400
|
// Matches any character that is not a word character from the basic Latin alphabet.
|
|
419
401
|
// Equivalent to [^A-Za-z0-9_]
|
|
@@ -425,12 +407,6 @@ const checkOriginalRangeCode = (range, state, startEndMap, type) => {
|
|
|
425
407
|
|
|
426
408
|
// type: bytes, functions, branches, statements
|
|
427
409
|
|
|
428
|
-
// do not check repeated range for `bytes`
|
|
429
|
-
// instead, use `dedupeCountRanges` to accumulate count
|
|
430
|
-
if (type === 'bytes') {
|
|
431
|
-
return true;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
410
|
// check repeated range
|
|
435
411
|
const key = `${start}_${end}`;
|
|
436
412
|
if (startEndMap.has(key)) {
|
|
@@ -1237,6 +1213,84 @@ const filterCoverageList = (item) => {
|
|
|
1237
1213
|
return coverageList;
|
|
1238
1214
|
};
|
|
1239
1215
|
|
|
1216
|
+
const initJsCoverageList = (item) => {
|
|
1217
|
+
const coverageList = filterCoverageList(item);
|
|
1218
|
+
|
|
1219
|
+
// function could be covered even it is defined after an uncovered return, see case closures.js
|
|
1220
|
+
// fix uncovered range if there are covered ranges in uncovered range
|
|
1221
|
+
|
|
1222
|
+
const uncoveredBlocks = [];
|
|
1223
|
+
const uncoveredList = [];
|
|
1224
|
+
coverageList.forEach((block) => {
|
|
1225
|
+
block.ranges.forEach((range, i) => {
|
|
1226
|
+
const {
|
|
1227
|
+
count, startOffset, endOffset
|
|
1228
|
+
} = range;
|
|
1229
|
+
|
|
1230
|
+
if (i === 0) {
|
|
1231
|
+
// check only first level
|
|
1232
|
+
if (count > 0) {
|
|
1233
|
+
const inUncoveredRange = Util.findInRanges(startOffset, endOffset, uncoveredBlocks, 'startOffset', 'endOffset');
|
|
1234
|
+
if (inUncoveredRange) {
|
|
1235
|
+
if (!inUncoveredRange.coveredList) {
|
|
1236
|
+
inUncoveredRange.coveredList = [];
|
|
1237
|
+
uncoveredList.push(inUncoveredRange);
|
|
1238
|
+
}
|
|
1239
|
+
inUncoveredRange.coveredList.push(range);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
if (count === 0) {
|
|
1244
|
+
uncoveredBlocks.push({
|
|
1245
|
+
... range,
|
|
1246
|
+
index: i,
|
|
1247
|
+
ranges: block.ranges
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
});
|
|
1253
|
+
|
|
1254
|
+
if (uncoveredList.length) {
|
|
1255
|
+
|
|
1256
|
+
uncoveredList.forEach((it) => {
|
|
1257
|
+
const {
|
|
1258
|
+
ranges, index, count, coveredList
|
|
1259
|
+
} = it;
|
|
1260
|
+
|
|
1261
|
+
// remove previous range first
|
|
1262
|
+
const args = [index, 1];
|
|
1263
|
+
|
|
1264
|
+
Util.sortOffsetRanges(coveredList);
|
|
1265
|
+
let startOffset = it.startOffset;
|
|
1266
|
+
coveredList.forEach((cov) => {
|
|
1267
|
+
// ignore sub functions in the function
|
|
1268
|
+
if (cov.startOffset > startOffset) {
|
|
1269
|
+
args.push({
|
|
1270
|
+
startOffset,
|
|
1271
|
+
endOffset: cov.startOffset,
|
|
1272
|
+
count
|
|
1273
|
+
});
|
|
1274
|
+
startOffset = cov.endOffset;
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
if (it.endOffset > startOffset) {
|
|
1279
|
+
args.push({
|
|
1280
|
+
startOffset,
|
|
1281
|
+
endOffset: it.endOffset,
|
|
1282
|
+
count
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
ranges.splice.apply(ranges, args);
|
|
1287
|
+
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
return coverageList;
|
|
1292
|
+
};
|
|
1293
|
+
|
|
1240
1294
|
// ========================================================================================================
|
|
1241
1295
|
|
|
1242
1296
|
const isCoveredInRanges = (range, uncoveredBytes) => {
|
|
@@ -1464,7 +1518,7 @@ const convertV8List = (v8list, options) => {
|
|
|
1464
1518
|
let coverageList = [];
|
|
1465
1519
|
let astInfo;
|
|
1466
1520
|
if (js) {
|
|
1467
|
-
coverageList =
|
|
1521
|
+
coverageList = initJsCoverageList(item);
|
|
1468
1522
|
// remove original functions
|
|
1469
1523
|
if (!Util.isDebug()) {
|
|
1470
1524
|
delete item.functions;
|
package/lib/index.d.ts
CHANGED
|
@@ -128,7 +128,7 @@ declare namespace MCR {
|
|
|
128
128
|
path: string;
|
|
129
129
|
type: "v8" | "istanbul";
|
|
130
130
|
data: any;
|
|
131
|
-
}
|
|
131
|
+
};
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
export interface MetricsSummary {
|
|
@@ -204,12 +204,13 @@ declare namespace MCR {
|
|
|
204
204
|
watermarks: Watermarks;
|
|
205
205
|
summary: CoverageSummary;
|
|
206
206
|
files: CoverageFile[];
|
|
207
|
-
}
|
|
207
|
+
};
|
|
208
208
|
|
|
209
|
+
export type LoggingType = "off" | "error" | "info" | "debug";
|
|
209
210
|
export interface CoverageReportOptions {
|
|
210
211
|
|
|
211
212
|
/** {string} logging levels: off, error, info, debug */
|
|
212
|
-
logging?:
|
|
213
|
+
logging?: LoggingType;
|
|
213
214
|
|
|
214
215
|
/** {string} Report name. Defaults to "Coverage Report". */
|
|
215
216
|
name?: string;
|
|
@@ -222,7 +223,7 @@ declare namespace MCR {
|
|
|
222
223
|
*
|
|
223
224
|
* By default, `v8` for V8 data, `html` for Istanbul data
|
|
224
225
|
*/
|
|
225
|
-
reports?: string | string
|
|
226
|
+
reports?: string | (string | ReportDescription)[];
|
|
226
227
|
|
|
227
228
|
/** {string} output dir */
|
|
228
229
|
outputDir?: string;
|
|
@@ -328,7 +329,7 @@ declare namespace MCR {
|
|
|
328
329
|
onEntry?: (entry: V8CoverageEntry) => Promise<void>;
|
|
329
330
|
|
|
330
331
|
/** {function} onEnd hook */
|
|
331
|
-
onEnd?: (coverageResults: CoverageResults) => Promise<void>;
|
|
332
|
+
onEnd?: (coverageResults: CoverageResults | undefined) => Promise<void>;
|
|
332
333
|
|
|
333
334
|
[key: string]: any;
|
|
334
335
|
}
|
|
@@ -356,7 +357,7 @@ declare namespace MCR {
|
|
|
356
357
|
/** add coverage data
|
|
357
358
|
*
|
|
358
359
|
* @param coverageData {array} V8 format, {object} Istanbul format */
|
|
359
|
-
add: (coverageData: any[] | any) => Promise<AddedResults>;
|
|
360
|
+
add: (coverageData: any[] | any) => Promise<AddedResults | undefined>;
|
|
360
361
|
|
|
361
362
|
/**
|
|
362
363
|
* add V8 coverage from a dir
|
|
@@ -365,7 +366,7 @@ declare namespace MCR {
|
|
|
365
366
|
addFromDir: (dir: string) => Promise<void>;
|
|
366
367
|
|
|
367
368
|
/** generate report */
|
|
368
|
-
generate: () => Promise<CoverageResults>;
|
|
369
|
+
generate: () => Promise<CoverageResults | undefined>;
|
|
369
370
|
|
|
370
371
|
/** check if cache exists */
|
|
371
372
|
hasCache: () => boolean;
|
|
@@ -494,6 +495,10 @@ declare namespace MCR {
|
|
|
494
495
|
|
|
495
496
|
export function CDPClient(cdpOptions: CDPOptions): Promise<CoverageClient | undefined>;
|
|
496
497
|
|
|
498
|
+
export const Util: {
|
|
499
|
+
initLoggingLevel: (logging: LoggingType) => string;
|
|
500
|
+
};
|
|
501
|
+
|
|
497
502
|
}
|
|
498
503
|
|
|
499
504
|
/** create coverage report */
|
package/lib/index.js
CHANGED
package/lib/index.mjs
CHANGED