vitest 4.0.7 → 4.0.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/LICENSE.md +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.D3GxgUMI.js → base.BgTO2qAg.js} +71 -36
- package/dist/chunks/{benchmark.DHKMYAts.js → benchmark.B3N2zMcH.js} +9 -4
- package/dist/chunks/{browser.d.-LKfRopd.d.ts → browser.d.DTTM2PTh.d.ts} +1 -1
- package/dist/chunks/{cac.G9DAn-c7.js → cac.CfkWq8Qy.js} +115 -42
- package/dist/chunks/{cli-api.Csks4as1.js → cli-api.BQ-bjcRi.js} +1857 -839
- package/dist/chunks/console.Cf-YriPC.js +146 -0
- package/dist/chunks/{coverage.C2LA1DSL.js → coverage.NVjCOln1.js} +273 -103
- package/dist/chunks/{creator.cqqifzG7.js → creator.fzVyoMf3.js} +74 -30
- package/dist/chunks/{date.-jtEtIeV.js → date.Bq6ZW5rf.js} +17 -6
- package/dist/chunks/{git.BFNcloKD.js → git.Bm2pzPAa.js} +3 -3
- package/dist/chunks/{global.d.DxtanrNO.d.ts → global.d.DVdCfKp5.d.ts} +1 -1
- package/dist/chunks/{globals.BGT_RUsD.js → globals.DOh96BiR.js} +5 -5
- package/dist/chunks/{index.DEPqWSIZ.js → index.BY4-tcno.js} +33 -16
- package/dist/chunks/{index.Bgo3tNWt.js → index.DAL392Ss.js} +40 -15
- package/dist/chunks/{index.RwjEGCQ0.js → index.DIFZf73e.js} +2 -2
- package/dist/chunks/{index.CWIFvlX5.js → index.DfKyPFVi.js} +159 -54
- package/dist/chunks/{index.CVpyv-Zg.js → index.kotH7DY7.js} +832 -373
- package/dist/chunks/{index.jMQYiEWE.js → index.op2Re5rn.js} +22 -12
- package/dist/chunks/{init-forks.IU-xQ2_X.js → init-forks.2hx7cf78.js} +14 -4
- package/dist/chunks/{init-threads.C_NWvZkU.js → init-threads.Cm4OCIWA.js} +1 -1
- package/dist/chunks/{init.fmH9J833.js → init.DMDG-idf.js} +53 -30
- package/dist/chunks/{inspector.DLZxSeU3.js → inspector.CvyFGlXm.js} +25 -10
- package/dist/chunks/{moduleRunner.d.DEkTotCv.d.ts → moduleRunner.d.CzOZ_4wC.d.ts} +1 -1
- package/dist/chunks/{node.BwAWWjHZ.js → node.Ce0vMQM7.js} +1 -1
- package/dist/chunks/{plugin.d.Cpes8Bt6.d.ts → plugin.d.D4RrtywJ.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CSNcMDxF.d.ts → reporters.d.Da1D1VbQ.d.ts} +6 -5
- package/dist/chunks/{rpc.D38ahn14.js → rpc.BUV7uWKJ.js} +20 -7
- package/dist/chunks/{setup-common.DR1sucx6.js → setup-common.LGjNSzXp.js} +20 -8
- package/dist/chunks/{startModuleRunner.Cn7hCL7D.js → startModuleRunner.BOmUtLIO.js} +206 -83
- package/dist/chunks/{test.B6aJd6T3.js → test.ClrAtjMv.js} +48 -22
- package/dist/chunks/{utils.CG9h5ccR.js → utils.DvEY5TfP.js} +14 -5
- package/dist/chunks/{vi.BZvkKVkM.js → vi.Bgcdy3bQ.js} +261 -111
- package/dist/chunks/{vm.BL7_zzOr.js → vm.BIkCDs68.js} +177 -71
- package/dist/chunks/{worker.d.D25zYZ7N.d.ts → worker.d.DadbA89M.d.ts} +30 -2
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +5 -5
- package/dist/coverage.d.ts +3 -3
- package/dist/coverage.js +1 -1
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/module-evaluator.d.ts +2 -2
- package/dist/module-evaluator.js +85 -35
- package/dist/module-runner.js +2 -2
- package/dist/node.d.ts +7 -7
- package/dist/node.js +16 -12
- package/dist/reporters.d.ts +3 -3
- package/dist/reporters.js +2 -2
- package/dist/runners.js +7 -7
- package/dist/snapshot.js +2 -2
- package/dist/suite.js +2 -2
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +15 -15
- package/dist/workers/forks.js +16 -16
- package/dist/workers/runVmTests.js +41 -22
- package/dist/workers/threads.js +16 -16
- package/dist/workers/vmForks.js +11 -11
- package/dist/workers/vmThreads.js +11 -11
- package/package.json +20 -20
- package/dist/chunks/console.CTJL2nuH.js +0 -115
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import { getTasks, getFullName, getTests } from '@vitest/runner/utils';
|
|
3
3
|
import * as pathe from 'pathe';
|
|
4
4
|
import c from 'tinyrainbow';
|
|
5
|
-
import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.
|
|
5
|
+
import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.kotH7DY7.js';
|
|
6
6
|
import { stripVTControlCharacters } from 'node:util';
|
|
7
7
|
import { notNullish } from '@vitest/utils/helpers';
|
|
8
8
|
|
|
@@ -98,16 +98,19 @@ function renderBenchmark(result, widths) {
|
|
|
98
98
|
].join(" ");
|
|
99
99
|
}
|
|
100
100
|
function renderTable(options) {
|
|
101
|
-
const output = []
|
|
101
|
+
const output = [];
|
|
102
|
+
const benchMap = {};
|
|
102
103
|
for (const task of options.tasks) if (task.meta.benchmark && task.result?.benchmark) benchMap[task.id] = {
|
|
103
104
|
current: task.result.benchmark,
|
|
104
105
|
baseline: options.compare?.[task.id]
|
|
105
106
|
};
|
|
106
|
-
const benchCount = Object.entries(benchMap).length
|
|
107
|
+
const benchCount = Object.entries(benchMap).length;
|
|
108
|
+
const columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish));
|
|
107
109
|
let idx = 0;
|
|
108
110
|
const padding = " ".repeat(1 );
|
|
109
111
|
for (const task of options.tasks) {
|
|
110
|
-
const duration = task.result?.duration
|
|
112
|
+
const duration = task.result?.duration;
|
|
113
|
+
const bench = benchMap[task.id];
|
|
111
114
|
let prefix = "";
|
|
112
115
|
if (idx === 0 && task.meta?.benchmark) prefix += `${renderTableHead(columnWidths)}\n${padding}`;
|
|
113
116
|
prefix += ` ${getStateSymbol(task)} `;
|
|
@@ -123,7 +126,8 @@ function renderTable(options) {
|
|
|
123
126
|
let body = renderBenchmark(bench.current, columnWidths);
|
|
124
127
|
if (options.compare && bench.baseline) {
|
|
125
128
|
if (bench.current.hz) {
|
|
126
|
-
const diff = bench.current.hz / bench.baseline.hz
|
|
129
|
+
const diff = bench.current.hz / bench.baseline.hz;
|
|
130
|
+
const diffFixed = diff.toFixed(2);
|
|
127
131
|
if (diffFixed === "1.0.0") body += c.gray(` [${diffFixed}x]`);
|
|
128
132
|
if (diff > 1) body += c.blue(` [${diffFixed}x] ⇑`);
|
|
129
133
|
else body += c.red(` [${diffFixed}x] ⇓`);
|
|
@@ -140,7 +144,8 @@ function renderTable(options) {
|
|
|
140
144
|
if (task.result?.state !== "pass" && outputMap.get(task) != null) {
|
|
141
145
|
let data = outputMap.get(task);
|
|
142
146
|
if (typeof data === "string") {
|
|
143
|
-
|
|
147
|
+
data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop());
|
|
148
|
+
if (data === "") data = void 0;
|
|
144
149
|
}
|
|
145
150
|
if (data != null) {
|
|
146
151
|
const out = ` ${" ".repeat(options.level)}${F_RIGHT} ${data}`;
|
|
@@ -155,7 +160,8 @@ function renderTable(options) {
|
|
|
155
160
|
class BenchmarkReporter extends DefaultReporter {
|
|
156
161
|
compare;
|
|
157
162
|
async onInit(ctx) {
|
|
158
|
-
|
|
163
|
+
super.onInit(ctx);
|
|
164
|
+
if (this.ctx.config.benchmark?.compare) {
|
|
159
165
|
const compareFile = pathe.resolve(this.ctx.config.root, this.ctx.config.benchmark?.compare);
|
|
160
166
|
try {
|
|
161
167
|
this.compare = flattenFormattedBenchmarkReport(JSON.parse(await fs.promises.readFile(compareFile, "utf-8")));
|
|
@@ -173,7 +179,8 @@ class BenchmarkReporter extends DefaultReporter {
|
|
|
173
179
|
}
|
|
174
180
|
}
|
|
175
181
|
onTestSuiteResult(testSuite) {
|
|
176
|
-
super.onTestSuiteResult(testSuite)
|
|
182
|
+
super.onTestSuiteResult(testSuite);
|
|
183
|
+
this.printSuiteTable(testSuite);
|
|
177
184
|
}
|
|
178
185
|
printTestModule(testModule) {
|
|
179
186
|
this.printSuiteTable(testModule);
|
|
@@ -181,11 +188,13 @@ class BenchmarkReporter extends DefaultReporter {
|
|
|
181
188
|
printSuiteTable(testTask) {
|
|
182
189
|
const state = testTask.state();
|
|
183
190
|
if (state === "pending" || state === "queued") return;
|
|
184
|
-
const benches = testTask.task.tasks.filter((t) => t.meta.benchmark)
|
|
191
|
+
const benches = testTask.task.tasks.filter((t) => t.meta.benchmark);
|
|
192
|
+
const duration = testTask.task.result?.duration || 0;
|
|
185
193
|
if (benches.length > 0 && benches.every((t) => t.result?.state !== "run" && t.result?.state !== "queued")) {
|
|
186
194
|
let title = `\n ${getStateSymbol(testTask.task)} ${formatProjectName(testTask.project)}${getFullName(testTask.task, separator)}`;
|
|
187
195
|
if (duration != null && duration > this.ctx.config.slowTestThreshold) title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
|
|
188
|
-
this.log(title)
|
|
196
|
+
this.log(title);
|
|
197
|
+
this.log(renderTable({
|
|
189
198
|
tasks: benches,
|
|
190
199
|
level: 1,
|
|
191
200
|
columns: this.ctx.logger.getColumns(),
|
|
@@ -203,8 +212,9 @@ class BenchmarkReporter extends DefaultReporter {
|
|
|
203
212
|
outputFile = pathe.resolve(this.ctx.config.root, outputFile);
|
|
204
213
|
const outputDirectory = pathe.dirname(outputFile);
|
|
205
214
|
if (!fs.existsSync(outputDirectory)) await fs.promises.mkdir(outputDirectory, { recursive: true });
|
|
206
|
-
const
|
|
207
|
-
await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2))
|
|
215
|
+
const output = createBenchmarkJsonReport(testModules.map((t) => t.task.file));
|
|
216
|
+
await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
|
|
217
|
+
this.log(`Benchmark report written to ${outputFile}`);
|
|
208
218
|
}
|
|
209
219
|
}
|
|
210
220
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import v8 from 'node:v8';
|
|
2
|
-
import { i as init } from './init.
|
|
2
|
+
import { i as init } from './init.DMDG-idf.js';
|
|
3
3
|
|
|
4
4
|
if (!process.send) throw new Error("Expected worker to be run in node:child_process");
|
|
5
5
|
// Store globals in case tests overwrite them
|
|
6
|
-
const processExit = process.exit.bind(process)
|
|
6
|
+
const processExit = process.exit.bind(process);
|
|
7
|
+
const processSend = process.send.bind(process);
|
|
8
|
+
const processOn = process.on.bind(process);
|
|
9
|
+
const processOff = process.off.bind(process);
|
|
10
|
+
const processRemoveAllListeners = process.removeAllListeners.bind(process);
|
|
7
11
|
// Work-around for nodejs/node#55094
|
|
8
12
|
if (process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir"))) processOn("SIGTERM", () => processExit());
|
|
9
13
|
function workerInit(options) {
|
|
@@ -37,7 +41,8 @@ function unwrapSerializableConfig(config) {
|
|
|
37
41
|
if (testNamePattern.startsWith("$$vitest:")) config.testNamePattern = parseRegexp(testNamePattern.slice(9));
|
|
38
42
|
}
|
|
39
43
|
if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) {
|
|
40
|
-
const { keys, original } = config.defines
|
|
44
|
+
const { keys, original } = config.defines;
|
|
45
|
+
const defines = {};
|
|
41
46
|
// Apply all keys from the original. Entries which had undefined value are missing from original now
|
|
42
47
|
for (const key of keys) defines[key] = original[key];
|
|
43
48
|
config.defines = defines;
|
|
@@ -48,8 +53,13 @@ function parseRegexp(input) {
|
|
|
48
53
|
// Parse input
|
|
49
54
|
// eslint-disable-next-line regexp/no-misleading-capturing-group
|
|
50
55
|
const m = input.match(/(\/?)(.+)\1([a-z]*)/i);
|
|
56
|
+
// match nothing
|
|
57
|
+
if (!m) return /$^/;
|
|
58
|
+
// Invalid flags
|
|
59
|
+
// eslint-disable-next-line regexp/optimal-quantifier-concatenation
|
|
60
|
+
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) return new RegExp(input);
|
|
51
61
|
// Create the regular expression
|
|
52
|
-
return
|
|
62
|
+
return new RegExp(m[2], m[3]);
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
export { workerInit as w };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isMainThread, parentPort } from 'node:worker_threads';
|
|
2
|
-
import { i as init } from './init.
|
|
2
|
+
import { i as init } from './init.DMDG-idf.js';
|
|
3
3
|
|
|
4
4
|
if (isMainThread || !parentPort) throw new Error("Expected worker to be run in node:worker_threads");
|
|
5
5
|
function workerInit(options) {
|
|
@@ -3,18 +3,19 @@ import { isBuiltin } from 'node:module';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { resolve } from 'pathe';
|
|
5
5
|
import { ModuleRunner } from 'vite/module-runner';
|
|
6
|
-
import { b as VitestTransport } from './startModuleRunner.
|
|
7
|
-
import { e as environments } from './index.
|
|
6
|
+
import { b as VitestTransport } from './startModuleRunner.BOmUtLIO.js';
|
|
7
|
+
import { e as environments } from './index.DfKyPFVi.js';
|
|
8
8
|
import { serializeError } from '@vitest/utils/error';
|
|
9
|
-
import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.
|
|
9
|
+
import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.BUV7uWKJ.js';
|
|
10
10
|
import { createStackString, parseStacktrace } from '@vitest/utils/source-map';
|
|
11
|
-
import { s as setupInspect } from './inspector.
|
|
11
|
+
import { s as setupInspect } from './inspector.CvyFGlXm.js';
|
|
12
12
|
import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
|
|
13
13
|
|
|
14
14
|
function isBuiltinEnvironment(env) {
|
|
15
15
|
return env in environments;
|
|
16
16
|
}
|
|
17
|
-
const isWindows = process.platform === "win32"
|
|
17
|
+
const isWindows = process.platform === "win32";
|
|
18
|
+
const _loaders = /* @__PURE__ */ new Map();
|
|
18
19
|
async function createEnvironmentLoader(root, rpc) {
|
|
19
20
|
const cachedLoader = _loaders.get(root);
|
|
20
21
|
if (!cachedLoader || cachedLoader.isClosed()) {
|
|
@@ -40,28 +41,37 @@ async function createEnvironmentLoader(root, rpc) {
|
|
|
40
41
|
}
|
|
41
42
|
})
|
|
42
43
|
});
|
|
43
|
-
_loaders.set(root, moduleRunner)
|
|
44
|
+
_loaders.set(root, moduleRunner);
|
|
45
|
+
await moduleRunner.import("/@vite/env");
|
|
44
46
|
}
|
|
45
47
|
return _loaders.get(root);
|
|
46
48
|
}
|
|
47
49
|
async function loadEnvironment(name, root, rpc) {
|
|
48
50
|
if (isBuiltinEnvironment(name)) return { environment: environments[name] };
|
|
49
|
-
const loader = await createEnvironmentLoader(root, rpc)
|
|
51
|
+
const loader = await createEnvironmentLoader(root, rpc);
|
|
52
|
+
const packageId = name[0] === "." || name[0] === "/" ? resolve(root, name) : (await rpc.resolve(`vitest-environment-${name}`, void 0, "__vitest__"))?.id ?? resolve(root, name);
|
|
53
|
+
const pkg = await loader.import(packageId);
|
|
50
54
|
if (!pkg || !pkg.default || typeof pkg.default !== "object") throw new TypeError(`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "setup" or/and "setupVM" method.`);
|
|
51
55
|
const environment = pkg.default;
|
|
52
56
|
if (environment.transformMode != null && environment.transformMode !== "web" && environment.transformMode !== "ssr") throw new TypeError(`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "transformMode" method equal to "ssr" or "web", received "${environment.transformMode}".`);
|
|
53
|
-
if (environment.transformMode)
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
if (environment.transformMode) {
|
|
58
|
+
console.warn(`The Vitest environment ${environment.name} defines the "transformMode". This options was deprecated in Vitest 4 and will be removed in the next major version. Please, use "viteEnvironment" instead.`);
|
|
59
|
+
// keep for backwards compat
|
|
60
|
+
environment.viteEnvironment ??= environment.transformMode === "ssr" ? "ssr" : "client";
|
|
61
|
+
}
|
|
56
62
|
return {
|
|
57
63
|
environment,
|
|
58
64
|
loader
|
|
59
65
|
};
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
const resolvingModules = /* @__PURE__ */ new Set()
|
|
68
|
+
const resolvingModules = /* @__PURE__ */ new Set();
|
|
69
|
+
const globalListeners = /* @__PURE__ */ new Set();
|
|
63
70
|
async function execute(method, ctx, worker) {
|
|
64
|
-
const prepareStart = performance.now()
|
|
71
|
+
const prepareStart = performance.now();
|
|
72
|
+
const cleanups = [setupInspect(ctx)];
|
|
73
|
+
// RPC is used to communicate between worker (be it a thread worker or child process or a custom implementation) and the main thread
|
|
74
|
+
const rpc = ctx.rpc;
|
|
65
75
|
try {
|
|
66
76
|
// do not close the RPC channel so that we can get the error messages sent to the main thread
|
|
67
77
|
cleanups.push(async () => {
|
|
@@ -88,11 +98,13 @@ async function execute(method, ctx, worker) {
|
|
|
88
98
|
return createStackString(parseStacktrace(stack));
|
|
89
99
|
},
|
|
90
100
|
metaEnv: createImportMetaEnvProxy()
|
|
91
|
-
}
|
|
101
|
+
};
|
|
102
|
+
const methodName = method === "collect" ? "collectTests" : "runTests";
|
|
92
103
|
if (!worker[methodName] || typeof worker[methodName] !== "function") throw new TypeError(`Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`);
|
|
93
104
|
await worker[methodName](state);
|
|
94
105
|
} finally {
|
|
95
|
-
await rpcDone().catch(() => {})
|
|
106
|
+
await rpcDone().catch(() => {});
|
|
107
|
+
await Promise.all(cleanups.map((fn) => fn())).catch(() => {});
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
110
|
function run(ctx, worker) {
|
|
@@ -114,7 +126,9 @@ function createImportMetaEnvProxy() {
|
|
|
114
126
|
];
|
|
115
127
|
return new Proxy(env, {
|
|
116
128
|
get(_, key) {
|
|
117
|
-
if (typeof key
|
|
129
|
+
if (typeof key !== "string") return;
|
|
130
|
+
if (booleanKeys.includes(key)) return !!process.env[key];
|
|
131
|
+
return process.env[key];
|
|
118
132
|
},
|
|
119
133
|
set(_, key, value) {
|
|
120
134
|
if (typeof key !== "string") return true;
|
|
@@ -125,30 +139,36 @@ function createImportMetaEnvProxy() {
|
|
|
125
139
|
});
|
|
126
140
|
}
|
|
127
141
|
|
|
128
|
-
const __vitest_worker_response__ = true
|
|
142
|
+
const __vitest_worker_response__ = true;
|
|
143
|
+
const memoryUsage = process.memoryUsage.bind(process);
|
|
129
144
|
let reportMemory = false;
|
|
130
145
|
/** @experimental */
|
|
131
146
|
function init(worker) {
|
|
132
147
|
worker.on(onMessage);
|
|
133
|
-
let runPromise
|
|
148
|
+
let runPromise;
|
|
149
|
+
let isRunning = false;
|
|
150
|
+
let workerTeardown;
|
|
151
|
+
let setupContext;
|
|
134
152
|
function send(response) {
|
|
135
153
|
worker.post(worker.serialize ? worker.serialize(response) : response);
|
|
136
154
|
}
|
|
137
155
|
async function onMessage(rawMessage) {
|
|
138
156
|
const message = worker.deserialize ? worker.deserialize(rawMessage) : rawMessage;
|
|
139
|
-
if (message?.__vitest_worker_request__
|
|
157
|
+
if (message?.__vitest_worker_request__ !== true) return;
|
|
158
|
+
switch (message.type) {
|
|
140
159
|
case "start": {
|
|
141
160
|
reportMemory = message.options.reportMemory;
|
|
142
161
|
const { environment, config, pool } = message.context;
|
|
143
162
|
try {
|
|
144
|
-
const rpc = createRuntimeRpc(worker);
|
|
145
163
|
setupContext = {
|
|
146
164
|
environment,
|
|
147
165
|
config,
|
|
148
166
|
pool,
|
|
149
|
-
rpc,
|
|
167
|
+
rpc: createRuntimeRpc(worker),
|
|
150
168
|
projectName: config.name || ""
|
|
151
|
-
}
|
|
169
|
+
};
|
|
170
|
+
workerTeardown = await worker.setup?.(setupContext);
|
|
171
|
+
send({
|
|
152
172
|
type: "started",
|
|
153
173
|
__vitest_worker_response__
|
|
154
174
|
});
|
|
@@ -172,7 +192,8 @@ function init(worker) {
|
|
|
172
192
|
return;
|
|
173
193
|
}
|
|
174
194
|
try {
|
|
175
|
-
process.env.VITEST_POOL_ID = String(message.poolId)
|
|
195
|
+
process.env.VITEST_POOL_ID = String(message.poolId);
|
|
196
|
+
process.env.VITEST_WORKER_ID = String(message.context.workerId);
|
|
176
197
|
} catch (error) {
|
|
177
198
|
return send({
|
|
178
199
|
type: "testfileFinished",
|
|
@@ -187,15 +208,15 @@ function init(worker) {
|
|
|
187
208
|
...setupContext,
|
|
188
209
|
...message.context
|
|
189
210
|
}, worker).catch((error) => serializeError(error));
|
|
190
|
-
const error = await runPromise;
|
|
191
211
|
send({
|
|
192
212
|
type: "testfileFinished",
|
|
193
213
|
__vitest_worker_response__,
|
|
194
|
-
error,
|
|
214
|
+
error: await runPromise,
|
|
195
215
|
usedMemory: reportMemory ? memoryUsage().heapUsed : void 0
|
|
196
216
|
});
|
|
197
217
|
} finally {
|
|
198
|
-
runPromise = void 0
|
|
218
|
+
runPromise = void 0;
|
|
219
|
+
isRunning = false;
|
|
199
220
|
}
|
|
200
221
|
break;
|
|
201
222
|
case "collect":
|
|
@@ -209,7 +230,8 @@ function init(worker) {
|
|
|
209
230
|
return;
|
|
210
231
|
}
|
|
211
232
|
try {
|
|
212
|
-
process.env.VITEST_POOL_ID = String(message.poolId)
|
|
233
|
+
process.env.VITEST_POOL_ID = String(message.poolId);
|
|
234
|
+
process.env.VITEST_WORKER_ID = String(message.context.workerId);
|
|
213
235
|
} catch (error) {
|
|
214
236
|
return send({
|
|
215
237
|
type: "testfileFinished",
|
|
@@ -224,22 +246,23 @@ function init(worker) {
|
|
|
224
246
|
...setupContext,
|
|
225
247
|
...message.context
|
|
226
248
|
}, worker).catch((error) => serializeError(error));
|
|
227
|
-
const error = await runPromise;
|
|
228
249
|
send({
|
|
229
250
|
type: "testfileFinished",
|
|
230
251
|
__vitest_worker_response__,
|
|
231
|
-
error,
|
|
252
|
+
error: await runPromise,
|
|
232
253
|
usedMemory: reportMemory ? memoryUsage().heapUsed : void 0
|
|
233
254
|
});
|
|
234
255
|
} finally {
|
|
235
|
-
runPromise = void 0
|
|
256
|
+
runPromise = void 0;
|
|
257
|
+
isRunning = false;
|
|
236
258
|
}
|
|
237
259
|
break;
|
|
238
260
|
case "stop":
|
|
239
261
|
await runPromise;
|
|
240
262
|
try {
|
|
241
263
|
const error = await teardown().catch((error) => serializeError(error));
|
|
242
|
-
await workerTeardown?.()
|
|
264
|
+
await workerTeardown?.();
|
|
265
|
+
send({
|
|
243
266
|
type: "stopped",
|
|
244
267
|
error,
|
|
245
268
|
__vitest_worker_response__
|
|
@@ -2,33 +2,48 @@ import { createRequire } from 'node:module';
|
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
|
|
4
4
|
const __require = createRequire(import.meta.url);
|
|
5
|
-
let inspector
|
|
5
|
+
let inspector;
|
|
6
|
+
let session;
|
|
6
7
|
/**
|
|
7
8
|
* Enables debugging inside `worker_threads` and `child_process`.
|
|
8
9
|
* Should be called as early as possible when worker/process has been set up.
|
|
9
10
|
*/
|
|
10
11
|
function setupInspect(ctx) {
|
|
11
|
-
const config = ctx.config
|
|
12
|
+
const config = ctx.config;
|
|
13
|
+
const isEnabled = config.inspector.enabled;
|
|
12
14
|
if (isEnabled) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
inspector = __require("node:inspector");
|
|
16
|
+
if (!(inspector.url() !== void 0)) {
|
|
17
|
+
inspector.open(config.inspector.port, config.inspector.host, config.inspector.waitForDebugger);
|
|
18
|
+
if (config.inspectBrk) {
|
|
15
19
|
const firstTestFile = typeof ctx.files[0] === "string" ? ctx.files[0] : ctx.files[0].filepath;
|
|
16
20
|
// Stop at first test file
|
|
17
|
-
if (firstTestFile)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
if (firstTestFile) {
|
|
22
|
+
session = new inspector.Session();
|
|
23
|
+
session.connect();
|
|
24
|
+
session.post("Debugger.enable");
|
|
25
|
+
session.post("Debugger.setBreakpointByUrl", {
|
|
26
|
+
lineNumber: 0,
|
|
27
|
+
url: pathToFileURL(firstTestFile)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
}
|
|
23
32
|
}
|
|
24
33
|
const keepOpen = shouldKeepOpen(config);
|
|
25
34
|
return function cleanup() {
|
|
26
|
-
if (isEnabled && !keepOpen && inspector)
|
|
35
|
+
if (isEnabled && !keepOpen && inspector) {
|
|
36
|
+
inspector.close();
|
|
37
|
+
session?.disconnect();
|
|
38
|
+
}
|
|
27
39
|
};
|
|
28
40
|
}
|
|
29
41
|
function closeInspector(config) {
|
|
30
42
|
const keepOpen = shouldKeepOpen(config);
|
|
31
|
-
if (inspector && !keepOpen)
|
|
43
|
+
if (inspector && !keepOpen) {
|
|
44
|
+
inspector.close();
|
|
45
|
+
session?.disconnect();
|
|
46
|
+
}
|
|
32
47
|
}
|
|
33
48
|
function shouldKeepOpen(config) {
|
|
34
49
|
// In watch mode the inspector can persist re-runs if isolation is disabled and a single worker is used
|
|
@@ -2,7 +2,7 @@ import * as _vitest_spy from '@vitest/spy';
|
|
|
2
2
|
import vm from 'node:vm';
|
|
3
3
|
import * as viteModuleRunner from 'vite/module-runner';
|
|
4
4
|
import { ModuleEvaluator, ModuleRunnerImportMeta, ModuleRunnerContext, EvaluatedModuleNode, FetchFunction, EvaluatedModules } from 'vite/module-runner';
|
|
5
|
-
import { R as RuntimeRPC, e as ResolveFunctionResult, W as WorkerGlobalState } from './worker.d.
|
|
5
|
+
import { R as RuntimeRPC, e as ResolveFunctionResult, W as WorkerGlobalState } from './worker.d.DadbA89M.js';
|
|
6
6
|
import { MockedModule, MockedModuleType } from '@vitest/mocker';
|
|
7
7
|
import { P as PendingSuiteMock, b as MockFactory, a as MockOptions } from './mocker.d.BE_2ls6u.js';
|
|
8
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
|
|
2
|
-
import { g as getWorkerState } from './utils.
|
|
2
|
+
import { g as getWorkerState } from './utils.DvEY5TfP.js';
|
|
3
3
|
import '@vitest/utils/timers';
|
|
4
4
|
|
|
5
5
|
class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { TaskMeta, Suite, File, TestAnnotation, ImportDuration, Test, Task, TaskResultPack, FileSpecification, CancelReason, SequenceSetupFiles, SequenceHooks } from '@vitest/runner';
|
|
2
2
|
import { TestError, SerializedError, Arrayable, ParsedStack, Awaitable } from '@vitest/utils';
|
|
3
|
-
import { A as AfterSuiteRunMeta, U as UserConsoleLog, P as ProvidedContext, d as ContextTestEnvironment, f as WorkerTestEnvironment, g as WorkerExecuteContext, L as LabelColor } from './worker.d.
|
|
3
|
+
import { A as AfterSuiteRunMeta, U as UserConsoleLog, P as ProvidedContext, d as ContextTestEnvironment, f as WorkerTestEnvironment, g as WorkerExecuteContext, L as LabelColor } from './worker.d.DadbA89M.js';
|
|
4
4
|
import { Writable } from 'node:stream';
|
|
5
5
|
import { TransformResult as TransformResult$1, ViteDevServer, Plugin, UserConfig as UserConfig$1, DepOptimizationConfig, ServerOptions, ConfigEnv, AliasOptions } from 'vite';
|
|
6
6
|
import { MockedModule } from '@vitest/mocker';
|
|
7
7
|
import { StackTraceParserOptions } from '@vitest/utils/source-map';
|
|
8
8
|
import { BrowserCommands } from 'vitest/browser';
|
|
9
9
|
import { B as BrowserTraceViewMode, S as SerializedConfig, F as FakeTimerInstallOpts } from './config.d.BTfZNUu9.js';
|
|
10
|
-
import { S as SerializedTestSpecification, B as BrowserTesterOptions } from './browser.d
|
|
10
|
+
import { S as SerializedTestSpecification, B as BrowserTesterOptions } from './browser.d.DTTM2PTh.js';
|
|
11
11
|
import { PrettyFormatOptions } from '@vitest/pretty-format';
|
|
12
12
|
import { SnapshotSummary, SnapshotStateOptions } from '@vitest/snapshot';
|
|
13
13
|
import { SerializedDiffOptions } from '@vitest/utils/diff';
|
|
@@ -1535,7 +1535,7 @@ interface BrowserConfigOptions {
|
|
|
1535
1535
|
/**
|
|
1536
1536
|
* Commands that will be executed on the server
|
|
1537
1537
|
* via the browser `import("vitest/browser").commands` API.
|
|
1538
|
-
* @see {@link https://vitest.dev/
|
|
1538
|
+
* @see {@link https://vitest.dev/api/browser/commands}
|
|
1539
1539
|
*/
|
|
1540
1540
|
commands?: Record<string, BrowserCommand<any>>;
|
|
1541
1541
|
/**
|
|
@@ -1696,7 +1696,7 @@ type ToMatchScreenshotResolvePath = (data: {
|
|
|
1696
1696
|
platform: NodeJS.Platform;
|
|
1697
1697
|
/**
|
|
1698
1698
|
* The value provided to
|
|
1699
|
-
* {@linkcode https://vitest.dev/
|
|
1699
|
+
* {@linkcode https://vitest.dev/config/browser/screenshotdirectory|browser.screenshotDirectory},
|
|
1700
1700
|
* if none is provided, its default value.
|
|
1701
1701
|
*/
|
|
1702
1702
|
screenshotDirectory: string;
|
|
@@ -2452,9 +2452,10 @@ interface InlineConfig {
|
|
|
2452
2452
|
*/
|
|
2453
2453
|
benchmark?: BenchmarkUserOptions;
|
|
2454
2454
|
/**
|
|
2455
|
-
*
|
|
2455
|
+
* A list of [glob patterns](https://superchupu.dev/tinyglobby/comparison) that match your test files.
|
|
2456
2456
|
*
|
|
2457
2457
|
* @default ['**\/*.{test,spec}.?(c|m)[jt]s?(x)']
|
|
2458
|
+
* @see {@link https://vitest.dev/config/include}
|
|
2458
2459
|
*/
|
|
2459
2460
|
include?: string[];
|
|
2460
2461
|
/**
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { getSafeTimers } from '@vitest/utils/timers';
|
|
2
|
-
import { c as createBirpc } from './index.
|
|
3
|
-
import { g as getWorkerState } from './utils.
|
|
2
|
+
import { c as createBirpc } from './index.DAL392Ss.js';
|
|
3
|
+
import { g as getWorkerState } from './utils.DvEY5TfP.js';
|
|
4
4
|
|
|
5
5
|
const { get } = Reflect;
|
|
6
6
|
function withSafeTimers(fn) {
|
|
7
|
-
const { setTimeout, clearTimeout, nextTick, setImmediate, clearImmediate } = getSafeTimers()
|
|
7
|
+
const { setTimeout, clearTimeout, nextTick, setImmediate, clearImmediate } = getSafeTimers();
|
|
8
|
+
const currentSetTimeout = globalThis.setTimeout;
|
|
9
|
+
const currentClearTimeout = globalThis.clearTimeout;
|
|
10
|
+
const currentSetImmediate = globalThis.setImmediate;
|
|
11
|
+
const currentClearImmediate = globalThis.clearImmediate;
|
|
12
|
+
const currentNextTick = globalThis.process?.nextTick;
|
|
8
13
|
try {
|
|
9
|
-
|
|
14
|
+
globalThis.setTimeout = setTimeout;
|
|
15
|
+
globalThis.clearTimeout = clearTimeout;
|
|
16
|
+
if (setImmediate) globalThis.setImmediate = setImmediate;
|
|
10
17
|
if (clearImmediate) globalThis.clearImmediate = clearImmediate;
|
|
11
18
|
if (globalThis.process && nextTick) globalThis.process.nextTick = nextTick;
|
|
12
19
|
return fn();
|
|
13
20
|
} finally {
|
|
14
|
-
|
|
21
|
+
globalThis.setTimeout = currentSetTimeout;
|
|
22
|
+
globalThis.clearTimeout = currentClearTimeout;
|
|
23
|
+
globalThis.setImmediate = currentSetImmediate;
|
|
24
|
+
globalThis.clearImmediate = currentClearImmediate;
|
|
25
|
+
if (globalThis.process && nextTick) nextTick(() => {
|
|
15
26
|
globalThis.process.nextTick = currentNextTick;
|
|
16
27
|
});
|
|
17
28
|
}
|
|
@@ -43,7 +54,8 @@ function createSafeRpc(rpc) {
|
|
|
43
54
|
return new Proxy(rpc, { get(target, p, handler) {
|
|
44
55
|
// keep $rejectPendingCalls as sync function
|
|
45
56
|
if (p === "$rejectPendingCalls") return rpc.$rejectPendingCalls;
|
|
46
|
-
const sendCall = get(target, p, handler)
|
|
57
|
+
const sendCall = get(target, p, handler);
|
|
58
|
+
const safeSendCall = (...args) => withSafeTimers(async () => {
|
|
47
59
|
const result = sendCall(...args);
|
|
48
60
|
promises.add(result);
|
|
49
61
|
try {
|
|
@@ -52,7 +64,8 @@ function createSafeRpc(rpc) {
|
|
|
52
64
|
promises.delete(result);
|
|
53
65
|
}
|
|
54
66
|
});
|
|
55
|
-
|
|
67
|
+
safeSendCall.asEvent = sendCall.asEvent;
|
|
68
|
+
return safeSendCall;
|
|
56
69
|
} });
|
|
57
70
|
}
|
|
58
71
|
function rpc() {
|
|
@@ -1,38 +1,50 @@
|
|
|
1
1
|
import { r as resolveCoverageProviderModule } from './coverage.D_JHT54q.js';
|
|
2
2
|
import { addSerializer } from '@vitest/snapshot';
|
|
3
3
|
import { setSafeTimers } from '@vitest/utils/timers';
|
|
4
|
-
import { g as getWorkerState } from './utils.
|
|
4
|
+
import { g as getWorkerState } from './utils.DvEY5TfP.js';
|
|
5
5
|
|
|
6
6
|
async function startCoverageInsideWorker(options, loader, runtimeOptions) {
|
|
7
7
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
8
|
-
|
|
8
|
+
if (coverageModule) return coverageModule.startCoverage?.(runtimeOptions);
|
|
9
|
+
return null;
|
|
9
10
|
}
|
|
10
11
|
async function takeCoverageInsideWorker(options, loader) {
|
|
11
12
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
12
|
-
|
|
13
|
+
if (coverageModule) return coverageModule.takeCoverage?.({ moduleExecutionInfo: loader.moduleExecutionInfo });
|
|
14
|
+
return null;
|
|
13
15
|
}
|
|
14
16
|
async function stopCoverageInsideWorker(options, loader, runtimeOptions) {
|
|
15
17
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
16
|
-
|
|
18
|
+
if (coverageModule) return coverageModule.stopCoverage?.(runtimeOptions);
|
|
19
|
+
return null;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
let globalSetup = false;
|
|
20
23
|
async function setupCommonEnv(config) {
|
|
21
|
-
|
|
24
|
+
setupDefines(config);
|
|
25
|
+
setupEnv(config.env);
|
|
26
|
+
if (globalSetup) return;
|
|
27
|
+
globalSetup = true;
|
|
28
|
+
setSafeTimers();
|
|
29
|
+
if (config.globals) (await import('./globals.DOh96BiR.js')).registerApiGlobally();
|
|
22
30
|
}
|
|
23
31
|
function setupDefines(config) {
|
|
24
32
|
for (const key in config.defines) globalThis[key] = config.defines[key];
|
|
25
33
|
}
|
|
26
34
|
function setupEnv(env) {
|
|
27
|
-
const state = getWorkerState()
|
|
28
|
-
|
|
35
|
+
const state = getWorkerState();
|
|
36
|
+
// same boolean-to-string assignment as VitestPlugin.configResolved
|
|
37
|
+
const { PROD, DEV,...restEnvs } = env;
|
|
38
|
+
state.metaEnv.PROD = PROD;
|
|
39
|
+
state.metaEnv.DEV = DEV;
|
|
40
|
+
for (const key in restEnvs) state.metaEnv[key] = env[key];
|
|
29
41
|
}
|
|
30
42
|
async function loadDiffConfig(config, moduleRunner) {
|
|
31
43
|
if (typeof config.diff === "object") return config.diff;
|
|
32
44
|
if (typeof config.diff !== "string") return;
|
|
33
45
|
const diffModule = await moduleRunner.import(config.diff);
|
|
34
46
|
if (diffModule && typeof diffModule.default === "object" && diffModule.default != null) return diffModule.default;
|
|
35
|
-
throw new Error(`invalid diff config file ${config.diff}. Must have a default export with config object`);
|
|
47
|
+
else throw new Error(`invalid diff config file ${config.diff}. Must have a default export with config object`);
|
|
36
48
|
}
|
|
37
49
|
async function loadSnapshotSerializers(config, moduleRunner) {
|
|
38
50
|
const files = config.snapshotSerializers;
|