vitest 4.0.0-beta.9 → 4.0.1
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 +86 -102
- package/browser/context.d.ts +7 -0
- package/browser/context.js +20 -0
- package/dist/browser.d.ts +24 -7
- package/dist/browser.js +15 -5
- package/dist/chunks/{base.CA5N8Af0.js → base.BYPMk0VN.js} +36 -36
- package/dist/chunks/{benchmark.CJUa-Hsa.js → benchmark.DHKMYAts.js} +2 -2
- package/dist/chunks/{browser.d.DtfyY9yS.d.ts → browser.d.B9iJzZyn.d.ts} +3 -3
- package/dist/chunks/{cac.Dt7e1TIu.js → cac.DrF4Gm0S.js} +47 -73
- package/dist/chunks/{cli-api.eAzsLIxz.js → cli-api.W2Q-JQoO.js} +1524 -296
- package/dist/chunks/{config.d.DacWrqWe.d.ts → config.d.u2CUDWwS.d.ts} +5 -19
- package/dist/chunks/{console.7h5kHUIf.js → console.CTJL2nuH.js} +4 -6
- package/dist/chunks/{coverage.CDRAMTt7.js → coverage.FU3w4IrQ.js} +125 -1108
- package/dist/chunks/{creator.KEg6n5IC.js → creator.DucAaYBz.js} +10 -37
- package/dist/chunks/{defaults.CXFFjsi8.js → defaults.BOqNVLsY.js} +0 -1
- package/dist/chunks/environment.d.CrsxCzP1.d.ts +29 -0
- package/dist/chunks/evaluatedModules.Dg1zASAC.js +17 -0
- package/dist/chunks/{global.d.K6uBQHzY.d.ts → global.d.BgJSTpgQ.d.ts} +2 -17
- package/dist/chunks/{globals.CJrTTbxC.js → globals.BGT_RUsD.js} +11 -7
- package/dist/chunks/{index.BjKEiSn0.js → index.BdSLhLDZ.js} +3 -3
- package/dist/chunks/{index.DfviD7lX.js → index.CbWINfS7.js} +49 -21
- package/dist/chunks/{index.BIP7prJq.js → index.CcRZ6fUh.js} +1493 -114
- package/dist/chunks/{index.X0nbfr6-.js → index.Dc3xnDvT.js} +48 -289
- package/dist/chunks/{index.C832ioot.js → index.RwjEGCQ0.js} +4 -4
- package/dist/chunks/init-forks.WglB-sfY.js +54 -0
- package/dist/chunks/init-threads.Czek6eA5.js +17 -0
- package/dist/chunks/init.94FWN9pW.js +213 -0
- package/dist/chunks/{inspector.CvQD-Nie.js → inspector.DLZxSeU3.js} +2 -6
- package/dist/chunks/{moduleRunner.d.DxTLreRD.d.ts → moduleRunner.d.YtNsMIoJ.d.ts} +9 -14
- package/dist/chunks/{node.CyipiPvJ.js → node.BwAWWjHZ.js} +3 -4
- package/dist/chunks/{plugin.d.CIk0YiKb.d.ts → plugin.d.DQU1R5px.d.ts} +1 -1
- package/dist/chunks/{reporters.d.DmP-iHLr.d.ts → reporters.d.BMKt7f6I.d.ts} +1064 -1021
- package/dist/chunks/{resolveSnapshotEnvironment.Bvv2zr69.js → resolveSnapshotEnvironment.DJJKMKxb.js} +7 -8
- package/dist/chunks/{rpc.BKr6mtxz.js → rpc.cD77ENhU.js} +13 -14
- package/dist/chunks/{setup-common.B7I37Tji.js → setup-common.DR1sucx6.js} +6 -6
- package/dist/chunks/{startModuleRunner.BDRvKSdz.js → startModuleRunner.iF1E9Bt4.js} +126 -110
- package/dist/chunks/{test.BAlBebnP.js → test.C3RPt8JR.js} +7 -7
- package/dist/chunks/{utils.D2R2NiOH.js → utils.CG9h5ccR.js} +2 -5
- package/dist/chunks/{vi.BB37KeLx.js → vi.BZvkKVkM.js} +61 -164
- package/dist/chunks/{vm.CjLTDaST.js → vm.CuMWYx_F.js} +20 -29
- package/dist/chunks/{worker.d.B2r4Ln6p.d.ts → worker.d.BFk-vvBU.d.ts} +42 -6
- package/dist/cli.js +12 -11
- package/dist/config.cjs +0 -1
- package/dist/config.d.ts +11 -13
- package/dist/config.js +1 -1
- package/dist/coverage.d.ts +7 -6
- package/dist/coverage.js +3 -14
- package/dist/environments.d.ts +3 -6
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +20 -25
- package/dist/index.js +11 -7
- package/dist/module-evaluator.d.ts +5 -4
- package/dist/module-evaluator.js +11 -13
- package/dist/module-runner.js +5 -5
- package/dist/node.d.ts +82 -25
- package/dist/node.js +23 -20
- package/dist/reporters.d.ts +10 -9
- package/dist/reporters.js +12 -11
- package/dist/runners.d.ts +1 -1
- package/dist/runners.js +9 -7
- package/dist/snapshot.js +3 -3
- package/dist/suite.js +4 -3
- package/dist/worker.d.ts +26 -0
- package/dist/worker.js +45 -165
- package/dist/workers/forks.js +26 -43
- package/dist/workers/runVmTests.js +16 -12
- package/dist/workers/threads.js +26 -31
- package/dist/workers/vmForks.js +26 -39
- package/dist/workers/vmThreads.js +26 -29
- package/package.json +48 -32
- package/worker.d.ts +1 -0
- package/browser.d.ts +0 -1
- package/dist/chunks/environment.d.2fYMoz3o.d.ts +0 -66
- package/dist/chunks/moduleTransport.I-bgQy0S.js +0 -19
- package/dist/chunks/resolver.Bx6lE0iq.js +0 -119
- package/dist/chunks/typechecker.DB-fIMaH.js +0 -805
- package/dist/chunks/utils.C2YI6McM.js +0 -52
- package/dist/chunks/worker.d.DJ6qxO2w.d.ts +0 -8
- package/dist/workers.d.ts +0 -38
- package/dist/workers.js +0 -49
- package/execute.d.ts +0 -1
- package/utils.d.ts +0 -1
- package/workers.d.ts +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { chai } from '@vitest/expect';
|
|
2
|
-
import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.
|
|
3
|
-
import { r as rpc } from './rpc.
|
|
4
|
-
import { g as getWorkerState } from './utils.
|
|
5
|
-
import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.
|
|
2
|
+
import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.DR1sucx6.js';
|
|
3
|
+
import { r as rpc } from './rpc.cD77ENhU.js';
|
|
4
|
+
import { g as getWorkerState } from './utils.CG9h5ccR.js';
|
|
5
|
+
import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.C3RPt8JR.js';
|
|
6
6
|
|
|
7
7
|
function setupChaiConfig(config) {
|
|
8
8
|
Object.assign(chai.config, config);
|
|
@@ -15,7 +15,7 @@ async function getTestRunnerConstructor(config, moduleRunner) {
|
|
|
15
15
|
return mod.default;
|
|
16
16
|
}
|
|
17
17
|
async function resolveTestRunner(config, moduleRunner) {
|
|
18
|
-
const
|
|
18
|
+
const testRunner = new (await (getTestRunnerConstructor(config, moduleRunner)))(config);
|
|
19
19
|
if (Object.defineProperty(testRunner, "moduleRunner", {
|
|
20
20
|
value: moduleRunner,
|
|
21
21
|
enumerable: false,
|
|
@@ -61,8 +61,7 @@ async function resolveTestRunner(config, moduleRunner) {
|
|
|
61
61
|
const originalOnAfterRunTask = testRunner.onAfterRunTask;
|
|
62
62
|
return testRunner.onAfterRunTask = async (test) => {
|
|
63
63
|
if (config.bail && test.result?.state === "fail") {
|
|
64
|
-
|
|
65
|
-
if (currentFailures >= config.bail) rpc().onCancel("test-failure"), testRunner.cancel?.("test-failure");
|
|
64
|
+
if (1 + await rpc().getCountOfFailedTests() >= config.bail) rpc().onCancel("test-failure"), testRunner.cancel?.("test-failure");
|
|
66
65
|
}
|
|
67
66
|
await originalOnAfterRunTask?.call(testRunner, test);
|
|
68
67
|
}, testRunner;
|
|
@@ -70,7 +69,7 @@ async function resolveTestRunner(config, moduleRunner) {
|
|
|
70
69
|
|
|
71
70
|
async function resolveSnapshotEnvironment(config, executor) {
|
|
72
71
|
if (!config.snapshotEnvironment) {
|
|
73
|
-
const { VitestNodeSnapshotEnvironment } = await import('./node.
|
|
72
|
+
const { VitestNodeSnapshotEnvironment } = await import('./node.BwAWWjHZ.js');
|
|
74
73
|
return new VitestNodeSnapshotEnvironment();
|
|
75
74
|
}
|
|
76
75
|
const mod = await executor.import(config.snapshotEnvironment);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getSafeTimers } from '@vitest/utils';
|
|
1
|
+
import { getSafeTimers } from '@vitest/utils/timers';
|
|
2
2
|
import { c as createBirpc } from './index.Bgo3tNWt.js';
|
|
3
|
-
import { g as getWorkerState } from './utils.
|
|
3
|
+
import { g as getWorkerState } from './utils.CG9h5ccR.js';
|
|
4
4
|
|
|
5
5
|
const { get } = Reflect;
|
|
6
6
|
function withSafeTimers(fn) {
|
|
@@ -9,8 +9,7 @@ function withSafeTimers(fn) {
|
|
|
9
9
|
if (globalThis.setTimeout = setTimeout, globalThis.clearTimeout = clearTimeout, setImmediate) globalThis.setImmediate = setImmediate;
|
|
10
10
|
if (clearImmediate) globalThis.clearImmediate = clearImmediate;
|
|
11
11
|
if (globalThis.process && nextTick) globalThis.process.nextTick = nextTick;
|
|
12
|
-
|
|
13
|
-
return result;
|
|
12
|
+
return fn();
|
|
14
13
|
} finally {
|
|
15
14
|
if (globalThis.setTimeout = currentSetTimeout, globalThis.clearTimeout = currentClearTimeout, globalThis.setImmediate = currentSetImmediate, globalThis.clearImmediate = currentClearImmediate, globalThis.process && nextTick) nextTick(() => {
|
|
16
15
|
globalThis.process.nextTick = currentNextTick;
|
|
@@ -27,17 +26,17 @@ function createRuntimeRpc(options) {
|
|
|
27
26
|
let setCancel = (_reason) => {};
|
|
28
27
|
const onCancel = new Promise((resolve) => {
|
|
29
28
|
setCancel = resolve;
|
|
30
|
-
})
|
|
31
|
-
eventNames: [
|
|
32
|
-
"onUserConsoleLog",
|
|
33
|
-
"onCollected",
|
|
34
|
-
"onCancel"
|
|
35
|
-
],
|
|
36
|
-
timeout: -1,
|
|
37
|
-
...options
|
|
38
|
-
}));
|
|
29
|
+
});
|
|
39
30
|
return {
|
|
40
|
-
rpc,
|
|
31
|
+
rpc: createSafeRpc(createBirpc({ onCancel: setCancel }, {
|
|
32
|
+
eventNames: [
|
|
33
|
+
"onUserConsoleLog",
|
|
34
|
+
"onCollected",
|
|
35
|
+
"onCancel"
|
|
36
|
+
],
|
|
37
|
+
timeout: -1,
|
|
38
|
+
...options
|
|
39
|
+
})),
|
|
41
40
|
onCancel
|
|
42
41
|
};
|
|
43
42
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as resolveCoverageProviderModule } from './coverage.D_JHT54q.js';
|
|
2
2
|
import { addSerializer } from '@vitest/snapshot';
|
|
3
|
-
import { setSafeTimers } from '@vitest/utils';
|
|
4
|
-
import { g as getWorkerState } from './utils.
|
|
3
|
+
import { setSafeTimers } from '@vitest/utils/timers';
|
|
4
|
+
import { g as getWorkerState } from './utils.CG9h5ccR.js';
|
|
5
5
|
|
|
6
6
|
async function startCoverageInsideWorker(options, loader, runtimeOptions) {
|
|
7
7
|
const coverageModule = await resolveCoverageProviderModule(options, loader);
|
|
@@ -18,7 +18,7 @@ async function stopCoverageInsideWorker(options, loader, runtimeOptions) {
|
|
|
18
18
|
|
|
19
19
|
let globalSetup = false;
|
|
20
20
|
async function setupCommonEnv(config) {
|
|
21
|
-
if (setupDefines(config), setupEnv(config.env), !globalSetup && (globalSetup = true, setSafeTimers(), config.globals)) (await import('./globals.
|
|
21
|
+
if (setupDefines(config), setupEnv(config.env), !globalSetup && (globalSetup = true, setSafeTimers(), config.globals)) (await import('./globals.BGT_RUsD.js')).registerApiGlobally();
|
|
22
22
|
}
|
|
23
23
|
function setupDefines(config) {
|
|
24
24
|
for (const key in config.defines) globalThis[key] = config.defines[key];
|
|
@@ -35,14 +35,14 @@ async function loadDiffConfig(config, moduleRunner) {
|
|
|
35
35
|
throw new Error(`invalid diff config file ${config.diff}. Must have a default export with config object`);
|
|
36
36
|
}
|
|
37
37
|
async function loadSnapshotSerializers(config, moduleRunner) {
|
|
38
|
-
const files = config.snapshotSerializers
|
|
38
|
+
const files = config.snapshotSerializers;
|
|
39
|
+
(await Promise.all(files.map(async (file) => {
|
|
39
40
|
const mo = await moduleRunner.import(file);
|
|
40
41
|
if (!mo || typeof mo.default !== "object" || mo.default === null) throw new Error(`invalid snapshot serializer file ${file}. Must export a default object`);
|
|
41
42
|
const config = mo.default;
|
|
42
43
|
if (typeof config.test !== "function" || typeof config.serialize !== "function" && typeof config.print !== "function") throw new TypeError(`invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.`);
|
|
43
44
|
return config;
|
|
44
|
-
}));
|
|
45
|
-
snapshotSerializers.forEach((serializer) => addSerializer(serializer));
|
|
45
|
+
}))).forEach((serializer) => addSerializer(serializer));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export { stopCoverageInsideWorker as a, loadSnapshotSerializers as b, setupCommonEnv as c, loadDiffConfig as l, startCoverageInsideWorker as s, takeCoverageInsideWorker as t };
|
|
@@ -1,68 +1,15 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { builtinModules, isBuiltin } from 'node:module';
|
|
3
|
-
import {
|
|
2
|
+
import nodeModule, { builtinModules, isBuiltin } from 'node:module';
|
|
3
|
+
import { isBareImport } from '@vitest/utils/helpers';
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { normalize as normalize$1, join as join$1 } from 'pathe';
|
|
6
6
|
import { distDir } from '../path.js';
|
|
7
|
-
import {
|
|
7
|
+
import { serializeValue } from '@vitest/utils/serialize';
|
|
8
8
|
import { VitestModuleEvaluator, unwrapId } from '../module-evaluator.js';
|
|
9
9
|
import { resolve as resolve$1, isAbsolute as isAbsolute$1 } from 'node:path';
|
|
10
10
|
import vm from 'node:vm';
|
|
11
11
|
import { MockerRegistry, mockObject, RedirectedModule, AutomockedModule } from '@vitest/mocker';
|
|
12
|
-
import
|
|
13
|
-
import { V as VitestTransport } from './moduleTransport.I-bgQy0S.js';
|
|
14
|
-
|
|
15
|
-
const bareVitestRegexp = /^@?vitest(?:\/|$)/, normalizedDistDir = normalize$1(distDir), relativeIds = {}, externalizeMap = /* @__PURE__ */ new Map();
|
|
16
|
-
// all Vitest imports always need to be externalized
|
|
17
|
-
function getCachedVitestImport(id, state) {
|
|
18
|
-
if (id.startsWith("/@fs/") || id.startsWith("\\@fs\\")) id = id.slice(process.platform === "win32" ? 5 : 4);
|
|
19
|
-
if (externalizeMap.has(id)) return {
|
|
20
|
-
externalize: externalizeMap.get(id),
|
|
21
|
-
type: "module"
|
|
22
|
-
};
|
|
23
|
-
// always externalize Vitest because we import from there before running tests
|
|
24
|
-
// so we already have it cached by Node.js
|
|
25
|
-
const root = state().config.root, relativeRoot = relativeIds[root] ?? (relativeIds[root] = normalizedDistDir.slice(root.length));
|
|
26
|
-
if (id.includes(distDir) || id.includes(normalizedDistDir)) {
|
|
27
|
-
const externalize = id.startsWith("file://") ? id : pathToFileURL(id).toString();
|
|
28
|
-
return externalizeMap.set(id, externalize), {
|
|
29
|
-
externalize,
|
|
30
|
-
type: "module"
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
if (relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) {
|
|
34
|
-
const path = join$1(root, id), externalize = pathToFileURL(path).toString();
|
|
35
|
-
return externalizeMap.set(id, externalize), {
|
|
36
|
-
externalize,
|
|
37
|
-
type: "module"
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
return bareVitestRegexp.test(id) ? (externalizeMap.set(id, id), {
|
|
41
|
-
externalize: id,
|
|
42
|
-
type: "module"
|
|
43
|
-
}) : null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const dispose = [];
|
|
47
|
-
function listenForErrors(state) {
|
|
48
|
-
dispose.forEach((fn) => fn()), dispose.length = 0;
|
|
49
|
-
function catchError(err, type, event) {
|
|
50
|
-
const worker = state(), listeners = process.listeners(event);
|
|
51
|
-
// if there is another listener, assume that it's handled by user code
|
|
52
|
-
// one is Vitest's own listener
|
|
53
|
-
if (listeners.length > 1) return;
|
|
54
|
-
const error = processError(err);
|
|
55
|
-
if (typeof error === "object" && error != null) {
|
|
56
|
-
if (error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0, worker.filepath) error.VITEST_TEST_PATH = worker.filepath;
|
|
57
|
-
error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun;
|
|
58
|
-
}
|
|
59
|
-
state().rpc.onUnhandledError(error, type);
|
|
60
|
-
}
|
|
61
|
-
const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException"), unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
|
|
62
|
-
process.on("uncaughtException", uncaughtException), process.on("unhandledRejection", unhandledRejection), dispose.push(() => {
|
|
63
|
-
process.off("uncaughtException", uncaughtException), process.off("unhandledRejection", unhandledRejection);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
12
|
+
import * as viteModuleRunner from 'vite/module-runner';
|
|
66
13
|
|
|
67
14
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
68
15
|
function normalizeWindowsPath(input = "") {
|
|
@@ -81,8 +28,8 @@ const _UNC_REGEX = /^[/\\]{2}/, _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\
|
|
|
81
28
|
for (const seg of segments) {
|
|
82
29
|
if (!seg) continue;
|
|
83
30
|
if (path.length > 0) {
|
|
84
|
-
const pathTrailing = path[path.length - 1] === "/", segLeading = seg[0] === "/"
|
|
85
|
-
if (
|
|
31
|
+
const pathTrailing = path[path.length - 1] === "/", segLeading = seg[0] === "/";
|
|
32
|
+
if (pathTrailing && segLeading) path += seg.slice(1);
|
|
86
33
|
else path += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
87
34
|
} else path += seg;
|
|
88
35
|
}
|
|
@@ -167,17 +114,14 @@ function findMockRedirect(root, mockPath, external) {
|
|
|
167
114
|
const baseOriginal = basename(path);
|
|
168
115
|
function findFile(mockFolder, baseOriginal) {
|
|
169
116
|
const files = readdirSync(mockFolder);
|
|
170
|
-
for (const file of files) {
|
|
171
|
-
const
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const indexFile = findFile(path, "index");
|
|
179
|
-
if (indexFile) return indexFile;
|
|
180
|
-
}
|
|
117
|
+
for (const file of files) if (basename(file, extname(file)) === baseOriginal) {
|
|
118
|
+
const path = resolve(mockFolder, file);
|
|
119
|
+
// if the same name, return the file
|
|
120
|
+
if (statSync(path).isFile()) return path;
|
|
121
|
+
{
|
|
122
|
+
// find folder/index.{js,ts}
|
|
123
|
+
const indexFile = findFile(path, "index");
|
|
124
|
+
if (indexFile) return indexFile;
|
|
181
125
|
}
|
|
182
126
|
}
|
|
183
127
|
return null;
|
|
@@ -188,7 +132,7 @@ function findMockRedirect(root, mockPath, external) {
|
|
|
188
132
|
return existsSync(fullPath) ? fullPath : null;
|
|
189
133
|
}
|
|
190
134
|
const builtins = new Set([
|
|
191
|
-
...builtinModules,
|
|
135
|
+
...nodeModule.builtinModules,
|
|
192
136
|
"assert/strict",
|
|
193
137
|
"diagnostics_channel",
|
|
194
138
|
"dns/promises",
|
|
@@ -209,7 +153,7 @@ const builtins = new Set([
|
|
|
209
153
|
"node:test/reporters"
|
|
210
154
|
]), NODE_BUILTIN_NAMESPACE = "node:";
|
|
211
155
|
function isNodeBuiltin(id) {
|
|
212
|
-
return prefixedBuiltins$1.has(id) ? true : builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(5) : id);
|
|
156
|
+
return nodeModule.isBuiltin ? nodeModule.isBuiltin(id) : prefixedBuiltins$1.has(id) ? true : builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(5) : id);
|
|
213
157
|
}
|
|
214
158
|
|
|
215
159
|
const spyModulePath = resolve$1(distDir, "spy.js");
|
|
@@ -331,16 +275,16 @@ class VitestMocker {
|
|
|
331
275
|
if (prop === "then") {
|
|
332
276
|
if (target instanceof Promise) return target.then.bind(target);
|
|
333
277
|
} else if (!(prop in target)) {
|
|
334
|
-
if (this.filterPublicKeys.includes(prop)) return
|
|
278
|
+
if (this.filterPublicKeys.includes(prop)) return;
|
|
335
279
|
throw this.createError(`[vitest] No "${String(prop)}" export is defined on the "${mock.raw}" mock. Did you forget to return it from "vi.mock"?
|
|
336
280
|
If you need to partially mock a module, you can use "importOriginal" helper inside:
|
|
337
|
-
`,
|
|
281
|
+
`, `vi.mock(import("${mock.raw}"), async (importOriginal) => {
|
|
338
282
|
const actual = await importOriginal()
|
|
339
283
|
return {
|
|
340
284
|
...actual,
|
|
341
285
|
// your mocked methods
|
|
342
286
|
}
|
|
343
|
-
})`)
|
|
287
|
+
})`);
|
|
344
288
|
}
|
|
345
289
|
return val;
|
|
346
290
|
} });
|
|
@@ -355,8 +299,7 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
355
299
|
return `mock:${dep}`;
|
|
356
300
|
}
|
|
357
301
|
getDependencyMock(id) {
|
|
358
|
-
|
|
359
|
-
return registry.getById(fixLeadingSlashes(id));
|
|
302
|
+
return this.getMockerRegistry().getById(fixLeadingSlashes(id));
|
|
360
303
|
}
|
|
361
304
|
findMockRedirect(mockPath, external) {
|
|
362
305
|
return findMockRedirect(this.root, mockPath, external);
|
|
@@ -371,8 +314,7 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
371
314
|
}, object, mockExports);
|
|
372
315
|
}
|
|
373
316
|
unmockPath(id) {
|
|
374
|
-
|
|
375
|
-
registry.deleteById(id), this.invalidateModuleById(id);
|
|
317
|
+
this.getMockerRegistry().deleteById(id), this.invalidateModuleById(id);
|
|
376
318
|
}
|
|
377
319
|
mockPath(originalId, id, url, external, mockType, factory) {
|
|
378
320
|
const registry = this.getMockerRegistry();
|
|
@@ -387,8 +329,8 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
|
|
|
387
329
|
this.invalidateModuleById(id);
|
|
388
330
|
}
|
|
389
331
|
async importActual(rawId, importer, callstack) {
|
|
390
|
-
const { url } = await this.resolveId(rawId, importer), node = await this.moduleRunner.fetchModule(url, importer)
|
|
391
|
-
return
|
|
332
|
+
const { url } = await this.resolveId(rawId, importer), node = await this.moduleRunner.fetchModule(url, importer);
|
|
333
|
+
return await this.moduleRunner.cachedRequest(node.url, node, callstack || [importer], void 0, true);
|
|
392
334
|
}
|
|
393
335
|
async importMock(rawId, importer) {
|
|
394
336
|
const { id, url, external } = await this.resolveId(rawId, importer);
|
|
@@ -473,11 +415,8 @@ const prefixedBuiltins = new Set([
|
|
|
473
415
|
// C:\root\id.js -> /id.js
|
|
474
416
|
// TODO: expose this in vite/module-runner
|
|
475
417
|
function normalizeModuleId(file) {
|
|
476
|
-
if (prefixedBuiltins.has(file)) return file;
|
|
477
|
-
// unix style, but Windows path still starts with the drive letter to check the root
|
|
478
|
-
const unixFile = slash(file).replace(/^\/@fs\//, isWindows$1 ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/");
|
|
479
418
|
// if it's not in the root, keep it as a path, not a URL
|
|
480
|
-
return
|
|
419
|
+
return prefixedBuiltins.has(file) ? file : slash(file).replace(/^\/@fs\//, isWindows$1 ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/").replace(/^file:\//, "/");
|
|
481
420
|
}
|
|
482
421
|
const windowsSlashRE = /\\/g;
|
|
483
422
|
function slash(p) {
|
|
@@ -489,18 +428,52 @@ function fixLeadingSlashes(id) {
|
|
|
489
428
|
return id.startsWith("//") ? id.replace(multipleSlashRe, "/") : id;
|
|
490
429
|
}
|
|
491
430
|
|
|
431
|
+
const nodeBuiltins = builtinModules.filter((id) => !id.includes(":"));
|
|
432
|
+
class VitestTransport {
|
|
433
|
+
constructor(options) {
|
|
434
|
+
this.options = options;
|
|
435
|
+
}
|
|
436
|
+
async invoke(event) {
|
|
437
|
+
if (event.type !== "custom") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support Vite HMR events.`) };
|
|
438
|
+
if (event.event !== "vite:invoke") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support ${event.event} event.`) };
|
|
439
|
+
const { name, data } = event.data;
|
|
440
|
+
if (name === "getBuiltins") return { result: [...nodeBuiltins, /^node:/] };
|
|
441
|
+
if (name !== "fetchModule") return { error: /* @__PURE__ */ new Error(`Unknown method: ${name}. Expected "fetchModule".`) };
|
|
442
|
+
try {
|
|
443
|
+
return { result: await this.options.fetchModule(...data) };
|
|
444
|
+
} catch (error) {
|
|
445
|
+
return { error };
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const createNodeImportMeta = (modulePath) => {
|
|
451
|
+
if (!viteModuleRunner.createDefaultImportMeta) throw new Error(`createNodeImportMeta is not supported in this version of Vite.`);
|
|
452
|
+
const defaultMeta = viteModuleRunner.createDefaultImportMeta(modulePath), href = defaultMeta.url, importMetaResolver = createImportMetaResolver();
|
|
453
|
+
return {
|
|
454
|
+
...defaultMeta,
|
|
455
|
+
main: false,
|
|
456
|
+
resolve(id, parent) {
|
|
457
|
+
return (importMetaResolver ?? defaultMeta.resolve)(id, parent ?? href);
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
function createImportMetaResolver() {
|
|
462
|
+
if (import.meta.resolve) return (specifier, importer) => import.meta.resolve(specifier, importer);
|
|
463
|
+
}
|
|
492
464
|
// @ts-expect-error overriding private method
|
|
493
|
-
class VitestModuleRunner extends ModuleRunner {
|
|
465
|
+
class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
|
|
494
466
|
mocker;
|
|
495
467
|
moduleExecutionInfo;
|
|
496
|
-
constructor(
|
|
497
|
-
const transport = new VitestTransport(options.transport), evaluatedModules = options.evaluatedModules;
|
|
468
|
+
constructor(vitestOptions) {
|
|
469
|
+
const options = vitestOptions, transport = new VitestTransport(options.transport), evaluatedModules = options.evaluatedModules;
|
|
498
470
|
if (super({
|
|
499
471
|
transport,
|
|
500
472
|
hmr: false,
|
|
501
473
|
evaluatedModules,
|
|
502
|
-
sourcemapInterceptor: "prepareStackTrace"
|
|
503
|
-
|
|
474
|
+
sourcemapInterceptor: "prepareStackTrace",
|
|
475
|
+
createImportMeta: vitestOptions.createImportMeta
|
|
476
|
+
}, options.evaluator), this.vitestOptions = vitestOptions, this.moduleExecutionInfo = options.getWorkerState().moduleExecutionInfo, this.mocker = options.mocker || new VitestMocker(this, {
|
|
504
477
|
spyModule: options.spyModule,
|
|
505
478
|
context: options.vm?.context,
|
|
506
479
|
resolveId: options.transport.resolveId,
|
|
@@ -521,12 +494,11 @@ class VitestModuleRunner extends ModuleRunner {
|
|
|
521
494
|
});
|
|
522
495
|
}
|
|
523
496
|
async import(rawId) {
|
|
524
|
-
const resolved = await this.
|
|
525
|
-
return
|
|
497
|
+
const resolved = await this.vitestOptions.transport.resolveId(rawId);
|
|
498
|
+
return super.import(resolved ? resolved.url : rawId);
|
|
526
499
|
}
|
|
527
500
|
async fetchModule(url, importer) {
|
|
528
|
-
|
|
529
|
-
return module;
|
|
501
|
+
return await this.cachedModule(url, importer);
|
|
530
502
|
}
|
|
531
503
|
_cachedRequest(url, module, callstack = [], metadata) {
|
|
532
504
|
// @ts-expect-error "cachedRequest" is private
|
|
@@ -560,6 +532,58 @@ class VitestModuleRunner extends ModuleRunner {
|
|
|
560
532
|
}
|
|
561
533
|
}
|
|
562
534
|
|
|
535
|
+
const bareVitestRegexp = /^@?vitest(?:\/|$)/, normalizedDistDir = normalize$1(distDir), relativeIds = {}, externalizeMap = /* @__PURE__ */ new Map();
|
|
536
|
+
// all Vitest imports always need to be externalized
|
|
537
|
+
function getCachedVitestImport(id, state) {
|
|
538
|
+
if (id.startsWith("/@fs/") || id.startsWith("\\@fs\\")) id = id.slice(process.platform === "win32" ? 5 : 4);
|
|
539
|
+
if (externalizeMap.has(id)) return {
|
|
540
|
+
externalize: externalizeMap.get(id),
|
|
541
|
+
type: "module"
|
|
542
|
+
};
|
|
543
|
+
// always externalize Vitest because we import from there before running tests
|
|
544
|
+
// so we already have it cached by Node.js
|
|
545
|
+
const root = state().config.root, relativeRoot = relativeIds[root] ?? (relativeIds[root] = normalizedDistDir.slice(root.length));
|
|
546
|
+
if (id.includes(distDir) || id.includes(normalizedDistDir)) {
|
|
547
|
+
const externalize = id.startsWith("file://") ? id : pathToFileURL(id).toString();
|
|
548
|
+
return externalizeMap.set(id, externalize), {
|
|
549
|
+
externalize,
|
|
550
|
+
type: "module"
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
if (relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) {
|
|
554
|
+
const path = join$1(root, id), externalize = pathToFileURL(path).toString();
|
|
555
|
+
return externalizeMap.set(id, externalize), {
|
|
556
|
+
externalize,
|
|
557
|
+
type: "module"
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
return bareVitestRegexp.test(id) ? (externalizeMap.set(id, id), {
|
|
561
|
+
externalize: id,
|
|
562
|
+
type: "module"
|
|
563
|
+
}) : null;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const dispose = [];
|
|
567
|
+
function listenForErrors(state) {
|
|
568
|
+
dispose.forEach((fn) => fn()), dispose.length = 0;
|
|
569
|
+
function catchError(err, type, event) {
|
|
570
|
+
const worker = state();
|
|
571
|
+
// if there is another listener, assume that it's handled by user code
|
|
572
|
+
// one is Vitest's own listener
|
|
573
|
+
if (process.listeners(event).length > 1) return;
|
|
574
|
+
const error = serializeValue(err);
|
|
575
|
+
if (typeof error === "object" && error != null) {
|
|
576
|
+
if (error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0, worker.filepath) error.VITEST_TEST_PATH = worker.filepath;
|
|
577
|
+
error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun;
|
|
578
|
+
}
|
|
579
|
+
state().rpc.onUnhandledError(error, type);
|
|
580
|
+
}
|
|
581
|
+
const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException"), unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
|
|
582
|
+
process.on("uncaughtException", uncaughtException), process.on("unhandledRejection", unhandledRejection), dispose.push(() => {
|
|
583
|
+
process.off("uncaughtException", uncaughtException), process.off("unhandledRejection", unhandledRejection);
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
563
587
|
const { readFileSync } = fs, browserExternalId = "__vite-browser-external", browserExternalLength = 24;
|
|
564
588
|
const VITEST_VM_CONTEXT_SYMBOL = "__vitest_vm_context__";
|
|
565
589
|
const cwd = process.cwd(), isWindows = process.platform === "win32";
|
|
@@ -593,10 +617,7 @@ function startVitestModuleRunner(options) {
|
|
|
593
617
|
if (isWindows) {
|
|
594
618
|
if (id[1] === ":") {
|
|
595
619
|
// The drive letter is different for whatever reason, we need to normalize it to CWD
|
|
596
|
-
if (id[0] !== cwd[0] && id[0].toUpperCase() === cwd[0].toUpperCase())
|
|
597
|
-
const isUpperCase = cwd[0].toUpperCase() === cwd[0];
|
|
598
|
-
id = (isUpperCase ? id[0].toUpperCase() : id[0].toLowerCase()) + id.slice(1);
|
|
599
|
-
}
|
|
620
|
+
if (id[0] !== cwd[0] && id[0].toUpperCase() === cwd[0].toUpperCase()) id = (cwd[0].toUpperCase() === cwd[0] ? id[0].toUpperCase() : id[0].toLowerCase()) + id.slice(1);
|
|
600
621
|
// always mark absolute windows paths, otherwise Vite will externalize it
|
|
601
622
|
id = `/@id/${id}`;
|
|
602
623
|
}
|
|
@@ -621,14 +642,10 @@ function startVitestModuleRunner(options) {
|
|
|
621
642
|
type: "builtin"
|
|
622
643
|
};
|
|
623
644
|
const result = await rpc().fetch(id, importer, environment(), options);
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
...result
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
return result;
|
|
645
|
+
return "cached" in result ? {
|
|
646
|
+
code: readFileSync(result.tmp, "utf-8"),
|
|
647
|
+
...result
|
|
648
|
+
} : result;
|
|
632
649
|
} catch (cause) {
|
|
633
650
|
// rethrow vite error if it cannot load the module because it's not resolved
|
|
634
651
|
if (typeof cause === "object" && cause != null && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url") || typeof cause?.message === "string" && cause.message.startsWith("Cannot find module '")) {
|
|
@@ -645,10 +662,9 @@ function startVitestModuleRunner(options) {
|
|
|
645
662
|
}
|
|
646
663
|
},
|
|
647
664
|
getWorkerState: state,
|
|
648
|
-
vm
|
|
665
|
+
vm,
|
|
666
|
+
createImportMeta: options.createImportMeta
|
|
649
667
|
});
|
|
650
|
-
// await moduleRunner.import('/@vite/env')
|
|
651
|
-
// await moduleRunner.mocker.initializeSpyModule()
|
|
652
668
|
return moduleRunner;
|
|
653
669
|
}
|
|
654
670
|
function toBuiltin(id) {
|
|
@@ -657,4 +673,4 @@ function toBuiltin(id) {
|
|
|
657
673
|
return id;
|
|
658
674
|
}
|
|
659
675
|
|
|
660
|
-
export { VitestModuleRunner as V, VITEST_VM_CONTEXT_SYMBOL as a, startVitestModuleRunner as s };
|
|
676
|
+
export { VitestModuleRunner as V, VITEST_VM_CONTEXT_SYMBOL as a, VitestTransport as b, createNodeImportMeta as c, startVitestModuleRunner as s };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { updateTask } from '@vitest/runner';
|
|
2
|
-
import { createDefer
|
|
3
|
-
import {
|
|
4
|
-
import { g as
|
|
2
|
+
import { createDefer } from '@vitest/utils/helpers';
|
|
3
|
+
import { getSafeTimers } from '@vitest/utils/timers';
|
|
4
|
+
import { a as getBenchOptions, g as getBenchFn } from './benchmark.DHKMYAts.js';
|
|
5
|
+
import { g as getWorkerState } from './utils.CG9h5ccR.js';
|
|
5
6
|
import { setState, GLOBAL_EXPECT, getState } from '@vitest/expect';
|
|
6
7
|
import { getTests, getNames, getTestName } from '@vitest/runner/utils';
|
|
7
8
|
import { processError } from '@vitest/utils/error';
|
|
8
9
|
import { normalize } from 'pathe';
|
|
9
|
-
import { a as getSnapshotClient, i as inject, c as createExpect, v as vi } from './vi.
|
|
10
|
-
import { r as rpc } from './rpc.
|
|
10
|
+
import { a as getSnapshotClient, i as inject, c as createExpect, v as vi } from './vi.BZvkKVkM.js';
|
|
11
|
+
import { r as rpc } from './rpc.cD77ENhU.js';
|
|
11
12
|
|
|
12
13
|
function createBenchmarkResult(name) {
|
|
13
14
|
return {
|
|
@@ -36,7 +37,7 @@ async function runBenchmarkSuite(suite, runner) {
|
|
|
36
37
|
}, updateTask$1("suite-prepare", suite);
|
|
37
38
|
const addBenchTaskListener = (task, benchmark) => {
|
|
38
39
|
task.addEventListener("complete", (e) => {
|
|
39
|
-
const
|
|
40
|
+
const taskRes = e.task.result, result = benchmark.result.benchmark;
|
|
40
41
|
benchmark.result.state = "pass", Object.assign(result, taskRes);
|
|
41
42
|
// compute extra stats and free raw samples as early as possible
|
|
42
43
|
const samples = result.samples;
|
|
@@ -93,7 +94,6 @@ class NodeBenchmarkRunner {
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
// import type { VitestExecutor } from '../execute'
|
|
97
97
|
// worker context is shared between all tests
|
|
98
98
|
const workerContext = Object.create(null);
|
|
99
99
|
class VitestTestRunner {
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { getSafeTimers } from '@vitest/utils';
|
|
1
|
+
import { getSafeTimers } from '@vitest/utils/timers';
|
|
2
2
|
|
|
3
3
|
const NAME_WORKER_STATE = "__vitest_worker__";
|
|
4
4
|
function getWorkerState() {
|
|
5
5
|
// @ts-expect-error untyped global
|
|
6
6
|
const workerState = globalThis[NAME_WORKER_STATE];
|
|
7
|
-
if (!workerState)
|
|
8
|
-
const errorMsg = "Vitest failed to access its internal state.\n\nOne of the following is possible:\n- \"vitest\" is imported directly without running \"vitest\" command\n- \"vitest\" is imported inside \"globalSetup\" (to fix this, use \"setupFiles\" instead, because \"globalSetup\" runs in a different context)\n- \"vitest\" is imported inside Vite / Vitest config file\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n";
|
|
9
|
-
throw new Error(errorMsg);
|
|
10
|
-
}
|
|
7
|
+
if (!workerState) throw new Error("Vitest failed to access its internal state.\n\nOne of the following is possible:\n- \"vitest\" is imported directly without running \"vitest\" command\n- \"vitest\" is imported inside \"globalSetup\" (to fix this, use \"setupFiles\" instead, because \"globalSetup\" runs in a different context)\n- \"vitest\" is imported inside Vite / Vitest config file\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n");
|
|
11
8
|
return workerState;
|
|
12
9
|
}
|
|
13
10
|
function provideWorkerState(context, state) {
|