@rpcbase/test 0.308.0 → 0.310.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/dist/clearDatabase.d.ts +2 -0
- package/dist/clearDatabase.d.ts.map +1 -0
- package/dist/clearDatabase.js +12 -0
- package/dist/clearDatabase.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +785 -0
- package/dist/cli.js.map +1 -0
- package/dist/coverage/collect.d.ts +5 -0
- package/dist/coverage/collect.d.ts.map +1 -0
- package/dist/coverage/collect.js +113 -0
- package/dist/coverage/collect.js.map +1 -0
- package/dist/coverage/config-loader.d.ts +11 -0
- package/dist/coverage/config-loader.d.ts.map +1 -0
- package/dist/coverage/config-loader.js +292 -0
- package/dist/coverage/config-loader.js.map +1 -0
- package/dist/coverage/config.d.ts +3 -0
- package/dist/coverage/config.d.ts.map +1 -0
- package/dist/coverage/config.js +110 -0
- package/dist/coverage/config.js.map +1 -0
- package/dist/coverage/files.d.ts +4 -0
- package/dist/coverage/files.d.ts.map +1 -0
- package/dist/coverage/files.js +52 -0
- package/dist/coverage/files.js.map +1 -0
- package/dist/coverage/fixtures.d.ts +5 -0
- package/dist/coverage/fixtures.d.ts.map +1 -0
- package/dist/coverage/fixtures.js +42 -0
- package/dist/coverage/fixtures.js.map +1 -0
- package/dist/coverage/global-setup.d.ts +3 -0
- package/dist/coverage/global-setup.d.ts.map +1 -0
- package/dist/coverage/global-setup.js +18 -0
- package/dist/coverage/global-setup.js.map +1 -0
- package/dist/coverage/index.d.ts +10 -0
- package/dist/coverage/index.d.ts.map +1 -0
- package/dist/coverage/index.js +62 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/coverage/report.d.ts +7 -0
- package/dist/coverage/report.d.ts.map +1 -0
- package/{src → dist}/coverage/report.js +262 -362
- package/dist/coverage/report.js.map +1 -0
- package/dist/coverage/reporter.d.ts +16 -0
- package/dist/coverage/reporter.d.ts.map +1 -0
- package/dist/coverage/reporter.js +57 -0
- package/dist/coverage/reporter.js.map +1 -0
- package/dist/coverage/types.d.ts +47 -0
- package/dist/coverage/types.d.ts.map +1 -0
- package/dist/coverage/v8-tracker.d.ts +6 -0
- package/dist/coverage/v8-tracker.d.ts.map +1 -0
- package/dist/coverage/v8-tracker.js +166 -0
- package/dist/coverage/v8-tracker.js.map +1 -0
- package/dist/defineConfig.d.ts +3 -0
- package/dist/defineConfig.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/serverCoverage.d.ts +8 -0
- package/dist/serverCoverage.d.ts.map +1 -0
- package/dist/serverCoverage.js +42 -0
- package/dist/serverCoverage.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +83 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +25 -14
- package/index.d.ts +0 -64
- package/src/clearDatabase.js +0 -19
- package/src/cli.js +0 -948
- package/src/coverage/collect.js +0 -134
- package/src/coverage/config-loader.js +0 -202
- package/src/coverage/config.js +0 -134
- package/src/coverage/files.js +0 -55
- package/src/coverage/fixtures.js +0 -37
- package/src/coverage/global-setup.js +0 -19
- package/src/coverage/index.js +0 -30
- package/src/coverage/reporter.js +0 -65
- package/src/coverage/v8-tracker.js +0 -205
- package/src/defineConfig.js +0 -129
- package/src/index.js +0 -49
- package/src/vitest.config.mjs +0 -107
- /package/{src → dist}/register-tty.cjs +0 -0
|
@@ -1,234 +1,212 @@
|
|
|
1
|
-
import fs from "node:fs/promises"
|
|
2
|
-
import path from "node:path"
|
|
3
|
-
import { fileURLToPath } from "node:url"
|
|
4
|
-
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { createCollectCoverageMatcher, toPosix } from "./collect.js"
|
|
14
|
-
import { findCoverageFiles } from "./files.js"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const TEXT_REPORT_FILENAME = "coverage.txt"
|
|
18
|
-
|
|
19
|
-
export class CoverageThresholdError extends Error {
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import * as libCoverage from "istanbul-lib-coverage";
|
|
5
|
+
import * as libInstrument from "istanbul-lib-instrument";
|
|
6
|
+
import fg from "fast-glob";
|
|
7
|
+
import picomatch from "picomatch";
|
|
8
|
+
import v8ToIstanbul from "v8-to-istanbul";
|
|
9
|
+
import { createCollectCoverageMatcher, toPosix } from "./collect.js";
|
|
10
|
+
import { findCoverageFiles } from "./files.js";
|
|
11
|
+
const TEXT_REPORT_FILENAME = "coverage.txt";
|
|
12
|
+
class CoverageThresholdError extends Error {
|
|
20
13
|
constructor(message) {
|
|
21
|
-
super(message)
|
|
22
|
-
this.name = "CoverageThresholdError"
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "CoverageThresholdError";
|
|
23
16
|
}
|
|
24
17
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const coverageFiles = await findCoverageFiles(config)
|
|
28
|
-
|
|
18
|
+
async function generateCoverageReport(config) {
|
|
19
|
+
const coverageFiles = await findCoverageFiles(config);
|
|
29
20
|
if (coverageFiles.length === 0) {
|
|
30
|
-
console.warn("[coverage] no V8 coverage artifacts were generated")
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)
|
|
37
|
-
|
|
21
|
+
console.warn("[coverage] no V8 coverage artifacts were generated");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const coverageLib = resolveCoverageLib();
|
|
25
|
+
const coverageMap = coverageLib.createCoverageMap({});
|
|
26
|
+
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir);
|
|
38
27
|
for (const file of coverageFiles) {
|
|
39
|
-
const payload = await readCoverageFile(file)
|
|
28
|
+
const payload = await readCoverageFile(file);
|
|
40
29
|
if (!payload) {
|
|
41
|
-
continue
|
|
30
|
+
continue;
|
|
42
31
|
}
|
|
43
|
-
|
|
44
32
|
for (const script of payload.scripts) {
|
|
45
|
-
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom)
|
|
33
|
+
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom);
|
|
46
34
|
}
|
|
47
35
|
}
|
|
48
|
-
|
|
49
36
|
if (config.includeAllFiles) {
|
|
50
|
-
await includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom)
|
|
37
|
+
await includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom);
|
|
51
38
|
}
|
|
52
|
-
|
|
53
39
|
if (coverageMap.files().length === 0) {
|
|
54
|
-
console.warn("[coverage] no library files matched the coverage filters")
|
|
55
|
-
return
|
|
40
|
+
console.warn("[coverage] no library files matched the coverage filters");
|
|
41
|
+
return;
|
|
56
42
|
}
|
|
57
|
-
|
|
58
|
-
await fs.
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
await fs.rm(config.coverageReportDir, { recursive: true, force: true });
|
|
44
|
+
await fs.mkdir(config.coverageReportDir, { recursive: true });
|
|
45
|
+
const { createContext, reports } = await loadIstanbulModules();
|
|
61
46
|
const context = createContext({
|
|
62
47
|
dir: config.coverageReportDir,
|
|
63
48
|
coverageMap,
|
|
64
|
-
defaultSummarizer: "pkg"
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
reports.create("text", {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const summary = coverageMap.getCoverageSummary()
|
|
73
|
-
enforceThresholds(summary, config.thresholds, "global")
|
|
74
|
-
|
|
75
|
-
const targets = Array.isArray(config.thresholdTargets) ? config.thresholdTargets : []
|
|
49
|
+
defaultSummarizer: "pkg"
|
|
50
|
+
});
|
|
51
|
+
reports.create("text", { maxCols: process.stdout.columns ?? 120 }).execute(context);
|
|
52
|
+
reports.create("text", { file: TEXT_REPORT_FILENAME }).execute(context);
|
|
53
|
+
console.log(`[coverage] Full text report saved to ${path.join(config.coverageReportDir, TEXT_REPORT_FILENAME)}`);
|
|
54
|
+
const summary = coverageMap.getCoverageSummary();
|
|
55
|
+
enforceThresholds(summary, config.thresholds, "global");
|
|
56
|
+
const targets = Array.isArray(config.thresholdTargets) ? config.thresholdTargets : [];
|
|
76
57
|
if (targets.length > 0) {
|
|
77
|
-
const fileSummaries = buildFileSummaries(coverageMap, config.rootDir)
|
|
58
|
+
const fileSummaries = buildFileSummaries(coverageMap, config.rootDir);
|
|
78
59
|
for (const target of targets) {
|
|
79
|
-
const matcher = createGlobMatcher(target.pattern)
|
|
80
|
-
const matchResult = collectTargetSummary(fileSummaries, matcher, coverageLib)
|
|
81
|
-
|
|
60
|
+
const matcher = createGlobMatcher(target.pattern);
|
|
61
|
+
const matchResult = collectTargetSummary(fileSummaries, matcher, coverageLib);
|
|
82
62
|
if (matchResult.matched === 0) {
|
|
83
63
|
console.warn(
|
|
84
|
-
`[coverage] threshold pattern "${target.pattern}" did not match any files — skipping
|
|
85
|
-
)
|
|
86
|
-
continue
|
|
64
|
+
`[coverage] threshold pattern "${target.pattern}" did not match any files — skipping`
|
|
65
|
+
);
|
|
66
|
+
continue;
|
|
87
67
|
}
|
|
88
|
-
|
|
89
|
-
enforceThresholds(matchResult.summary, target.thresholds, target.pattern)
|
|
68
|
+
enforceThresholds(matchResult.summary, target.thresholds, target.pattern);
|
|
90
69
|
}
|
|
91
70
|
}
|
|
92
71
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const coverageFiles = await findCoverageFiles(config)
|
|
72
|
+
async function collectCoveredFiles(config) {
|
|
73
|
+
const coverageFiles = await findCoverageFiles(config);
|
|
96
74
|
if (coverageFiles.length === 0) {
|
|
97
|
-
return []
|
|
75
|
+
return [];
|
|
98
76
|
}
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)
|
|
103
|
-
|
|
77
|
+
const coverageLib = resolveCoverageLib();
|
|
78
|
+
const coverageMap = coverageLib.createCoverageMap({});
|
|
79
|
+
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir);
|
|
104
80
|
for (const file of coverageFiles) {
|
|
105
|
-
const payload = await readCoverageFile(file)
|
|
81
|
+
const payload = await readCoverageFile(file);
|
|
106
82
|
if (!payload) {
|
|
107
|
-
continue
|
|
83
|
+
continue;
|
|
108
84
|
}
|
|
109
|
-
|
|
110
85
|
for (const script of payload.scripts) {
|
|
111
|
-
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom)
|
|
86
|
+
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom);
|
|
112
87
|
}
|
|
113
88
|
}
|
|
114
|
-
|
|
115
|
-
|
|
89
|
+
return coverageMap.files().sort();
|
|
90
|
+
}
|
|
91
|
+
async function loadIstanbulModules() {
|
|
92
|
+
maybeForceColor();
|
|
93
|
+
const [libReportMod, reportsMod] = await Promise.all([
|
|
94
|
+
import("istanbul-lib-report"),
|
|
95
|
+
import("istanbul-reports")
|
|
96
|
+
]);
|
|
97
|
+
const createContext = typeof libReportMod.createContext === "function" ? libReportMod.createContext : libReportMod.default?.createContext;
|
|
98
|
+
if (typeof createContext !== "function") {
|
|
99
|
+
throw new Error("istanbul-lib-report exports are unavailable");
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
createContext,
|
|
103
|
+
reports: reportsMod.default ?? reportsMod
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function maybeForceColor() {
|
|
107
|
+
if (process.stdout.isTTY) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (process.env.FORCE_COLOR !== void 0) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (process.env.NO_COLOR !== void 0 || process.env.NODE_DISABLE_COLORS !== void 0) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (process.env.CI !== void 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
process.env.FORCE_COLOR = "1";
|
|
116
120
|
}
|
|
117
|
-
|
|
118
121
|
async function mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom) {
|
|
119
|
-
const scriptPath = script.absolutePath
|
|
122
|
+
const scriptPath = script.absolutePath;
|
|
120
123
|
if (!scriptPath) {
|
|
121
|
-
return
|
|
124
|
+
return;
|
|
122
125
|
}
|
|
123
|
-
|
|
124
126
|
if (isNodeModulesPath(scriptPath)) {
|
|
125
|
-
return
|
|
127
|
+
return;
|
|
126
128
|
}
|
|
127
|
-
|
|
128
129
|
if (isViteVirtualModulePath(scriptPath)) {
|
|
129
|
-
return
|
|
130
|
+
return;
|
|
130
131
|
}
|
|
131
|
-
|
|
132
|
-
let source = script.source && script.source.length > 0
|
|
133
|
-
? script.source
|
|
134
|
-
: ""
|
|
135
|
-
|
|
132
|
+
let source = script.source && script.source.length > 0 ? script.source : "";
|
|
136
133
|
if (!source) {
|
|
137
134
|
try {
|
|
138
|
-
source = await fs.readFile(scriptPath, "utf8")
|
|
135
|
+
source = await fs.readFile(scriptPath, "utf8");
|
|
139
136
|
} catch (error) {
|
|
140
|
-
const base = path.basename(scriptPath)
|
|
137
|
+
const base = path.basename(scriptPath);
|
|
141
138
|
if (error?.code === "ENOENT" && base && !base.includes(".")) {
|
|
142
|
-
return
|
|
139
|
+
return;
|
|
143
140
|
}
|
|
144
|
-
throw error
|
|
141
|
+
throw error;
|
|
145
142
|
}
|
|
146
143
|
}
|
|
147
|
-
|
|
148
|
-
const sourceMap = await loadSourceMapForScript(scriptPath, source)
|
|
144
|
+
const sourceMap = await loadSourceMapForScript(scriptPath, source);
|
|
149
145
|
const converter = v8ToIstanbul(
|
|
150
146
|
scriptPath,
|
|
151
147
|
0,
|
|
152
|
-
sourceMap ? { source, sourceMap: { sourcemap: sourceMap } } : { source }
|
|
153
|
-
)
|
|
154
|
-
await converter.load()
|
|
155
|
-
converter.applyCoverage(script.functions)
|
|
156
|
-
|
|
157
|
-
const filtered = filterCoverageMap(converter.toIstanbul(), config, matchesCollectCoverageFrom)
|
|
148
|
+
sourceMap ? { source, sourceMap: { sourcemap: sourceMap } } : { source }
|
|
149
|
+
);
|
|
150
|
+
await converter.load();
|
|
151
|
+
converter.applyCoverage(script.functions);
|
|
152
|
+
const filtered = filterCoverageMap(converter.toIstanbul(), config, matchesCollectCoverageFrom);
|
|
158
153
|
if (Object.keys(filtered).length > 0) {
|
|
159
|
-
coverageMap.merge(filtered)
|
|
154
|
+
coverageMap.merge(filtered);
|
|
160
155
|
}
|
|
161
156
|
}
|
|
162
|
-
|
|
163
157
|
async function readCoverageFile(file) {
|
|
164
158
|
try {
|
|
165
|
-
const raw = await fs.readFile(file, "utf8")
|
|
166
|
-
return JSON.parse(raw)
|
|
159
|
+
const raw = await fs.readFile(file, "utf8");
|
|
160
|
+
return JSON.parse(raw);
|
|
167
161
|
} catch (error) {
|
|
168
|
-
console.warn(`[coverage] failed to parse ${file}:`, error)
|
|
169
|
-
return null
|
|
162
|
+
console.warn(`[coverage] failed to parse ${file}:`, error);
|
|
163
|
+
return null;
|
|
170
164
|
}
|
|
171
165
|
}
|
|
172
|
-
|
|
173
166
|
function enforceThresholds(summary, thresholds, label = "global") {
|
|
174
|
-
const failures = []
|
|
175
|
-
|
|
167
|
+
const failures = [];
|
|
176
168
|
for (const metric of Object.keys(thresholds)) {
|
|
177
|
-
const minimum = thresholds[metric]
|
|
178
|
-
const actual = summary[metric]?.pct ?? 0
|
|
169
|
+
const minimum = thresholds[metric];
|
|
170
|
+
const actual = summary[metric]?.pct ?? 0;
|
|
179
171
|
if (actual < minimum) {
|
|
180
|
-
failures.push({ metric, actual, minimum })
|
|
172
|
+
failures.push({ metric, actual, minimum });
|
|
181
173
|
}
|
|
182
174
|
}
|
|
183
|
-
|
|
184
175
|
if (failures.length === 0) {
|
|
185
|
-
return
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
.map(({ metric, actual, minimum }) => `${metric}: ${actual.toFixed(2)}% < ${minimum}%`)
|
|
190
|
-
.join("; ")
|
|
191
|
-
|
|
192
|
-
throw new CoverageThresholdError(`[coverage] thresholds not met (target: ${label}) — ${details}`)
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const details = failures.map(({ metric, actual, minimum }) => `${metric}: ${actual.toFixed(2)}% < ${minimum}%`).join("; ");
|
|
179
|
+
throw new CoverageThresholdError(`[coverage] thresholds not met (target: ${label}) — ${details}`);
|
|
193
180
|
}
|
|
194
|
-
|
|
195
181
|
function resolveCoverageLib() {
|
|
196
|
-
const candidate = libCoverage
|
|
182
|
+
const candidate = libCoverage;
|
|
197
183
|
if (typeof candidate.createCoverageMap === "function") {
|
|
198
|
-
return candidate
|
|
184
|
+
return candidate;
|
|
199
185
|
}
|
|
200
|
-
|
|
201
186
|
if (candidate.default && typeof candidate.default.createCoverageMap === "function") {
|
|
202
|
-
return candidate.default
|
|
187
|
+
return candidate.default;
|
|
203
188
|
}
|
|
204
|
-
|
|
205
|
-
throw new Error("istanbul-lib-coverage exports are unavailable")
|
|
189
|
+
throw new Error("istanbul-lib-coverage exports are unavailable");
|
|
206
190
|
}
|
|
207
|
-
|
|
208
191
|
function resolveInstrumentLib() {
|
|
209
|
-
const candidate = libInstrument
|
|
192
|
+
const candidate = libInstrument;
|
|
210
193
|
if (typeof candidate.createInstrumenter === "function") {
|
|
211
|
-
return candidate
|
|
194
|
+
return candidate;
|
|
212
195
|
}
|
|
213
|
-
|
|
214
196
|
if (candidate.default && typeof candidate.default.createInstrumenter === "function") {
|
|
215
|
-
return candidate.default
|
|
197
|
+
return candidate.default;
|
|
216
198
|
}
|
|
217
|
-
|
|
218
|
-
throw new Error("istanbul-lib-instrument exports are unavailable")
|
|
199
|
+
throw new Error("istanbul-lib-instrument exports are unavailable");
|
|
219
200
|
}
|
|
220
|
-
|
|
221
201
|
async function includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom) {
|
|
222
202
|
const existing = new Set(
|
|
223
|
-
coverageMap.files().map((filePath) => path.resolve(String(filePath ?? "")))
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
const candidates = await findCollectCoverageFiles(config, matchesCollectCoverageFrom)
|
|
203
|
+
coverageMap.files().map((filePath) => path.resolve(String(filePath ?? "")))
|
|
204
|
+
);
|
|
205
|
+
const candidates = await findCollectCoverageFiles(config, matchesCollectCoverageFrom);
|
|
227
206
|
if (candidates.length === 0) {
|
|
228
|
-
return
|
|
207
|
+
return;
|
|
229
208
|
}
|
|
230
|
-
|
|
231
|
-
const instrumentLib = resolveInstrumentLib()
|
|
209
|
+
const instrumentLib = resolveInstrumentLib();
|
|
232
210
|
const instrumenter = instrumentLib.createInstrumenter({
|
|
233
211
|
esModules: true,
|
|
234
212
|
parserPlugins: [
|
|
@@ -239,39 +217,35 @@ async function includeUntestedFiles(coverageMap, config, matchesCollectCoverageF
|
|
|
239
217
|
"classPrivateMethods",
|
|
240
218
|
"decorators-legacy",
|
|
241
219
|
"importMeta",
|
|
242
|
-
"topLevelAwait"
|
|
243
|
-
]
|
|
244
|
-
})
|
|
245
|
-
|
|
220
|
+
"topLevelAwait"
|
|
221
|
+
]
|
|
222
|
+
});
|
|
246
223
|
for (const filePath of candidates) {
|
|
247
|
-
const normalized = path.resolve(filePath)
|
|
224
|
+
const normalized = path.resolve(filePath);
|
|
248
225
|
if (existing.has(normalized)) {
|
|
249
|
-
continue
|
|
226
|
+
continue;
|
|
250
227
|
}
|
|
251
|
-
|
|
252
|
-
const source = await fs.readFile(normalized, "utf8").catch(() => null)
|
|
228
|
+
const source = await fs.readFile(normalized, "utf8").catch(() => null);
|
|
253
229
|
if (source === null) {
|
|
254
|
-
continue
|
|
230
|
+
continue;
|
|
255
231
|
}
|
|
256
|
-
|
|
257
232
|
try {
|
|
258
|
-
instrumenter.instrumentSync(source, normalized)
|
|
259
|
-
const fileCoverage = instrumenter.lastFileCoverage()
|
|
233
|
+
instrumenter.instrumentSync(source, normalized);
|
|
234
|
+
const fileCoverage = instrumenter.lastFileCoverage();
|
|
260
235
|
if (!fileCoverage) {
|
|
261
|
-
continue
|
|
236
|
+
continue;
|
|
262
237
|
}
|
|
263
|
-
coverageMap.addFileCoverage(fileCoverage)
|
|
264
|
-
existing.add(normalized)
|
|
238
|
+
coverageMap.addFileCoverage(fileCoverage);
|
|
239
|
+
existing.add(normalized);
|
|
265
240
|
} catch (error) {
|
|
266
|
-
const relative = path.relative(config.rootDir, normalized)
|
|
241
|
+
const relative = path.relative(config.rootDir, normalized);
|
|
267
242
|
console.warn(
|
|
268
243
|
`[coverage] failed to instrument ${relative && !relative.startsWith("..") ? relative : normalized}:`,
|
|
269
|
-
error
|
|
270
|
-
)
|
|
244
|
+
error
|
|
245
|
+
);
|
|
271
246
|
}
|
|
272
247
|
}
|
|
273
248
|
}
|
|
274
|
-
|
|
275
249
|
const DEFAULT_COLLECT_COVERAGE_IGNORES = [
|
|
276
250
|
"**/.git/**",
|
|
277
251
|
"**/.next/**",
|
|
@@ -289,18 +263,13 @@ const DEFAULT_COLLECT_COVERAGE_IGNORES = [
|
|
|
289
263
|
"**/tests/**",
|
|
290
264
|
"**/__tests__/**",
|
|
291
265
|
"**/*.d.ts",
|
|
292
|
-
"**/*.map"
|
|
293
|
-
]
|
|
294
|
-
|
|
266
|
+
"**/*.map"
|
|
267
|
+
];
|
|
295
268
|
async function findCollectCoverageFiles(config, matchesCollectCoverageFrom) {
|
|
296
|
-
const patterns = Array.isArray(config.collectCoverageFrom)
|
|
297
|
-
? config.collectCoverageFrom
|
|
298
|
-
: []
|
|
299
|
-
|
|
269
|
+
const patterns = Array.isArray(config.collectCoverageFrom) ? config.collectCoverageFrom : [];
|
|
300
270
|
if (patterns.length === 0) {
|
|
301
|
-
return []
|
|
271
|
+
return [];
|
|
302
272
|
}
|
|
303
|
-
|
|
304
273
|
const rawFiles = await fg(patterns, {
|
|
305
274
|
cwd: config.rootDir,
|
|
306
275
|
absolute: true,
|
|
@@ -308,317 +277,248 @@ async function findCollectCoverageFiles(config, matchesCollectCoverageFrom) {
|
|
|
308
277
|
onlyFiles: true,
|
|
309
278
|
unique: true,
|
|
310
279
|
followSymbolicLinks: false,
|
|
311
|
-
ignore: DEFAULT_COLLECT_COVERAGE_IGNORES
|
|
312
|
-
}).catch(() => [])
|
|
313
|
-
|
|
314
|
-
const collected = new Set()
|
|
315
|
-
|
|
280
|
+
ignore: DEFAULT_COLLECT_COVERAGE_IGNORES
|
|
281
|
+
}).catch(() => []);
|
|
282
|
+
const collected = /* @__PURE__ */ new Set();
|
|
316
283
|
for (const file of rawFiles) {
|
|
317
|
-
const normalized = path.resolve(String(file ?? ""))
|
|
284
|
+
const normalized = path.resolve(String(file ?? ""));
|
|
318
285
|
if (!normalized) {
|
|
319
|
-
continue
|
|
286
|
+
continue;
|
|
320
287
|
}
|
|
321
|
-
|
|
322
288
|
if (normalized.endsWith(".d.ts") || normalized.endsWith(".map")) {
|
|
323
|
-
continue
|
|
289
|
+
continue;
|
|
324
290
|
}
|
|
325
|
-
|
|
326
291
|
if (isNodeModulesPath(normalized)) {
|
|
327
|
-
continue
|
|
292
|
+
continue;
|
|
328
293
|
}
|
|
329
|
-
|
|
330
294
|
if (isViteVirtualModulePath(normalized)) {
|
|
331
|
-
continue
|
|
295
|
+
continue;
|
|
332
296
|
}
|
|
333
|
-
|
|
334
297
|
if (!matchesCollectCoverageFrom(normalized)) {
|
|
335
|
-
continue
|
|
298
|
+
continue;
|
|
336
299
|
}
|
|
337
|
-
|
|
338
|
-
collected.add(normalized)
|
|
300
|
+
collected.add(normalized);
|
|
339
301
|
}
|
|
340
|
-
|
|
341
|
-
return Array.from(collected).sort()
|
|
302
|
+
return Array.from(collected).sort();
|
|
342
303
|
}
|
|
343
|
-
|
|
344
304
|
function buildFileSummaries(coverageMap, rootDir) {
|
|
345
|
-
const normalizedRoot = path.resolve(rootDir)
|
|
305
|
+
const normalizedRoot = path.resolve(rootDir);
|
|
346
306
|
return coverageMap.files().map((filePath) => {
|
|
347
|
-
const normalizedAbsolute = path.resolve(filePath)
|
|
348
|
-
const summary = coverageMap.fileCoverageFor(filePath).toSummary()
|
|
349
|
-
const relativePath = path.relative(normalizedRoot, normalizedAbsolute)
|
|
350
|
-
const candidates = new Set()
|
|
351
|
-
|
|
307
|
+
const normalizedAbsolute = path.resolve(filePath);
|
|
308
|
+
const summary = coverageMap.fileCoverageFor(filePath).toSummary();
|
|
309
|
+
const relativePath = path.relative(normalizedRoot, normalizedAbsolute);
|
|
310
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
352
311
|
if (relativePath) {
|
|
353
|
-
const relativePosix = toPosix(relativePath)
|
|
354
|
-
candidates.add(relativePosix)
|
|
355
|
-
candidates.add(`./${relativePosix}`)
|
|
312
|
+
const relativePosix = toPosix(relativePath);
|
|
313
|
+
candidates.add(relativePosix);
|
|
314
|
+
candidates.add(`./${relativePosix}`);
|
|
356
315
|
} else {
|
|
357
|
-
candidates.add(toPosix(path.basename(normalizedAbsolute)))
|
|
316
|
+
candidates.add(toPosix(path.basename(normalizedAbsolute)));
|
|
358
317
|
}
|
|
359
|
-
|
|
360
318
|
return {
|
|
361
319
|
summary,
|
|
362
|
-
candidates: Array.from(candidates)
|
|
363
|
-
}
|
|
364
|
-
})
|
|
320
|
+
candidates: Array.from(candidates)
|
|
321
|
+
};
|
|
322
|
+
});
|
|
365
323
|
}
|
|
366
|
-
|
|
367
324
|
function collectTargetSummary(fileSummaries, matcher, coverageLib) {
|
|
368
|
-
const summary = coverageLib.createCoverageSummary()
|
|
369
|
-
let matched = 0
|
|
370
|
-
|
|
325
|
+
const summary = coverageLib.createCoverageSummary();
|
|
326
|
+
let matched = 0;
|
|
371
327
|
for (const file of fileSummaries) {
|
|
372
328
|
if (file.candidates.some((candidate) => matcher(candidate))) {
|
|
373
|
-
summary.merge(file.summary)
|
|
374
|
-
matched += 1
|
|
329
|
+
summary.merge(file.summary);
|
|
330
|
+
matched += 1;
|
|
375
331
|
}
|
|
376
332
|
}
|
|
377
|
-
|
|
378
|
-
return { summary, matched }
|
|
333
|
+
return { summary, matched };
|
|
379
334
|
}
|
|
380
|
-
|
|
381
335
|
function createGlobMatcher(pattern) {
|
|
382
|
-
const normalized = toPosix(String(pattern ?? "")).trim()
|
|
336
|
+
const normalized = toPosix(String(pattern ?? "")).trim();
|
|
383
337
|
if (!normalized) {
|
|
384
|
-
return () => false
|
|
338
|
+
return () => false;
|
|
385
339
|
}
|
|
386
340
|
if (isAbsoluteGlobPattern(normalized)) {
|
|
387
|
-
throw new Error(`[coverage] threshold patterns must be relative (absolute paths are not supported): "${pattern}"`)
|
|
341
|
+
throw new Error(`[coverage] threshold patterns must be relative (absolute paths are not supported): "${pattern}"`);
|
|
388
342
|
}
|
|
389
|
-
return picomatch(normalized, { dot: true })
|
|
343
|
+
return picomatch(normalized, { dot: true });
|
|
390
344
|
}
|
|
391
|
-
|
|
392
345
|
function isAbsoluteGlobPattern(pattern) {
|
|
393
|
-
const normalized = String(pattern ?? "").trim()
|
|
346
|
+
const normalized = String(pattern ?? "").trim();
|
|
394
347
|
if (!normalized) {
|
|
395
|
-
return false
|
|
348
|
+
return false;
|
|
396
349
|
}
|
|
397
|
-
|
|
398
350
|
if (normalized.startsWith("/")) {
|
|
399
|
-
return true
|
|
351
|
+
return true;
|
|
400
352
|
}
|
|
401
|
-
|
|
402
353
|
if (normalized.startsWith("file://")) {
|
|
403
|
-
return true
|
|
354
|
+
return true;
|
|
404
355
|
}
|
|
405
|
-
|
|
406
|
-
return /^[A-Za-z]:\//.test(normalized)
|
|
356
|
+
return /^[A-Za-z]:\//.test(normalized);
|
|
407
357
|
}
|
|
408
|
-
|
|
409
358
|
function stripQuery(url) {
|
|
410
|
-
const queryIndex = url.indexOf("?")
|
|
411
|
-
const hashIndex = url.indexOf("#")
|
|
412
|
-
|
|
359
|
+
const queryIndex = url.indexOf("?");
|
|
360
|
+
const hashIndex = url.indexOf("#");
|
|
413
361
|
const endIndex = Math.min(
|
|
414
362
|
queryIndex === -1 ? Number.POSITIVE_INFINITY : queryIndex,
|
|
415
|
-
hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex
|
|
416
|
-
)
|
|
417
|
-
|
|
363
|
+
hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex
|
|
364
|
+
);
|
|
418
365
|
if (!Number.isFinite(endIndex)) {
|
|
419
|
-
return url
|
|
366
|
+
return url;
|
|
420
367
|
}
|
|
421
|
-
|
|
422
|
-
return url.slice(0, endIndex)
|
|
368
|
+
return url.slice(0, endIndex);
|
|
423
369
|
}
|
|
424
|
-
|
|
425
370
|
function extractSourceMappingUrl(source) {
|
|
426
|
-
const regex = /\/\/[#@]\s*sourceMappingURL=([^\s]+)/g
|
|
427
|
-
|
|
428
|
-
let
|
|
429
|
-
let match = null
|
|
430
|
-
|
|
371
|
+
const regex = /\/\/[#@]\s*sourceMappingURL=([^\s]+)/g;
|
|
372
|
+
let last = null;
|
|
373
|
+
let match = null;
|
|
431
374
|
while ((match = regex.exec(source)) !== null) {
|
|
432
|
-
last = match[1]
|
|
375
|
+
last = match[1];
|
|
433
376
|
}
|
|
434
|
-
|
|
435
|
-
return typeof last === "string" && last.length > 0 ? last : null
|
|
377
|
+
return typeof last === "string" && last.length > 0 ? last : null;
|
|
436
378
|
}
|
|
437
|
-
|
|
438
379
|
function resolveSourceMapPath(scriptPath, mappingUrl) {
|
|
439
|
-
const cleaned = stripQuery(mappingUrl)
|
|
440
|
-
|
|
380
|
+
const cleaned = stripQuery(mappingUrl);
|
|
441
381
|
if (cleaned.startsWith("file://")) {
|
|
442
|
-
return fileURLToPath(cleaned)
|
|
382
|
+
return fileURLToPath(cleaned);
|
|
443
383
|
}
|
|
444
|
-
|
|
445
384
|
if (path.isAbsolute(cleaned)) {
|
|
446
|
-
return cleaned
|
|
385
|
+
return cleaned;
|
|
447
386
|
}
|
|
448
|
-
|
|
449
|
-
return path.resolve(path.dirname(scriptPath), cleaned)
|
|
387
|
+
return path.resolve(path.dirname(scriptPath), cleaned);
|
|
450
388
|
}
|
|
451
|
-
|
|
452
389
|
function filterCoverageMap(map, config, matchesCollectCoverageFrom) {
|
|
453
390
|
if (!map || typeof map !== "object") {
|
|
454
|
-
return {}
|
|
391
|
+
return {};
|
|
455
392
|
}
|
|
456
|
-
|
|
457
|
-
const filtered = {}
|
|
458
|
-
|
|
393
|
+
const filtered = {};
|
|
459
394
|
for (const [filePath, fileCoverage] of Object.entries(map)) {
|
|
460
|
-
const absolutePath = resolveCoveragePath(filePath, config.rootDir)
|
|
395
|
+
const absolutePath = resolveCoveragePath(filePath, config.rootDir);
|
|
461
396
|
if (!absolutePath) {
|
|
462
|
-
continue
|
|
397
|
+
continue;
|
|
463
398
|
}
|
|
464
|
-
|
|
465
399
|
if (absolutePath.endsWith(".d.ts") || absolutePath.endsWith(".map")) {
|
|
466
|
-
continue
|
|
400
|
+
continue;
|
|
467
401
|
}
|
|
468
|
-
|
|
469
402
|
if (isNodeModulesPath(absolutePath)) {
|
|
470
|
-
continue
|
|
403
|
+
continue;
|
|
471
404
|
}
|
|
472
|
-
|
|
473
405
|
if (isViteVirtualModulePath(absolutePath)) {
|
|
474
|
-
continue
|
|
406
|
+
continue;
|
|
475
407
|
}
|
|
476
|
-
|
|
477
408
|
if (!matchesCollectCoverageFrom(absolutePath)) {
|
|
478
|
-
continue
|
|
409
|
+
continue;
|
|
479
410
|
}
|
|
480
|
-
|
|
481
411
|
if (fileCoverage && typeof fileCoverage === "object") {
|
|
482
|
-
filtered[absolutePath] = { ...fileCoverage, path: absolutePath }
|
|
412
|
+
filtered[absolutePath] = { ...fileCoverage, path: absolutePath };
|
|
483
413
|
} else {
|
|
484
|
-
filtered[absolutePath] = fileCoverage
|
|
414
|
+
filtered[absolutePath] = fileCoverage;
|
|
485
415
|
}
|
|
486
416
|
}
|
|
487
|
-
|
|
488
|
-
return filtered
|
|
417
|
+
return filtered;
|
|
489
418
|
}
|
|
490
|
-
|
|
491
419
|
function resolveCoveragePath(filePath, rootDir) {
|
|
492
|
-
const raw = String(filePath ?? "").trim()
|
|
420
|
+
const raw = String(filePath ?? "").trim();
|
|
493
421
|
if (!raw) {
|
|
494
|
-
return null
|
|
422
|
+
return null;
|
|
495
423
|
}
|
|
496
|
-
|
|
497
|
-
const cleaned = stripQuery(raw)
|
|
498
|
-
|
|
424
|
+
const cleaned = stripQuery(raw);
|
|
499
425
|
if (cleaned.startsWith("file://")) {
|
|
500
426
|
try {
|
|
501
|
-
return path.normalize(fileURLToPath(cleaned))
|
|
427
|
+
return path.normalize(fileURLToPath(cleaned));
|
|
502
428
|
} catch {
|
|
503
|
-
return null
|
|
429
|
+
return null;
|
|
504
430
|
}
|
|
505
431
|
}
|
|
506
|
-
|
|
507
432
|
if (path.isAbsolute(cleaned)) {
|
|
508
|
-
return path.normalize(cleaned)
|
|
433
|
+
return path.normalize(cleaned);
|
|
509
434
|
}
|
|
510
|
-
|
|
511
435
|
if (cleaned.includes("://")) {
|
|
512
|
-
return null
|
|
436
|
+
return null;
|
|
513
437
|
}
|
|
514
|
-
|
|
515
|
-
return path.normalize(path.resolve(rootDir, cleaned))
|
|
438
|
+
return path.normalize(path.resolve(rootDir, cleaned));
|
|
516
439
|
}
|
|
517
|
-
|
|
518
440
|
function isNodeModulesPath(filePath) {
|
|
519
|
-
return path
|
|
520
|
-
.normalize(String(filePath ?? ""))
|
|
521
|
-
.split(path.sep)
|
|
522
|
-
.includes("node_modules")
|
|
441
|
+
return path.normalize(String(filePath ?? "")).split(path.sep).includes("node_modules");
|
|
523
442
|
}
|
|
524
|
-
|
|
525
443
|
function isViteVirtualModulePath(filePath) {
|
|
526
|
-
const normalized = path.normalize(String(filePath ?? ""))
|
|
527
|
-
const baseName = path.basename(normalized)
|
|
528
|
-
return baseName === "__vite-browser-external"
|
|
529
|
-
|| baseName.startsWith("__vite-browser-external:")
|
|
530
|
-
|| baseName.startsWith("__vite-")
|
|
444
|
+
const normalized = path.normalize(String(filePath ?? ""));
|
|
445
|
+
const baseName = path.basename(normalized);
|
|
446
|
+
return baseName === "__vite-browser-external" || baseName.startsWith("__vite-browser-external:") || baseName.startsWith("__vite-");
|
|
531
447
|
}
|
|
532
|
-
|
|
533
448
|
function parseSourceMapPayload(raw) {
|
|
534
449
|
if (!raw || typeof raw !== "object") {
|
|
535
|
-
return null
|
|
450
|
+
return null;
|
|
536
451
|
}
|
|
537
|
-
|
|
538
|
-
const sources = raw.sources
|
|
452
|
+
const sources = raw.sources;
|
|
539
453
|
if (!Array.isArray(sources) || sources.length === 0) {
|
|
540
|
-
return null
|
|
454
|
+
return null;
|
|
541
455
|
}
|
|
542
|
-
|
|
543
|
-
return raw
|
|
456
|
+
return raw;
|
|
544
457
|
}
|
|
545
|
-
|
|
546
458
|
function normalizeSourceMap(sourceMap, scriptPath) {
|
|
547
|
-
const root = typeof sourceMap.sourceRoot === "string"
|
|
548
|
-
|
|
549
|
-
: ""
|
|
550
|
-
|
|
551
|
-
const dir = path.dirname(scriptPath)
|
|
459
|
+
const root = typeof sourceMap.sourceRoot === "string" ? sourceMap.sourceRoot.replace("file://", "") : "";
|
|
460
|
+
const dir = path.dirname(scriptPath);
|
|
552
461
|
const fixedSources = sourceMap.sources.map((source) => {
|
|
553
|
-
const raw = String(source ?? "")
|
|
554
|
-
const cleaned = stripQuery(raw)
|
|
555
|
-
|
|
462
|
+
const raw = String(source ?? "");
|
|
463
|
+
const cleaned = stripQuery(raw);
|
|
556
464
|
if (cleaned.startsWith("file://")) {
|
|
557
465
|
try {
|
|
558
|
-
return path.normalize(fileURLToPath(cleaned))
|
|
466
|
+
return path.normalize(fileURLToPath(cleaned));
|
|
559
467
|
} catch {
|
|
560
|
-
return cleaned
|
|
468
|
+
return cleaned;
|
|
561
469
|
}
|
|
562
470
|
}
|
|
563
|
-
|
|
564
|
-
const
|
|
565
|
-
const candidate = path.join(root, withoutWebpack)
|
|
566
|
-
|
|
471
|
+
const withoutWebpack = cleaned.replace(/^webpack:\/\//, "");
|
|
472
|
+
const candidate = path.join(root, withoutWebpack);
|
|
567
473
|
if (path.isAbsolute(candidate)) {
|
|
568
|
-
return path.normalize(candidate)
|
|
474
|
+
return path.normalize(candidate);
|
|
569
475
|
}
|
|
570
|
-
|
|
571
|
-
const normalizedCandidate = candidate.split("/").join(path.sep)
|
|
572
|
-
|
|
476
|
+
const normalizedCandidate = candidate.split("/").join(path.sep);
|
|
573
477
|
if (dir.endsWith(`${path.sep}dist`) && !normalizedCandidate.startsWith(`..${path.sep}`)) {
|
|
574
478
|
if (normalizedCandidate.startsWith(`src${path.sep}`) || normalizedCandidate.startsWith(`lib${path.sep}`)) {
|
|
575
|
-
return path.normalize(path.resolve(dir, "..", normalizedCandidate))
|
|
479
|
+
return path.normalize(path.resolve(dir, "..", normalizedCandidate));
|
|
576
480
|
}
|
|
577
481
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
})
|
|
581
|
-
|
|
482
|
+
return path.normalize(path.resolve(dir, normalizedCandidate));
|
|
483
|
+
});
|
|
582
484
|
return {
|
|
583
485
|
...sourceMap,
|
|
584
|
-
sources: fixedSources
|
|
585
|
-
}
|
|
486
|
+
sources: fixedSources
|
|
487
|
+
};
|
|
586
488
|
}
|
|
587
|
-
|
|
588
489
|
async function loadSourceMapForScript(scriptPath, source) {
|
|
589
|
-
const mappingUrl = extractSourceMappingUrl(source)
|
|
490
|
+
const mappingUrl = extractSourceMappingUrl(source);
|
|
590
491
|
if (!mappingUrl) {
|
|
591
|
-
return null
|
|
492
|
+
return null;
|
|
592
493
|
}
|
|
593
|
-
|
|
594
|
-
const cleaned = stripQuery(mappingUrl)
|
|
595
|
-
|
|
494
|
+
const cleaned = stripQuery(mappingUrl);
|
|
596
495
|
if (cleaned.startsWith("data:")) {
|
|
597
|
-
const commaIndex = cleaned.indexOf(",")
|
|
496
|
+
const commaIndex = cleaned.indexOf(",");
|
|
598
497
|
if (commaIndex === -1) {
|
|
599
|
-
return null
|
|
498
|
+
return null;
|
|
600
499
|
}
|
|
601
|
-
|
|
602
|
-
const
|
|
603
|
-
const
|
|
604
|
-
const raw = meta.includes(";base64")
|
|
605
|
-
? Buffer.from(payload, "base64").toString("utf8")
|
|
606
|
-
: decodeURIComponent(payload)
|
|
607
|
-
|
|
500
|
+
const meta = cleaned.slice(0, commaIndex);
|
|
501
|
+
const payload = cleaned.slice(commaIndex + 1);
|
|
502
|
+
const raw = meta.includes(";base64") ? Buffer.from(payload, "base64").toString("utf8") : decodeURIComponent(payload);
|
|
608
503
|
try {
|
|
609
|
-
const parsed = parseSourceMapPayload(JSON.parse(raw))
|
|
610
|
-
return parsed ? normalizeSourceMap(parsed, scriptPath) : null
|
|
504
|
+
const parsed = parseSourceMapPayload(JSON.parse(raw));
|
|
505
|
+
return parsed ? normalizeSourceMap(parsed, scriptPath) : null;
|
|
611
506
|
} catch {
|
|
612
|
-
return null
|
|
507
|
+
return null;
|
|
613
508
|
}
|
|
614
509
|
}
|
|
615
|
-
|
|
616
510
|
try {
|
|
617
|
-
const mapPath = resolveSourceMapPath(scriptPath, cleaned)
|
|
618
|
-
const raw = await fs.readFile(mapPath, "utf8")
|
|
619
|
-
const parsed = parseSourceMapPayload(JSON.parse(raw))
|
|
620
|
-
return parsed ? normalizeSourceMap(parsed, scriptPath) : null
|
|
511
|
+
const mapPath = resolveSourceMapPath(scriptPath, cleaned);
|
|
512
|
+
const raw = await fs.readFile(mapPath, "utf8");
|
|
513
|
+
const parsed = parseSourceMapPayload(JSON.parse(raw));
|
|
514
|
+
return parsed ? normalizeSourceMap(parsed, scriptPath) : null;
|
|
621
515
|
} catch {
|
|
622
|
-
return null
|
|
516
|
+
return null;
|
|
623
517
|
}
|
|
624
518
|
}
|
|
519
|
+
export {
|
|
520
|
+
CoverageThresholdError,
|
|
521
|
+
collectCoveredFiles,
|
|
522
|
+
generateCoverageReport
|
|
523
|
+
};
|
|
524
|
+
//# sourceMappingURL=report.js.map
|