monocart-coverage-reports 2.13.2 → 3.1.0
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 +314 -116
- package/README.zh-Hans.md +315 -117
- package/lib/assets.js +6 -6
- package/lib/cli.js +191 -95
- package/lib/client/cdp-client.js +74 -43
- package/lib/client/coverage-client.js +24 -8
- package/lib/client/ws-session.js +115 -37
- package/lib/converter/ast-visitor.js +5 -7
- package/lib/converter/ast.js +29 -8
- package/lib/converter/collect-source-maps.js +42 -21
- package/lib/converter/converter.js +124 -129
- package/lib/converter/css-coverage.js +76 -0
- package/lib/converter/fake-source-coverage.js +64 -0
- package/lib/converter/find-original-range.js +214 -6
- package/lib/converter/flatten-source-maps.js +2 -4
- package/lib/converter/ignore.js +2 -4
- package/lib/converter/info-branch.js +5 -3
- package/lib/converter/info-function.js +5 -3
- package/lib/converter/info-statement.js +5 -3
- package/lib/converter/range-index.js +78 -0
- package/lib/converter/source-range-merge.js +103 -0
- package/lib/converter/untested.js +30 -60
- package/lib/default/options.js +13 -1
- package/lib/generate.js +44 -26
- package/lib/index.d.ts +52 -4
- package/lib/index.js +35 -41
- package/lib/istanbul/istanbul-summary.js +2 -2
- package/lib/istanbul/istanbul.js +35 -13
- package/lib/packages/monocart-coverage-assets.js +4 -3
- package/lib/packages/monocart-coverage-converter.js +27 -0
- package/lib/packages/monocart-coverage-vendor.js +2 -41
- package/lib/packages/monocart-coverage-vendor.js.LICENSE +3 -221
- package/lib/platform/concurrency.js +47 -43
- package/lib/platform/share.js +8 -1
- package/lib/register/hooks.js +19 -13
- package/lib/register/register.js +5 -3
- package/lib/reports/codacy.js +3 -5
- package/lib/reports/codecov.js +3 -5
- package/lib/reports/console-details.js +5 -5
- package/lib/reports/console-summary.js +4 -4
- package/lib/reports/custom.js +8 -24
- package/lib/reports/markdown-details.js +4 -6
- package/lib/reports/markdown-summary.js +4 -6
- package/lib/reports/raw.js +10 -12
- package/lib/reports/v8-json.js +3 -5
- package/lib/reports/v8.js +3 -5
- package/lib/utils/dedupe.js +1 -1
- package/lib/utils/gc.js +30 -14
- package/lib/utils/markdown.js +2 -2
- package/lib/utils/merge/merge.js +2 -4
- package/lib/utils/merge/range-tree.js +1 -1
- package/lib/utils/request.js +85 -73
- package/lib/utils/snapshot.js +4 -4
- package/lib/utils/source-path.js +26 -11
- package/lib/utils/util.js +67 -42
- package/lib/v8/v8-summary.js +2 -4
- package/lib/v8/v8.js +11 -11
- package/migrate-to-3.md +175 -0
- package/package.json +54 -42
- package/skills/monocart-coverage-reports/SKILL.md +106 -0
- package/skills/monocart-coverage-reports/references/best-practices.md +218 -0
- package/skills/monocart-coverage-reports/references/cli.md +108 -0
- package/skills/monocart-coverage-reports/references/collection.md +154 -0
- package/skills/monocart-coverage-reports/references/filtering-and-sourcemaps.md +170 -0
- package/skills/monocart-coverage-reports/references/reports-and-ci.md +219 -0
- package/skills/monocart-coverage-reports/references/repository-map.md +59 -0
- package/lib/index.mjs +0 -9
- package/lib/register/hooks.mjs +0 -3
- package/lib/register/register.mjs +0 -3
package/lib/default/options.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const defaultOptions = {
|
|
2
2
|
|
|
3
3
|
// {string} logging levels: off, error, info, debug
|
|
4
4
|
logging: 'info',
|
|
@@ -24,6 +24,12 @@ module.exports = {
|
|
|
24
24
|
// {string|string[]} input raw dir(s)
|
|
25
25
|
inputDir: null,
|
|
26
26
|
|
|
27
|
+
// (mcr test only) {string|string[]|null} Test file paths or glob patterns accepted by node --test.
|
|
28
|
+
// A string is one positional argument; an array supplies multiple arguments unchanged.
|
|
29
|
+
// Used when no CLI targets are supplied; null skips tests and is not passed to Node.
|
|
30
|
+
// Ignored by other CLI commands and the API.
|
|
31
|
+
test: null,
|
|
32
|
+
|
|
27
33
|
// {string} base dir for normalizing the relative source path, defaults to cwd
|
|
28
34
|
baseDir: null,
|
|
29
35
|
|
|
@@ -43,6 +49,10 @@ module.exports = {
|
|
|
43
49
|
// sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1,
|
|
44
50
|
sourceFilter: null,
|
|
45
51
|
|
|
52
|
+
// (V8 only) Filter final files by sourcePath after sourcemap conversion and adding untested files.
|
|
53
|
+
// outputFilter: (entry) => entry.sourcePath.startsWith('src/'),
|
|
54
|
+
outputFilter: null,
|
|
55
|
+
|
|
46
56
|
// The combined filter for entryFilter and sourceFilter
|
|
47
57
|
filter: null,
|
|
48
58
|
|
|
@@ -105,3 +115,5 @@ module.exports = {
|
|
|
105
115
|
// onEnd: async (reportData) => {}
|
|
106
116
|
onEnd: null
|
|
107
117
|
};
|
|
118
|
+
|
|
119
|
+
export { defaultOptions };
|
package/lib/generate.js
CHANGED
|
@@ -1,35 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import EC from 'eight-colors';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { resolveSourceMap } = require('./converter/collect-source-maps.js');
|
|
9
|
-
const { StreamZip } = require('./packages/monocart-coverage-vendor.js');
|
|
6
|
+
import { Util } from './utils/util.js';
|
|
7
|
+
import { resolveSourceMap } from './converter/collect-source-maps.js';
|
|
10
8
|
|
|
11
9
|
// ========================================================================================================
|
|
12
10
|
// built-in reports
|
|
13
11
|
|
|
14
|
-
// istanbul
|
|
15
|
-
const { mergeIstanbulCoverage, saveIstanbulReports } = require('./istanbul/istanbul.js');
|
|
16
|
-
|
|
17
12
|
// v8
|
|
18
|
-
|
|
13
|
+
import { mergeV8Coverage, saveV8Report } from './v8/v8.js';
|
|
19
14
|
|
|
20
15
|
// both
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const { consoleDetailsReport } = require('./reports/console-details.js');
|
|
25
|
-
const { consoleSummaryReport } = require('./reports/console-summary.js');
|
|
16
|
+
import { codecovReport } from './reports/codecov.js';
|
|
17
|
+
import { codacyReport } from './reports/codacy.js';
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
import { consoleDetailsReport } from './reports/console-details.js';
|
|
20
|
+
import { consoleSummaryReport } from './reports/console-summary.js';
|
|
29
21
|
|
|
30
|
-
|
|
22
|
+
import { markdownDetailsReport } from './reports/markdown-details.js';
|
|
23
|
+
import { markdownSummaryReport } from './reports/markdown-summary.js';
|
|
31
24
|
|
|
32
|
-
|
|
25
|
+
import { customReport } from './reports/custom.js';
|
|
33
26
|
|
|
34
27
|
const allBuiltInReports = {
|
|
35
28
|
// v8
|
|
@@ -71,7 +64,10 @@ const bothBuiltInReports = {
|
|
|
71
64
|
'markdown-details': markdownDetailsReport,
|
|
72
65
|
'markdown-summary': markdownSummaryReport,
|
|
73
66
|
|
|
74
|
-
'raw':
|
|
67
|
+
'raw': async (... args) => {
|
|
68
|
+
const { rawReport } = await import('./reports/raw.js');
|
|
69
|
+
return rawReport(... args);
|
|
70
|
+
}
|
|
75
71
|
};
|
|
76
72
|
|
|
77
73
|
// ========================================================================================================
|
|
@@ -146,6 +142,7 @@ const generateV8ListReports = async (v8list, coverageData, fileSources, options)
|
|
|
146
142
|
let istanbulReportPath;
|
|
147
143
|
// v8 to istanbul reports
|
|
148
144
|
if (options.reportGroup.has('istanbul')) {
|
|
145
|
+
const { saveIstanbulReports } = await import('./istanbul/istanbul.js');
|
|
149
146
|
const istanbulCoverageResults = await saveIstanbulReports(coverageData, fileSources, options);
|
|
150
147
|
istanbulReportPath = istanbulCoverageResults.reportPath;
|
|
151
148
|
}
|
|
@@ -175,17 +172,34 @@ const getCoverageResults = async (dataList, sourceCache, options) => {
|
|
|
175
172
|
// console.log('after merge', v8list.map((it) => it.url));
|
|
176
173
|
|
|
177
174
|
const t2 = Date.now();
|
|
178
|
-
const
|
|
175
|
+
const { convertV8List } = await import('./converter/converter.js');
|
|
176
|
+
const results = await convertV8List(v8list, options, options.reportGroup.has('istanbul'));
|
|
179
177
|
Util.logTime(`${EC.magenta('├')} [generate] converted coverage data`, t2);
|
|
180
178
|
|
|
181
179
|
const {
|
|
182
180
|
v8DataList, coverageData, fileSources
|
|
183
181
|
} = results;
|
|
184
|
-
|
|
182
|
+
|
|
183
|
+
let filteredV8DataList = v8DataList;
|
|
184
|
+
if (options.outputFilter) {
|
|
185
|
+
const outputFilter = Util.createFilterHandler(options.outputFilter, (entry) => entry.sourcePath);
|
|
186
|
+
filteredV8DataList = v8DataList.filter(outputFilter);
|
|
187
|
+
// Keep V8 and converted Istanbul reports in sync.
|
|
188
|
+
const sourcePaths = new Set(filteredV8DataList.map((entry) => entry.sourcePath));
|
|
189
|
+
Object.keys(coverageData).forEach((sourcePath) => {
|
|
190
|
+
if (!sourcePaths.has(sourcePath)) {
|
|
191
|
+
delete coverageData[sourcePath];
|
|
192
|
+
delete fileSources[sourcePath];
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return generateV8ListReports(filteredV8DataList, coverageData, fileSources, options);
|
|
185
198
|
}
|
|
186
199
|
|
|
187
200
|
// istanbul data
|
|
188
201
|
const t3 = Date.now();
|
|
202
|
+
const { mergeIstanbulCoverage, saveIstanbulReports } = await import('./istanbul/istanbul.js');
|
|
189
203
|
const istanbulData = await mergeIstanbulCoverage(dataList, options);
|
|
190
204
|
Util.logTime(`${EC.magenta('├')} [generate] prepared istanbul coverage data`, t3);
|
|
191
205
|
const fileSources = options.fileSources || {};
|
|
@@ -277,6 +291,8 @@ const addDirData = async (mcr, dataList, sourceCache, dir) => {
|
|
|
277
291
|
};
|
|
278
292
|
|
|
279
293
|
const addZipData = async (mcr, dataList, sourceCache, dir) => {
|
|
294
|
+
const { default: StreamZipModule } = await import('node-stream-zip');
|
|
295
|
+
const StreamZip = StreamZipModule.async;
|
|
280
296
|
const zip = new StreamZip({
|
|
281
297
|
file: dir
|
|
282
298
|
});
|
|
@@ -327,7 +343,9 @@ const getInputData = async (mcr) => {
|
|
|
327
343
|
return;
|
|
328
344
|
}
|
|
329
345
|
// No coverage input: use V8 so `all` can add untested files.
|
|
330
|
-
dataList.push({
|
|
346
|
+
dataList.push({
|
|
347
|
+
type: 'v8', data: []
|
|
348
|
+
});
|
|
331
349
|
}
|
|
332
350
|
|
|
333
351
|
return {
|
|
@@ -491,7 +509,7 @@ const readFromDir = async (mcr, dir) => {
|
|
|
491
509
|
|
|
492
510
|
};
|
|
493
511
|
|
|
494
|
-
|
|
512
|
+
export {
|
|
495
513
|
getInputData,
|
|
496
514
|
readFromDir,
|
|
497
515
|
generateCoverageReports
|
package/lib/index.d.ts
CHANGED
|
@@ -322,6 +322,14 @@ declare namespace MCR {
|
|
|
322
322
|
[pattern: string]: boolean;
|
|
323
323
|
} | ((sourcePath: string) => boolean);
|
|
324
324
|
|
|
325
|
+
/** (V8 only) Filter final files after sourcemap conversion and adding untested files.
|
|
326
|
+
* Applies to V8 reports and converted Istanbul reports. Defaults to null (disabled).
|
|
327
|
+
* Strings and object keys match sourcePath using the same rules as entryFilter and sourceFilter.
|
|
328
|
+
*/
|
|
329
|
+
outputFilter?: string | {
|
|
330
|
+
[pattern: string]: boolean;
|
|
331
|
+
} | ((entry: CoverageFile) => boolean) | null;
|
|
332
|
+
|
|
325
333
|
/**
|
|
326
334
|
* The combined filter for entryFilter and sourceFilter
|
|
327
335
|
*/
|
|
@@ -405,7 +413,7 @@ declare namespace MCR {
|
|
|
405
413
|
cleanCache?: boolean;
|
|
406
414
|
|
|
407
415
|
/**
|
|
408
|
-
* {number}
|
|
416
|
+
* {number} JavaScript heapUsed threshold in MB
|
|
409
417
|
* for example: sets gc to 1024 means that force gc when the memory > 1024M at certain critical stages
|
|
410
418
|
* https://nodejs.org/docs/latest/api/v8.html#v8setflagsfromstringflags
|
|
411
419
|
*/
|
|
@@ -432,6 +440,15 @@ declare namespace MCR {
|
|
|
432
440
|
|
|
433
441
|
export interface McrCliOptions extends CoverageReportOptions {
|
|
434
442
|
|
|
443
|
+
/** Only used by `mcr test`. Test file paths or glob patterns accepted by node --test.
|
|
444
|
+
* A string is one positional argument; an array supplies multiple arguments unchanged.
|
|
445
|
+
* Node handles parsing and discovery relative to cwd; null is not passed to Node.
|
|
446
|
+
* Positional CLI targets override this option.
|
|
447
|
+
* Defaults to null (skip tests unless CLI targets are supplied).
|
|
448
|
+
* Requires Node.js >= 22.15.0. Ignored by other commands and the API.
|
|
449
|
+
*/
|
|
450
|
+
test?: string | string[] | null;
|
|
451
|
+
|
|
435
452
|
/** (CLI only) {function} onStart hook */
|
|
436
453
|
onStart?: (coverageReport: CoverageReport) => void | Promise<void>;
|
|
437
454
|
|
|
@@ -479,6 +496,8 @@ declare namespace MCR {
|
|
|
479
496
|
/** load config file.
|
|
480
497
|
*
|
|
481
498
|
* @param configFile custom config file path
|
|
499
|
+
* Throws if a custom config is missing or a discovered config fails to load.
|
|
500
|
+
* If no custom config is specified and no default config is found, returns normally.
|
|
482
501
|
*
|
|
483
502
|
* Supports loading default config file if no custom config specified:
|
|
484
503
|
'mcr.config.js',
|
|
@@ -532,6 +551,9 @@ declare namespace MCR {
|
|
|
532
551
|
//=====================================================================================================
|
|
533
552
|
|
|
534
553
|
export class CoverageClient {
|
|
554
|
+
/** Best-effort command: logs failures at debug level and resolves to null instead of rejecting. */
|
|
555
|
+
safeSend: (method: string, params?: any) => Promise<any>;
|
|
556
|
+
|
|
535
557
|
/** start js coverage */
|
|
536
558
|
startJSCoverage: () => Promise<void>;
|
|
537
559
|
/** stop and return js coverage */
|
|
@@ -567,7 +589,8 @@ declare namespace MCR {
|
|
|
567
589
|
|
|
568
590
|
/** custom websocket CDPSession */
|
|
569
591
|
export class WSSession implements CDPSession {
|
|
570
|
-
|
|
592
|
+
/** Request timeout defaults to 30000ms; 0 disables the deadline. */
|
|
593
|
+
constructor(ws: any, options?: { timeout?: number });
|
|
571
594
|
send: (method: string, params?: any) => Promise<any>;
|
|
572
595
|
on: (type: string, handler: (e: any) => void) => void;
|
|
573
596
|
detach: () => Promise<void>;
|
|
@@ -588,8 +611,10 @@ declare namespace MCR {
|
|
|
588
611
|
target?: (targets: any) => any;
|
|
589
612
|
/** websocket options */
|
|
590
613
|
ws?: any;
|
|
591
|
-
/** timeout, defaults to
|
|
614
|
+
/** HTTP discovery / WebSocket connection timeout, defaults to 10000ms; 0 disables it. */
|
|
592
615
|
timeout?: number;
|
|
616
|
+
/** Per-command timeout for built-in WebSocket sessions, defaults to 30000ms; 0 disables it. */
|
|
617
|
+
requestTimeout?: number;
|
|
593
618
|
}
|
|
594
619
|
|
|
595
620
|
export function CDPClient(cdpOptions: CDPOptions): Promise<CoverageClient | undefined>;
|
|
@@ -603,4 +628,27 @@ declare namespace MCR {
|
|
|
603
628
|
/** create coverage report */
|
|
604
629
|
declare function MCR(options?: MCR.CoverageReportOptions): MCR.CoverageReport;
|
|
605
630
|
|
|
606
|
-
export
|
|
631
|
+
export { MCR as default, MCR };
|
|
632
|
+
export import V8CoverageEntry = MCR.V8CoverageEntry;
|
|
633
|
+
export import Watermarks = MCR.Watermarks;
|
|
634
|
+
export import ReportDescription = MCR.ReportDescription;
|
|
635
|
+
export import AddedResults = MCR.AddedResults;
|
|
636
|
+
export import MetricsSummary = MCR.MetricsSummary;
|
|
637
|
+
export import CoverageSummary = MCR.CoverageSummary;
|
|
638
|
+
export import CoverageRange = MCR.CoverageRange;
|
|
639
|
+
export import IgnoredRange = MCR.IgnoredRange;
|
|
640
|
+
export import CoverageFile = MCR.CoverageFile;
|
|
641
|
+
export import CoverageResults = MCR.CoverageResults;
|
|
642
|
+
export import LoggingType = MCR.LoggingType;
|
|
643
|
+
export import CoverageReportOptions = MCR.CoverageReportOptions;
|
|
644
|
+
export import McrCliOptions = MCR.McrCliOptions;
|
|
645
|
+
export import CoverageSnapshot = MCR.CoverageSnapshot;
|
|
646
|
+
export import CoverageClient = MCR.CoverageClient;
|
|
647
|
+
export import CDPSession = MCR.CDPSession;
|
|
648
|
+
export import CDPOptions = MCR.CDPOptions;
|
|
649
|
+
export import CoverageReport = MCR.CoverageReport;
|
|
650
|
+
export import getSnapshot = MCR.getSnapshot;
|
|
651
|
+
export import diffSnapshot = MCR.diffSnapshot;
|
|
652
|
+
export import WSSession = MCR.WSSession;
|
|
653
|
+
export import CDPClient = MCR.CDPClient;
|
|
654
|
+
export import Util = MCR.Util;
|
package/lib/index.js
CHANGED
|
@@ -1,46 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import EC from 'eight-colors';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { defaultOptions } from './default/options.js';
|
|
7
|
+
import { Util } from './utils/util.js';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import { initV8ListAndSourcemap } from './v8/v8.js';
|
|
10
|
+
import {
|
|
11
11
|
getInputData, readFromDir, generateCoverageReports
|
|
12
|
-
}
|
|
13
|
-
|
|
12
|
+
} from './generate.js';
|
|
13
|
+
import { getSnapshot, diffSnapshot } from './utils/snapshot.js';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
import { WSSession } from './client/ws-session.js';
|
|
16
|
+
import { CDPClient } from './client/cdp-client.js';
|
|
17
|
+
import { CoverageClient } from './client/coverage-client.js';
|
|
17
18
|
|
|
18
19
|
const resolveConfigOptions = async (configPath) => {
|
|
19
|
-
// json format
|
|
20
|
-
const ext = path.extname(configPath);
|
|
21
|
-
if (ext === '.json' || configPath.slice(-2) === 'rc') {
|
|
22
|
-
return JSON.parse(Util.readFileSync(configPath));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
let configOptions;
|
|
26
|
-
let err;
|
|
27
20
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (err) {
|
|
34
|
-
Util.logError(`ERROR: failed to load config "${configPath}": ${err && err.message} `);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
21
|
+
// json format
|
|
22
|
+
const ext = path.extname(configPath);
|
|
23
|
+
if (ext === '.json' || configPath.slice(-2) === 'rc') {
|
|
24
|
+
return JSON.parse(Util.readFileSync(configPath));
|
|
25
|
+
}
|
|
37
26
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
configOptions
|
|
27
|
+
let configOptions = await import(pathToFileURL(configPath));
|
|
28
|
+
// could be multiple level default
|
|
29
|
+
while (configOptions && configOptions.default) {
|
|
30
|
+
configOptions = configOptions.default;
|
|
31
|
+
}
|
|
32
|
+
return configOptions;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
throw new Error(`Failed to load config file "${configPath}": ${message}`, {
|
|
36
|
+
cause: error
|
|
37
|
+
});
|
|
41
38
|
}
|
|
42
|
-
|
|
43
|
-
return configOptions;
|
|
44
39
|
};
|
|
45
40
|
|
|
46
41
|
class CoverageReport {
|
|
@@ -237,7 +232,7 @@ class CoverageReport {
|
|
|
237
232
|
const configPath = Util.findUpConfig(customConfigFile);
|
|
238
233
|
if (!configPath) {
|
|
239
234
|
if (customConfigFile) {
|
|
240
|
-
|
|
235
|
+
throw new Error(`The config file does not exist: ${customConfigFile}`);
|
|
241
236
|
}
|
|
242
237
|
// not found config
|
|
243
238
|
return;
|
|
@@ -245,11 +240,7 @@ class CoverageReport {
|
|
|
245
240
|
|
|
246
241
|
const configOptions = await resolveConfigOptions(configPath);
|
|
247
242
|
if (!configOptions) {
|
|
248
|
-
|
|
249
|
-
if (customConfigFile) {
|
|
250
|
-
Util.logError(`Failed to load config file: ${customConfigFile}`);
|
|
251
|
-
}
|
|
252
|
-
return;
|
|
243
|
+
throw new Error(`Failed to load config file: ${configPath}`);
|
|
253
244
|
}
|
|
254
245
|
|
|
255
246
|
Util.logInfo(`Loaded: ${EC.cyan(Util.relativePath(configPath))}`);
|
|
@@ -271,10 +262,13 @@ const MCR = function(options) {
|
|
|
271
262
|
return new CoverageReport(options);
|
|
272
263
|
};
|
|
273
264
|
MCR.CoverageReport = CoverageReport;
|
|
265
|
+
MCR.CoverageClient = CoverageClient;
|
|
274
266
|
MCR.getSnapshot = getSnapshot;
|
|
275
267
|
MCR.diffSnapshot = diffSnapshot;
|
|
276
268
|
MCR.WSSession = WSSession;
|
|
277
269
|
MCR.CDPClient = CDPClient;
|
|
278
270
|
MCR.Util = Util;
|
|
279
271
|
|
|
280
|
-
|
|
272
|
+
export {
|
|
273
|
+
MCR as default, MCR, CoverageReport, CoverageClient, getSnapshot, diffSnapshot, WSSession, CDPClient, Util
|
|
274
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import istanbulLibReport from 'istanbul-lib-report';
|
|
2
2
|
|
|
3
3
|
const ReportBase = istanbulLibReport.ReportBase;
|
|
4
4
|
class IstanbulSummary extends ReportBase {
|
|
@@ -70,4 +70,4 @@ class IstanbulSummary extends ReportBase {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
export { IstanbulSummary };
|
package/lib/istanbul/istanbul.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import istanbulLibCoverage from 'istanbul-lib-coverage';
|
|
5
|
+
import istanbulLibReport from 'istanbul-lib-report';
|
|
6
|
+
import EC from 'eight-colors';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import { Util } from '../utils/util.js';
|
|
9
|
+
import { IstanbulSummary } from './istanbul-summary.js';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
import { initIstanbulSourcePath } from '../utils/source-path.js';
|
|
12
|
+
import { getUntestedList } from '../converter/untested.js';
|
|
13
13
|
|
|
14
14
|
const findHtmlPath = (outputDir) => {
|
|
15
15
|
const defaultHtml = path.resolve(outputDir, 'index.html');
|
|
@@ -35,7 +35,29 @@ const findHtmlPath = (outputDir) => {
|
|
|
35
35
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const createIstanbulReport = async (name, options) => {
|
|
39
|
+
let reporter;
|
|
40
|
+
const isFile = path.isAbsolute(name) || name.startsWith('.');
|
|
41
|
+
// Built-in reports remain CommonJS dependencies; custom reports may be ESM.
|
|
42
|
+
if (!isFile) {
|
|
43
|
+
try {
|
|
44
|
+
reporter = await import(`istanbul-reports/lib/${name}/index.js`);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!reporter) {
|
|
52
|
+
// Native import() also handles CJS reporters without a separate loader.
|
|
53
|
+
const specifier = isFile ? pathToFileURL(path.resolve(name)).href : name;
|
|
54
|
+
reporter = await import(specifier);
|
|
55
|
+
}
|
|
56
|
+
const Reporter = reporter.default || reporter;
|
|
57
|
+
return new Reporter(options);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const saveIstanbulReports = async (coverageData, fileSources, options) => {
|
|
39
61
|
|
|
40
62
|
coverageData = initIstanbulSourcePath(coverageData, fileSources, options);
|
|
41
63
|
|
|
@@ -96,7 +118,7 @@ const saveIstanbulReports = (coverageData, fileSources, options) => {
|
|
|
96
118
|
if (istanbulGroup) {
|
|
97
119
|
for (const [reportName, reportOptions] of istanbulGroup) {
|
|
98
120
|
const t1 = Date.now();
|
|
99
|
-
const report =
|
|
121
|
+
const report = await createIstanbulReport(reportName, reportOptions);
|
|
100
122
|
report.execute(context);
|
|
101
123
|
Util.logTime(`${EC.magenta('├')} [generate] saved report: ${reportName}`, t1);
|
|
102
124
|
}
|
|
@@ -163,7 +185,7 @@ const mergeIstanbulCoverage = async (dataList, options) => {
|
|
|
163
185
|
return istanbulData;
|
|
164
186
|
};
|
|
165
187
|
|
|
166
|
-
|
|
188
|
+
export {
|
|
167
189
|
saveIstanbulReports,
|
|
168
190
|
mergeIstanbulDataList,
|
|
169
191
|
mergeIstanbulCoverage
|