monocart-coverage-reports 2.9.0 → 2.9.2
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 +16 -1
- package/README.zh-Hans.md +16 -1
- package/lib/cli.js +2 -4
- package/lib/converter/ast.js +3 -3
- package/lib/converter/collect-source-maps.js +51 -9
- package/lib/converter/converter.js +9 -3
- package/lib/converter/find-original-range.js +2 -2
- package/lib/converter/flatten-source-maps.js +166 -0
- package/lib/generate.js +1 -1
- package/lib/packages/monocart-coverage-app.js +1 -1
- package/lib/packages/monocart-coverage-vendor.js +23 -37
- package/lib/utils/source-path.js +2 -0
- package/lib/utils/util.js +3 -3
- package/lib/v8/v8.js +3 -1
- package/package.json +112 -104
- package/lib/packages/monocart-coverage-cli.js +0 -43
package/README.md
CHANGED
|
@@ -585,6 +585,20 @@ const coverageOptions = {
|
|
|
585
585
|
}
|
|
586
586
|
};
|
|
587
587
|
```
|
|
588
|
+
Normalize the full path of the file:
|
|
589
|
+
```js
|
|
590
|
+
const path = require("path")
|
|
591
|
+
|
|
592
|
+
// MCR coverage options
|
|
593
|
+
const coverageOptions = {
|
|
594
|
+
sourcePath: (filePath, info)=> {
|
|
595
|
+
if (!filePath.includes('/') && info.distFile) {
|
|
596
|
+
return `${path.dirname(info.distFile)}/${filePath}`;
|
|
597
|
+
}
|
|
598
|
+
return filePath;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
```
|
|
588
602
|
|
|
589
603
|
## Adding Empty Coverage for Untested Files
|
|
590
604
|
By default the untested files will not be included in the coverage report, we can add empty coverage data for all files with option `all`, the untested files will show 0% coverage.
|
|
@@ -1021,8 +1035,9 @@ const coverageOptions = {
|
|
|
1021
1035
|
- Github actions:
|
|
1022
1036
|
```yml
|
|
1023
1037
|
- name: Codecov
|
|
1024
|
-
uses: codecov/codecov-action@
|
|
1038
|
+
uses: codecov/codecov-action@v4
|
|
1025
1039
|
with:
|
|
1040
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
1026
1041
|
files: ./coverage-reports/codecov.json
|
|
1027
1042
|
```
|
|
1028
1043
|
|
package/README.zh-Hans.md
CHANGED
|
@@ -588,6 +588,20 @@ const coverageOptions = {
|
|
|
588
588
|
}
|
|
589
589
|
};
|
|
590
590
|
```
|
|
591
|
+
解决文件路径不完整的问题:
|
|
592
|
+
```js
|
|
593
|
+
const path = require("path")
|
|
594
|
+
|
|
595
|
+
// MCR coverage options
|
|
596
|
+
const coverageOptions = {
|
|
597
|
+
sourcePath: (filePath, info)=> {
|
|
598
|
+
if (!filePath.includes('/') && info.distFile) {
|
|
599
|
+
return `${path.dirname(info.distFile)}/${filePath}`;
|
|
600
|
+
}
|
|
601
|
+
return filePath;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
```
|
|
591
605
|
|
|
592
606
|
## Adding Empty Coverage for Untested Files
|
|
593
607
|
默认,未测试的文件是不会包含到覆盖率报告的,需要使用`all`选项来为这些文件添加一个空的覆盖率,也就是0%
|
|
@@ -1025,8 +1039,9 @@ const coverageOptions = {
|
|
|
1025
1039
|
- Github actions example:
|
|
1026
1040
|
```yml
|
|
1027
1041
|
- name: Codecov
|
|
1028
|
-
uses: codecov/codecov-action@
|
|
1042
|
+
uses: codecov/codecov-action@v4
|
|
1029
1043
|
with:
|
|
1044
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
1030
1045
|
files: ./coverage-reports/codecov.json
|
|
1031
1046
|
```
|
|
1032
1047
|
|
package/lib/cli.js
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const EC = require('eight-colors');
|
|
5
5
|
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
} = require('./packages/monocart-coverage-cli.js');
|
|
6
|
+
const { program } = require('commander');
|
|
7
|
+
const { foregroundChild } = require('foreground-child');
|
|
10
8
|
|
|
11
9
|
const MCR = require('./index.js');
|
|
12
10
|
const Util = require('./utils/util.js');
|
package/lib/converter/ast.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
} = require('../packages/monocart-coverage-vendor.js');
|
|
1
|
+
const acorn = require('acorn');
|
|
2
|
+
const acornLoose = require('acorn-loose');
|
|
3
|
+
const { parseCss } = require('../packages/monocart-coverage-vendor.js');
|
|
4
4
|
const Util = require('../utils/util.js');
|
|
5
5
|
|
|
6
6
|
const { collectAstInfo } = require('./ast-visitor.js');
|
|
@@ -4,6 +4,7 @@ const EC = require('eight-colors');
|
|
|
4
4
|
const { fileURLToPath, pathToFileURL } = require('url');
|
|
5
5
|
const Concurrency = require('../platform/concurrency.js');
|
|
6
6
|
const { convertSourceMap } = require('../packages/monocart-coverage-vendor.js');
|
|
7
|
+
const { flattenSourceMaps } = require('./flatten-source-maps.js');
|
|
7
8
|
|
|
8
9
|
const Util = require('../utils/util.js');
|
|
9
10
|
|
|
@@ -100,27 +101,68 @@ const resolveSourcesContent = (data, url) => {
|
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
103
|
|
|
104
|
+
const checkSourcesContent = (data) => {
|
|
105
|
+
const { sourcesContent, sources } = data;
|
|
106
|
+
|
|
107
|
+
if (!sourcesContent) {
|
|
108
|
+
data.sourcesContent = [];
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// all should be string, could be [null]
|
|
113
|
+
const contents = sourcesContent.filter((content) => typeof content === 'string');
|
|
114
|
+
if (contents.length === sources.length) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const resolveSectionedSourceMap = (data, url, sections) => {
|
|
122
|
+
|
|
123
|
+
let hasSourceContent = false;
|
|
124
|
+
sections.forEach((item) => {
|
|
125
|
+
// offset: { line: 1, column: 0 },
|
|
126
|
+
// map: { sources, sourcesContent }
|
|
127
|
+
|
|
128
|
+
const map = item.map;
|
|
129
|
+
|
|
130
|
+
if (checkSourcesContent(map)) {
|
|
131
|
+
hasSourceContent = true;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const done = resolveSourcesContent(map, url);
|
|
136
|
+
if (done) {
|
|
137
|
+
hasSourceContent = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (hasSourceContent) {
|
|
143
|
+
return flattenSourceMaps(data);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
103
147
|
const resolveSourceMap = (data, url) => {
|
|
104
148
|
if (!data) {
|
|
105
149
|
return;
|
|
106
150
|
}
|
|
107
151
|
const {
|
|
108
|
-
|
|
152
|
+
sections, sources, mappings
|
|
109
153
|
} = data;
|
|
110
154
|
|
|
155
|
+
if (sections) {
|
|
156
|
+
return resolveSectionedSourceMap(data, url, sections);
|
|
157
|
+
}
|
|
158
|
+
|
|
111
159
|
if (!sources || !mappings) {
|
|
112
160
|
return;
|
|
113
161
|
}
|
|
114
162
|
|
|
115
163
|
// check sources content
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
const contents = sourcesContent.filter((content) => typeof content === 'string');
|
|
119
|
-
if (contents.length === sources.length) {
|
|
120
|
-
return data;
|
|
121
|
-
}
|
|
122
|
-
} else {
|
|
123
|
-
data.sourcesContent = [];
|
|
164
|
+
if (checkSourcesContent(data)) {
|
|
165
|
+
return data;
|
|
124
166
|
}
|
|
125
167
|
|
|
126
168
|
// load sources content by sources
|
|
@@ -17,7 +17,9 @@ const {
|
|
|
17
17
|
sortRanges, dedupeCountRanges, mergeRangesWith
|
|
18
18
|
} = require('../utils/dedupe.js');
|
|
19
19
|
const { getSourceType, initSourceMapSourcesPath } = require('../utils/source-path.js');
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
const { decode } = require('@jridgewell/sourcemap-codec');
|
|
22
|
+
const { minimatch } = require('minimatch');
|
|
21
23
|
|
|
22
24
|
const InfoBranch = require('./info-branch.js');
|
|
23
25
|
const InfoFunction = require('./info-function.js');
|
|
@@ -839,9 +841,13 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
|
|
|
839
841
|
|
|
840
842
|
const generatedLocator = state.locator;
|
|
841
843
|
|
|
842
|
-
const {
|
|
844
|
+
const {
|
|
845
|
+
sources, mappings, decodedMappings
|
|
846
|
+
} = state.sourceMap;
|
|
847
|
+
|
|
848
|
+
const decodedList = decodedMappings || decode(mappings);
|
|
843
849
|
|
|
844
|
-
|
|
850
|
+
// console.log(decodedList);
|
|
845
851
|
|
|
846
852
|
sources.forEach((source, i) => {
|
|
847
853
|
originalDecodedMap.set(i, []);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const diffSequence = require('diff-sequences').default;
|
|
2
2
|
const Util = require('../utils/util.js');
|
|
3
3
|
const EC = Util.EC;
|
|
4
4
|
|
|
@@ -79,7 +79,7 @@ const alignText = (gt, ot, info) => {
|
|
|
79
79
|
// console.log(ol);
|
|
80
80
|
|
|
81
81
|
const commonItems = [];
|
|
82
|
-
|
|
82
|
+
diffSequence(gl.length, ol.length, (gi, oi) => {
|
|
83
83
|
return gl[gi].value === ol[oi].value;
|
|
84
84
|
}, (len, gi, oi) => {
|
|
85
85
|
commonItems.push([gi, oi, len]);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const { decode } = require('@jridgewell/sourcemap-codec');
|
|
2
|
+
|
|
3
|
+
function getLine(arr, index) {
|
|
4
|
+
for (let i = arr.length; i <= index; i++) {
|
|
5
|
+
arr[i] = [];
|
|
6
|
+
}
|
|
7
|
+
return arr[index];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function addMappings(options, sourcesOffset) {
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
input,
|
|
14
|
+
lineOffset,
|
|
15
|
+
columnOffset,
|
|
16
|
+
stopLine,
|
|
17
|
+
stopColumn
|
|
18
|
+
} = options;
|
|
19
|
+
|
|
20
|
+
const decoded = decode(input.mappings);
|
|
21
|
+
const COLUMN = 0;
|
|
22
|
+
const SOURCES_INDEX = 1;
|
|
23
|
+
const SOURCE_LINE = 2;
|
|
24
|
+
const SOURCE_COLUMN = 3;
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
27
|
+
const lineI = lineOffset + i;
|
|
28
|
+
|
|
29
|
+
if (lineI > stopLine) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const out = getLine(options.decodedMappings, lineI);
|
|
34
|
+
const cOffset = i === 0 ? columnOffset : 0;
|
|
35
|
+
|
|
36
|
+
const line = decoded[i];
|
|
37
|
+
for (let j = 0; j < line.length; j++) {
|
|
38
|
+
const seg = line[j];
|
|
39
|
+
const column = cOffset + seg[COLUMN];
|
|
40
|
+
|
|
41
|
+
if (lineI === stopLine && column >= stopColumn) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (seg.length === 1) {
|
|
46
|
+
out.push([column]);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX];
|
|
51
|
+
const sourceLine = seg[SOURCE_LINE];
|
|
52
|
+
const sourceColumn = seg[SOURCE_COLUMN];
|
|
53
|
+
out.push([column, sourcesIndex, sourceLine, sourceColumn]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function addSection(options) {
|
|
59
|
+
|
|
60
|
+
const { input } = options;
|
|
61
|
+
|
|
62
|
+
const { sections } = input;
|
|
63
|
+
if (sections) {
|
|
64
|
+
return flatten(options);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const sourcesOffset = options.sources.length;
|
|
68
|
+
|
|
69
|
+
if (!input.sourcesContent) {
|
|
70
|
+
input.sourcesContent = [];
|
|
71
|
+
}
|
|
72
|
+
input.sources.forEach((src, i) => {
|
|
73
|
+
options.sources.push(src);
|
|
74
|
+
options.sourcesContent.push(input.sourcesContent[i] || null);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
addMappings(options, sourcesOffset);
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function flatten(options) {
|
|
82
|
+
|
|
83
|
+
const {
|
|
84
|
+
input,
|
|
85
|
+
lineOffset,
|
|
86
|
+
columnOffset,
|
|
87
|
+
stopLine,
|
|
88
|
+
stopColumn
|
|
89
|
+
} = options;
|
|
90
|
+
|
|
91
|
+
const { sections } = input;
|
|
92
|
+
|
|
93
|
+
for (let i = 0, l = sections.length; i < l; i++) {
|
|
94
|
+
const { map, offset } = sections[i];
|
|
95
|
+
|
|
96
|
+
let sl = stopLine;
|
|
97
|
+
let sc = stopColumn;
|
|
98
|
+
if (i + 1 < sections.length) {
|
|
99
|
+
const nextOffset = sections[i + 1].offset;
|
|
100
|
+
sl = Math.min(stopLine, lineOffset + nextOffset.line);
|
|
101
|
+
|
|
102
|
+
if (sl === stopLine) {
|
|
103
|
+
sc = Math.min(stopColumn, columnOffset + nextOffset.column);
|
|
104
|
+
} else if (sl < stopLine) {
|
|
105
|
+
sc = columnOffset + nextOffset.column;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
options.input = map;
|
|
110
|
+
options.lineOffset = lineOffset + offset.line;
|
|
111
|
+
options.columnOffset = columnOffset + offset.column;
|
|
112
|
+
options.stopLine = sl;
|
|
113
|
+
options.stopColumn = sc;
|
|
114
|
+
|
|
115
|
+
addSection(options);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const flattenSourceMaps = function(indexedMap, mapUrl) {
|
|
120
|
+
|
|
121
|
+
const sections = indexedMap.sections;
|
|
122
|
+
if (!sections) {
|
|
123
|
+
return indexedMap;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const decodedMappings = [];
|
|
127
|
+
const sources = [];
|
|
128
|
+
const sourcesContent = [];
|
|
129
|
+
const names = [];
|
|
130
|
+
const ignoreList = [];
|
|
131
|
+
|
|
132
|
+
const lineOffset = 0;
|
|
133
|
+
const columnOffset = 0;
|
|
134
|
+
const stopLine = Infinity;
|
|
135
|
+
const stopColumn = Infinity;
|
|
136
|
+
|
|
137
|
+
flatten({
|
|
138
|
+
input: indexedMap,
|
|
139
|
+
|
|
140
|
+
mapUrl,
|
|
141
|
+
|
|
142
|
+
decodedMappings,
|
|
143
|
+
sources,
|
|
144
|
+
sourcesContent,
|
|
145
|
+
|
|
146
|
+
names,
|
|
147
|
+
ignoreList,
|
|
148
|
+
|
|
149
|
+
lineOffset,
|
|
150
|
+
columnOffset,
|
|
151
|
+
stopLine,
|
|
152
|
+
stopColumn
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
indexedMap.sources = sources;
|
|
156
|
+
indexedMap.sourcesContent = sourcesContent;
|
|
157
|
+
indexedMap.decodedMappings = decodedMappings;
|
|
158
|
+
|
|
159
|
+
// console.log(decodedMappings);
|
|
160
|
+
|
|
161
|
+
return indexedMap;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
module.exports = {
|
|
165
|
+
flattenSourceMaps
|
|
166
|
+
};
|
package/lib/generate.js
CHANGED
|
@@ -14,7 +14,7 @@ const { mergeV8Coverage, saveV8Report } = require('./v8/v8.js');
|
|
|
14
14
|
const { convertV8List } = require('./converter/converter.js');
|
|
15
15
|
const { resolveSourceMap } = require('./converter/collect-source-maps.js');
|
|
16
16
|
|
|
17
|
-
const { minimatch } = require('
|
|
17
|
+
const { minimatch } = require('minimatch');
|
|
18
18
|
const { getGroupedRows } = require('./utils/snapshot.js');
|
|
19
19
|
const generateMarkdownGrid = require('./utils/markdown.js');
|
|
20
20
|
|