monocart-coverage-reports 2.2.1 → 2.2.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 +2 -0
- package/lib/cli.js +1 -1
- package/lib/converter/converter.js +13 -0
- package/lib/generate.js +34 -39
- package/lib/index.d.ts +3 -0
- package/lib/istanbul/istanbul.js +3 -3
- package/lib/v8/v8.js +98 -23
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -64,6 +64,8 @@ console.log(coverageResults.summary);
|
|
|
64
64
|
|
|
65
65
|
- `v8-json` (V8 data only)
|
|
66
66
|
- [V8 coverage-report.json](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/coverage-report.json)
|
|
67
|
+
- `codecov` (V8 data only)
|
|
68
|
+
- coverage data for [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format), see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports)
|
|
67
69
|
- `console-summary` shows coverage summary in console
|
|
68
70
|
|
|
69
71
|

|
package/lib/cli.js
CHANGED
|
@@ -313,9 +313,21 @@ const collectFileCoverage = (item, state, coverageData, options) => {
|
|
|
313
313
|
b: {}
|
|
314
314
|
};
|
|
315
315
|
|
|
316
|
+
// for codecov https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
317
|
+
data.lines = {};
|
|
318
|
+
|
|
316
319
|
lines.filter((it) => !it.ignored).forEach((line, index) => {
|
|
317
320
|
istanbulCoverage.statementMap[`${index}`] = line.generate();
|
|
318
321
|
istanbulCoverage.s[`${index}`] = line.count;
|
|
322
|
+
|
|
323
|
+
let count = 0;
|
|
324
|
+
if (line.covered) {
|
|
325
|
+
count = line.count;
|
|
326
|
+
} else if (!line.covered && line.count > 0) {
|
|
327
|
+
count = '1/2';
|
|
328
|
+
}
|
|
329
|
+
// 1-base
|
|
330
|
+
data.lines[`${line.line}`] = count;
|
|
319
331
|
});
|
|
320
332
|
|
|
321
333
|
functions.filter((it) => !it.ignored).forEach((fn, index) => {
|
|
@@ -987,6 +999,7 @@ const convertV8List = async (v8list, options) => {
|
|
|
987
999
|
if (sourceList.length) {
|
|
988
1000
|
sourceList.forEach((item) => {
|
|
989
1001
|
|
|
1002
|
+
// second time filter for empty source
|
|
990
1003
|
// exists same id, mark previous item as dedupe
|
|
991
1004
|
const prevItem = v8list.find((it) => it.id === item.id);
|
|
992
1005
|
if (prevItem) {
|
package/lib/generate.js
CHANGED
|
@@ -67,59 +67,50 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
67
67
|
reportMap[defaultReport] = {};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const allSupportedReports =
|
|
70
|
+
const allSupportedReports = {
|
|
71
71
|
|
|
72
72
|
// v8
|
|
73
|
-
'v8',
|
|
74
|
-
'v8-json',
|
|
73
|
+
'v8': 'v8',
|
|
74
|
+
'v8-json': 'v8',
|
|
75
|
+
'codecov': 'v8',
|
|
75
76
|
|
|
76
77
|
// both
|
|
77
|
-
'console-summary',
|
|
78
|
+
'console-summary': 'both',
|
|
78
79
|
|
|
79
80
|
// istanbul
|
|
80
|
-
'clover',
|
|
81
|
-
'cobertura',
|
|
82
|
-
'html',
|
|
83
|
-
'html-spa',
|
|
84
|
-
'json',
|
|
85
|
-
'json-summary',
|
|
86
|
-
'lcov',
|
|
87
|
-
'lcovonly',
|
|
88
|
-
'none',
|
|
89
|
-
'teamcity',
|
|
90
|
-
'text',
|
|
91
|
-
'text-lcov',
|
|
92
|
-
'text-summary'
|
|
93
|
-
|
|
81
|
+
'clover': 'istanbul',
|
|
82
|
+
'cobertura': 'istanbul',
|
|
83
|
+
'html': 'istanbul',
|
|
84
|
+
'html-spa': 'istanbul',
|
|
85
|
+
'json': 'istanbul',
|
|
86
|
+
'json-summary': 'istanbul',
|
|
87
|
+
'lcov': 'istanbul',
|
|
88
|
+
'lcovonly': 'istanbul',
|
|
89
|
+
'none': 'istanbul',
|
|
90
|
+
'teamcity': 'istanbul',
|
|
91
|
+
'text': 'istanbul',
|
|
92
|
+
'text-lcov': 'istanbul',
|
|
93
|
+
'text-summary': 'istanbul'
|
|
94
|
+
};
|
|
94
95
|
|
|
95
96
|
// group v8 and istanbul
|
|
96
97
|
const reportGroup = {};
|
|
97
98
|
Object.keys(reportMap).forEach((k) => {
|
|
98
|
-
if (!allSupportedReports.includes(k)) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
if (!reportGroup.v8) {
|
|
106
|
-
reportGroup.v8 = {};
|
|
107
|
-
}
|
|
108
|
-
reportGroup.v8[k] = reportMap[k];
|
|
100
|
+
const groupName = allSupportedReports[k];
|
|
101
|
+
if (!groupName) {
|
|
102
|
+
Util.logError(`Unsupported report: ${k}`);
|
|
109
103
|
return;
|
|
110
104
|
}
|
|
111
105
|
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
106
|
+
let group = reportGroup[groupName];
|
|
107
|
+
if (!group) {
|
|
108
|
+
group = {};
|
|
109
|
+
reportGroup[groupName] = group;
|
|
116
110
|
}
|
|
117
111
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
reportGroup.istanbul = {};
|
|
121
|
-
}
|
|
122
|
-
reportGroup.istanbul[k] = reportMap[k];
|
|
112
|
+
group[k] = reportMap[k];
|
|
113
|
+
|
|
123
114
|
});
|
|
124
115
|
|
|
125
116
|
return reportGroup;
|
|
@@ -156,8 +147,12 @@ const nFormatter = (v) => {
|
|
|
156
147
|
|
|
157
148
|
const showConsoleSummary = (coverageResults, options) => {
|
|
158
149
|
|
|
159
|
-
const
|
|
160
|
-
|
|
150
|
+
const bothGroup = options.reportGroup.both;
|
|
151
|
+
if (!bothGroup) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const consoleOptions = bothGroup['console-summary'];
|
|
161
156
|
if (!consoleOptions) {
|
|
162
157
|
return;
|
|
163
158
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -34,6 +34,9 @@ declare namespace MCR {
|
|
|
34
34
|
['v8-json'] | ["v8-json", {
|
|
35
35
|
outputFile?: string;
|
|
36
36
|
}] |
|
|
37
|
+
['codecov'] | ["codecov", {
|
|
38
|
+
outputFile?: string;
|
|
39
|
+
}] |
|
|
37
40
|
['console-summary'] | ['console-summary', {
|
|
38
41
|
metrics?: Array<"bytes" | "functions" | "branches" | "lines" | "statements">;
|
|
39
42
|
}] |
|
package/lib/istanbul/istanbul.js
CHANGED
|
@@ -87,9 +87,9 @@ const saveIstanbulReports = (coverageData, fileSources, options) => {
|
|
|
87
87
|
// create a context for report generation
|
|
88
88
|
const context = istanbulLibReport.createContext(contextOptions);
|
|
89
89
|
|
|
90
|
-
const
|
|
91
|
-
Object.keys(
|
|
92
|
-
const report = istanbulReports.create(reportName,
|
|
90
|
+
const istanbulGroup = options.reportGroup.istanbul;
|
|
91
|
+
Object.keys(istanbulGroup).forEach((reportName) => {
|
|
92
|
+
const report = istanbulReports.create(reportName, istanbulGroup[reportName]);
|
|
93
93
|
report.execute(context);
|
|
94
94
|
});
|
|
95
95
|
|
package/lib/v8/v8.js
CHANGED
|
@@ -21,9 +21,18 @@ const initV8ListAndSourcemap = async (v8list, options) => {
|
|
|
21
21
|
|
|
22
22
|
v8list = v8list.filter((item) => {
|
|
23
23
|
if (typeof item.source === 'string' && item.functions) {
|
|
24
|
+
item.type = 'js';
|
|
24
25
|
return true;
|
|
25
26
|
}
|
|
26
27
|
if (typeof item.text === 'string' && item.ranges) {
|
|
28
|
+
item.type = 'css';
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
// allow empty coverage
|
|
32
|
+
if (item.empty) {
|
|
33
|
+
if (!['js', 'css'].includes(item.type)) {
|
|
34
|
+
item.type = 'js';
|
|
35
|
+
}
|
|
27
36
|
return true;
|
|
28
37
|
}
|
|
29
38
|
// 404 css, text will be empty
|
|
@@ -39,22 +48,30 @@ const initV8ListAndSourcemap = async (v8list, options) => {
|
|
|
39
48
|
// init id, sourcePath
|
|
40
49
|
v8list = v8list.map((item, i) => {
|
|
41
50
|
|
|
51
|
+
const type = item.type;
|
|
52
|
+
|
|
42
53
|
const data = {
|
|
43
|
-
url: item.url
|
|
54
|
+
url: item.url,
|
|
55
|
+
type
|
|
44
56
|
};
|
|
45
57
|
|
|
46
|
-
if (
|
|
47
|
-
data.type = 'js';
|
|
58
|
+
if (type === 'js') {
|
|
48
59
|
data.functions = item.functions;
|
|
49
60
|
data.source = item.source;
|
|
50
61
|
// could be existed
|
|
51
62
|
data.sourceMap = item.sourceMap;
|
|
52
|
-
} else
|
|
53
|
-
|
|
63
|
+
} else {
|
|
64
|
+
// css
|
|
54
65
|
data.ranges = item.ranges;
|
|
55
66
|
data.source = item.text;
|
|
56
67
|
}
|
|
57
68
|
|
|
69
|
+
|
|
70
|
+
// no functions and ranges
|
|
71
|
+
if (item.empty) {
|
|
72
|
+
data.empty = true;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
const idList = [];
|
|
59
76
|
// could be existed
|
|
60
77
|
const distFile = item.distFile;
|
|
@@ -122,17 +139,17 @@ const mergeJsFunctions = (itemList) => {
|
|
|
122
139
|
|
|
123
140
|
const mergeV8Coverage = async (dataList, options) => {
|
|
124
141
|
|
|
125
|
-
let
|
|
142
|
+
let allList = [];
|
|
126
143
|
dataList.forEach((d) => {
|
|
127
|
-
|
|
144
|
+
allList = allList.concat(d.data);
|
|
128
145
|
});
|
|
129
146
|
|
|
130
|
-
|
|
147
|
+
const coverageList = allList.filter((it) => !it.empty);
|
|
131
148
|
|
|
132
149
|
// connect all functions and ranges
|
|
133
150
|
const itemMap = {};
|
|
134
151
|
const mergeMap = {};
|
|
135
|
-
|
|
152
|
+
coverageList.forEach((item) => {
|
|
136
153
|
const { id } = item;
|
|
137
154
|
const prev = itemMap[id];
|
|
138
155
|
if (prev) {
|
|
@@ -158,11 +175,17 @@ const mergeV8Coverage = async (dataList, options) => {
|
|
|
158
175
|
}
|
|
159
176
|
}
|
|
160
177
|
|
|
161
|
-
|
|
178
|
+
// first time filter for empty, (not for sources)
|
|
179
|
+
const emptyList = allList.filter((it) => it.empty).filter((it) => !itemMap[it.id]);
|
|
180
|
+
|
|
181
|
+
// empty list + merged list
|
|
182
|
+
const mergedList = emptyList.concat(Object.values(itemMap));
|
|
162
183
|
|
|
163
184
|
// try to load coverage and source by id
|
|
164
|
-
for (const item of
|
|
165
|
-
const {
|
|
185
|
+
for (const item of mergedList) {
|
|
186
|
+
const {
|
|
187
|
+
id, type, empty
|
|
188
|
+
} = item;
|
|
166
189
|
const sourcePath = Util.resolveCacheSourcePath(options.cacheDir, id);
|
|
167
190
|
const content = await Util.readFile(sourcePath);
|
|
168
191
|
if (content) {
|
|
@@ -173,24 +196,63 @@ const mergeV8Coverage = async (dataList, options) => {
|
|
|
173
196
|
Util.logError(`failed to read source: ${item.url}`);
|
|
174
197
|
item.source = '';
|
|
175
198
|
}
|
|
199
|
+
|
|
200
|
+
// add empty coverage after merged
|
|
201
|
+
if (empty) {
|
|
202
|
+
if (type === 'js') {
|
|
203
|
+
item.functions = [{
|
|
204
|
+
functionName: '',
|
|
205
|
+
ranges: [{
|
|
206
|
+
startOffset: 0,
|
|
207
|
+
endOffset: item.source.length,
|
|
208
|
+
count: 0
|
|
209
|
+
}]
|
|
210
|
+
}];
|
|
211
|
+
} else {
|
|
212
|
+
// empty css
|
|
213
|
+
item.ranges = [];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
176
217
|
}
|
|
177
218
|
|
|
178
|
-
return
|
|
219
|
+
return mergedList;
|
|
179
220
|
};
|
|
180
221
|
|
|
181
222
|
// ============================================================
|
|
182
223
|
|
|
224
|
+
const saveCodecovReport = async (reportData, options, codecovOptions) => {
|
|
225
|
+
const mergedOptions = {
|
|
226
|
+
outputFile: 'codecov.json',
|
|
227
|
+
... codecovOptions
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// console.log(mergedOptions);
|
|
231
|
+
const jsonPath = path.resolve(options.outputDir, mergedOptions.outputFile);
|
|
232
|
+
|
|
233
|
+
// https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
234
|
+
const coverage = {};
|
|
235
|
+
reportData.files.forEach((item) => {
|
|
236
|
+
const { sourcePath, data } = item;
|
|
237
|
+
coverage[sourcePath] = data.lines;
|
|
238
|
+
});
|
|
239
|
+
const codecovData = {
|
|
240
|
+
coverage
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
await Util.writeFile(jsonPath, JSON.stringify(codecovData));
|
|
244
|
+
return Util.relativePath(jsonPath);
|
|
245
|
+
};
|
|
246
|
+
|
|
183
247
|
const saveV8JsonReport = async (reportData, options, v8JsonOptions) => {
|
|
184
|
-
const
|
|
248
|
+
const mergedOptions = {
|
|
185
249
|
outputFile: 'coverage-report.json',
|
|
186
250
|
... v8JsonOptions
|
|
187
251
|
};
|
|
188
252
|
|
|
189
|
-
// console.log(
|
|
190
|
-
const jsonPath = path.resolve(options.outputDir,
|
|
191
|
-
// console.log(reportPath);
|
|
253
|
+
// console.log(mergedOptions);
|
|
254
|
+
const jsonPath = path.resolve(options.outputDir, mergedOptions.outputFile);
|
|
192
255
|
await Util.writeFile(jsonPath, JSON.stringify(reportData));
|
|
193
|
-
|
|
194
256
|
return Util.relativePath(jsonPath);
|
|
195
257
|
};
|
|
196
258
|
|
|
@@ -255,10 +317,10 @@ const saveV8Report = async (v8list, options) => {
|
|
|
255
317
|
let outputPath;
|
|
256
318
|
|
|
257
319
|
// v8 reports
|
|
258
|
-
const
|
|
320
|
+
const v8Group = options.reportGroup.v8;
|
|
259
321
|
|
|
260
322
|
// v8 html
|
|
261
|
-
const v8Options =
|
|
323
|
+
const v8Options = v8Group.v8;
|
|
262
324
|
if (v8Options) {
|
|
263
325
|
|
|
264
326
|
// V8 only options, merged with root options
|
|
@@ -276,12 +338,25 @@ const saveV8Report = async (v8list, options) => {
|
|
|
276
338
|
outputPath = await saveV8HtmlReport(reportData, options, v8HtmlOptions);
|
|
277
339
|
}
|
|
278
340
|
|
|
279
|
-
// v8 json
|
|
280
|
-
const v8JsonOptions =
|
|
341
|
+
// v8 json (after html for metrics data)
|
|
342
|
+
const v8JsonOptions = v8Group['v8-json'];
|
|
281
343
|
if (v8JsonOptions) {
|
|
282
|
-
|
|
344
|
+
const jsonPath = await saveV8JsonReport(reportData, options, v8JsonOptions);
|
|
345
|
+
if (!outputPath) {
|
|
346
|
+
outputPath = jsonPath;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// codecov
|
|
351
|
+
const codecovOptions = v8Group.codecov;
|
|
352
|
+
if (codecovOptions) {
|
|
353
|
+
const jsonPath = await saveCodecovReport(reportData, options, codecovOptions);
|
|
354
|
+
if (!outputPath) {
|
|
355
|
+
outputPath = jsonPath;
|
|
356
|
+
}
|
|
283
357
|
}
|
|
284
358
|
|
|
359
|
+
// outputPath last one is html
|
|
285
360
|
const reportPath = Util.resolveReportPath(options, () => {
|
|
286
361
|
return outputPath;
|
|
287
362
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-coverage-reports",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Monocart coverage reports",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"test-node-cdp": "node --inspect=9229 ./test/test-node-cdp.js",
|
|
29
29
|
"test-node-koa": "node ./test/test-node-koa.js",
|
|
30
30
|
"test-browser": "node ./test/test.js",
|
|
31
|
-
"test-cli": "npx mcr \"node ./test/test-node-env.js\" -o docs/cli -
|
|
31
|
+
"test-cli": "npx mcr \"node ./test/test-node-env.js\" -o docs/cli -c test/cli-options.js",
|
|
32
32
|
"test": "npm run test-browser && npm run test-node && npm run test-cli && npm run build-docs",
|
|
33
33
|
"dev": "sf d v8",
|
|
34
34
|
"open": "node ./scripts/open.js",
|