vitest 4.1.0-beta.1 → 4.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE.md +36 -0
  2. package/dist/browser.d.ts +1 -1
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/acorn.B2iPLyUM.js +5958 -0
  5. package/dist/chunks/{base.CBRNZa3k.js → base.DiopZV8F.js} +48 -14
  6. package/dist/chunks/{benchmark.B3N2zMcH.js → benchmark.BoqSLF53.js} +1 -1
  7. package/dist/chunks/{browser.d.8hOapKZr.d.ts → browser.d.BE4kbYok.d.ts} +2 -1
  8. package/dist/chunks/{cac.B1v3xxoC.js → cac.C4jjt2RX.js} +797 -13
  9. package/dist/chunks/{cli-api.B4CqEpI6.js → cli-api.ChbI1JU9.js} +322 -124
  10. package/dist/chunks/{config.d.idH22YSr.d.ts → config.d.Cr1Ep39N.d.ts} +6 -1
  11. package/dist/chunks/{console.uGgdMhyZ.js → console.CNlG1KsP.js} +2 -2
  12. package/dist/chunks/{constants.D_Q9UYh-.js → constants.B63TT-Bl.js} +1 -1
  13. package/dist/chunks/coverage.tyqbzn4W.js +1001 -0
  14. package/dist/chunks/{creator.C7WwjkuR.js → creator.yyCHuw5R.js} +1 -1
  15. package/dist/chunks/{global.d.B15mdLcR.d.ts → global.d.JeWMqlOm.d.ts} +1 -1
  16. package/dist/chunks/{globals.DjuGMoMc.js → globals.C6Ecf1TO.js} +6 -6
  17. package/dist/chunks/{index.Dm4xqZ0s.js → index.B-iBE_Gx.js} +20 -4
  18. package/dist/chunks/{coverage.BMlOMIWl.js → index.BCY_7LL2.js} +5 -969
  19. package/dist/chunks/{index.BiOAd_ki.js → index.CAN630q3.js} +7 -7
  20. package/dist/chunks/{index.DyBZXrH3.js → index.CFulQRmC.js} +1 -1
  21. package/dist/chunks/{index.BEFi2-_3.js → index.CouFDptX.js} +2 -2
  22. package/dist/chunks/{init-forks.CHeQ9Moq.js → init-forks.BnCXPazU.js} +1 -1
  23. package/dist/chunks/{init-threads.uZiNAuPk.js → init-threads.Cyh2PqXi.js} +1 -1
  24. package/dist/chunks/{init.DVtKdFty.js → init.B95Mm0Iz.js} +47 -9
  25. package/dist/chunks/native.mV0-490A.js +148 -0
  26. package/dist/chunks/nativeModuleMocker.D_q5sFv6.js +206 -0
  27. package/dist/chunks/nativeModuleRunner.BIakptoF.js +36 -0
  28. package/dist/chunks/{node.Ce0vMQM7.js → node.CrSEwhm4.js} +1 -1
  29. package/dist/chunks/{plugin.d.D8KU2PY_.d.ts → plugin.d.C9o5bttz.d.ts} +1 -1
  30. package/dist/chunks/{reporters.d.Db3MiIWX.d.ts → reporters.d.7faYdkxy.d.ts} +120 -51
  31. package/dist/chunks/{rpc.HLmECnw_.js → rpc.DcRWTy5G.js} +1 -1
  32. package/dist/chunks/{rpc.d.RH3apGEf.d.ts → rpc.d.CM7x9-sm.d.ts} +1 -0
  33. package/dist/chunks/{setup-common.BcqLPsn5.js → setup-common.cvFp-ao9.js} +2 -2
  34. package/dist/chunks/{startModuleRunner.C5CcWyXW.js → startVitestModuleRunner.BK-u7y4N.js} +163 -372
  35. package/dist/chunks/{test.prxIahgM.js → test.G82XYNFk.js} +9 -4
  36. package/dist/chunks/{utils.DvEY5TfP.js → utils.DT4VyRyl.js} +5 -1
  37. package/dist/chunks/{vm.CrifS09m.js → vm.BdLtzhnj.js} +13 -6
  38. package/dist/chunks/{worker.d.Bji1eq5g.d.ts → worker.d.CPzI2ZzJ.d.ts} +2 -2
  39. package/dist/cli.js +4 -3
  40. package/dist/config.d.ts +8 -8
  41. package/dist/config.js +1 -1
  42. package/dist/coverage.d.ts +7 -5
  43. package/dist/coverage.js +5 -4
  44. package/dist/index.d.ts +18 -23
  45. package/dist/index.js +5 -5
  46. package/dist/module-evaluator.d.ts +10 -1
  47. package/dist/node.d.ts +9 -9
  48. package/dist/node.js +18 -16
  49. package/dist/nodejs-worker-loader.js +41 -0
  50. package/dist/reporters.d.ts +5 -5
  51. package/dist/reporters.js +2 -2
  52. package/dist/runners.d.ts +2 -1
  53. package/dist/runners.js +4 -4
  54. package/dist/runtime.js +4 -5
  55. package/dist/snapshot.js +2 -2
  56. package/dist/suite.js +2 -2
  57. package/dist/worker.d.ts +6 -6
  58. package/dist/worker.js +25 -18
  59. package/dist/workers/forks.js +21 -14
  60. package/dist/workers/runVmTests.js +7 -7
  61. package/dist/workers/threads.js +21 -14
  62. package/dist/workers/vmForks.js +14 -10
  63. package/dist/workers/vmThreads.js +14 -10
  64. package/package.json +17 -14
  65. package/suppress-warnings.cjs +1 -0
@@ -1,19 +1,19 @@
1
1
  import { chai } from '@vitest/expect';
2
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.BcqLPsn5.js';
3
- import { r as rpc } from './rpc.HLmECnw_.js';
4
- import { g as getWorkerState } from './utils.DvEY5TfP.js';
5
- import { T as TestRunner, N as NodeBenchmarkRunner } from './test.prxIahgM.js';
2
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.cvFp-ao9.js';
3
+ import { r as rpc } from './rpc.DcRWTy5G.js';
4
+ import { g as getWorkerState } from './utils.DT4VyRyl.js';
5
+ import { T as TestRunner, N as NodeBenchmarkRunner } from './test.G82XYNFk.js';
6
6
 
7
7
  function setupChaiConfig(config) {
8
8
  Object.assign(chai.config, config);
9
9
  }
10
10
 
11
- async function resolveSnapshotEnvironment(config, executor) {
11
+ async function resolveSnapshotEnvironment(config, moduleRunner) {
12
12
  if (!config.snapshotEnvironment) {
13
- const { VitestNodeSnapshotEnvironment } = await import('./node.Ce0vMQM7.js');
13
+ const { VitestNodeSnapshotEnvironment } = await import('./node.CrSEwhm4.js');
14
14
  return new VitestNodeSnapshotEnvironment();
15
15
  }
16
- const mod = await executor.import(config.snapshotEnvironment);
16
+ const mod = await moduleRunner.import(config.snapshotEnvironment);
17
17
  if (typeof mod.default !== "object" || !mod.default) throw new Error("Snapshot environment module must have a default export object with a shape of `SnapshotEnvironment`");
18
18
  return mod.default;
19
19
  }
@@ -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.Dm4xqZ0s.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.B-iBE_Gx.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils/helpers';
8
8
 
@@ -1,5 +1,5 @@
1
- import { N as NodeBenchmarkRunner, T as TestRunner, a as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, b as vitest } from './test.prxIahgM.js';
2
- import { b as bench } from './benchmark.B3N2zMcH.js';
1
+ import { N as NodeBenchmarkRunner, T as TestRunner, a as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, b as vitest } from './test.G82XYNFk.js';
2
+ import { b as bench } from './benchmark.BoqSLF53.js';
3
3
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
4
4
  import { expectTypeOf } from 'expect-type';
5
5
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, recordArtifact, suite, test } from '@vitest/runner';
@@ -1,4 +1,4 @@
1
- import { i as init } from './init.DVtKdFty.js';
1
+ import { i as init } from './init.B95Mm0Iz.js';
2
2
 
3
3
  if (!process.send) throw new Error("Expected worker to be run in node:child_process");
4
4
  // Store globals in case tests overwrite them
@@ -1,5 +1,5 @@
1
1
  import { isMainThread, parentPort } from 'node:worker_threads';
2
- import { i as init } from './init.DVtKdFty.js';
2
+ import { i as init } from './init.B95Mm0Iz.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,11 +3,12 @@ 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.C5CcWyXW.js';
6
+ import { b as VitestTransport } from './startVitestModuleRunner.BK-u7y4N.js';
7
7
  import { e as environments } from './index.CyBMJtT7.js';
8
+ import { serializeValue } from '@vitest/utils/serialize';
8
9
  import { serializeError } from '@vitest/utils/error';
9
10
  import { T as Traces } from './traces.CCmnQaNT.js';
10
- import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.HLmECnw_.js';
11
+ import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.DcRWTy5G.js';
11
12
  import { createStackString, parseStacktrace } from '@vitest/utils/source-map';
12
13
  import { s as setupInspect } from './inspector.CvyFGlXm.js';
13
14
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
@@ -46,11 +47,11 @@ function createEnvironmentLoader(root, rpc) {
46
47
  }
47
48
  return _loaders.get(root);
48
49
  }
49
- async function loadEnvironment(name, root, rpc, traces) {
50
- if (isBuiltinEnvironment(name)) return { environment: environments[name] };
51
- const loader = createEnvironmentLoader(root, rpc);
52
- const packageId = name[0] === "." || name[0] === "/" ? resolve(root, name) : (await traces.$("vitest.runtime.environment.resolve", () => rpc.resolve(`vitest-environment-${name}`, void 0, "__vitest__")))?.id ?? resolve(root, name);
53
- const pkg = await traces.$("vitest.runtime.environment.import", () => loader.import(packageId));
50
+ async function loadNativeEnvironment(name, root, traces) {
51
+ const packageId = name[0] === "." || name[0] === "/" ? pathToFileURL(resolve(root, name)).toString() : import.meta.resolve(`vitest-environment-${name}`, pathToFileURL(root).toString());
52
+ return resolveEnvironmentFromModule(name, packageId, await traces.$("vitest.runtime.environment.import", () => import(packageId)));
53
+ }
54
+ function resolveEnvironmentFromModule(name, packageId, pkg) {
54
55
  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.`);
55
56
  const environment = pkg.default;
56
57
  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}".`);
@@ -59,8 +60,15 @@ async function loadEnvironment(name, root, rpc, traces) {
59
60
  // keep for backwards compat
60
61
  environment.viteEnvironment ??= environment.transformMode === "ssr" ? "ssr" : "client";
61
62
  }
63
+ return environment;
64
+ }
65
+ async function loadEnvironment(name, root, rpc, traces, viteModuleRunner) {
66
+ if (isBuiltinEnvironment(name)) return { environment: environments[name] };
67
+ if (!viteModuleRunner) return { environment: await loadNativeEnvironment(name, root, traces) };
68
+ const loader = createEnvironmentLoader(root, rpc);
69
+ const packageId = name[0] === "." || name[0] === "/" ? resolve(root, name) : (await traces.$("vitest.runtime.environment.resolve", () => rpc.resolve(`vitest-environment-${name}`, void 0, "__vitest__")))?.id ?? resolve(root, name);
62
70
  return {
63
- environment,
71
+ environment: resolveEnvironmentFromModule(name, packageId, await traces.$("vitest.runtime.environment.import", () => loader.import(packageId))),
64
72
  loader
65
73
  };
66
74
  }
@@ -80,6 +88,36 @@ function emitModuleRunner(moduleRunner) {
80
88
  moduleRunnerListeners.forEach((l) => l(moduleRunner));
81
89
  }
82
90
 
91
+ // Store globals in case tests overwrite them
92
+ const processListeners = process.listeners.bind(process);
93
+ const processOn = process.on.bind(process);
94
+ const processOff = process.off.bind(process);
95
+ const dispose = [];
96
+ function listenForErrors(state) {
97
+ dispose.forEach((fn) => fn());
98
+ dispose.length = 0;
99
+ function catchError(err, type, event) {
100
+ const worker = state();
101
+ // if there is another listener, assume that it's handled by user code
102
+ // one is Vitest's own listener
103
+ if (processListeners(event).length > 1) return;
104
+ const error = serializeValue(err);
105
+ if (typeof error === "object" && error != null) {
106
+ error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0;
107
+ if (worker.filepath) error.VITEST_TEST_PATH = worker.filepath;
108
+ }
109
+ state().rpc.onUnhandledError(error, type);
110
+ }
111
+ const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException");
112
+ const unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
113
+ processOn("uncaughtException", uncaughtException);
114
+ processOn("unhandledRejection", unhandledRejection);
115
+ dispose.push(() => {
116
+ processOff("uncaughtException", uncaughtException);
117
+ processOff("unhandledRejection", unhandledRejection);
118
+ });
119
+ }
120
+
83
121
  const resolvingModules = /* @__PURE__ */ new Set();
84
122
  async function execute(method, ctx, worker, traces) {
85
123
  const prepareStart = performance.now();
@@ -331,4 +369,4 @@ function getFilesWithLocations(files) {
331
369
  });
332
370
  }
333
371
 
334
- export { emitModuleRunner as e, init as i, loadEnvironment as l };
372
+ export { listenForErrors as a, emitModuleRunner as e, init as i, loadEnvironment as l };
@@ -0,0 +1,148 @@
1
+ import module$1, { isBuiltin } from 'node:module';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { MessageChannel } from 'node:worker_threads';
4
+ import { initSyntaxLexers, hoistMocks } from '@vitest/mocker/transforms';
5
+ import { cleanUrl } from '@vitest/utils/helpers';
6
+ import { p as parse } from './acorn.B2iPLyUM.js';
7
+ import MagicString from 'magic-string';
8
+ import { resolve } from 'pathe';
9
+ import c from 'tinyrainbow';
10
+ import { distDir } from '../path.js';
11
+ import { t as toBuiltin } from './modules.BJuCwlRJ.js';
12
+ import 'node:path';
13
+
14
+ const NOW_LENGTH = Date.now().toString().length;
15
+ const REGEXP_VITEST = /* @__PURE__ */ new RegExp(`%3Fvitest=\\d{${NOW_LENGTH}}`);
16
+ const REGEXP_MOCK_ACTUAL = /\?mock=actual/;
17
+ async function setupNodeLoaderHooks(worker) {
18
+ if (module$1.setSourceMapsSupport) module$1.setSourceMapsSupport(true);
19
+ else if (process.setSourceMapsEnabled) process.setSourceMapsEnabled(true);
20
+ if (worker.config.experimental.nodeLoader !== false) await initSyntaxLexers();
21
+ if (typeof module$1.registerHooks === "function") module$1.registerHooks({
22
+ resolve(specifier, context, nextResolve) {
23
+ if (specifier.includes("mock=actual")) {
24
+ // url is already resolved by `importActual`
25
+ const moduleId = specifier.replace(REGEXP_MOCK_ACTUAL, "");
26
+ const builtin = isBuiltin(moduleId);
27
+ return {
28
+ url: builtin ? toBuiltin(moduleId) : moduleId,
29
+ format: builtin ? "builtin" : void 0,
30
+ shortCircuit: true
31
+ };
32
+ }
33
+ const isVitest = specifier.includes("%3Fvitest=");
34
+ const result = nextResolve(isVitest ? specifier.replace(REGEXP_VITEST, "") : specifier, context);
35
+ // avoid tracking /node_modules/ module graph for performance reasons
36
+ if (context.parentURL && result.url && !result.url.includes("/node_modules/")) worker.rpc.ensureModuleGraphEntry(result.url, context.parentURL).catch(() => {
37
+ // ignore errors
38
+ });
39
+ // this is require for in-source tests to be invalidated if
40
+ // one of the files already imported it in --maxWorkers=1 --no-isolate
41
+ if (isVitest) result.url = `${result.url}?vitest=${Date.now()}`;
42
+ if (worker.config.experimental.nodeLoader === false || !context.parentURL || result.url.includes(distDir) || context.parentURL?.toString().includes(distDir)) return result;
43
+ const mockedResult = getNativeMocker()?.resolveMockedModule(result.url, context.parentURL);
44
+ if (mockedResult != null) return mockedResult;
45
+ return result;
46
+ },
47
+ load: worker.config.experimental.nodeLoader === false ? void 0 : createLoadHook()
48
+ });
49
+ else if (module$1.register) {
50
+ if (worker.config.experimental.nodeLoader !== false) console.warn(`${c.bgYellow(" WARNING ")} "module.registerHooks" is not supported in Node.js ${process.version}. This means that some features like module mocking or in-source testing are not supported. Upgrade your Node.js version to at least 22.15 or disable "experimental.nodeLoader" flag manually.\n`);
51
+ const { port1, port2 } = new MessageChannel();
52
+ port1.unref();
53
+ port2.unref();
54
+ port1.on("message", (data) => {
55
+ if (!data || typeof data !== "object") return;
56
+ switch (data.event) {
57
+ case "register-module-graph-entry": {
58
+ const { url, parentURL } = data;
59
+ worker.rpc.ensureModuleGraphEntry(url, parentURL);
60
+ return;
61
+ }
62
+ default: console.error("Unknown message event:", data.event);
63
+ }
64
+ });
65
+ /** Registers {@link file://./../nodejsWorkerLoader.ts} */
66
+ module$1.register("#nodejs-worker-loader", {
67
+ parentURL: import.meta.url,
68
+ data: { port: port2 },
69
+ transferList: [port2]
70
+ });
71
+ } else if (!process.versions.deno && !process.versions.bun) console.warn("\"module.registerHooks\" and \"module.register\" are not supported. Some Vitest features may not work. Please, use Node.js 18.19.0 or higher.");
72
+ }
73
+ function replaceInSourceMarker(url, source, ms) {
74
+ const re = /import\.meta\.vitest/g;
75
+ let match;
76
+ let overridden = false;
77
+ // eslint-disable-next-line no-cond-assign
78
+ while (match = re.exec(source)) {
79
+ const { index, "0": code } = match;
80
+ overridden = true;
81
+ // should it support process.vitest for CJS modules?
82
+ ms().overwrite(index, index + code.length, "IMPORT_META_TEST()");
83
+ }
84
+ if (overridden) {
85
+ const filename = resolve(fileURLToPath(url));
86
+ // appending instead of prepending because functions are hoisted and we don't change the offset
87
+ ms().append(`;\nfunction IMPORT_META_TEST() { return typeof __vitest_worker__ !== 'undefined' && __vitest_worker__.filepath === "${filename.replace(/"/g, "\\\"")}" ? __vitest_index__ : undefined; }`);
88
+ }
89
+ }
90
+ const ignoreFormats = new Set([
91
+ "addon",
92
+ "builtin",
93
+ "wasm"
94
+ ]);
95
+ function createLoadHook(_worker) {
96
+ return (url, context, nextLoad) => {
97
+ const result = url.includes("mock=") && isBuiltin(cleanUrl(url)) ? { format: "commonjs" } : nextLoad(url, context);
98
+ if (result.format && ignoreFormats.has(result.format) || url.includes(distDir)) return result;
99
+ const mocker = getNativeMocker();
100
+ mocker?.checkCircularManualMock(url);
101
+ if (url.includes("mock=automock") || url.includes("mock=autospy")) {
102
+ const automockedResult = mocker?.loadAutomock(url, result);
103
+ if (automockedResult != null) return automockedResult;
104
+ return result;
105
+ }
106
+ if (url.includes("mock=manual")) {
107
+ const mockedResult = mocker?.loadManualMock(url, result);
108
+ if (mockedResult != null) return mockedResult;
109
+ return result;
110
+ }
111
+ // ignore non-vitest modules for performance reasons,
112
+ // vi.hoisted and vi.mock won't work outside of test files or setup files
113
+ if (!result.source || !url.includes("vitest=")) return result;
114
+ const filename = url.startsWith("file://") ? fileURLToPath(url) : url;
115
+ const source = result.source.toString();
116
+ const transformedCode = result.format?.includes("typescript") ? module$1.stripTypeScriptTypes(source) : source;
117
+ let _ms;
118
+ const ms = () => _ms || (_ms = new MagicString(source));
119
+ if (source.includes("import.meta.vitest")) replaceInSourceMarker(url, source, ms);
120
+ hoistMocks(transformedCode, filename, (code) => parse(code, {
121
+ ecmaVersion: "latest",
122
+ sourceType: result.format === "module" || result.format === "module-typescript" || result.format === "typescript" ? "module" : "script"
123
+ }), {
124
+ magicString: ms,
125
+ globalThisAccessor: "\"__vitest_mocker__\""
126
+ });
127
+ let code;
128
+ if (_ms) code = `${_ms.toString()}\n//# sourceMappingURL=${genSourceMapUrl(_ms.generateMap({
129
+ hires: "boundary",
130
+ source: filename
131
+ }))}`;
132
+ else code = source;
133
+ return {
134
+ format: result.format,
135
+ shortCircuit: true,
136
+ source: code
137
+ };
138
+ };
139
+ }
140
+ function genSourceMapUrl(map) {
141
+ if (typeof map !== "string") map = JSON.stringify(map);
142
+ return `data:application/json;base64,${Buffer.from(map).toString("base64")}`;
143
+ }
144
+ function getNativeMocker() {
145
+ return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : void 0;
146
+ }
147
+
148
+ export { setupNodeLoaderHooks };
@@ -0,0 +1,206 @@
1
+ import module$1, { isBuiltin } from 'node:module';
2
+ import { fileURLToPath, pathToFileURL } from 'node:url';
3
+ import { automockModule, createManualModuleSource, collectModuleExports } from '@vitest/mocker/transforms';
4
+ import { cleanUrl, createDefer } from '@vitest/utils/helpers';
5
+ import { p as parse } from './acorn.B2iPLyUM.js';
6
+ import { isAbsolute } from 'pathe';
7
+ import { t as toBuiltin } from './modules.BJuCwlRJ.js';
8
+ import { B as BareModuleMocker, n as normalizeModuleId } from './startVitestModuleRunner.BK-u7y4N.js';
9
+ import 'node:fs';
10
+ import './utils.DT4VyRyl.js';
11
+ import '@vitest/utils/timers';
12
+ import '../path.js';
13
+ import 'node:path';
14
+ import '../module-evaluator.js';
15
+ import 'node:vm';
16
+ import 'vite/module-runner';
17
+ import './traces.CCmnQaNT.js';
18
+ import '@vitest/mocker';
19
+ import '@vitest/mocker/redirect';
20
+
21
+ class NativeModuleMocker extends BareModuleMocker {
22
+ wrapDynamicImport(moduleFactory) {
23
+ if (typeof moduleFactory === "function") return new Promise((resolve, reject) => {
24
+ this.resolveMocks().finally(() => {
25
+ moduleFactory().then(resolve, reject);
26
+ });
27
+ });
28
+ return moduleFactory;
29
+ }
30
+ resolveMockedModule(url, parentURL) {
31
+ // don't mock modules inside of packages because there is
32
+ // a high chance that it uses `require` which is not mockable
33
+ // because we use top-level await in "manual" mocks.
34
+ // for the sake of consistency we don't support mocking anything at all
35
+ if (parentURL.includes("/node_modules/")) return;
36
+ const moduleId = normalizeModuleId(url.startsWith("file://") ? fileURLToPath(url) : url);
37
+ const mockedModule = this.getDependencyMock(moduleId);
38
+ if (!mockedModule) return;
39
+ if (mockedModule.type === "redirect") return {
40
+ url: pathToFileURL(mockedModule.redirect).toString(),
41
+ shortCircuit: true
42
+ };
43
+ if (mockedModule.type === "automock" || mockedModule.type === "autospy") return {
44
+ url: injectQuery(url, parentURL, `mock=${mockedModule.type}`),
45
+ shortCircuit: true
46
+ };
47
+ if (mockedModule.type === "manual") return {
48
+ url: injectQuery(url, parentURL, "mock=manual"),
49
+ shortCircuit: true
50
+ };
51
+ }
52
+ loadAutomock(url, result) {
53
+ const moduleId = cleanUrl(normalizeModuleId(url.startsWith("file://") ? fileURLToPath(url) : url));
54
+ let source;
55
+ if (isBuiltin(moduleId)) {
56
+ const builtinModule = getBuiltinModule(moduleId);
57
+ const exports$1 = Object.keys(builtinModule);
58
+ source = `
59
+ import * as builtinModule from '${toBuiltin(moduleId)}?mock=actual'
60
+
61
+ ${exports$1.map((key, index) => {
62
+ return `
63
+ const __${index} = builtinModule["${key}"]
64
+ export { __${index} as "${key}" }
65
+ `;
66
+ }).join("")}`;
67
+ } else source = result.source?.toString();
68
+ if (source == null) return;
69
+ const mockType = url.includes("mock=automock") ? "automock" : "autospy";
70
+ const transformedCode = transformCode(source, result.format || "module", moduleId);
71
+ try {
72
+ const ms = automockModule(transformedCode, mockType, (code) => parse(code, {
73
+ sourceType: "module",
74
+ ecmaVersion: "latest"
75
+ }), { id: moduleId });
76
+ return {
77
+ format: "module",
78
+ source: `${ms.toString()}\n//# sourceMappingURL=${genSourceMapUrl(ms.generateMap({
79
+ hires: "boundary",
80
+ source: moduleId
81
+ }))}`,
82
+ shortCircuit: true
83
+ };
84
+ } catch (cause) {
85
+ throw new Error(`Cannot automock '${url}' because it failed to parse.`, { cause });
86
+ }
87
+ }
88
+ loadManualMock(url, result) {
89
+ const moduleId = cleanUrl(normalizeModuleId(url.startsWith("file://") ? fileURLToPath(url) : url));
90
+ // should not be possible
91
+ if (this.getDependencyMock(moduleId)?.type !== "manual") {
92
+ console.warn(`Vitest detected unregistered manual mock ${moduleId}. This is a bug in Vitest. Please, open a new issue with reproduction.`);
93
+ return;
94
+ }
95
+ if (isBuiltin(moduleId)) {
96
+ const builtinModule = getBuiltinModule(toBuiltin(moduleId));
97
+ return {
98
+ format: "module",
99
+ source: createManualModuleSource(moduleId, Object.keys(builtinModule)),
100
+ shortCircuit: true
101
+ };
102
+ }
103
+ if (!result.source) return;
104
+ const transformedCode = transformCode(result.source.toString(), result.format || "module", moduleId);
105
+ if (transformedCode == null) return;
106
+ const format = result.format?.startsWith("module") ? "module" : "commonjs";
107
+ try {
108
+ return {
109
+ format: "module",
110
+ source: createManualModuleSource(moduleId, collectModuleExports(moduleId, transformedCode, format)),
111
+ shortCircuit: true
112
+ };
113
+ } catch (cause) {
114
+ throw new Error(`Failed to mock '${url}'. See the cause for more information.`, { cause });
115
+ }
116
+ }
117
+ processedModules = /* @__PURE__ */ new Map();
118
+ checkCircularManualMock(url) {
119
+ const id = cleanUrl(normalizeModuleId(url.startsWith("file://") ? fileURLToPath(url) : url));
120
+ this.processedModules.set(id, (this.processedModules.get(id) ?? 0) + 1);
121
+ // the module is mocked and requested a second time, let's resolve
122
+ // the factory function that will redefine the exports later
123
+ if (this.originalModulePromises.has(id)) {
124
+ const factoryPromise = this.factoryPromises.get(id);
125
+ this.originalModulePromises.get(id)?.resolve({ __factoryPromise: factoryPromise });
126
+ }
127
+ }
128
+ originalModulePromises = /* @__PURE__ */ new Map();
129
+ factoryPromises = /* @__PURE__ */ new Map();
130
+ // potential performance improvement:
131
+ // store by URL, not ids, no need to call url.*to* methods and normalizeModuleId
132
+ getFactoryModule(id) {
133
+ const mock = this.getMockerRegistry().getById(id);
134
+ if (!mock || mock.type !== "manual") throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`);
135
+ const mockResult = mock.resolve();
136
+ if (mockResult instanceof Promise) {
137
+ // to avoid circular dependency, we resolve this function as {__factoryPromise} in `checkCircularManualMock`
138
+ // when it's requested the second time. then the exports are exposed as `undefined`,
139
+ // but later redefined when the promise is actually resolved
140
+ const promise = createDefer();
141
+ promise.finally(() => {
142
+ this.originalModulePromises.delete(id);
143
+ });
144
+ mockResult.then(promise.resolve, promise.reject).finally(() => {
145
+ this.factoryPromises.delete(id);
146
+ });
147
+ this.factoryPromises.set(id, mockResult);
148
+ this.originalModulePromises.set(id, promise);
149
+ // Node.js on windows processes all the files first, and then runs them
150
+ // unlike Node.js logic on Mac and Unix where it also runs the code while evaluating
151
+ // So on Linux/Mac this `if` won't be hit because `checkCircularManualMock` will resolve it
152
+ // And on Windows, the `checkCircularManualMock` will never have `originalModulePromises`
153
+ // because `getFactoryModule` is not called until the evaluation phase
154
+ // But if we track how many times the module was transformed,
155
+ // we can deduce when to return `__factoryPromise` to support circular modules
156
+ if ((this.processedModules.get(id) ?? 0) > 1) {
157
+ this.processedModules.set(id, (this.processedModules.get(id) ?? 1) - 1);
158
+ promise.resolve({ __factoryPromise: mockResult });
159
+ }
160
+ return promise;
161
+ }
162
+ return mockResult;
163
+ }
164
+ importActual(rawId, importer) {
165
+ const resolvedId = import.meta.resolve(rawId, pathToFileURL(importer).toString());
166
+ const url = new URL(resolvedId);
167
+ url.searchParams.set("mock", "actual");
168
+ return import(url.toString());
169
+ }
170
+ importMock(rawId, importer) {
171
+ const resolvedId = import.meta.resolve(rawId, pathToFileURL(importer).toString());
172
+ // file is already mocked
173
+ if (resolvedId.includes("mock=")) return import(resolvedId);
174
+ const filename = fileURLToPath(resolvedId);
175
+ const external = !isAbsolute(filename) || this.isModuleDirectory(resolvedId) ? normalizeModuleId(rawId) : null;
176
+ // file is not mocked, automock or redirect it
177
+ const redirect = this.findMockRedirect(filename, external);
178
+ if (redirect) return import(pathToFileURL(redirect).toString());
179
+ const url = new URL(resolvedId);
180
+ url.searchParams.set("mock", "automock");
181
+ return import(url.toString());
182
+ }
183
+ }
184
+ const replacePercentageRE = /%/g;
185
+ function injectQuery(url, importer, queryToInject) {
186
+ const { search, hash } = new URL(url.replace(replacePercentageRE, "%25"), importer);
187
+ return `${cleanUrl(url)}?${queryToInject}${search ? `&${search.slice(1)}` : ""}${hash ?? ""}`;
188
+ }
189
+ let __require;
190
+ function getBuiltinModule(moduleId) {
191
+ __require ??= module$1.createRequire(import.meta.url);
192
+ return __require(`${moduleId}?mock=actual`);
193
+ }
194
+ function genSourceMapUrl(map) {
195
+ if (typeof map !== "string") map = JSON.stringify(map);
196
+ return `data:application/json;base64,${Buffer.from(map).toString("base64")}`;
197
+ }
198
+ function transformCode(code, format, filename) {
199
+ if (format.includes("typescript")) {
200
+ if (!module$1.stripTypeScriptTypes) throw new Error(`Cannot parse '${filename}' because "module.stripTypeScriptTypes" is not supported. Module mocking requires Node.js 22.15 or higher. This is NOT a bug of Vitest.`);
201
+ return module$1.stripTypeScriptTypes(code);
202
+ }
203
+ return code;
204
+ }
205
+
206
+ export { NativeModuleMocker };
@@ -0,0 +1,36 @@
1
+ import { pathToFileURL } from 'node:url';
2
+ import { r as resolveModule } from './index.BCY_7LL2.js';
3
+ import { resolve } from 'pathe';
4
+ import { ModuleRunner } from 'vite/module-runner';
5
+
6
+ class NativeModuleRunner extends ModuleRunner {
7
+ /**
8
+ * @internal
9
+ */
10
+ mocker;
11
+ constructor(root, mocker) {
12
+ super({
13
+ hmr: false,
14
+ sourcemapInterceptor: false,
15
+ transport: { invoke() {
16
+ throw new Error("Unexpected `invoke`");
17
+ } }
18
+ });
19
+ this.root = root;
20
+ this.mocker = mocker;
21
+ if (mocker) Object.defineProperty(globalThis, "__vitest_mocker__", {
22
+ configurable: true,
23
+ writable: true,
24
+ value: mocker
25
+ });
26
+ }
27
+ async import(moduleId) {
28
+ const path = resolveModule(moduleId, { paths: [this.root] }) ?? resolve(this.root, moduleId);
29
+ // resolveModule doesn't keep the query params, so we need to add them back
30
+ let queryParams = "";
31
+ if (moduleId.includes("?") && !path.includes("?")) queryParams = moduleId.slice(moduleId.indexOf("?"));
32
+ return import(pathToFileURL(path + queryParams).toString());
33
+ }
34
+ }
35
+
36
+ export { NativeModuleRunner as N };
@@ -1,5 +1,5 @@
1
1
  import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
2
- import { g as getWorkerState } from './utils.DvEY5TfP.js';
2
+ import { g as getWorkerState } from './utils.DT4VyRyl.js';
3
3
  import '@vitest/utils/timers';
4
4
 
5
5
  class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {
@@ -1,5 +1,5 @@
1
1
  import { DevEnvironment } from 'vite';
2
- import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.Db3MiIWX.js';
2
+ import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.7faYdkxy.js';
3
3
 
4
4
  /**
5
5
  * Generate a unique cache identifier.