supercov 4.24.6 → 4.24.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/supported-suites.md +7 -0
- package/package.json +9 -9
- package/runtime/javascript/atomic.mjs +42 -2
- package/runtime/javascript/bunTest.mjs +4 -0
- package/runtime/javascript/register.mjs +8 -114
- package/runtime/javascript/resolve-loader.mjs +4 -0
- package/runtime/javascript/runnerEntry.mjs +108 -0
package/docs/supported-suites.md
CHANGED
|
@@ -77,6 +77,13 @@ Bun keeps its own formatted reporter titles. Async test bodies retain their
|
|
|
77
77
|
identity across `await`, including concurrent execution. Lifecycle hooks have
|
|
78
78
|
separate setup identities and do not credit their coverage to the test body.
|
|
79
79
|
|
|
80
|
+
Bun can also run another test runner by its entry point, such as
|
|
81
|
+
`bun node_modules/vitest/vitest.mjs run` or `bun node_modules/mocha/bin/mocha.js`.
|
|
82
|
+
The Bun adapter sets that runner up as Node's preload would: Vitest gets
|
|
83
|
+
Supercov's generated config, which merges the project's own (including one given
|
|
84
|
+
by `--config`), and Mocha's runner is patched before it loads. Their tests are
|
|
85
|
+
attributed as they are under Node.
|
|
86
|
+
|
|
80
87
|
Callback completion supplies the recorded outcome. If Bun interrupts a callback
|
|
81
88
|
before it completes, Supercov preserves its named coverage with an **unknown**
|
|
82
89
|
outcome. Bun's final runner verdict can additionally reflect a timeout, hook
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supercov",
|
|
3
|
-
"version": "4.24.
|
|
3
|
+
"version": "4.24.8",
|
|
4
4
|
"description": "Coverage, security and code quality for coding agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"coverage",
|
|
@@ -123,14 +123,14 @@
|
|
|
123
123
|
"test:windows-tls": "node scripts/windows-tls-test.mjs"
|
|
124
124
|
},
|
|
125
125
|
"optionalDependencies": {
|
|
126
|
-
"@supercov/cli-darwin-arm64": "4.24.
|
|
127
|
-
"@supercov/cli-darwin-x64": "4.24.
|
|
128
|
-
"@supercov/cli-linux-arm64-gnu": "4.24.
|
|
129
|
-
"@supercov/cli-linux-arm64-musl": "4.24.
|
|
130
|
-
"@supercov/cli-linux-x64-gnu": "4.24.
|
|
131
|
-
"@supercov/cli-linux-x64-musl": "4.24.
|
|
132
|
-
"@supercov/cli-win32-arm64": "4.24.
|
|
133
|
-
"@supercov/cli-win32-x64": "4.24.
|
|
126
|
+
"@supercov/cli-darwin-arm64": "4.24.8",
|
|
127
|
+
"@supercov/cli-darwin-x64": "4.24.8",
|
|
128
|
+
"@supercov/cli-linux-arm64-gnu": "4.24.8",
|
|
129
|
+
"@supercov/cli-linux-arm64-musl": "4.24.8",
|
|
130
|
+
"@supercov/cli-linux-x64-gnu": "4.24.8",
|
|
131
|
+
"@supercov/cli-linux-x64-musl": "4.24.8",
|
|
132
|
+
"@supercov/cli-win32-arm64": "4.24.8",
|
|
133
|
+
"@supercov/cli-win32-x64": "4.24.8"
|
|
134
134
|
},
|
|
135
135
|
"peerDependencies": {
|
|
136
136
|
"@playwright/test": ">=1.55.0",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { appendFileSync, chmodSync, existsSync, mkdirSync, openSync, closeSync, fsyncSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
1
|
+
import fs, { appendFileSync, chmodSync, existsSync, mkdirSync, openSync, closeSync, fsyncSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import { syncBuiltinESMExports } from "node:module";
|
|
4
|
+
import { threadId } from "node:worker_threads";
|
|
5
|
+
import { dirname, resolve, sep } from "node:path";
|
|
4
6
|
import { Buffer } from "node:buffer";
|
|
5
7
|
|
|
6
8
|
// In a container Supercov's `docker` launcher mounts the run's directory
|
|
@@ -146,3 +148,41 @@ export function appendEvidenceRecord(directory, prefix, payload) {
|
|
|
146
148
|
append(journal.path, line);
|
|
147
149
|
journal.size += Buffer.byteLength(line);
|
|
148
150
|
}
|
|
151
|
+
|
|
152
|
+
// Playwright 1.59 writes each file it compiles into its cache in place and
|
|
153
|
+
// reads it back unchecked: a process that read one while another wrote it
|
|
154
|
+
// ran an empty module -- a config of no `default` failed at "Cannot add
|
|
155
|
+
// property metadata, object is not extensible", a test file at "does not
|
|
156
|
+
// provide an export named". The cache a run gives it starts empty and is
|
|
157
|
+
// shared by every Playwright of the run, the containers a sealed suite execs
|
|
158
|
+
// into among them, so every first compile raced; there each file is written
|
|
159
|
+
// whole, or is not there yet and is compiled again. A file written beside the
|
|
160
|
+
// cache's folders, not in one, is never taken for an old entry and removed.
|
|
161
|
+
//
|
|
162
|
+
// Playwright compiles in two threads: the config and CommonJS files in the
|
|
163
|
+
// process's own, ES modules in the thread its loader hooks run in, which has
|
|
164
|
+
// its own `fs` and does not run `--import`. Each calls this. The partial
|
|
165
|
+
// file's name is unique to the write: a process ID repeats across containers
|
|
166
|
+
// and both threads of one process count from zero.
|
|
167
|
+
let cacheWritesWhole = false;
|
|
168
|
+
export function writePlaywrightCacheWhole() {
|
|
169
|
+
const transformCache = process.env.PWTEST_CACHE_DIR;
|
|
170
|
+
if (!transformCache || cacheWritesWhole)
|
|
171
|
+
return;
|
|
172
|
+
cacheWritesWhole = true;
|
|
173
|
+
const cacheFolder = resolve(transformCache) + sep;
|
|
174
|
+
const writeFileSync = fs.writeFileSync;
|
|
175
|
+
fs.writeFileSync = function (file, ...rest) {
|
|
176
|
+
if (typeof file !== "string" || !resolve(file).startsWith(cacheFolder))
|
|
177
|
+
return writeFileSync.call(this, file, ...rest);
|
|
178
|
+
const partial = resolve(transformCache, `.writing-${process.pid}-${threadId}-${randomUUID()}`);
|
|
179
|
+
try {
|
|
180
|
+
writeFileSync.call(this, partial, ...rest);
|
|
181
|
+
fs.renameSync(partial, file);
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
fs.rmSync(partial, { force: true });
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
syncBuiltinESMExports();
|
|
188
|
+
}
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
// existing API so both keep native test registration and execution semantics.
|
|
6
6
|
import * as runtime from "./runtime.mjs";
|
|
7
7
|
import { callerLocation, runnerExecutionScope, runnerTestId, writeRunnerEvidence } from "./runnerEvidence.mjs";
|
|
8
|
+
import { adaptRunnerEntry } from "./runnerEntry.mjs";
|
|
9
|
+
|
|
10
|
+
// Bun runs no Node preload: a runner it starts is adapted here.
|
|
11
|
+
await adaptRunnerEntry(process.argv[1]?.replaceAll("\\", "/") ?? "");
|
|
8
12
|
|
|
9
13
|
const adapted = new WeakSet();
|
|
10
14
|
const nativeJest = Bun.jest;
|
|
@@ -12,28 +12,11 @@ import path, { basename, dirname, isAbsolute, relative, resolve, sep } from "nod
|
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { installLaunchSupervisor, wrapImportedCapability } from "./launchSupervisor.mjs";
|
|
14
14
|
import { __supercovBindCapabilityWrapper } from "./capability.mjs";
|
|
15
|
+
import { adaptRunnerEntry, noteSkippedCoverageThresholds } from "./runnerEntry.mjs";
|
|
16
|
+
import { writePlaywrightCacheWhole } from "./atomic.mjs";
|
|
15
17
|
installLaunchSupervisor();
|
|
16
|
-
// Playwright
|
|
17
|
-
|
|
18
|
-
// ran an empty module, and a config of no `default` failed at "Cannot add
|
|
19
|
-
// property metadata, object is not extensible". The cache a run gives it
|
|
20
|
-
// starts empty, so every run compiled; there each file is written whole, or
|
|
21
|
-
// is not there yet and is compiled again. A file written beside the cache's
|
|
22
|
-
// folders, not in one, is never taken for an old entry and removed.
|
|
23
|
-
const transformCache = process.env.PWTEST_CACHE_DIR;
|
|
24
|
-
if (transformCache) {
|
|
25
|
-
const cacheFolder = resolve(transformCache) + sep;
|
|
26
|
-
const writeFileSync = fs.writeFileSync;
|
|
27
|
-
let written = 0;
|
|
28
|
-
fs.writeFileSync = function (file, ...rest) {
|
|
29
|
-
if (typeof file !== "string" || !resolve(file).startsWith(cacheFolder))
|
|
30
|
-
return writeFileSync.call(this, file, ...rest);
|
|
31
|
-
const partial = resolve(transformCache, `.writing-${process.pid}-${written++}`);
|
|
32
|
-
writeFileSync.call(this, partial, ...rest);
|
|
33
|
-
fs.renameSync(partial, file);
|
|
34
|
-
};
|
|
35
|
-
syncBuiltinESMExports();
|
|
36
|
-
}
|
|
18
|
+
// Playwright's compile cache, written whole (atomic.mjs says why).
|
|
19
|
+
writePlaywrightCacheWhole();
|
|
37
20
|
// Instrumented sources import the browser-safe capability seam; bind the
|
|
38
21
|
// real supervisor implementation before any user module evaluates.
|
|
39
22
|
__supercovBindCapabilityWrapper(wrapImportedCapability);
|
|
@@ -167,7 +150,6 @@ syncBuiltinESMExports();
|
|
|
167
150
|
// is Vitest, replace its config with our generated merging config before the
|
|
168
151
|
// CLI parses argv. This is what makes `supercov -- npm test` work
|
|
169
152
|
// without editing package scripts, Vitest configs, setup files, or test imports.
|
|
170
|
-
const generatedVitestConfig = process.env.SUPERCOV_GENERATED_VITEST_CONFIG;
|
|
171
153
|
const generatedPlaywrightConfig = process.env.SUPERCOV_GENERATED_PLAYWRIGHT_CONFIG;
|
|
172
154
|
const entrypoint = process.argv[1]?.replaceAll("\\", "/") ?? "";
|
|
173
155
|
// Node's own test coverage filters files by `--test-coverage-include` and
|
|
@@ -789,19 +771,9 @@ function installAuthoredSourceView() {
|
|
|
789
771
|
};
|
|
790
772
|
syncBuiltinESMExports();
|
|
791
773
|
}
|
|
792
|
-
//
|
|
793
|
-
//
|
|
794
|
-
|
|
795
|
-
// every branch (80%, 83.33%, 87.5%). The tool still runs and reports; its
|
|
796
|
-
// thresholds are not checked, and the run says so once. Jest's and Vitest's
|
|
797
|
-
// thresholds are dropped from the configurations Supercov hands them, which
|
|
798
|
-
// call this too.
|
|
799
|
-
process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS__ ??= (tool) => {
|
|
800
|
-
if (process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS_NOTED__)
|
|
801
|
-
return;
|
|
802
|
-
process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS_NOTED__ = true;
|
|
803
|
-
console.error(`[supercov] ${tool}'s coverage thresholds were not checked: under Supercov, ${tool} measures the instrumented copy, probes included. Supercov's own report has this run's coverage.`);
|
|
804
|
-
};
|
|
774
|
+
// Jest's and Vitest's thresholds are dropped from the configurations Supercov
|
|
775
|
+
// hands them, which call this too.
|
|
776
|
+
process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS__ ??= noteSkippedCoverageThresholds;
|
|
805
777
|
const coverageTool = /\/node_modules\/(?:\.bin\/(c8|nyc)|(c8|nyc)\/bin\/(?:c8|nyc)\.js)$/.exec(entrypoint);
|
|
806
778
|
if (coverageTool)
|
|
807
779
|
skipCoverageThresholds(coverageTool[1] ?? coverageTool[2]);
|
|
@@ -1004,59 +976,7 @@ register(new URL("./resolve-loader.mjs", import.meta.url), {
|
|
|
1004
976
|
if (process.env.SUPERCOV_DEBUG === "1") {
|
|
1005
977
|
console.error("[supercov] preload", { entrypoint });
|
|
1006
978
|
}
|
|
1007
|
-
|
|
1008
|
-
// Worker processes inherit this marker. In particular, do not eagerly load
|
|
1009
|
-
// Playwright's expect implementation in a Vitest worker: both runners use
|
|
1010
|
-
// the Jest matcher registry symbol and intentionally cannot coexist there.
|
|
1011
|
-
process.env.SUPERCOV_INSIDE_VITEST = "1";
|
|
1012
|
-
let originalConfig;
|
|
1013
|
-
for (let index = 2; index < process.argv.length; index += 1) {
|
|
1014
|
-
const argument = process.argv[index];
|
|
1015
|
-
if (argument === "--config" || argument === "-c") {
|
|
1016
|
-
const configured = process.argv[index + 1];
|
|
1017
|
-
const resolvedConfig = configured
|
|
1018
|
-
? resolve(process.cwd(), configured)
|
|
1019
|
-
: undefined;
|
|
1020
|
-
if (resolvedConfig && resolvedConfig !== resolve(generatedVitestConfig)) {
|
|
1021
|
-
originalConfig = resolvedConfig;
|
|
1022
|
-
}
|
|
1023
|
-
process.argv.splice(index, configured ? 2 : 1);
|
|
1024
|
-
index -= 1;
|
|
1025
|
-
}
|
|
1026
|
-
else if (argument?.startsWith("--config=")) {
|
|
1027
|
-
const resolvedConfig = resolve(process.cwd(), argument.slice("--config=".length));
|
|
1028
|
-
if (resolvedConfig !== resolve(generatedVitestConfig)) {
|
|
1029
|
-
originalConfig = resolvedConfig;
|
|
1030
|
-
}
|
|
1031
|
-
process.argv.splice(index, 1);
|
|
1032
|
-
index -= 1;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
// Thresholds on the command line override the configuration's, which the
|
|
1036
|
-
// generated config leaves out (see the coverage tools above). Vitest 0.x
|
|
1037
|
-
// took them directly under --coverage.
|
|
1038
|
-
for (let index = 2; index < process.argv.length; index += 1) {
|
|
1039
|
-
const argument = process.argv[index];
|
|
1040
|
-
if (!/^--coverage\.(?:thresholds(?:\.[^=]+)?|lines|functions|branches|statements|perFile|100|thresholdAutoUpdate)(?:=|$)/.test(argument))
|
|
1041
|
-
continue;
|
|
1042
|
-
const valued = !argument.includes("=") && /^(?:\d+(?:\.\d+)?|true|false)$/.test(process.argv[index + 1] ?? "");
|
|
1043
|
-
process.argv.splice(index, valued ? 2 : 1);
|
|
1044
|
-
index -= 1;
|
|
1045
|
-
process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS__("Vitest");
|
|
1046
|
-
}
|
|
1047
|
-
if (originalConfig) {
|
|
1048
|
-
process.env.SUPERCOV_ORIGINAL_VITEST_CONFIG = originalConfig;
|
|
1049
|
-
}
|
|
1050
|
-
process.argv.push("--config", generatedVitestConfig);
|
|
1051
|
-
if (process.env.SUPERCOV_DEBUG === "1") {
|
|
1052
|
-
console.error("[supercov] Vitest argv configured", {
|
|
1053
|
-
entrypoint,
|
|
1054
|
-
originalConfig,
|
|
1055
|
-
generatedVitestConfig,
|
|
1056
|
-
argv: process.argv.slice(2),
|
|
1057
|
-
});
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
979
|
+
await adaptRunnerEntry(entrypoint);
|
|
1060
980
|
if ((isJestEntrypoint || process.env.JEST_WORKER_ID) && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
1061
981
|
// Jest evaluates instrumented modules in its own module system, past the
|
|
1062
982
|
// loader hook that imports the runtime on first use elsewhere, and
|
|
@@ -1068,32 +988,6 @@ if ((isJestEntrypoint || process.env.JEST_WORKER_ID) && process.env.SUPERCOV_EVI
|
|
|
1068
988
|
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
1069
989
|
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
1070
990
|
}
|
|
1071
|
-
// The Mocha CLI, the child it forks for Node options, and each --parallel
|
|
1072
|
-
// worker run tests through Mocha's Runner, which the adapter patches before
|
|
1073
|
-
// Mocha loads it.
|
|
1074
|
-
const isMochaEntrypoint = /\/node_modules\/(?:\.bin\/_?mocha|mocha\/(?:bin\/_?mocha(?:\.js)?|lib\/cli\/cli\.js|lib\/nodejs\/worker\.c?js))$/.test(entrypoint);
|
|
1075
|
-
if (isMochaEntrypoint && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
1076
|
-
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
1077
|
-
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
1078
|
-
const { adaptMocha } = await import(new URL("./mocha.mjs", import.meta.url).href);
|
|
1079
|
-
await adaptMocha(entrypoint);
|
|
1080
|
-
}
|
|
1081
|
-
// An AVA worker, a thread or a child process, runs one test file through
|
|
1082
|
-
// AVA's Runner, which the adapter patches before the worker loads it.
|
|
1083
|
-
if (/\/node_modules\/ava\/lib\/worker\/base\.js$/.test(entrypoint) && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
1084
|
-
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
1085
|
-
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
1086
|
-
const { adaptAva } = await import(new URL("./ava.mjs", import.meta.url).href);
|
|
1087
|
-
await adaptAva(entrypoint);
|
|
1088
|
-
}
|
|
1089
|
-
// The tap CLI runs each test file as a process of its own, marked with
|
|
1090
|
-
// TAP_CHILD_ID; the adapter patches tap's TestBase before the file loads it.
|
|
1091
|
-
if (process.env.TAP_CHILD_ID && process.env.SUPERCOV_EVIDENCE_DIR && entrypoint) {
|
|
1092
|
-
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
1093
|
-
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
1094
|
-
const { adaptTap } = await import(new URL("./tap.mjs", import.meta.url).href);
|
|
1095
|
-
await adaptTap(entrypoint);
|
|
1096
|
-
}
|
|
1097
991
|
if (isJestEntrypoint && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
1098
992
|
// Jest reads one configuration. Ours (jest.config.mjs) reads the user's
|
|
1099
993
|
// the way Jest would and adds the adapter and reporter; an explicit
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { appendFileSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, resolve as resolvePath } from "node:path";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
import { writePlaywrightCacheWhole } from "./atomic.mjs";
|
|
5
|
+
// This thread is where Playwright compiles ES modules and writes them into
|
|
6
|
+
// its cache: written whole here too (atomic.mjs says why).
|
|
7
|
+
writePlaywrightCacheWhole();
|
|
4
8
|
const GENERATED_TARGET = "__SUPERCOV_PLAYWRIGHT_MODULE__";
|
|
5
9
|
const TARGET = process.env.SUPERCOV_PLAYWRIGHT_MODULE ??
|
|
6
10
|
(GENERATED_TARGET.startsWith("__") ? "@playwright/test" : GENERATED_TARGET);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// A runner started by its own entry point -- Vitest, Mocha, an AVA worker, a
|
|
2
|
+
// tap child -- is adapted as it starts: Vitest takes the run's generated
|
|
3
|
+
// config, the others' runners are patched before they load. Without it every
|
|
4
|
+
// probe a test reaches is counted as background. Node runs this from
|
|
5
|
+
// register.mjs before the CLI parses argv; Bun loads no Node preload, so its
|
|
6
|
+
// adapter does instead.
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
|
|
9
|
+
// A project's own coverage tool measures what runs, and under Supercov that is
|
|
10
|
+
// the instrumented copy, whose probes are branches no test was written to
|
|
11
|
+
// cover: c8, Jest and Vitest each failed a 100% gate on a suite that covers
|
|
12
|
+
// every branch (80%, 83.33%, 87.5%). The tool still runs and reports; its
|
|
13
|
+
// thresholds are not checked, and the run says so once.
|
|
14
|
+
export function noteSkippedCoverageThresholds(tool) {
|
|
15
|
+
if (process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS_NOTED__)
|
|
16
|
+
return;
|
|
17
|
+
process.__SUPERCOV_SKIPPED_COVERAGE_THRESHOLDS_NOTED__ = true;
|
|
18
|
+
console.error(`[supercov] ${tool}'s coverage thresholds were not checked: under Supercov, ${tool} measures the instrumented copy, probes included. Supercov's own report has this run's coverage.`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Point a Vitest process at the run's generated config. */
|
|
22
|
+
function useGeneratedVitestConfig(entrypoint) {
|
|
23
|
+
const generatedVitestConfig = process.env.SUPERCOV_GENERATED_VITEST_CONFIG;
|
|
24
|
+
if (!generatedVitestConfig || !/\/vitest(?:\.m?js)?$/.test(entrypoint))
|
|
25
|
+
return;
|
|
26
|
+
// Worker processes inherit this marker. In particular, do not eagerly load
|
|
27
|
+
// Playwright's expect implementation in a Vitest worker: both runners use
|
|
28
|
+
// the Jest matcher registry symbol and intentionally cannot coexist there.
|
|
29
|
+
process.env.SUPERCOV_INSIDE_VITEST = "1";
|
|
30
|
+
let originalConfig;
|
|
31
|
+
for (let index = 2; index < process.argv.length; index += 1) {
|
|
32
|
+
const argument = process.argv[index];
|
|
33
|
+
if (argument === "--config" || argument === "-c") {
|
|
34
|
+
const configured = process.argv[index + 1];
|
|
35
|
+
const resolvedConfig = configured
|
|
36
|
+
? resolve(process.cwd(), configured)
|
|
37
|
+
: undefined;
|
|
38
|
+
if (resolvedConfig && resolvedConfig !== resolve(generatedVitestConfig)) {
|
|
39
|
+
originalConfig = resolvedConfig;
|
|
40
|
+
}
|
|
41
|
+
process.argv.splice(index, configured ? 2 : 1);
|
|
42
|
+
index -= 1;
|
|
43
|
+
}
|
|
44
|
+
else if (argument?.startsWith("--config=")) {
|
|
45
|
+
const resolvedConfig = resolve(process.cwd(), argument.slice("--config=".length));
|
|
46
|
+
if (resolvedConfig !== resolve(generatedVitestConfig)) {
|
|
47
|
+
originalConfig = resolvedConfig;
|
|
48
|
+
}
|
|
49
|
+
process.argv.splice(index, 1);
|
|
50
|
+
index -= 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Thresholds on the command line override the configuration's, which the
|
|
54
|
+
// generated config leaves out (see the coverage tools above). Vitest 0.x
|
|
55
|
+
// took them directly under --coverage.
|
|
56
|
+
for (let index = 2; index < process.argv.length; index += 1) {
|
|
57
|
+
const argument = process.argv[index];
|
|
58
|
+
if (!/^--coverage\.(?:thresholds(?:\.[^=]+)?|lines|functions|branches|statements|perFile|100|thresholdAutoUpdate)(?:=|$)/.test(argument))
|
|
59
|
+
continue;
|
|
60
|
+
const valued = !argument.includes("=") && /^(?:\d+(?:\.\d+)?|true|false)$/.test(process.argv[index + 1] ?? "");
|
|
61
|
+
process.argv.splice(index, valued ? 2 : 1);
|
|
62
|
+
index -= 1;
|
|
63
|
+
noteSkippedCoverageThresholds("Vitest");
|
|
64
|
+
}
|
|
65
|
+
if (originalConfig) {
|
|
66
|
+
process.env.SUPERCOV_ORIGINAL_VITEST_CONFIG = originalConfig;
|
|
67
|
+
}
|
|
68
|
+
process.argv.push("--config", generatedVitestConfig);
|
|
69
|
+
if (process.env.SUPERCOV_DEBUG === "1") {
|
|
70
|
+
console.error("[supercov] Vitest argv configured", {
|
|
71
|
+
entrypoint,
|
|
72
|
+
originalConfig,
|
|
73
|
+
generatedVitestConfig,
|
|
74
|
+
argv: process.argv.slice(2),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Adapt the runner whose entry point `entrypoint` is, if any. */
|
|
80
|
+
export async function adaptRunnerEntry(entrypoint) {
|
|
81
|
+
useGeneratedVitestConfig(entrypoint);
|
|
82
|
+
// The Mocha CLI, the child it forks for Node options, and each --parallel
|
|
83
|
+
// worker run tests through Mocha's Runner, which the adapter patches before
|
|
84
|
+
// Mocha loads it.
|
|
85
|
+
const isMochaEntrypoint = /\/node_modules\/(?:\.bin\/_?mocha|mocha\/(?:bin\/_?mocha(?:\.js)?|lib\/cli\/cli\.js|lib\/nodejs\/worker\.c?js))$/.test(entrypoint);
|
|
86
|
+
if (isMochaEntrypoint && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
87
|
+
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
88
|
+
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
89
|
+
const { adaptMocha } = await import(new URL("./mocha.mjs", import.meta.url).href);
|
|
90
|
+
await adaptMocha(entrypoint);
|
|
91
|
+
}
|
|
92
|
+
// An AVA worker, a thread or a child process, runs one test file through
|
|
93
|
+
// AVA's Runner, which the adapter patches before the worker loads it.
|
|
94
|
+
if (/\/node_modules\/ava\/lib\/worker\/base\.js$/.test(entrypoint) && process.env.SUPERCOV_EVIDENCE_DIR) {
|
|
95
|
+
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
96
|
+
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
97
|
+
const { adaptAva } = await import(new URL("./ava.mjs", import.meta.url).href);
|
|
98
|
+
await adaptAva(entrypoint);
|
|
99
|
+
}
|
|
100
|
+
// The tap CLI runs each test file as a process of its own, marked with
|
|
101
|
+
// TAP_CHILD_ID; the adapter patches tap's TestBase before the file loads it.
|
|
102
|
+
if (process.env.TAP_CHILD_ID && process.env.SUPERCOV_EVIDENCE_DIR && entrypoint) {
|
|
103
|
+
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.mjs");
|
|
104
|
+
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
105
|
+
const { adaptTap } = await import(new URL("./tap.mjs", import.meta.url).href);
|
|
106
|
+
await adaptTap(entrypoint);
|
|
107
|
+
}
|
|
108
|
+
}
|