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.
Files changed (83) hide show
  1. package/LICENSE.md +86 -102
  2. package/browser/context.d.ts +7 -0
  3. package/browser/context.js +20 -0
  4. package/dist/browser.d.ts +24 -7
  5. package/dist/browser.js +15 -5
  6. package/dist/chunks/{base.CA5N8Af0.js → base.BYPMk0VN.js} +36 -36
  7. package/dist/chunks/{benchmark.CJUa-Hsa.js → benchmark.DHKMYAts.js} +2 -2
  8. package/dist/chunks/{browser.d.DtfyY9yS.d.ts → browser.d.B9iJzZyn.d.ts} +3 -3
  9. package/dist/chunks/{cac.Dt7e1TIu.js → cac.DrF4Gm0S.js} +47 -73
  10. package/dist/chunks/{cli-api.eAzsLIxz.js → cli-api.W2Q-JQoO.js} +1524 -296
  11. package/dist/chunks/{config.d.DacWrqWe.d.ts → config.d.u2CUDWwS.d.ts} +5 -19
  12. package/dist/chunks/{console.7h5kHUIf.js → console.CTJL2nuH.js} +4 -6
  13. package/dist/chunks/{coverage.CDRAMTt7.js → coverage.FU3w4IrQ.js} +125 -1108
  14. package/dist/chunks/{creator.KEg6n5IC.js → creator.DucAaYBz.js} +10 -37
  15. package/dist/chunks/{defaults.CXFFjsi8.js → defaults.BOqNVLsY.js} +0 -1
  16. package/dist/chunks/environment.d.CrsxCzP1.d.ts +29 -0
  17. package/dist/chunks/evaluatedModules.Dg1zASAC.js +17 -0
  18. package/dist/chunks/{global.d.K6uBQHzY.d.ts → global.d.BgJSTpgQ.d.ts} +2 -17
  19. package/dist/chunks/{globals.CJrTTbxC.js → globals.BGT_RUsD.js} +11 -7
  20. package/dist/chunks/{index.BjKEiSn0.js → index.BdSLhLDZ.js} +3 -3
  21. package/dist/chunks/{index.DfviD7lX.js → index.CbWINfS7.js} +49 -21
  22. package/dist/chunks/{index.BIP7prJq.js → index.CcRZ6fUh.js} +1493 -114
  23. package/dist/chunks/{index.X0nbfr6-.js → index.Dc3xnDvT.js} +48 -289
  24. package/dist/chunks/{index.C832ioot.js → index.RwjEGCQ0.js} +4 -4
  25. package/dist/chunks/init-forks.WglB-sfY.js +54 -0
  26. package/dist/chunks/init-threads.Czek6eA5.js +17 -0
  27. package/dist/chunks/init.94FWN9pW.js +213 -0
  28. package/dist/chunks/{inspector.CvQD-Nie.js → inspector.DLZxSeU3.js} +2 -6
  29. package/dist/chunks/{moduleRunner.d.DxTLreRD.d.ts → moduleRunner.d.YtNsMIoJ.d.ts} +9 -14
  30. package/dist/chunks/{node.CyipiPvJ.js → node.BwAWWjHZ.js} +3 -4
  31. package/dist/chunks/{plugin.d.CIk0YiKb.d.ts → plugin.d.DQU1R5px.d.ts} +1 -1
  32. package/dist/chunks/{reporters.d.DmP-iHLr.d.ts → reporters.d.BMKt7f6I.d.ts} +1064 -1021
  33. package/dist/chunks/{resolveSnapshotEnvironment.Bvv2zr69.js → resolveSnapshotEnvironment.DJJKMKxb.js} +7 -8
  34. package/dist/chunks/{rpc.BKr6mtxz.js → rpc.cD77ENhU.js} +13 -14
  35. package/dist/chunks/{setup-common.B7I37Tji.js → setup-common.DR1sucx6.js} +6 -6
  36. package/dist/chunks/{startModuleRunner.BDRvKSdz.js → startModuleRunner.iF1E9Bt4.js} +126 -110
  37. package/dist/chunks/{test.BAlBebnP.js → test.C3RPt8JR.js} +7 -7
  38. package/dist/chunks/{utils.D2R2NiOH.js → utils.CG9h5ccR.js} +2 -5
  39. package/dist/chunks/{vi.BB37KeLx.js → vi.BZvkKVkM.js} +61 -164
  40. package/dist/chunks/{vm.CjLTDaST.js → vm.CuMWYx_F.js} +20 -29
  41. package/dist/chunks/{worker.d.B2r4Ln6p.d.ts → worker.d.BFk-vvBU.d.ts} +42 -6
  42. package/dist/cli.js +12 -11
  43. package/dist/config.cjs +0 -1
  44. package/dist/config.d.ts +11 -13
  45. package/dist/config.js +1 -1
  46. package/dist/coverage.d.ts +7 -6
  47. package/dist/coverage.js +3 -14
  48. package/dist/environments.d.ts +3 -6
  49. package/dist/environments.js +1 -1
  50. package/dist/index.d.ts +20 -25
  51. package/dist/index.js +11 -7
  52. package/dist/module-evaluator.d.ts +5 -4
  53. package/dist/module-evaluator.js +11 -13
  54. package/dist/module-runner.js +5 -5
  55. package/dist/node.d.ts +82 -25
  56. package/dist/node.js +23 -20
  57. package/dist/reporters.d.ts +10 -9
  58. package/dist/reporters.js +12 -11
  59. package/dist/runners.d.ts +1 -1
  60. package/dist/runners.js +9 -7
  61. package/dist/snapshot.js +3 -3
  62. package/dist/suite.js +4 -3
  63. package/dist/worker.d.ts +26 -0
  64. package/dist/worker.js +45 -165
  65. package/dist/workers/forks.js +26 -43
  66. package/dist/workers/runVmTests.js +16 -12
  67. package/dist/workers/threads.js +26 -31
  68. package/dist/workers/vmForks.js +26 -39
  69. package/dist/workers/vmThreads.js +26 -29
  70. package/package.json +48 -32
  71. package/worker.d.ts +1 -0
  72. package/browser.d.ts +0 -1
  73. package/dist/chunks/environment.d.2fYMoz3o.d.ts +0 -66
  74. package/dist/chunks/moduleTransport.I-bgQy0S.js +0 -19
  75. package/dist/chunks/resolver.Bx6lE0iq.js +0 -119
  76. package/dist/chunks/typechecker.DB-fIMaH.js +0 -805
  77. package/dist/chunks/utils.C2YI6McM.js +0 -52
  78. package/dist/chunks/worker.d.DJ6qxO2w.d.ts +0 -8
  79. package/dist/workers.d.ts +0 -38
  80. package/dist/workers.js +0 -49
  81. package/execute.d.ts +0 -1
  82. package/utils.d.ts +0 -1
  83. 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.B7I37Tji.js';
3
- import { r as rpc } from './rpc.BKr6mtxz.js';
4
- import { g as getWorkerState } from './utils.D2R2NiOH.js';
5
- import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.BAlBebnP.js';
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 TestRunner = await getTestRunnerConstructor(config, moduleRunner), testRunner = new TestRunner(config);
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
- const previousFailures = await rpc().getCountOfFailedTests(), currentFailures = 1 + previousFailures;
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.CyipiPvJ.js');
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.D2R2NiOH.js';
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
- const result = fn();
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
- }), rpc = createSafeRpc(createBirpc({ onCancel: setCancel }, {
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.D2R2NiOH.js';
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.CJrTTbxC.js')).registerApiGlobally();
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, snapshotSerializers = await Promise.all(files.map(async (file) => {
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 { highlight, isBareImport } from '@vitest/utils';
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 { processError } from '@vitest/utils/error';
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 { ModuleRunner } from 'vite/module-runner';
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] === "/", both = pathTrailing && segLeading;
85
- if (both) path += seg.slice(1);
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 baseFile = basename(file, extname(file));
172
- if (baseFile === baseOriginal) {
173
- const path = resolve(mockFolder, file);
174
- // if the same name, return the file
175
- if (statSync(path).isFile()) return path;
176
- {
177
- // find folder/index.{js,ts}
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 void 0;
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
- `, highlight(`vi.mock(import("${mock.raw}"), async (importOriginal) => {
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
- const registry = this.getMockerRegistry();
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
- const registry = this.getMockerRegistry();
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), result = await this.moduleRunner.cachedRequest(node.url, node, callstack || [importer], void 0, true);
391
- return result;
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 unixFile.replace(/^file:\//, "/");
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(options) {
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
- }, options.evaluator), this.options = options, this.moduleExecutionInfo = options.getWorkerState().moduleExecutionInfo, this.mocker = options.mocker || new VitestMocker(this, {
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.options.transport.resolveId(rawId);
525
- return resolved ? super.import(resolved.url) : super.import(rawId);
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
- const module = await this.cachedModule(url, importer);
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
- if ("cached" in result) {
625
- const code = readFileSync(result.tmp, "utf-8");
626
- return {
627
- code,
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, getSafeTimers } from '@vitest/utils';
3
- import { a as getBenchOptions, g as getBenchFn } from './benchmark.CJUa-Hsa.js';
4
- import { g as getWorkerState } from './utils.D2R2NiOH.js';
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.BB37KeLx.js';
10
- import { r as rpc } from './rpc.BKr6mtxz.js';
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 task = e.task, taskRes = task.result, result = benchmark.result.benchmark;
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) {