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