monocart-coverage-reports 2.6.0 → 2.6.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 +11 -7
- package/lib/cli.js +76 -39
- package/lib/converter/collect-source-maps.js +1 -1
- package/lib/generate.js +12 -11
- package/lib/index.js +7 -3
- package/lib/v8/v8.js +14 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
- [Vitest](#vitest)
|
|
40
40
|
- [CodeceptJS](#codeceptjs)
|
|
41
41
|
- [WebdriverIO](#webdriverio)
|
|
42
|
+
- [Storybook Test Runner](#storybook-test-runner)
|
|
42
43
|
- [Codecov](#codecov)
|
|
43
44
|
- [Coveralls](#coveralls)
|
|
44
45
|
- [Sonar Cloud](#sonar-cloud)
|
|
@@ -257,15 +258,15 @@ const coverageOptions = {
|
|
|
257
258
|
|
|
258
259
|
## `mcr` CLI
|
|
259
260
|
> The CLI will run the program as a [child process](https://nodejs.org/docs/latest/api/child_process.html) with `NODE_V8_COVERAGE=dir` until it exits gracefully, and generate the coverage report with the coverage data from the `dir`.
|
|
260
|
-
-
|
|
261
|
+
- Installing globally
|
|
261
262
|
```sh
|
|
262
263
|
npm i monocart-coverage-reports -g
|
|
263
|
-
mcr
|
|
264
|
+
mcr node ./test/test-node-env.js -r v8,console-summary --lcov
|
|
264
265
|
```
|
|
265
|
-
-
|
|
266
|
+
- Locally in your project
|
|
266
267
|
```sh
|
|
267
268
|
npm i monocart-coverage-reports
|
|
268
|
-
npx mcr
|
|
269
|
+
npx mcr node ./test/test-node-env.js -r v8,console-summary --lcov
|
|
269
270
|
```
|
|
270
271
|
- CLI Options
|
|
271
272
|
```sh
|
|
@@ -292,15 +293,15 @@ Options:
|
|
|
292
293
|
--logging <logging> off, error, info, debug
|
|
293
294
|
-h, --help display help for command
|
|
294
295
|
```
|
|
295
|
-
-
|
|
296
|
+
- Loading default configuration file
|
|
296
297
|
- `.mcrrc`
|
|
297
298
|
- `mcr.config.json`
|
|
298
299
|
- `mcr.config.mjs`
|
|
299
300
|
- `mcr.config.cjs`
|
|
300
301
|
- `mcr.config.js`
|
|
301
|
-
-
|
|
302
|
+
- Or loading custom configuration file with `-c` or `--config`
|
|
302
303
|
```sh
|
|
303
|
-
mcr
|
|
304
|
+
mcr node ./test.js -c path-to/my-custom-config.js
|
|
304
305
|
```
|
|
305
306
|
|
|
306
307
|
## Compare Reports
|
|
@@ -723,6 +724,9 @@ When `logging` is `debug`, the raw report data will be preserved in `[outputDir]
|
|
|
723
724
|
### [WebdriverIO](https://github.com/webdriverio/webdriverio)
|
|
724
725
|
- [wdio-monocart-service](https://github.com/cenfun/wdio-monocart-service) - A WebdriverIO service for coverage reports
|
|
725
726
|
|
|
727
|
+
### [Storybook Test Runner](https://github.com/storybookjs/test-runner)
|
|
728
|
+
- [storybook-monocart-coverage](https://github.com/cenfun/storybook-monocart-coverage) - Storybook V8 Coverage Example
|
|
729
|
+
|
|
726
730
|
### [Codecov](https://codecov.com/)
|
|
727
731
|
[](https://codecov.io/gh/cenfun/monocart-coverage-reports)
|
|
728
732
|
- Supports native `codecov` built-in report ([specification](https://docs.codecov.com/docs/codecov-custom-coverage-format))
|
package/lib/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const EC = require('eight-colors');
|
|
6
6
|
const { fileURLToPath, pathToFileURL } = require('url');
|
|
7
|
+
|
|
7
8
|
const {
|
|
8
9
|
foregroundChild,
|
|
9
10
|
program
|
|
@@ -98,6 +99,71 @@ const initOptions = async (cliOptions) => {
|
|
|
98
99
|
return options;
|
|
99
100
|
};
|
|
100
101
|
|
|
102
|
+
const resolveEntrySource = (entry, sourceMapCache = {}) => {
|
|
103
|
+
let source;
|
|
104
|
+
const filePath = fileURLToPath(entry.url);
|
|
105
|
+
const extname = path.extname(filePath);
|
|
106
|
+
if (fs.existsSync(filePath)) {
|
|
107
|
+
source = fs.readFileSync(filePath).toString('utf8');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// not for typescript
|
|
111
|
+
if (source && !['.ts', '.tsx'].includes(extname)) {
|
|
112
|
+
entry.source = source;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const sourcemapData = sourceMapCache[entry.url];
|
|
117
|
+
const lineLengths = sourcemapData && sourcemapData.lineLengths;
|
|
118
|
+
|
|
119
|
+
// for fake source file (can not parse to AST)
|
|
120
|
+
if (lineLengths) {
|
|
121
|
+
// get runtime code with ts-node
|
|
122
|
+
let fakeSource = '';
|
|
123
|
+
sourcemapData.lineLengths.forEach((length) => {
|
|
124
|
+
fakeSource += `${''.padEnd(length, '*')}\n`;
|
|
125
|
+
});
|
|
126
|
+
entry.fake = true;
|
|
127
|
+
entry.source = fakeSource;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Note: no runtime code in source map cache
|
|
131
|
+
// This is a problem for typescript
|
|
132
|
+
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const resolveEntrySourceMap = (entry, sourceMapCache = {}) => {
|
|
136
|
+
// sourcemap data
|
|
137
|
+
const sourcemapData = sourceMapCache[entry.url];
|
|
138
|
+
if (sourcemapData) {
|
|
139
|
+
if (sourcemapData.data) {
|
|
140
|
+
entry.sourceMap = resolveSourceMap(sourcemapData.data, entry.url);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const collectCoverageData = (coverageList, entryFilterHandler, sourceMapCache = {}) => {
|
|
146
|
+
|
|
147
|
+
if (!Util.isList(coverageList)) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// filter node internal files
|
|
152
|
+
coverageList = coverageList.filter((entry) => entry.url && entry.url.startsWith('file:'));
|
|
153
|
+
coverageList = coverageList.filter(entryFilterHandler);
|
|
154
|
+
|
|
155
|
+
if (!Util.isList(coverageList)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
for (const entry of coverageList) {
|
|
160
|
+
resolveEntrySource(entry, sourceMapCache);
|
|
161
|
+
resolveEntrySourceMap(entry, sourceMapCache);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return coverageList;
|
|
165
|
+
};
|
|
166
|
+
|
|
101
167
|
const executeCommand = async (command, cliOptions) => {
|
|
102
168
|
|
|
103
169
|
const options = await initOptions(cliOptions);
|
|
@@ -130,49 +196,18 @@ const executeCommand = async (command, cliOptions) => {
|
|
|
130
196
|
return 1;
|
|
131
197
|
}
|
|
132
198
|
|
|
199
|
+
const entryFilterHandler = coverageReport.getEntryFilter();
|
|
200
|
+
|
|
133
201
|
const files = fs.readdirSync(nodeV8CoverageDir);
|
|
134
202
|
for (const filename of files) {
|
|
135
203
|
const content = fs.readFileSync(path.resolve(nodeV8CoverageDir, filename)).toString('utf-8');
|
|
136
204
|
const json = JSON.parse(content);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// filter node internal files
|
|
143
|
-
coverageList = coverageList.filter((entry) => entry.url && entry.url.startsWith('file:'));
|
|
144
|
-
|
|
145
|
-
if (!coverageList.length) {
|
|
146
|
-
continue;
|
|
205
|
+
const coverageList = json.result;
|
|
206
|
+
const sourceMapCache = json['source-map-cache'];
|
|
207
|
+
const coverageData = await collectCoverageData(coverageList, entryFilterHandler, sourceMapCache);
|
|
208
|
+
if (coverageData) {
|
|
209
|
+
await coverageReport.add(coverageData);
|
|
147
210
|
}
|
|
148
|
-
// attached source content
|
|
149
|
-
coverageList.forEach((entry) => {
|
|
150
|
-
// source content
|
|
151
|
-
const filePath = fileURLToPath(entry.url);
|
|
152
|
-
if (fs.existsSync(filePath)) {
|
|
153
|
-
entry.source = fs.readFileSync(filePath).toString('utf8');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// sourcemap data
|
|
157
|
-
const sourcemapData = sourceMapCache[entry.url];
|
|
158
|
-
if (sourcemapData) {
|
|
159
|
-
if (sourcemapData.data) {
|
|
160
|
-
entry.sourceMap = resolveSourceMap(sourcemapData.data, entry.url);
|
|
161
|
-
}
|
|
162
|
-
// sourcemapData.lineLengths just for fake source file (can not parse to AST)
|
|
163
|
-
if (!entry.source && sourcemapData.lineLengths) {
|
|
164
|
-
// get runtime code with ts-node
|
|
165
|
-
let source = '';
|
|
166
|
-
sourcemapData.lineLengths.forEach((length) => {
|
|
167
|
-
source += `${''.padEnd(length, '*')}\n`;
|
|
168
|
-
});
|
|
169
|
-
entry.fake = true;
|
|
170
|
-
entry.source = source;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
await coverageReport.add(coverageList);
|
|
176
211
|
}
|
|
177
212
|
|
|
178
213
|
await coverageReport.generate();
|
|
@@ -192,6 +227,7 @@ program
|
|
|
192
227
|
.description('CLI to generate coverage reports')
|
|
193
228
|
.version(version)
|
|
194
229
|
.argument('<command>', 'command to execute')
|
|
230
|
+
.allowUnknownOption()
|
|
195
231
|
.option('-c, --config <path>', 'custom config path')
|
|
196
232
|
.option('-o, --outputDir <dir>', 'output dir for reports')
|
|
197
233
|
.option('-r, --reports <name[,name]>', 'coverage reports to use')
|
|
@@ -209,7 +245,8 @@ program
|
|
|
209
245
|
|
|
210
246
|
.option('--logging <logging>', 'off, error, info, debug')
|
|
211
247
|
|
|
212
|
-
.action((
|
|
248
|
+
.action((_command, cliOptions) => {
|
|
249
|
+
const command = program.args.join(' ');
|
|
213
250
|
executeCommand(command, cliOptions);
|
|
214
251
|
});
|
|
215
252
|
|
package/lib/generate.js
CHANGED
|
@@ -21,21 +21,22 @@ const { getGroupedRows } = require('./utils/snapshot.js');
|
|
|
21
21
|
// maybe v8 or to istanbul reports
|
|
22
22
|
const generateV8ListReports = async (v8list, coverageData, fileSources, options) => {
|
|
23
23
|
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// generate istanbul reports first
|
|
29
|
-
if (istanbul) {
|
|
30
|
-
report = await saveIstanbulReports(coverageData, fileSources, options);
|
|
24
|
+
let istanbulCoverageResults;
|
|
25
|
+
// v8 to istanbul reports
|
|
26
|
+
if (options.reportGroup.istanbul) {
|
|
27
|
+
istanbulCoverageResults = await saveIstanbulReports(coverageData, fileSources, options);
|
|
31
28
|
}
|
|
32
29
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
// v8 reports and v8 coverage results
|
|
31
|
+
// could be no v8 or v8-json, but requires v8 coverage results
|
|
32
|
+
const v8CoverageResults = await saveV8Report(v8list, options);
|
|
33
|
+
|
|
34
|
+
// fix reportPath
|
|
35
|
+
if (!v8CoverageResults.reportPath && istanbulCoverageResults) {
|
|
36
|
+
v8CoverageResults.reportPath = istanbulCoverageResults.reportPath;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
return
|
|
39
|
+
return v8CoverageResults;
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
// ========================================================================================================
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const defaultOptions = require('./default/options.js');
|
|
4
4
|
const Util = require('./utils/util.js');
|
|
5
5
|
|
|
6
|
-
const { initV8ListAndSourcemap } = require('./v8/v8.js');
|
|
6
|
+
const { initV8ListAndSourcemap, getEntryFilter } = require('./v8/v8.js');
|
|
7
7
|
const { getInputData, generateCoverageReports } = require('./generate.js');
|
|
8
8
|
const { getSnapshot, diffSnapshot } = require('./utils/snapshot.js');
|
|
9
9
|
|
|
@@ -63,12 +63,12 @@ class CoverageReport {
|
|
|
63
63
|
const dataPath = path.resolve(this.options.cacheDir, dataName);
|
|
64
64
|
|
|
65
65
|
const results = {
|
|
66
|
-
id: dataId
|
|
67
|
-
path: dataPath
|
|
66
|
+
id: dataId
|
|
68
67
|
};
|
|
69
68
|
|
|
70
69
|
if (Array.isArray(data)) {
|
|
71
70
|
results.type = 'v8';
|
|
71
|
+
// could be empty list after entryFilter
|
|
72
72
|
results.data = await initV8ListAndSourcemap(data, this.options);
|
|
73
73
|
} else {
|
|
74
74
|
results.type = 'istanbul';
|
|
@@ -170,6 +170,10 @@ class CoverageReport {
|
|
|
170
170
|
return false;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
getEntryFilter() {
|
|
174
|
+
return getEntryFilter(this.options);
|
|
175
|
+
}
|
|
176
|
+
|
|
173
177
|
}
|
|
174
178
|
|
|
175
179
|
/** create coverage report */
|
package/lib/v8/v8.js
CHANGED
|
@@ -356,7 +356,7 @@ const saveV8Report = async (v8list, options) => {
|
|
|
356
356
|
files: v8list
|
|
357
357
|
};
|
|
358
358
|
|
|
359
|
-
// v8 reports
|
|
359
|
+
// v8 only reports
|
|
360
360
|
const buildInV8Reports = {
|
|
361
361
|
'v8': handleV8HtmlReport,
|
|
362
362
|
'v8-json': handleV8JsonReport
|
|
@@ -364,14 +364,17 @@ const saveV8Report = async (v8list, options) => {
|
|
|
364
364
|
|
|
365
365
|
const outputs = {};
|
|
366
366
|
const v8Group = options.reportGroup.v8;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
const
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
367
|
+
// could be no v8 only reports, but have `both` data reports
|
|
368
|
+
if (v8Group) {
|
|
369
|
+
const v8Reports = Object.keys(v8Group);
|
|
370
|
+
for (const reportName of v8Reports) {
|
|
371
|
+
const reportOptions = v8Group[reportName];
|
|
372
|
+
const buildInHandler = buildInV8Reports[reportName];
|
|
373
|
+
if (buildInHandler) {
|
|
374
|
+
outputs[reportName] = await buildInHandler(reportData, reportOptions, options);
|
|
375
|
+
} else {
|
|
376
|
+
outputs[reportName] = await Util.runCustomReporter(reportName, reportData, reportOptions, options);
|
|
377
|
+
}
|
|
375
378
|
}
|
|
376
379
|
}
|
|
377
380
|
|
|
@@ -395,5 +398,6 @@ const saveV8Report = async (v8list, options) => {
|
|
|
395
398
|
module.exports = {
|
|
396
399
|
initV8ListAndSourcemap,
|
|
397
400
|
mergeV8Coverage,
|
|
398
|
-
saveV8Report
|
|
401
|
+
saveV8Report,
|
|
402
|
+
getEntryFilter
|
|
399
403
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-coverage-reports",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"description": "Monocart coverage reports",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"test-browser": "node ./test/test-browser.js && npm run test-istanbul && npm run test-v8 && npm run test-puppeteer && npm run test-anonymous && npm run test-css",
|
|
35
35
|
"test-anonymous": "node ./test/test-anonymous.js",
|
|
36
36
|
"test-css": "node ./test/test-css.js",
|
|
37
|
-
"test-cli": "npx mcr
|
|
37
|
+
"test-cli": "npx mcr node ./test/test-node-env.js -o docs/cli -c test/cli-options.js",
|
|
38
38
|
"test-merge": "node ./test/test-merge.js",
|
|
39
39
|
"test-merge-istanbul": "node ./test/test-merge-istanbul.js",
|
|
40
40
|
"test-all": "npm run test-browser && npm run test-node && npm run test-cli && npm run test-merge && npm run build-docs",
|
|
41
|
-
"test": "npx mcr
|
|
41
|
+
"test": "npx mcr npm run test-all -c test/mcr-options.js",
|
|
42
42
|
"test:snap": "cross-env TEST_SNAPSHOT=true npm run test",
|
|
43
43
|
"dev": "sf d v8",
|
|
44
44
|
"open": "node ./scripts/open.js",
|