@rpcbase/test 0.334.0 → 0.335.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.
@@ -7,20 +7,8 @@ import { createRequire } from "node:module";
7
7
  import { pathToFileURL } from "node:url";
8
8
  import { buildSync, build } from "esbuild";
9
9
  const require$1 = createRequire(import.meta.url);
10
- const DEFAULT_COVERAGE_CANDIDATES = [
11
- "spec/coverage.config.ts",
12
- "spec/coverage.config.js",
13
- "spec/coverage.config.mjs",
14
- "spec/coverage.config.cjs",
15
- "spec/coverage.config.json"
16
- ];
17
- const LEGACY_COVERAGE_CANDIDATES = [
18
- "spec/coverage.ts",
19
- "spec/coverage.js",
20
- "spec/coverage.mjs",
21
- "spec/coverage.cjs",
22
- "spec/coverage.json"
23
- ];
10
+ const DEFAULT_COVERAGE_CANDIDATES = ["spec/coverage.config.ts", "spec/coverage.config.js", "spec/coverage.config.mjs", "spec/coverage.config.cjs", "spec/coverage.config.json"];
11
+ const LEGACY_COVERAGE_CANDIDATES = ["spec/coverage.ts", "spec/coverage.js", "spec/coverage.mjs", "spec/coverage.cjs", "spec/coverage.json"];
24
12
  async function loadCoverageOptions({
25
13
  optional = false,
26
14
  candidates = DEFAULT_COVERAGE_CANDIDATES
@@ -30,18 +18,14 @@ async function loadCoverageOptions({
30
18
  if (legacy) {
31
19
  const ext = path.extname(legacy);
32
20
  const suggested = path.join("spec", `coverage.config${ext}`);
33
- throw new Error(
34
- `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`
35
- );
21
+ throw new Error(`Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`);
36
22
  }
37
23
  const resolved = await findCoverageFile(projectRoot, candidates);
38
24
  if (!resolved) {
39
25
  if (optional) {
40
26
  return null;
41
27
  }
42
- throw new Error(
43
- "Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings."
44
- );
28
+ throw new Error("Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.");
45
29
  }
46
30
  const raw = await importCoverageModule(resolved);
47
31
  if (!raw || typeof raw !== "object") {
@@ -58,18 +42,14 @@ function loadCoverageOptionsSync({
58
42
  if (legacy) {
59
43
  const ext = path.extname(legacy);
60
44
  const suggested = path.join("spec", `coverage.config${ext}`);
61
- throw new Error(
62
- `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`
63
- );
45
+ throw new Error(`Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`);
64
46
  }
65
47
  const resolved = findCoverageFileSync(projectRoot, candidates);
66
48
  if (!resolved) {
67
49
  if (optional) {
68
50
  return null;
69
51
  }
70
- throw new Error(
71
- "Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings."
72
- );
52
+ throw new Error("Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.");
73
53
  }
74
54
  const raw = importCoverageModuleSync(resolved);
75
55
  if (!raw || typeof raw !== "object") {
@@ -128,7 +108,9 @@ async function compileTsModule(filePath) {
128
108
  const stat = await fs$1.stat(filePath);
129
109
  const hash = crypto.createHash("sha1").update(filePath).update(String(stat.mtimeMs)).digest("hex");
130
110
  const outDir = path.join(os.tmpdir(), "rpcbase-test");
131
- await fs$1.mkdir(outDir, { recursive: true });
111
+ await fs$1.mkdir(outDir, {
112
+ recursive: true
113
+ });
132
114
  const outfile = path.join(outDir, `coverage-${hash}.mjs`);
133
115
  await build({
134
116
  entryPoints: [filePath],
@@ -145,7 +127,9 @@ function compileCjsModuleSync(filePath) {
145
127
  const stat = fs.statSync(filePath);
146
128
  const hash = crypto.createHash("sha1").update(filePath).update(String(stat.mtimeMs)).digest("hex");
147
129
  const outDir = path.join(os.tmpdir(), "rpcbase-test");
148
- fs.mkdirSync(outDir, { recursive: true });
130
+ fs.mkdirSync(outDir, {
131
+ recursive: true
132
+ });
149
133
  const outfile = path.join(outDir, `coverage-${hash}.cjs`);
150
134
  buildSync({
151
135
  entryPoints: [filePath],
@@ -184,9 +168,7 @@ async function resolveCollectCoverageFrom(rawPatterns, rootDir) {
184
168
  }
185
169
  const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir);
186
170
  if (defaults.length === 0) {
187
- throw new Error(
188
- "Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern."
189
- );
171
+ throw new Error("Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.");
190
172
  }
191
173
  return withDefaultExcludes([...defaults, ...excludes]);
192
174
  }
@@ -200,9 +182,7 @@ function resolveCollectCoverageFromSync(rawPatterns, rootDir) {
200
182
  }
201
183
  const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir);
202
184
  if (defaults.length === 0) {
203
- throw new Error(
204
- "Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern."
205
- );
185
+ throw new Error("Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.");
206
186
  }
207
187
  return withDefaultExcludes([...defaults, ...excludes]);
208
188
  }
@@ -253,7 +233,9 @@ function isDirectorySync(filePath) {
253
233
  }
254
234
  }
255
235
  async function normalizeOptions(rawOptions, filePath) {
256
- const options = { ...rawOptions };
236
+ const options = {
237
+ ...rawOptions
238
+ };
257
239
  const configDir = path.dirname(filePath);
258
240
  const rootDir = path.resolve(configDir, "..");
259
241
  const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir);
@@ -266,7 +248,9 @@ async function normalizeOptions(rawOptions, filePath) {
266
248
  };
267
249
  }
268
250
  function normalizeOptionsSync(rawOptions, filePath) {
269
- const options = { ...rawOptions };
251
+ const options = {
252
+ ...rawOptions
253
+ };
270
254
  const configDir = path.dirname(filePath);
271
255
  const rootDir = path.resolve(configDir, "..");
272
256
  const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir);
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.js","sources":["../../src/coverage/config-loader.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport fsSync from \"node:fs\"\nimport path from \"node:path\"\nimport os from \"node:os\"\nimport crypto from \"node:crypto\"\nimport { createRequire } from \"node:module\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { build, buildSync } from \"esbuild\"\n\nimport type { CoverageHarnessOptions } from \"./types\"\n\n\nconst require = createRequire(import.meta.url)\n\ntype LoadCoverageOptionsArgs = {\n optional?: boolean\n candidates?: string[]\n}\n\nconst DEFAULT_COVERAGE_CANDIDATES = [\n \"spec/coverage.config.ts\",\n \"spec/coverage.config.js\",\n \"spec/coverage.config.mjs\",\n \"spec/coverage.config.cjs\",\n \"spec/coverage.config.json\",\n]\n\nconst LEGACY_COVERAGE_CANDIDATES = [\n \"spec/coverage.ts\",\n \"spec/coverage.js\",\n \"spec/coverage.mjs\",\n \"spec/coverage.cjs\",\n \"spec/coverage.json\",\n]\n\nexport async function loadCoverageOptions({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): Promise<CoverageHarnessOptions | null> {\n const projectRoot = process.cwd()\n const legacy = await findCoverageFile(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = await findCoverageFile(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = await importCoverageModule(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return await normalizeOptions(raw, resolved)\n}\n\nexport function loadCoverageOptionsSync({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): CoverageHarnessOptions | null {\n const projectRoot = process.cwd()\n const legacy = findCoverageFileSync(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = findCoverageFileSync(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = importCoverageModuleSync(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return normalizeOptionsSync(raw, resolved)\n}\n\nasync function findCoverageFile(root: string, candidates: string[]): Promise<string | null> {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n await fs.access(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nfunction findCoverageFileSync(root: string, candidates: string[]): string | null {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n fsSync.accessSync(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nasync function importCoverageModule(filePath: string): Promise<unknown> {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = await fs.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".ts\") {\n const compiledUrl = await compileTsModule(filePath)\n return loadModule(compiledUrl)\n }\n\n const moduleUrl = pathToFileURL(filePath).href\n return loadModule(moduleUrl)\n}\n\nfunction importCoverageModuleSync(filePath: string): unknown {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = fsSync.readFileSync(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".cjs\") {\n return loadModuleSync(filePath)\n }\n\n const compiledPath = compileCjsModuleSync(filePath)\n return loadModuleSync(compiledPath)\n}\n\nasync function compileTsModule(filePath: string): Promise<string> {\n const stat = await fs.stat(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n await fs.mkdir(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.mjs`)\n\n await build({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"esm\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return pathToFileURL(outfile).href\n}\n\nfunction compileCjsModuleSync(filePath: string): string {\n const stat = fsSync.statSync(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n fsSync.mkdirSync(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.cjs`)\n\n buildSync({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"cjs\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return outfile\n}\n\nasync function loadModule(url: string): Promise<unknown> {\n const imported = await import(url)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nfunction loadModuleSync(modulePath: string): unknown {\n const imported = require(modulePath)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nconst DEFAULT_COLLECT_COVERAGE_EXTENSIONS = \"ts,tsx,js,jsx,mjs,cjs\"\nconst DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE = `!**/*.test.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`\n\nasync function resolveCollectCoverageFrom(rawPatterns: unknown, rootDir: string): Promise<string[]> {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nfunction resolveCollectCoverageFromSync(rawPatterns: unknown, rootDir: string): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nasync function inferDefaultCollectCoverageFrom(rootDir: string): Promise<string[]> {\n const srcDir = path.join(rootDir, \"src\")\n if (await isDirectory(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction inferDefaultCollectCoverageFromSync(rootDir: string): string[] {\n const srcDir = path.join(rootDir, \"src\")\n if (isDirectorySync(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction withDefaultExcludes(patterns: string[]): string[] {\n if (!Array.isArray(patterns) || patterns.length === 0) {\n return patterns\n }\n\n const hasTestExclude = patterns.some((pattern) => {\n const raw = String(pattern ?? \"\")\n if (!raw.startsWith(\"!\")) {\n return false\n }\n return /\\.test(?:\\.|\\{|$)/.test(raw.slice(1))\n })\n if (hasTestExclude) {\n return patterns\n }\n\n return [...patterns, DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE]\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nfunction isDirectorySync(filePath: string): boolean {\n try {\n const stat = fsSync.statSync(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nasync function normalizeOptions(\n rawOptions: any,\n filePath: string,\n): Promise<CoverageHarnessOptions> {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nfunction normalizeOptionsSync(\n rawOptions: any,\n filePath: string,\n): CoverageHarnessOptions {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nexport { DEFAULT_COVERAGE_CANDIDATES }\n"],"names":["require","fs","fsSync"],"mappings":"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"}
1
+ {"version":3,"file":"config-loader.js","sources":["../../src/coverage/config-loader.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport fsSync from \"node:fs\"\nimport path from \"node:path\"\nimport os from \"node:os\"\nimport crypto from \"node:crypto\"\nimport { createRequire } from \"node:module\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { build, buildSync } from \"esbuild\"\n\nimport type { CoverageHarnessOptions } from \"./types\"\n\n\nconst require = createRequire(import.meta.url)\n\ntype LoadCoverageOptionsArgs = {\n optional?: boolean\n candidates?: string[]\n}\n\nconst DEFAULT_COVERAGE_CANDIDATES = [\n \"spec/coverage.config.ts\",\n \"spec/coverage.config.js\",\n \"spec/coverage.config.mjs\",\n \"spec/coverage.config.cjs\",\n \"spec/coverage.config.json\",\n]\n\nconst LEGACY_COVERAGE_CANDIDATES = [\n \"spec/coverage.ts\",\n \"spec/coverage.js\",\n \"spec/coverage.mjs\",\n \"spec/coverage.cjs\",\n \"spec/coverage.json\",\n]\n\nexport async function loadCoverageOptions({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): Promise<CoverageHarnessOptions | null> {\n const projectRoot = process.cwd()\n const legacy = await findCoverageFile(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = await findCoverageFile(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = await importCoverageModule(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return await normalizeOptions(raw, resolved)\n}\n\nexport function loadCoverageOptionsSync({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): CoverageHarnessOptions | null {\n const projectRoot = process.cwd()\n const legacy = findCoverageFileSync(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = findCoverageFileSync(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = importCoverageModuleSync(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return normalizeOptionsSync(raw, resolved)\n}\n\nasync function findCoverageFile(root: string, candidates: string[]): Promise<string | null> {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n await fs.access(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nfunction findCoverageFileSync(root: string, candidates: string[]): string | null {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n fsSync.accessSync(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nasync function importCoverageModule(filePath: string): Promise<unknown> {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = await fs.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".ts\") {\n const compiledUrl = await compileTsModule(filePath)\n return loadModule(compiledUrl)\n }\n\n const moduleUrl = pathToFileURL(filePath).href\n return loadModule(moduleUrl)\n}\n\nfunction importCoverageModuleSync(filePath: string): unknown {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = fsSync.readFileSync(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".cjs\") {\n return loadModuleSync(filePath)\n }\n\n const compiledPath = compileCjsModuleSync(filePath)\n return loadModuleSync(compiledPath)\n}\n\nasync function compileTsModule(filePath: string): Promise<string> {\n const stat = await fs.stat(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n await fs.mkdir(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.mjs`)\n\n await build({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"esm\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return pathToFileURL(outfile).href\n}\n\nfunction compileCjsModuleSync(filePath: string): string {\n const stat = fsSync.statSync(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n fsSync.mkdirSync(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.cjs`)\n\n buildSync({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"cjs\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return outfile\n}\n\nasync function loadModule(url: string): Promise<unknown> {\n const imported = await import(url)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nfunction loadModuleSync(modulePath: string): unknown {\n const imported = require(modulePath)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nconst DEFAULT_COLLECT_COVERAGE_EXTENSIONS = \"ts,tsx,js,jsx,mjs,cjs\"\nconst DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE = `!**/*.test.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`\n\nasync function resolveCollectCoverageFrom(rawPatterns: unknown, rootDir: string): Promise<string[]> {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nfunction resolveCollectCoverageFromSync(rawPatterns: unknown, rootDir: string): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nasync function inferDefaultCollectCoverageFrom(rootDir: string): Promise<string[]> {\n const srcDir = path.join(rootDir, \"src\")\n if (await isDirectory(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction inferDefaultCollectCoverageFromSync(rootDir: string): string[] {\n const srcDir = path.join(rootDir, \"src\")\n if (isDirectorySync(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction withDefaultExcludes(patterns: string[]): string[] {\n if (!Array.isArray(patterns) || patterns.length === 0) {\n return patterns\n }\n\n const hasTestExclude = patterns.some((pattern) => {\n const raw = String(pattern ?? \"\")\n if (!raw.startsWith(\"!\")) {\n return false\n }\n return /\\.test(?:\\.|\\{|$)/.test(raw.slice(1))\n })\n if (hasTestExclude) {\n return patterns\n }\n\n return [...patterns, DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE]\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nfunction isDirectorySync(filePath: string): boolean {\n try {\n const stat = fsSync.statSync(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nasync function normalizeOptions(\n rawOptions: any,\n filePath: string,\n): Promise<CoverageHarnessOptions> {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nfunction normalizeOptionsSync(\n rawOptions: any,\n filePath: string,\n): CoverageHarnessOptions {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nexport { DEFAULT_COVERAGE_CANDIDATES }\n"],"names":["require","createRequire","import","url","DEFAULT_COVERAGE_CANDIDATES","LEGACY_COVERAGE_CANDIDATES","loadCoverageOptions","optional","candidates","projectRoot","process","cwd","legacy","findCoverageFile","ext","path","extname","suggested","join","Error","relative","resolved","raw","importCoverageModule","normalizeOptions","loadCoverageOptionsSync","findCoverageFileSync","importCoverageModuleSync","normalizeOptionsSync","root","candidate","resolve","fs","access","fsSync","accessSync","filePath","readFile","JSON","parse","compiledUrl","compileTsModule","loadModule","moduleUrl","pathToFileURL","href","readFileSync","loadModuleSync","compiledPath","compileCjsModuleSync","stat","hash","crypto","createHash","update","String","mtimeMs","digest","outDir","os","tmpdir","mkdir","recursive","outfile","build","entryPoints","platform","format","bundle","sourcemap","logLevel","statSync","mkdirSync","buildSync","imported","default","modulePath","DEFAULT_COLLECT_COVERAGE_EXTENSIONS","DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE","resolveCollectCoverageFrom","rawPatterns","rootDir","resolvedRootDir","normalized","Array","isArray","map","pattern","trim","filter","length","excludes","startsWith","hasIncludes","some","withDefaultExcludes","defaults","inferDefaultCollectCoverageFrom","resolveCollectCoverageFromSync","inferDefaultCollectCoverageFromSync","srcDir","isDirectory","isDirectorySync","patterns","hasTestExclude","test","slice","rawOptions","options","configDir","dirname","collectCoverageFrom","coverageFileName","includeAllFiles","thresholds"],"mappings":"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"}
@@ -8,7 +8,9 @@ const DEFAULT_THRESHOLDS = {
8
8
  const THRESHOLD_KEYS = Object.keys(DEFAULT_THRESHOLDS);
9
9
  const THRESHOLD_KEY_SET = new Set(THRESHOLD_KEYS);
10
10
  function createCoverageConfig(options) {
11
- const { rootDir } = options;
11
+ const {
12
+ rootDir
13
+ } = options;
12
14
  if (!rootDir) {
13
15
  throw new Error("createCoverageConfig requires a rootDir");
14
16
  }
@@ -23,7 +25,10 @@ function createCoverageConfig(options) {
23
25
  const coverageFileName = options.coverageFileName ?? "v8-coverage.json";
24
26
  const disabledEnvVar = options.disabledEnvVar ?? "RB_DISABLE_COVERAGE";
25
27
  const coverageEnabled = process.env[disabledEnvVar] !== "1";
26
- const { global: thresholds, targets: thresholdTargets } = normalizeThresholdOptions(options.thresholds);
28
+ const {
29
+ global: thresholds,
30
+ targets: thresholdTargets
31
+ } = normalizeThresholdOptions(options.thresholds);
27
32
  return {
28
33
  rootDir: resolvedRootDir,
29
34
  collectCoverageFrom,
@@ -38,10 +43,15 @@ function createCoverageConfig(options) {
38
43
  };
39
44
  }
40
45
  function normalizeThresholdOptions(rawThresholds) {
41
- const globalThresholds = { ...DEFAULT_THRESHOLDS };
46
+ const globalThresholds = {
47
+ ...DEFAULT_THRESHOLDS
48
+ };
42
49
  const targets = [];
43
50
  if (!isPlainObject(rawThresholds)) {
44
- return { global: globalThresholds, targets };
51
+ return {
52
+ global: globalThresholds,
53
+ targets
54
+ };
45
55
  }
46
56
  const thresholdMap = rawThresholds;
47
57
  for (const key of THRESHOLD_KEYS) {
@@ -61,9 +71,7 @@ function normalizeThresholdOptions(rawThresholds) {
61
71
  continue;
62
72
  }
63
73
  if (!isPlainObject(overrides)) {
64
- throw new Error(
65
- `coverage thresholds: override for "${pattern}" must be an object containing coverage metrics`
66
- );
74
+ throw new Error(`coverage thresholds: override for "${pattern}" must be an object containing coverage metrics`);
67
75
  }
68
76
  targets.push({
69
77
  id: pattern,
@@ -74,7 +82,10 @@ function normalizeThresholdOptions(rawThresholds) {
74
82
  }
75
83
  });
76
84
  }
77
- return { global: globalThresholds, targets };
85
+ return {
86
+ global: globalThresholds,
87
+ targets
88
+ };
78
89
  }
79
90
  function pickThresholdOverrides(source) {
80
91
  const overrides = {};
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../src/coverage/config.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport type { CoverageConfig, CoverageHarnessOptions, CoverageThresholdMap, CoverageThresholdOption, CoverageThresholdTarget, CoverageThresholds } from \"./types\"\n\n\nconst DEFAULT_THRESHOLDS = {\n branches: 60,\n functions: 75,\n lines: 75,\n statements: 75,\n}\n\nconst THRESHOLD_KEYS = Object.keys(DEFAULT_THRESHOLDS) as Array<keyof CoverageThresholds>\nconst THRESHOLD_KEY_SET = new Set<string>(THRESHOLD_KEYS as string[])\n\nexport function createCoverageConfig(options: CoverageHarnessOptions): CoverageConfig {\n const { rootDir } = options as CoverageHarnessOptions\n if (!rootDir) {\n throw new Error(\"createCoverageConfig requires a rootDir\")\n }\n\n const resolvedRootDir = path.resolve(rootDir)\n const includeAllFiles = options.includeAllFiles !== false\n\n const collectCoverageFrom = Array.isArray(options.collectCoverageFrom)\n ? options.collectCoverageFrom\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n if (collectCoverageFrom.length === 0) {\n throw new Error(\"createCoverageConfig requires a collectCoverageFrom option\")\n }\n\n const testResultsRoot = path.join(resolvedRootDir, \"build\", \"coverage\")\n const coverageReportDir = path.join(testResultsRoot, \"report\")\n const coverageFileName = options.coverageFileName ?? \"v8-coverage.json\"\n const disabledEnvVar = options.disabledEnvVar ?? \"RB_DISABLE_COVERAGE\"\n const coverageEnabled = process.env[disabledEnvVar] !== \"1\"\n\n const { global: thresholds, targets: thresholdTargets } = normalizeThresholdOptions(options.thresholds)\n\n return {\n rootDir: resolvedRootDir,\n collectCoverageFrom,\n testResultsRoot,\n coverageReportDir,\n coverageFileName,\n thresholds,\n thresholdTargets,\n coverageEnabled,\n disabledEnvVar,\n includeAllFiles,\n }\n}\n\nfunction normalizeThresholdOptions(rawThresholds: CoverageThresholdOption | undefined): {\n global: CoverageThresholds\n targets: CoverageThresholdTarget[]\n} {\n const globalThresholds: CoverageThresholds = { ...DEFAULT_THRESHOLDS }\n const targets: CoverageThresholdTarget[] = []\n\n if (!isPlainObject(rawThresholds)) {\n return { global: globalThresholds, targets }\n }\n\n const thresholdMap = rawThresholds as CoverageThresholdMap\n\n for (const key of THRESHOLD_KEYS) {\n const value = thresholdMap[key]\n if (isThresholdValue(value)) {\n globalThresholds[key] = value\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(thresholdMap, \"global\")) {\n if (!isPlainObject(thresholdMap.global)) {\n throw new Error(\"coverage thresholds: the `global` override must be an object of metric values\")\n }\n Object.assign(globalThresholds, pickThresholdOverrides(thresholdMap.global))\n }\n\n for (const [pattern, overrides] of Object.entries(thresholdMap)) {\n if (pattern === \"global\" || THRESHOLD_KEY_SET.has(pattern)) {\n continue\n }\n\n if (!isPlainObject(overrides)) {\n throw new Error(\n `coverage thresholds: override for \"${pattern}\" must be an object containing coverage metrics`,\n )\n }\n\n targets.push({\n id: pattern,\n pattern,\n thresholds: {\n ...globalThresholds,\n ...pickThresholdOverrides(overrides),\n },\n })\n }\n\n return { global: globalThresholds, targets }\n}\n\nfunction pickThresholdOverrides(source: unknown): Partial<CoverageThresholds> {\n const overrides: Partial<CoverageThresholds> = {}\n if (!isPlainObject(source)) {\n return overrides\n }\n\n for (const key of THRESHOLD_KEYS) {\n const value = (source as any)[key]\n if (isThresholdValue(value)) {\n overrides[key] = value\n }\n }\n\n return overrides\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n}\n\nfunction isThresholdValue(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value)\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sources":["../../src/coverage/config.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport type { CoverageConfig, CoverageHarnessOptions, CoverageThresholdMap, CoverageThresholdOption, CoverageThresholdTarget, CoverageThresholds } from \"./types\"\n\n\nconst DEFAULT_THRESHOLDS = {\n branches: 60,\n functions: 75,\n lines: 75,\n statements: 75,\n}\n\nconst THRESHOLD_KEYS = Object.keys(DEFAULT_THRESHOLDS) as Array<keyof CoverageThresholds>\nconst THRESHOLD_KEY_SET = new Set<string>(THRESHOLD_KEYS as string[])\n\nexport function createCoverageConfig(options: CoverageHarnessOptions): CoverageConfig {\n const { rootDir } = options as CoverageHarnessOptions\n if (!rootDir) {\n throw new Error(\"createCoverageConfig requires a rootDir\")\n }\n\n const resolvedRootDir = path.resolve(rootDir)\n const includeAllFiles = options.includeAllFiles !== false\n\n const collectCoverageFrom = Array.isArray(options.collectCoverageFrom)\n ? options.collectCoverageFrom\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n if (collectCoverageFrom.length === 0) {\n throw new Error(\"createCoverageConfig requires a collectCoverageFrom option\")\n }\n\n const testResultsRoot = path.join(resolvedRootDir, \"build\", \"coverage\")\n const coverageReportDir = path.join(testResultsRoot, \"report\")\n const coverageFileName = options.coverageFileName ?? \"v8-coverage.json\"\n const disabledEnvVar = options.disabledEnvVar ?? \"RB_DISABLE_COVERAGE\"\n const coverageEnabled = process.env[disabledEnvVar] !== \"1\"\n\n const { global: thresholds, targets: thresholdTargets } = normalizeThresholdOptions(options.thresholds)\n\n return {\n rootDir: resolvedRootDir,\n collectCoverageFrom,\n testResultsRoot,\n coverageReportDir,\n coverageFileName,\n thresholds,\n thresholdTargets,\n coverageEnabled,\n disabledEnvVar,\n includeAllFiles,\n }\n}\n\nfunction normalizeThresholdOptions(rawThresholds: CoverageThresholdOption | undefined): {\n global: CoverageThresholds\n targets: CoverageThresholdTarget[]\n} {\n const globalThresholds: CoverageThresholds = { ...DEFAULT_THRESHOLDS }\n const targets: CoverageThresholdTarget[] = []\n\n if (!isPlainObject(rawThresholds)) {\n return { global: globalThresholds, targets }\n }\n\n const thresholdMap = rawThresholds as CoverageThresholdMap\n\n for (const key of THRESHOLD_KEYS) {\n const value = thresholdMap[key]\n if (isThresholdValue(value)) {\n globalThresholds[key] = value\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(thresholdMap, \"global\")) {\n if (!isPlainObject(thresholdMap.global)) {\n throw new Error(\"coverage thresholds: the `global` override must be an object of metric values\")\n }\n Object.assign(globalThresholds, pickThresholdOverrides(thresholdMap.global))\n }\n\n for (const [pattern, overrides] of Object.entries(thresholdMap)) {\n if (pattern === \"global\" || THRESHOLD_KEY_SET.has(pattern)) {\n continue\n }\n\n if (!isPlainObject(overrides)) {\n throw new Error(\n `coverage thresholds: override for \"${pattern}\" must be an object containing coverage metrics`,\n )\n }\n\n targets.push({\n id: pattern,\n pattern,\n thresholds: {\n ...globalThresholds,\n ...pickThresholdOverrides(overrides),\n },\n })\n }\n\n return { global: globalThresholds, targets }\n}\n\nfunction pickThresholdOverrides(source: unknown): Partial<CoverageThresholds> {\n const overrides: Partial<CoverageThresholds> = {}\n if (!isPlainObject(source)) {\n return overrides\n }\n\n for (const key of THRESHOLD_KEYS) {\n const value = (source as any)[key]\n if (isThresholdValue(value)) {\n overrides[key] = value\n }\n }\n\n return overrides\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n}\n\nfunction isThresholdValue(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value)\n}\n"],"names":["DEFAULT_THRESHOLDS","branches","functions","lines","statements","THRESHOLD_KEYS","Object","keys","THRESHOLD_KEY_SET","Set","createCoverageConfig","options","rootDir","Error","resolvedRootDir","path","resolve","includeAllFiles","collectCoverageFrom","Array","isArray","map","pattern","String","trim","filter","length","testResultsRoot","join","coverageReportDir","coverageFileName","disabledEnvVar","coverageEnabled","process","env","global","thresholds","targets","thresholdTargets","normalizeThresholdOptions","rawThresholds","globalThresholds","isPlainObject","thresholdMap","key","value","isThresholdValue","prototype","hasOwnProperty","call","assign","pickThresholdOverrides","overrides","entries","has","push","id","source","Number","isFinite"],"mappings":"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"}
@@ -4,19 +4,30 @@ const CONSOLE_SUMMARIZER = "rbCwd";
4
4
  function generateConsoleTextCoverageReport(reports, context) {
5
5
  const debug = resolveConsoleReportDebugInfo();
6
6
  const summarizer = registerConsoleSummarizer(context);
7
- writeConsoleReportDebugLog({ ...debug, summarizer });
7
+ writeConsoleReportDebugLog({
8
+ ...debug,
9
+ summarizer
10
+ });
8
11
  const reportOutput = createConsoleTextReportOutput(reports, context, {
9
12
  maxCols: debug.maxCols + 20,
10
13
  summarizer
11
14
  });
12
- return { output: stripUncoveredLineNumbersColumn(reportOutput), summarizer };
15
+ return {
16
+ output: stripUncoveredLineNumbersColumn(reportOutput),
17
+ summarizer
18
+ };
13
19
  }
14
20
  function resolveConsoleReportDebugInfo() {
15
21
  const isTTY = Boolean(process.stdout.isTTY);
16
22
  const stdoutColumns = process.stdout.columns;
17
23
  const envColumns = process.env.COLUMNS;
18
24
  const maxCols = resolveConsoleMaxCols(stdoutColumns, envColumns);
19
- return { isTTY, stdoutColumns, envColumns, maxCols };
25
+ return {
26
+ isTTY,
27
+ stdoutColumns,
28
+ envColumns,
29
+ maxCols
30
+ };
20
31
  }
21
32
  function resolveConsoleMaxCols(stdoutColumns, envColumns) {
22
33
  if (typeof stdoutColumns === "number" && Number.isFinite(stdoutColumns) && stdoutColumns > 0) {
@@ -35,14 +46,7 @@ function writeConsoleReportDebugLog({
35
46
  maxCols,
36
47
  summarizer
37
48
  }) {
38
- const message = [
39
- "[coverage] debug",
40
- `stdout.isTTY=${isTTY ? "1" : "0"}`,
41
- `stdout.columns=${stdoutColumns ?? "undefined"}`,
42
- `env.COLUMNS=${envColumns ?? "undefined"}`,
43
- `resolvedMaxCols=${maxCols}`,
44
- `summarizer=${summarizer ?? "undefined"}`
45
- ].join(" ");
49
+ const message = ["[coverage] debug", `stdout.isTTY=${isTTY ? "1" : "0"}`, `stdout.columns=${stdoutColumns ?? "undefined"}`, `env.COLUMNS=${envColumns ?? "undefined"}`, `resolvedMaxCols=${maxCols}`, `summarizer=${summarizer ?? "undefined"}`].join(" ");
46
50
  process.stderr.write(`${message}
47
51
  `);
48
52
  }
@@ -50,13 +54,19 @@ function createConsoleTextReportOutput(reports, context, options) {
50
54
  const fileWriter = context?.writer;
51
55
  const fileWriterCtor = fileWriter?.constructor;
52
56
  if (!fileWriterCtor || typeof fileWriterCtor.startCapture !== "function" || typeof fileWriterCtor.stopCapture !== "function" || typeof fileWriterCtor.getOutput !== "function" || typeof fileWriterCtor.resetOutput !== "function") {
53
- reports.create("text", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context);
57
+ reports.create("text", {
58
+ maxCols: options.maxCols,
59
+ summarizer: options.summarizer
60
+ }).execute(context);
54
61
  return "";
55
62
  }
56
63
  fileWriterCtor.resetOutput();
57
64
  fileWriterCtor.startCapture();
58
65
  try {
59
- reports.create("text", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context);
66
+ reports.create("text", {
67
+ maxCols: options.maxCols,
68
+ summarizer: options.summarizer
69
+ }).execute(context);
60
70
  } finally {
61
71
  fileWriterCtor.stopCapture();
62
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"console-text-report.js","sources":["../../src/coverage/console-text-report.ts"],"sourcesContent":["import path from \"node:path\"\n\n\nconst DEFAULT_CONSOLE_MAX_COLS = 80\nconst CONSOLE_SUMMARIZER = \"rbCwd\"\n\nexport function generateConsoleTextCoverageReport(\n reports: any,\n context: any,\n): { output: string; summarizer: string | undefined } {\n const debug = resolveConsoleReportDebugInfo()\n const summarizer = registerConsoleSummarizer(context)\n writeConsoleReportDebugLog({ ...debug, summarizer })\n\n const reportOutput = createConsoleTextReportOutput(reports, context, {\n maxCols: debug.maxCols + 20,\n summarizer,\n })\n\n return { output: stripUncoveredLineNumbersColumn(reportOutput), summarizer }\n}\n\nfunction resolveConsoleReportDebugInfo(): {\n isTTY: boolean\n stdoutColumns: number | undefined\n envColumns: string | undefined\n maxCols: number\n} {\n const isTTY = Boolean(process.stdout.isTTY)\n const stdoutColumns = process.stdout.columns\n const envColumns = process.env.COLUMNS\n const maxCols = resolveConsoleMaxCols(stdoutColumns, envColumns)\n\n return { isTTY, stdoutColumns, envColumns, maxCols }\n}\n\nfunction resolveConsoleMaxCols(stdoutColumns: number | undefined, envColumns: string | undefined): number {\n if (typeof stdoutColumns === \"number\" && Number.isFinite(stdoutColumns) && stdoutColumns > 0) {\n return stdoutColumns\n }\n\n const parsed = typeof envColumns === \"string\" ? Number.parseInt(envColumns, 10) : Number.NaN\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed\n }\n\n return DEFAULT_CONSOLE_MAX_COLS\n}\n\nfunction writeConsoleReportDebugLog({\n isTTY,\n stdoutColumns,\n envColumns,\n maxCols,\n summarizer,\n}: {\n isTTY: boolean\n stdoutColumns: number | undefined\n envColumns: string | undefined\n maxCols: number\n summarizer: string | undefined\n}): void {\n const message = [\n \"[coverage] debug\",\n `stdout.isTTY=${isTTY ? \"1\" : \"0\"}`,\n `stdout.columns=${stdoutColumns ?? \"undefined\"}`,\n `env.COLUMNS=${envColumns ?? \"undefined\"}`,\n `resolvedMaxCols=${maxCols}`,\n `summarizer=${summarizer ?? \"undefined\"}`,\n ].join(\" \")\n\n process.stderr.write(`${message}\\n`)\n}\n\nfunction createConsoleTextReportOutput(\n reports: any,\n context: any,\n options: { maxCols: number; summarizer?: string },\n): string {\n const fileWriter = context?.writer\n const fileWriterCtor = fileWriter?.constructor\n\n if (\n !fileWriterCtor\n || typeof fileWriterCtor.startCapture !== \"function\"\n || typeof fileWriterCtor.stopCapture !== \"function\"\n || typeof fileWriterCtor.getOutput !== \"function\"\n || typeof fileWriterCtor.resetOutput !== \"function\"\n ) {\n reports.create(\"text\", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context)\n return \"\"\n }\n\n fileWriterCtor.resetOutput()\n fileWriterCtor.startCapture()\n try {\n reports.create(\"text\", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context)\n } finally {\n fileWriterCtor.stopCapture()\n }\n const output = fileWriterCtor.getOutput()\n fileWriterCtor.resetOutput()\n return output\n}\n\nfunction stripUncoveredLineNumbersColumn(output: string): string {\n const lines = output.split(\"\\n\")\n const filtered = lines.map((line) => {\n const parts = line.split(\"|\")\n if (parts.length < 6) {\n return line.trimEnd()\n }\n return parts.slice(0, 5).join(\"|\").trimEnd()\n })\n return filtered.join(\"\\n\")\n}\n\nfunction registerConsoleSummarizer(context: any): string | undefined {\n const summarizerFactory = context?._summarizerFactory\n if (!summarizerFactory || typeof summarizerFactory !== \"object\") {\n return undefined\n }\n\n if (CONSOLE_SUMMARIZER in summarizerFactory) {\n return CONSOLE_SUMMARIZER\n }\n\n const pkgTree = context.getTree?.(\"pkg\")\n const pkgRoot = pkgTree?.getRoot?.()\n if (!pkgRoot) {\n return undefined\n }\n\n summarizerFactory[CONSOLE_SUMMARIZER] = createCollapsedCwdTree(pkgRoot, process.cwd())\n return CONSOLE_SUMMARIZER\n}\n\nfunction createCollapsedCwdTree(\n root: any,\n cwd: string,\n): { getRoot: () => any; visit: (visitor: any, state: any) => void } {\n const treeRoot = createCwdTreeFromCoverage(root, cwd)\n const clonedRoot = cloneReportNode(treeRoot, null)\n return {\n getRoot: () => clonedRoot,\n visit: (visitor: any, state: any) => {\n const fullVisitor = toFullVisitor(visitor)\n fullVisitor.onStart(clonedRoot, state)\n clonedRoot.visit(fullVisitor, state)\n fullVisitor.onEnd(clonedRoot, state)\n },\n }\n}\n\nfunction createCwdTreeFromCoverage(root: any, cwd: string): any {\n const proto = Object.getPrototypeOf(root)\n const pathCtor = root?.path?.constructor\n\n const fileCoverages: any[] = []\n collectFileCoverages(root, fileCoverages)\n\n const treeRoot = Object.create(proto)\n treeRoot.path = pathCtor ? new pathCtor([]) : root.path\n treeRoot.fileCoverage = null\n treeRoot.parent = null\n treeRoot.children = []\n\n const dirNodes = new Map<string, any>()\n dirNodes.set(\"\", treeRoot)\n\n for (const fileCoverage of fileCoverages) {\n const absolutePath = path.resolve(String(fileCoverage?.path ?? \"\"))\n if (!absolutePath) {\n continue\n }\n\n let relativePath = toPosix(path.relative(cwd, absolutePath))\n if (!relativePath) {\n relativePath = toPosix(absolutePath)\n }\n\n if (isInsideCwd(relativePath) && (relativePath === \"src\" || relativePath.startsWith(\"src/\"))) {\n relativePath = relativePath === \"src\" ? \"\" : relativePath.slice(\"src/\".length)\n }\n\n if (!relativePath) {\n relativePath = toPosix(path.basename(absolutePath))\n }\n\n const segments = relativePath.split(\"/\").filter(Boolean)\n if (segments.length === 0) {\n continue\n }\n\n let parent = treeRoot\n let prefix = \"\"\n\n for (let i = 0; i < segments.length - 1; i += 1) {\n prefix = prefix ? `${prefix}/${segments[i]}` : segments[i]\n const existing = dirNodes.get(prefix)\n if (existing) {\n parent = existing\n continue\n }\n\n const dirNode = Object.create(proto)\n dirNode.path = pathCtor ? new pathCtor(prefix.split(\"/\")) : root.path\n dirNode.fileCoverage = null\n dirNode.parent = parent\n dirNode.children = []\n parent.children.push(dirNode)\n dirNodes.set(prefix, dirNode)\n parent = dirNode\n }\n\n const fileNode = Object.create(proto)\n fileNode.path = pathCtor ? new pathCtor(segments) : root.path\n fileNode.fileCoverage = fileCoverage\n fileNode.parent = parent\n fileNode.children = []\n parent.children.push(fileNode)\n }\n\n sortReportTree(treeRoot)\n\n return treeRoot\n}\n\nfunction collectFileCoverages(node: any, out: any[]): void {\n if (!node || typeof node.isSummary !== \"function\") {\n return\n }\n\n if (!node.isSummary()) {\n const fileCoverage = typeof node.getFileCoverage === \"function\" ? node.getFileCoverage() : node.fileCoverage\n if (fileCoverage) {\n out.push(fileCoverage)\n }\n return\n }\n\n const children: any[] = typeof node.getChildren === \"function\" ? node.getChildren() : []\n for (const child of children) {\n collectFileCoverages(child, out)\n }\n}\n\nfunction sortReportTree(node: any): void {\n const children: any[] = Array.isArray(node?.children) ? node.children : []\n if (children.length === 0) {\n return\n }\n\n children.sort((a, b) => {\n const aKey = typeof a?.path?.toString === \"function\" ? a.path.toString() : \"\"\n const bKey = typeof b?.path?.toString === \"function\" ? b.path.toString() : \"\"\n return aKey < bKey ? -1 : aKey > bKey ? 1 : 0\n })\n\n for (const child of children) {\n sortReportTree(child)\n }\n}\n\nfunction isInsideCwd(relativePosix: string): boolean {\n if (!relativePosix) {\n return false\n }\n return !(relativePosix === \"..\" || relativePosix.startsWith(\"../\"))\n}\n\nfunction toPosix(input: string): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nfunction toFullVisitor(visitor: any): {\n onStart: (node: any, state: any) => void\n onEnd: (node: any, state: any) => void\n onSummary: (node: any, state: any) => void\n onSummaryEnd: (node: any, state: any) => void\n onDetail: (node: any, state: any) => void\n} {\n const call = (method: string) => (node: any, state: any) => {\n if (typeof visitor?.[method] === \"function\") {\n visitor[method](node, state)\n }\n }\n\n return {\n onStart: call(\"onStart\"),\n onEnd: call(\"onEnd\"),\n onSummary: call(\"onSummary\"),\n onSummaryEnd: call(\"onSummaryEnd\"),\n onDetail: call(\"onDetail\"),\n }\n}\n\nfunction cloneReportNode(node: any, parent: any): any {\n const clone = Object.create(Object.getPrototypeOf(node))\n clone.path = node.path\n clone.fileCoverage = node.fileCoverage\n clone.parent = parent\n\n const children: any[] = typeof node.getChildren === \"function\" ? node.getChildren() : []\n clone.children = children.flatMap((child) => cloneOrCollapseNode(child, clone))\n\n return clone\n}\n\nfunction cloneOrCollapseNode(node: any, parent: any): any[] {\n if (\n typeof node?.isSummary === \"function\"\n && node.isSummary()\n && typeof node.isRoot === \"function\"\n && !node.isRoot()\n && typeof node.getChildren === \"function\"\n ) {\n const children = node.getChildren()\n if (\n Array.isArray(children)\n && children.length === 1\n && typeof children[0]?.isSummary === \"function\"\n && !children[0].isSummary()\n ) {\n return [cloneReportNode(children[0], parent)]\n }\n }\n\n return [cloneReportNode(node, parent)]\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"console-text-report.js","sources":["../../src/coverage/console-text-report.ts"],"sourcesContent":["import path from \"node:path\"\n\n\nconst DEFAULT_CONSOLE_MAX_COLS = 80\nconst CONSOLE_SUMMARIZER = \"rbCwd\"\n\nexport function generateConsoleTextCoverageReport(\n reports: any,\n context: any,\n): { output: string; summarizer: string | undefined } {\n const debug = resolveConsoleReportDebugInfo()\n const summarizer = registerConsoleSummarizer(context)\n writeConsoleReportDebugLog({ ...debug, summarizer })\n\n const reportOutput = createConsoleTextReportOutput(reports, context, {\n maxCols: debug.maxCols + 20,\n summarizer,\n })\n\n return { output: stripUncoveredLineNumbersColumn(reportOutput), summarizer }\n}\n\nfunction resolveConsoleReportDebugInfo(): {\n isTTY: boolean\n stdoutColumns: number | undefined\n envColumns: string | undefined\n maxCols: number\n} {\n const isTTY = Boolean(process.stdout.isTTY)\n const stdoutColumns = process.stdout.columns\n const envColumns = process.env.COLUMNS\n const maxCols = resolveConsoleMaxCols(stdoutColumns, envColumns)\n\n return { isTTY, stdoutColumns, envColumns, maxCols }\n}\n\nfunction resolveConsoleMaxCols(stdoutColumns: number | undefined, envColumns: string | undefined): number {\n if (typeof stdoutColumns === \"number\" && Number.isFinite(stdoutColumns) && stdoutColumns > 0) {\n return stdoutColumns\n }\n\n const parsed = typeof envColumns === \"string\" ? Number.parseInt(envColumns, 10) : Number.NaN\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed\n }\n\n return DEFAULT_CONSOLE_MAX_COLS\n}\n\nfunction writeConsoleReportDebugLog({\n isTTY,\n stdoutColumns,\n envColumns,\n maxCols,\n summarizer,\n}: {\n isTTY: boolean\n stdoutColumns: number | undefined\n envColumns: string | undefined\n maxCols: number\n summarizer: string | undefined\n}): void {\n const message = [\n \"[coverage] debug\",\n `stdout.isTTY=${isTTY ? \"1\" : \"0\"}`,\n `stdout.columns=${stdoutColumns ?? \"undefined\"}`,\n `env.COLUMNS=${envColumns ?? \"undefined\"}`,\n `resolvedMaxCols=${maxCols}`,\n `summarizer=${summarizer ?? \"undefined\"}`,\n ].join(\" \")\n\n process.stderr.write(`${message}\\n`)\n}\n\nfunction createConsoleTextReportOutput(\n reports: any,\n context: any,\n options: { maxCols: number; summarizer?: string },\n): string {\n const fileWriter = context?.writer\n const fileWriterCtor = fileWriter?.constructor\n\n if (\n !fileWriterCtor\n || typeof fileWriterCtor.startCapture !== \"function\"\n || typeof fileWriterCtor.stopCapture !== \"function\"\n || typeof fileWriterCtor.getOutput !== \"function\"\n || typeof fileWriterCtor.resetOutput !== \"function\"\n ) {\n reports.create(\"text\", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context)\n return \"\"\n }\n\n fileWriterCtor.resetOutput()\n fileWriterCtor.startCapture()\n try {\n reports.create(\"text\", { maxCols: options.maxCols, summarizer: options.summarizer }).execute(context)\n } finally {\n fileWriterCtor.stopCapture()\n }\n const output = fileWriterCtor.getOutput()\n fileWriterCtor.resetOutput()\n return output\n}\n\nfunction stripUncoveredLineNumbersColumn(output: string): string {\n const lines = output.split(\"\\n\")\n const filtered = lines.map((line) => {\n const parts = line.split(\"|\")\n if (parts.length < 6) {\n return line.trimEnd()\n }\n return parts.slice(0, 5).join(\"|\").trimEnd()\n })\n return filtered.join(\"\\n\")\n}\n\nfunction registerConsoleSummarizer(context: any): string | undefined {\n const summarizerFactory = context?._summarizerFactory\n if (!summarizerFactory || typeof summarizerFactory !== \"object\") {\n return undefined\n }\n\n if (CONSOLE_SUMMARIZER in summarizerFactory) {\n return CONSOLE_SUMMARIZER\n }\n\n const pkgTree = context.getTree?.(\"pkg\")\n const pkgRoot = pkgTree?.getRoot?.()\n if (!pkgRoot) {\n return undefined\n }\n\n summarizerFactory[CONSOLE_SUMMARIZER] = createCollapsedCwdTree(pkgRoot, process.cwd())\n return CONSOLE_SUMMARIZER\n}\n\nfunction createCollapsedCwdTree(\n root: any,\n cwd: string,\n): { getRoot: () => any; visit: (visitor: any, state: any) => void } {\n const treeRoot = createCwdTreeFromCoverage(root, cwd)\n const clonedRoot = cloneReportNode(treeRoot, null)\n return {\n getRoot: () => clonedRoot,\n visit: (visitor: any, state: any) => {\n const fullVisitor = toFullVisitor(visitor)\n fullVisitor.onStart(clonedRoot, state)\n clonedRoot.visit(fullVisitor, state)\n fullVisitor.onEnd(clonedRoot, state)\n },\n }\n}\n\nfunction createCwdTreeFromCoverage(root: any, cwd: string): any {\n const proto = Object.getPrototypeOf(root)\n const pathCtor = root?.path?.constructor\n\n const fileCoverages: any[] = []\n collectFileCoverages(root, fileCoverages)\n\n const treeRoot = Object.create(proto)\n treeRoot.path = pathCtor ? new pathCtor([]) : root.path\n treeRoot.fileCoverage = null\n treeRoot.parent = null\n treeRoot.children = []\n\n const dirNodes = new Map<string, any>()\n dirNodes.set(\"\", treeRoot)\n\n for (const fileCoverage of fileCoverages) {\n const absolutePath = path.resolve(String(fileCoverage?.path ?? \"\"))\n if (!absolutePath) {\n continue\n }\n\n let relativePath = toPosix(path.relative(cwd, absolutePath))\n if (!relativePath) {\n relativePath = toPosix(absolutePath)\n }\n\n if (isInsideCwd(relativePath) && (relativePath === \"src\" || relativePath.startsWith(\"src/\"))) {\n relativePath = relativePath === \"src\" ? \"\" : relativePath.slice(\"src/\".length)\n }\n\n if (!relativePath) {\n relativePath = toPosix(path.basename(absolutePath))\n }\n\n const segments = relativePath.split(\"/\").filter(Boolean)\n if (segments.length === 0) {\n continue\n }\n\n let parent = treeRoot\n let prefix = \"\"\n\n for (let i = 0; i < segments.length - 1; i += 1) {\n prefix = prefix ? `${prefix}/${segments[i]}` : segments[i]\n const existing = dirNodes.get(prefix)\n if (existing) {\n parent = existing\n continue\n }\n\n const dirNode = Object.create(proto)\n dirNode.path = pathCtor ? new pathCtor(prefix.split(\"/\")) : root.path\n dirNode.fileCoverage = null\n dirNode.parent = parent\n dirNode.children = []\n parent.children.push(dirNode)\n dirNodes.set(prefix, dirNode)\n parent = dirNode\n }\n\n const fileNode = Object.create(proto)\n fileNode.path = pathCtor ? new pathCtor(segments) : root.path\n fileNode.fileCoverage = fileCoverage\n fileNode.parent = parent\n fileNode.children = []\n parent.children.push(fileNode)\n }\n\n sortReportTree(treeRoot)\n\n return treeRoot\n}\n\nfunction collectFileCoverages(node: any, out: any[]): void {\n if (!node || typeof node.isSummary !== \"function\") {\n return\n }\n\n if (!node.isSummary()) {\n const fileCoverage = typeof node.getFileCoverage === \"function\" ? node.getFileCoverage() : node.fileCoverage\n if (fileCoverage) {\n out.push(fileCoverage)\n }\n return\n }\n\n const children: any[] = typeof node.getChildren === \"function\" ? node.getChildren() : []\n for (const child of children) {\n collectFileCoverages(child, out)\n }\n}\n\nfunction sortReportTree(node: any): void {\n const children: any[] = Array.isArray(node?.children) ? node.children : []\n if (children.length === 0) {\n return\n }\n\n children.sort((a, b) => {\n const aKey = typeof a?.path?.toString === \"function\" ? a.path.toString() : \"\"\n const bKey = typeof b?.path?.toString === \"function\" ? b.path.toString() : \"\"\n return aKey < bKey ? -1 : aKey > bKey ? 1 : 0\n })\n\n for (const child of children) {\n sortReportTree(child)\n }\n}\n\nfunction isInsideCwd(relativePosix: string): boolean {\n if (!relativePosix) {\n return false\n }\n return !(relativePosix === \"..\" || relativePosix.startsWith(\"../\"))\n}\n\nfunction toPosix(input: string): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nfunction toFullVisitor(visitor: any): {\n onStart: (node: any, state: any) => void\n onEnd: (node: any, state: any) => void\n onSummary: (node: any, state: any) => void\n onSummaryEnd: (node: any, state: any) => void\n onDetail: (node: any, state: any) => void\n} {\n const call = (method: string) => (node: any, state: any) => {\n if (typeof visitor?.[method] === \"function\") {\n visitor[method](node, state)\n }\n }\n\n return {\n onStart: call(\"onStart\"),\n onEnd: call(\"onEnd\"),\n onSummary: call(\"onSummary\"),\n onSummaryEnd: call(\"onSummaryEnd\"),\n onDetail: call(\"onDetail\"),\n }\n}\n\nfunction cloneReportNode(node: any, parent: any): any {\n const clone = Object.create(Object.getPrototypeOf(node))\n clone.path = node.path\n clone.fileCoverage = node.fileCoverage\n clone.parent = parent\n\n const children: any[] = typeof node.getChildren === \"function\" ? node.getChildren() : []\n clone.children = children.flatMap((child) => cloneOrCollapseNode(child, clone))\n\n return clone\n}\n\nfunction cloneOrCollapseNode(node: any, parent: any): any[] {\n if (\n typeof node?.isSummary === \"function\"\n && node.isSummary()\n && typeof node.isRoot === \"function\"\n && !node.isRoot()\n && typeof node.getChildren === \"function\"\n ) {\n const children = node.getChildren()\n if (\n Array.isArray(children)\n && children.length === 1\n && typeof children[0]?.isSummary === \"function\"\n && !children[0].isSummary()\n ) {\n return [cloneReportNode(children[0], parent)]\n }\n }\n\n return [cloneReportNode(node, parent)]\n}\n"],"names":["DEFAULT_CONSOLE_MAX_COLS","CONSOLE_SUMMARIZER","generateConsoleTextCoverageReport","reports","context","debug","resolveConsoleReportDebugInfo","summarizer","registerConsoleSummarizer","writeConsoleReportDebugLog","reportOutput","createConsoleTextReportOutput","maxCols","output","stripUncoveredLineNumbersColumn","isTTY","Boolean","process","stdout","stdoutColumns","columns","envColumns","env","COLUMNS","resolveConsoleMaxCols","Number","isFinite","parsed","parseInt","NaN","message","join","stderr","write","options","fileWriter","writer","fileWriterCtor","constructor","startCapture","stopCapture","getOutput","resetOutput","create","execute","lines","split","filtered","map","line","parts","length","trimEnd","slice","summarizerFactory","_summarizerFactory","undefined","pkgTree","getTree","pkgRoot","getRoot","createCollapsedCwdTree","cwd","root","treeRoot","createCwdTreeFromCoverage","clonedRoot","cloneReportNode","visit","visitor","state","fullVisitor","toFullVisitor","onStart","onEnd","proto","Object","getPrototypeOf","pathCtor","path","fileCoverages","collectFileCoverages","fileCoverage","parent","children","dirNodes","Map","set","absolutePath","resolve","String","relativePath","toPosix","relative","isInsideCwd","startsWith","basename","segments","filter","prefix","i","existing","get","dirNode","push","fileNode","sortReportTree","node","out","isSummary","getFileCoverage","getChildren","child","Array","isArray","sort","a","b","aKey","toString","bKey","relativePosix","input","sep","call","method","onSummary","onSummaryEnd","onDetail","clone","flatMap","cloneOrCollapseNode","isRoot"],"mappings":"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"}
@@ -2,29 +2,24 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  function resolveCoverageRoots(config) {
4
4
  const buildDir = path.join(config.rootDir, "build");
5
- const roots = [
6
- path.join(buildDir, "playwright", "coverage"),
7
- path.join(buildDir, "vitest", "coverage"),
8
- path.join(config.testResultsRoot, "playwright"),
9
- path.join(config.testResultsRoot, "vitest")
10
- ];
5
+ const roots = [path.join(buildDir, "playwright", "coverage"), path.join(buildDir, "vitest", "coverage"), path.join(config.testResultsRoot, "playwright"), path.join(config.testResultsRoot, "vitest")];
11
6
  return Array.from(new Set(roots.map((root) => path.resolve(root))));
12
7
  }
13
8
  async function findCoverageFiles(config, root) {
14
9
  const roots = root === void 0 ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root];
15
10
  const files = [];
16
11
  async function walk(current) {
17
- const entries = await fs.readdir(current, { withFileTypes: true });
18
- await Promise.all(
19
- entries.map(async (entry) => {
20
- const entryPath = path.join(current, entry.name);
21
- if (entry.isDirectory()) {
22
- await walk(entryPath);
23
- } else if (entry.isFile() && entry.name === config.coverageFileName) {
24
- files.push(entryPath);
25
- }
26
- })
27
- );
12
+ const entries = await fs.readdir(current, {
13
+ withFileTypes: true
14
+ });
15
+ await Promise.all(entries.map(async (entry) => {
16
+ const entryPath = path.join(current, entry.name);
17
+ if (entry.isDirectory()) {
18
+ await walk(entryPath);
19
+ } else if (entry.isFile() && entry.name === config.coverageFileName) {
20
+ files.push(entryPath);
21
+ }
22
+ }));
28
23
  }
29
24
  for (const root2 of roots) {
30
25
  try {
@@ -42,17 +37,19 @@ async function findCoverageFiles(config, root) {
42
37
  async function removeCoverageFiles(config, root) {
43
38
  const roots = root === void 0 ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root];
44
39
  async function walk(current) {
45
- const entries = await fs.readdir(current, { withFileTypes: true });
46
- await Promise.all(
47
- entries.map(async (entry) => {
48
- const entryPath = path.join(current, entry.name);
49
- if (entry.isDirectory()) {
50
- await walk(entryPath);
51
- } else if (entry.isFile() && entry.name === config.coverageFileName) {
52
- await fs.rm(entryPath, { force: true });
53
- }
54
- })
55
- );
40
+ const entries = await fs.readdir(current, {
41
+ withFileTypes: true
42
+ });
43
+ await Promise.all(entries.map(async (entry) => {
44
+ const entryPath = path.join(current, entry.name);
45
+ if (entry.isDirectory()) {
46
+ await walk(entryPath);
47
+ } else if (entry.isFile() && entry.name === config.coverageFileName) {
48
+ await fs.rm(entryPath, {
49
+ force: true
50
+ });
51
+ }
52
+ }));
56
53
  }
57
54
  for (const root2 of roots) {
58
55
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sources":["../../src/coverage/files.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CoverageConfig } from \"./types\"\n\n\nfunction resolveCoverageRoots(config: CoverageConfig): string[] {\n const buildDir = path.join(config.rootDir, \"build\")\n const roots = [\n path.join(buildDir, \"playwright\", \"coverage\"),\n path.join(buildDir, \"vitest\", \"coverage\"),\n path.join(config.testResultsRoot, \"playwright\"),\n path.join(config.testResultsRoot, \"vitest\"),\n ]\n\n return Array.from(new Set(roots.map((root) => path.resolve(root))))\n}\n\nexport async function findCoverageFiles(\n config: CoverageConfig,\n root?: string | string[],\n): Promise<string[]> {\n const roots = root === undefined ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root]\n const files: string[] = []\n\n async function walk(current: string): Promise<void> {\n const entries = await fs.readdir(current, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n const entryPath = path.join(current, entry.name)\n if (entry.isDirectory()) {\n await walk(entryPath)\n } else if (entry.isFile() && entry.name === config.coverageFileName) {\n files.push(entryPath)\n }\n }),\n )\n }\n\n for (const root of roots) {\n try {\n const stats = await fs.stat(root)\n if (!stats.isDirectory()) {\n continue\n }\n } catch {\n continue\n }\n\n await walk(root)\n }\n\n return files.sort()\n}\n\nexport async function removeCoverageFiles(\n config: CoverageConfig,\n root?: string | string[],\n): Promise<void> {\n const roots = root === undefined ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root]\n\n async function walk(current: string): Promise<void> {\n const entries = await fs.readdir(current, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n const entryPath = path.join(current, entry.name)\n if (entry.isDirectory()) {\n await walk(entryPath)\n } else if (entry.isFile() && entry.name === config.coverageFileName) {\n await fs.rm(entryPath, { force: true })\n }\n }),\n )\n }\n\n for (const root of roots) {\n try {\n await walk(root)\n } catch {\n // ignore cleanup errors\n }\n }\n}\n"],"names":["root"],"mappings":";;AAMA,SAAS,qBAAqB,QAAkC;AAC9D,QAAM,WAAW,KAAK,KAAK,OAAO,SAAS,OAAO;AAClD,QAAM,QAAQ;AAAA,IACZ,KAAK,KAAK,UAAU,cAAc,UAAU;AAAA,IAC5C,KAAK,KAAK,UAAU,UAAU,UAAU;AAAA,IACxC,KAAK,KAAK,OAAO,iBAAiB,YAAY;AAAA,IAC9C,KAAK,KAAK,OAAO,iBAAiB,QAAQ;AAAA,EAAA;AAG5C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC;AACpE;AAEA,eAAsB,kBACpB,QACA,MACmB;AACnB,QAAM,QAAQ,SAAS,SAAY,qBAAqB,MAAM,IAAI,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AACpG,QAAM,QAAkB,CAAA;AAExB,iBAAe,KAAK,SAAgC;AAClD,UAAM,UAAU,MAAM,GAAG,QAAQ,SAAS,EAAE,eAAe,MAAM;AACjE,UAAM,QAAQ;AAAA,MACZ,QAAQ,IAAI,OAAO,UAAU;AAC3B,cAAM,YAAY,KAAK,KAAK,SAAS,MAAM,IAAI;AAC/C,YAAI,MAAM,eAAe;AACvB,gBAAM,KAAK,SAAS;AAAA,QACtB,WAAW,MAAM,OAAA,KAAY,MAAM,SAAS,OAAO,kBAAkB;AACnE,gBAAM,KAAK,SAAS;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IAAA;AAAA,EAEL;AAEA,aAAWA,SAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAQ,MAAM,GAAG,KAAKA,KAAI;AAChC,UAAI,CAAC,MAAM,eAAe;AACxB;AAAA,MACF;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAEA,UAAM,KAAKA,KAAI;AAAA,EACjB;AAEA,SAAO,MAAM,KAAA;AACf;AAEA,eAAsB,oBACpB,QACA,MACe;AACf,QAAM,QAAQ,SAAS,SAAY,qBAAqB,MAAM,IAAI,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAEpG,iBAAe,KAAK,SAAgC;AAClD,UAAM,UAAU,MAAM,GAAG,QAAQ,SAAS,EAAE,eAAe,MAAM;AACjE,UAAM,QAAQ;AAAA,MACZ,QAAQ,IAAI,OAAO,UAAU;AAC3B,cAAM,YAAY,KAAK,KAAK,SAAS,MAAM,IAAI;AAC/C,YAAI,MAAM,eAAe;AACvB,gBAAM,KAAK,SAAS;AAAA,QACtB,WAAW,MAAM,OAAA,KAAY,MAAM,SAAS,OAAO,kBAAkB;AACnE,gBAAM,GAAG,GAAG,WAAW,EAAE,OAAO,MAAM;AAAA,QACxC;AAAA,MACF,CAAC;AAAA,IAAA;AAAA,EAEL;AAEA,aAAWA,SAAQ,OAAO;AACxB,QAAI;AACF,YAAM,KAAKA,KAAI;AAAA,IACjB,QAAQ;AAAA,IAER;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"files.js","sources":["../../src/coverage/files.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CoverageConfig } from \"./types\"\n\n\nfunction resolveCoverageRoots(config: CoverageConfig): string[] {\n const buildDir = path.join(config.rootDir, \"build\")\n const roots = [\n path.join(buildDir, \"playwright\", \"coverage\"),\n path.join(buildDir, \"vitest\", \"coverage\"),\n path.join(config.testResultsRoot, \"playwright\"),\n path.join(config.testResultsRoot, \"vitest\"),\n ]\n\n return Array.from(new Set(roots.map((root) => path.resolve(root))))\n}\n\nexport async function findCoverageFiles(\n config: CoverageConfig,\n root?: string | string[],\n): Promise<string[]> {\n const roots = root === undefined ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root]\n const files: string[] = []\n\n async function walk(current: string): Promise<void> {\n const entries = await fs.readdir(current, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n const entryPath = path.join(current, entry.name)\n if (entry.isDirectory()) {\n await walk(entryPath)\n } else if (entry.isFile() && entry.name === config.coverageFileName) {\n files.push(entryPath)\n }\n }),\n )\n }\n\n for (const root of roots) {\n try {\n const stats = await fs.stat(root)\n if (!stats.isDirectory()) {\n continue\n }\n } catch {\n continue\n }\n\n await walk(root)\n }\n\n return files.sort()\n}\n\nexport async function removeCoverageFiles(\n config: CoverageConfig,\n root?: string | string[],\n): Promise<void> {\n const roots = root === undefined ? resolveCoverageRoots(config) : Array.isArray(root) ? root : [root]\n\n async function walk(current: string): Promise<void> {\n const entries = await fs.readdir(current, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n const entryPath = path.join(current, entry.name)\n if (entry.isDirectory()) {\n await walk(entryPath)\n } else if (entry.isFile() && entry.name === config.coverageFileName) {\n await fs.rm(entryPath, { force: true })\n }\n }),\n )\n }\n\n for (const root of roots) {\n try {\n await walk(root)\n } catch {\n // ignore cleanup errors\n }\n }\n}\n"],"names":["resolveCoverageRoots","config","buildDir","path","join","rootDir","roots","testResultsRoot","Array","from","Set","map","root","resolve","findCoverageFiles","undefined","isArray","files","walk","current","entries","fs","readdir","withFileTypes","Promise","all","entry","entryPath","name","isDirectory","isFile","coverageFileName","push","stats","stat","sort","removeCoverageFiles","rm","force"],"mappings":";;AAMA,SAASA,qBAAqBC,QAAkC;AAC9D,QAAMC,WAAWC,KAAKC,KAAKH,OAAOI,SAAS,OAAO;AAClD,QAAMC,QAAQ,CACZH,KAAKC,KAAKF,UAAU,cAAc,UAAU,GAC5CC,KAAKC,KAAKF,UAAU,UAAU,UAAU,GACxCC,KAAKC,KAAKH,OAAOM,iBAAiB,YAAY,GAC9CJ,KAAKC,KAAKH,OAAOM,iBAAiB,QAAQ,CAAC;AAG7C,SAAOC,MAAMC,KAAK,IAAIC,IAAIJ,MAAMK,IAAKC,CAAAA,SAAST,KAAKU,QAAQD,IAAI,CAAC,CAAC,CAAC;AACpE;AAEA,eAAsBE,kBACpBb,QACAW,MACmB;AACnB,QAAMN,QAAQM,SAASG,SAAYf,qBAAqBC,MAAM,IAAIO,MAAMQ,QAAQJ,IAAI,IAAIA,OAAO,CAACA,IAAI;AACpG,QAAMK,QAAkB,CAAA;AAExB,iBAAeC,KAAKC,SAAgC;AAClD,UAAMC,UAAU,MAAMC,GAAGC,QAAQH,SAAS;AAAA,MAAEI,eAAe;AAAA,IAAA,CAAM;AACjE,UAAMC,QAAQC,IACZL,QAAQT,IAAI,OAAOe,UAAU;AAC3B,YAAMC,YAAYxB,KAAKC,KAAKe,SAASO,MAAME,IAAI;AAC/C,UAAIF,MAAMG,eAAe;AACvB,cAAMX,KAAKS,SAAS;AAAA,MACtB,WAAWD,MAAMI,OAAAA,KAAYJ,MAAME,SAAS3B,OAAO8B,kBAAkB;AACnEd,cAAMe,KAAKL,SAAS;AAAA,MACtB;AAAA,IACF,CAAC,CACH;AAAA,EACF;AAEA,aAAWf,SAAQN,OAAO;AACxB,QAAI;AACF,YAAM2B,QAAQ,MAAMZ,GAAGa,KAAKtB,KAAI;AAChC,UAAI,CAACqB,MAAMJ,eAAe;AACxB;AAAA,MACF;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAEA,UAAMX,KAAKN,KAAI;AAAA,EACjB;AAEA,SAAOK,MAAMkB,KAAAA;AACf;AAEA,eAAsBC,oBACpBnC,QACAW,MACe;AACf,QAAMN,QAAQM,SAASG,SAAYf,qBAAqBC,MAAM,IAAIO,MAAMQ,QAAQJ,IAAI,IAAIA,OAAO,CAACA,IAAI;AAEpG,iBAAeM,KAAKC,SAAgC;AAClD,UAAMC,UAAU,MAAMC,GAAGC,QAAQH,SAAS;AAAA,MAAEI,eAAe;AAAA,IAAA,CAAM;AACjE,UAAMC,QAAQC,IACZL,QAAQT,IAAI,OAAOe,UAAU;AAC3B,YAAMC,YAAYxB,KAAKC,KAAKe,SAASO,MAAME,IAAI;AAC/C,UAAIF,MAAMG,eAAe;AACvB,cAAMX,KAAKS,SAAS;AAAA,MACtB,WAAWD,MAAMI,OAAAA,KAAYJ,MAAME,SAAS3B,OAAO8B,kBAAkB;AACnE,cAAMV,GAAGgB,GAAGV,WAAW;AAAA,UAAEW,OAAO;AAAA,QAAA,CAAM;AAAA,MACxC;AAAA,IACF,CAAC,CACH;AAAA,EACF;AAEA,aAAW1B,SAAQN,OAAO;AACxB,QAAI;AACF,YAAMY,KAAKN,KAAI;AAAA,IACjB,QAAQ;AAAA,IACN;AAAA,EAEJ;AACF;"}
@@ -14,7 +14,9 @@ function noopTracker() {
14
14
  }
15
15
  function createCoverageFixtures(baseTest, config) {
16
16
  return baseTest.extend({
17
- page: async ({ page }, use, testInfo) => {
17
+ page: async ({
18
+ page
19
+ }, use, testInfo) => {
18
20
  let tracker = noopTracker();
19
21
  if (config.coverageEnabled && isChromiumPage(page)) {
20
22
  try {