vitest 4.0.0-beta.1 → 4.0.0-beta.11

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 (90) hide show
  1. package/LICENSE.md +83 -2
  2. package/dist/browser.d.ts +19 -16
  3. package/dist/browser.js +11 -7
  4. package/dist/chunks/{benchmark.CYdenmiT.js → benchmark.LXhJ0F0X.js} +7 -9
  5. package/dist/chunks/{benchmark.d.BwvBVTda.d.ts → benchmark.d.DAaHLpsq.d.ts} +4 -4
  6. package/dist/chunks/{browser.d.q8Z0P0q1.d.ts → browser.d.Dx7DO_Ce.d.ts} +5 -5
  7. package/dist/chunks/{cac.D3EzDDZd.js → cac.elvK37c9.js} +71 -153
  8. package/dist/chunks/{cli-api.Dn5gKePv.js → cli-api.C7plPyhs.js} +1376 -1693
  9. package/dist/chunks/{config.d.HJdfX-8k.d.ts → config.d.B_LthbQq.d.ts} +58 -63
  10. package/dist/chunks/{console.CtFJOzRO.js → console.CiTi59Jy.js} +35 -71
  11. package/dist/chunks/{constants.DnKduX2e.js → constants.D_Q9UYh-.js} +1 -9
  12. package/dist/chunks/{coverage.Cwa-XhJt.js → coverage.CG6Uhorw.js} +522 -792
  13. package/dist/chunks/{coverage.DVF1vEu8.js → coverage.D_JHT54q.js} +2 -2
  14. package/dist/chunks/{coverage.d.S9RMNXIe.d.ts → coverage.d.BZtK59WP.d.ts} +10 -8
  15. package/dist/chunks/{creator.GK6I-cL4.js → creator.08Gi-vCA.js} +93 -77
  16. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  17. package/dist/chunks/{environment.d.CUq4cUgQ.d.ts → environment.d.BsToaxti.d.ts} +27 -6
  18. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  19. package/dist/chunks/{global.d.CVbXEflG.d.ts → global.d.BK3X7FW1.d.ts} +2 -5
  20. package/dist/chunks/{globals.Cxal6MLI.js → globals.BjvYA-AD.js} +11 -9
  21. package/dist/chunks/{index.BWf_gE5n.js → index.AZOjjqWP.js} +7 -6
  22. package/dist/chunks/{index.B521nVV-.js → index.Bgo3tNWt.js} +23 -4
  23. package/dist/chunks/{index.TfbsX-3I.js → index.BhY64fF0.js} +16 -26
  24. package/dist/chunks/{index.CZI_8rVt.js → index.BwBttQPf.js} +340 -663
  25. package/dist/chunks/{index.CmSc2RE5.js → index.DIWhzsUh.js} +72 -118
  26. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  27. package/dist/chunks/moduleRunner.d.BNa-CL9e.d.ts +201 -0
  28. package/dist/chunks/{node.fjCdwEIl.js → node.BsdMi6DV.js} +2 -2
  29. package/dist/chunks/{plugin.d.C2EcJUjo.d.ts → plugin.d.C5phQR6o.d.ts} +1 -1
  30. package/dist/chunks/{reporters.d.DxZg19fy.d.ts → reporters.d.CVzhsTvK.d.ts} +1233 -1293
  31. package/dist/chunks/resolveSnapshotEnvironment.DQVamkje.js +81 -0
  32. package/dist/chunks/rpc.jKGRSXIH.js +65 -0
  33. package/dist/chunks/{setup-common.D7ZqXFx-.js → setup-common.NAWRuMRP.js} +18 -30
  34. package/dist/chunks/startModuleRunner.oAuCu1yL.js +682 -0
  35. package/dist/chunks/{suite.d.FvehnV49.d.ts → suite.d.BJWk38HB.d.ts} +1 -1
  36. package/dist/chunks/test.KC5tH8hC.js +214 -0
  37. package/dist/chunks/typechecker.gXq-5P3n.js +1438 -0
  38. package/dist/chunks/{utils.XdZDrNZV.js → utils.DGKhod2J.js} +9 -28
  39. package/dist/chunks/{vi.bdSIJ99Y.js → vi.CiJ0Laa6.js} +159 -306
  40. package/dist/chunks/worker.d.B_Fd9M_w.d.ts +100 -0
  41. package/dist/chunks/worker.rPGLlbkW.js +200 -0
  42. package/dist/cli.js +8 -6
  43. package/dist/config.cjs +3 -9
  44. package/dist/config.d.ts +49 -54
  45. package/dist/config.js +1 -1
  46. package/dist/coverage.d.ts +27 -26
  47. package/dist/coverage.js +6 -8
  48. package/dist/environments.d.ts +9 -13
  49. package/dist/environments.js +1 -1
  50. package/dist/index.d.ts +38 -45
  51. package/dist/index.js +10 -10
  52. package/dist/module-evaluator.d.ts +13 -0
  53. package/dist/module-evaluator.js +276 -0
  54. package/dist/module-runner.js +15 -0
  55. package/dist/node.d.ts +44 -42
  56. package/dist/node.js +30 -36
  57. package/dist/reporters.d.ts +12 -13
  58. package/dist/reporters.js +7 -5
  59. package/dist/runners.d.ts +3 -3
  60. package/dist/runners.js +15 -232
  61. package/dist/snapshot.js +3 -3
  62. package/dist/suite.d.ts +2 -2
  63. package/dist/suite.js +4 -3
  64. package/dist/worker-base.js +203 -0
  65. package/dist/{chunks/vm.BThCzidc.js → worker-vm.js} +179 -228
  66. package/dist/workers/runVmTests.js +39 -56
  67. package/globals.d.ts +17 -17
  68. package/package.json +40 -38
  69. package/browser.d.ts +0 -1
  70. package/dist/chunks/base.Bj3pWTr1.js +0 -38
  71. package/dist/chunks/execute.B7h3T_Hc.js +0 -708
  72. package/dist/chunks/index.D-VkfKhf.js +0 -105
  73. package/dist/chunks/rpc.CsFtxqeq.js +0 -83
  74. package/dist/chunks/runBaseTests.BC7ZIH5L.js +0 -129
  75. package/dist/chunks/typechecker.CVytUJuF.js +0 -874
  76. package/dist/chunks/utils.CAioKnHs.js +0 -61
  77. package/dist/chunks/worker.d.CmvJfRGs.d.ts +0 -8
  78. package/dist/chunks/worker.d.DoNjFAiv.d.ts +0 -169
  79. package/dist/execute.d.ts +0 -148
  80. package/dist/execute.js +0 -13
  81. package/dist/worker.js +0 -124
  82. package/dist/workers/forks.js +0 -43
  83. package/dist/workers/threads.js +0 -31
  84. package/dist/workers/vmForks.js +0 -47
  85. package/dist/workers/vmThreads.js +0 -37
  86. package/dist/workers.d.ts +0 -37
  87. package/dist/workers.js +0 -30
  88. package/execute.d.ts +0 -1
  89. package/utils.d.ts +0 -1
  90. package/workers.d.ts +0 -1
@@ -1,15 +1,32 @@
1
+ import { c as createForksRpcOptions, u as unwrapSerializableConfig, a as createThreadsRpcOptions, e as execute, t as teardown$1 } from './chunks/worker.rPGLlbkW.js';
2
+ import v8 from 'node:v8';
1
3
  import { fileURLToPath, pathToFileURL } from 'node:url';
2
- import vm, { isContext } from 'node:vm';
3
- import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
4
- import { distDir } from '../path.js';
5
- import { createCustomConsole } from './console.CtFJOzRO.js';
6
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.B7h3T_Hc.js';
4
+ import vm, { isContext, runInContext } from 'node:vm';
5
+ import { dirname, basename, extname, normalize, resolve } from 'pathe';
6
+ import { distDir } from './path.js';
7
+ import { createCustomConsole } from './chunks/console.CiTi59Jy.js';
7
8
  import fs from 'node:fs';
9
+ import { createRequire, Module, isBuiltin } from 'node:module';
10
+ import { toArray, isBareImport } from '@vitest/utils/helpers';
11
+ import { findNearestPackageData } from '@vitest/utils/resolver';
8
12
  import { dirname as dirname$1 } from 'node:path';
9
- import { isPrimitive, isNodeBuiltin, toArray, getCachedData, setCacheData, isBareImport } from 'vite-node/utils';
10
- import { createRequire, Module } from 'node:module';
11
- import { CSS_LANGS_RE, KNOWN_ASSET_RE } from 'vite-node/constants';
12
- import { p as provideWorkerState } from './utils.XdZDrNZV.js';
13
+ import { CSS_LANGS_RE, KNOWN_ASSET_RE } from '@vitest/utils/constants';
14
+ import { getDefaultRequestStubs } from './module-evaluator.js';
15
+ import { s as startVitestModuleRunner, c as createNodeImportMeta, a as VITEST_VM_CONTEXT_SYMBOL } from './chunks/startModuleRunner.oAuCu1yL.js';
16
+ import { p as provideWorkerState } from './chunks/utils.DGKhod2J.js';
17
+ import '@vitest/utils/source-map';
18
+ import 'vite/module-runner';
19
+ import './chunks/index.DIWhzsUh.js';
20
+ import 'node:console';
21
+ import './chunks/inspector.CvQD-Nie.js';
22
+ import './chunks/rpc.jKGRSXIH.js';
23
+ import '@vitest/utils/timers';
24
+ import './chunks/index.Bgo3tNWt.js';
25
+ import 'node:stream';
26
+ import 'tinyrainbow';
27
+ import './chunks/date.-jtEtIeV.js';
28
+ import '@vitest/utils/serialize';
29
+ import '@vitest/mocker';
13
30
 
14
31
  function interopCommonJsModule(interopDefault, mod) {
15
32
  if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) return {
@@ -18,11 +35,8 @@ function interopCommonJsModule(interopDefault, mod) {
18
35
  defaultExport: mod
19
36
  };
20
37
  if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) {
21
- const defaultKets = Object.keys(mod.default);
22
- const moduleKeys = Object.keys(mod);
23
- const allKeys = new Set([...defaultKets, ...moduleKeys]);
24
- allKeys.delete("default");
25
- return {
38
+ const defaultKets = Object.keys(mod.default), moduleKeys = Object.keys(mod), allKeys = new Set([...defaultKets, ...moduleKeys]);
39
+ return allKeys.delete("default"), {
26
40
  keys: Array.from(allKeys),
27
41
  moduleExports: new Proxy(mod, { get(mod, prop) {
28
42
  return mod[prop] ?? mod.default?.[prop];
@@ -36,11 +50,14 @@ function interopCommonJsModule(interopDefault, mod) {
36
50
  defaultExport: mod
37
51
  };
38
52
  }
53
+ function isPrimitive(obj) {
54
+ const isObject = obj != null && (typeof obj === "object" || typeof obj === "function");
55
+ return !isObject;
56
+ }
39
57
  const SyntheticModule = vm.SyntheticModule;
40
58
  const SourceTextModule = vm.SourceTextModule;
41
59
 
42
- const _require = createRequire(import.meta.url);
43
- const requiresCache = /* @__PURE__ */ new WeakMap();
60
+ const _require = createRequire(import.meta.url), requiresCache = /* @__PURE__ */ new WeakMap();
44
61
  class CommonjsExecutor {
45
62
  context;
46
63
  requireCache = /* @__PURE__ */ new Map();
@@ -52,12 +69,8 @@ class CommonjsExecutor {
52
69
  Module;
53
70
  interopDefault;
54
71
  constructor(options) {
55
- this.context = options.context;
56
- this.fs = options.fileMap;
57
- this.interopDefault = options.interopDefault;
58
- const primitives = vm.runInContext("({ Object, Array, Error })", this.context);
59
- // eslint-disable-next-line ts/no-this-alias
60
- const executor = this;
72
+ this.context = options.context, this.fs = options.fileMap, this.interopDefault = options.interopDefault;
73
+ const primitives = vm.runInContext("({ Object, Array, Error })", this.context), executor = this;
61
74
  this.Module = class Module$1 {
62
75
  exports;
63
76
  isPreloading = false;
@@ -69,21 +82,22 @@ class CommonjsExecutor {
69
82
  path;
70
83
  paths = [];
71
84
  constructor(id = "", parent) {
72
- this.exports = primitives.Object.create(Object.prototype);
73
- // in our case the path should always be resolved already
74
- this.path = dirname(id);
75
- this.id = id;
76
- this.filename = id;
77
- this.loaded = false;
78
- this.parent = parent;
85
+ this.exports = primitives.Object.create(Object.prototype), this.path = dirname(id), this.id = id, this.filename = id, this.loaded = false, this.parent = parent;
79
86
  }
80
87
  get require() {
81
88
  const require = requiresCache.get(this);
82
89
  if (require) return require;
83
90
  const _require = Module$1.createRequire(this.id);
84
- requiresCache.set(this, _require);
85
- return _require;
91
+ return requiresCache.set(this, _require), _require;
86
92
  }
93
+ static getSourceMapsSupport = () => ({
94
+ enabled: false,
95
+ nodeModules: false,
96
+ generatedCode: false
97
+ });
98
+ static setSourceMapsSupport = () => {
99
+ // noop
100
+ };
87
101
  static register = () => {
88
102
  throw new Error(`[vitest] "register" is not available when running in Vitest.`);
89
103
  };
@@ -91,19 +105,16 @@ class CommonjsExecutor {
91
105
  throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`);
92
106
  };
93
107
  _compile(code, filename) {
94
- const cjsModule = Module$1.wrap(code);
95
- const script = new vm.Script(cjsModule, {
108
+ const cjsModule = Module$1.wrap(code), script = new vm.Script(cjsModule, {
96
109
  filename,
97
110
  importModuleDynamically: options.importModuleDynamically
98
111
  });
99
112
  // @ts-expect-error mark script with current identifier
100
113
  script.identifier = filename;
101
- const fn = script.runInContext(executor.context);
102
- const __dirname = dirname(filename);
114
+ const fn = script.runInContext(executor.context), __dirname = dirname(filename);
103
115
  executor.requireCache.set(filename, this);
104
116
  try {
105
- fn(this.exports, this.require, this, filename, __dirname);
106
- return this.exports;
117
+ return fn(this.exports, this.require, this, filename, __dirname), this.exports;
107
118
  } finally {
108
119
  this.loaded = true;
109
120
  }
@@ -149,9 +160,7 @@ class CommonjsExecutor {
149
160
  static stripTypeScriptTypes = Module.stripTypeScriptTypes;
150
161
  static findPackageJSON = Module.findPackageJSON;
151
162
  static Module = Module$1;
152
- };
153
- this.extensions[".js"] = this.requireJs;
154
- this.extensions[".json"] = this.requireJson;
163
+ }, this.extensions[".js"] = this.requireJs, this.extensions[".json"] = this.requireJson;
155
164
  }
156
165
  requireJs = (m, filename) => {
157
166
  const content = this.fs.readFile(filename);
@@ -162,23 +171,17 @@ class CommonjsExecutor {
162
171
  m.exports = JSON.parse(code);
163
172
  };
164
173
  createRequire = (filename) => {
165
- const _require = createRequire(filename);
166
- const require = (id) => {
167
- const resolved = _require.resolve(id);
168
- const ext = extname(resolved);
169
- if (ext === ".node" || isNodeBuiltin(resolved)) return this.requireCoreModule(resolved);
174
+ const _require = createRequire(filename), require = ((id) => {
175
+ const resolved = _require.resolve(id), ext = extname(resolved);
176
+ if (ext === ".node" || isBuiltin(resolved)) return this.requireCoreModule(resolved);
170
177
  const module = new this.Module(resolved);
171
178
  return this.loadCommonJSModule(module, resolved);
172
- };
173
- require.resolve = _require.resolve;
174
- Object.defineProperty(require, "extensions", {
179
+ });
180
+ return require.resolve = _require.resolve, Object.defineProperty(require, "extensions", {
175
181
  get: () => this.extensions,
176
182
  set: () => {},
177
183
  configurable: true
178
- });
179
- require.main = void 0;
180
- require.cache = this.publicRequireCache;
181
- return require;
184
+ }), require.main = void 0, require.cache = this.publicRequireCache, require;
182
185
  };
183
186
  createProxyCache() {
184
187
  return new Proxy(Object.create(null), {
@@ -200,53 +203,40 @@ class CommonjsExecutor {
200
203
  loadCommonJSModule(module, filename) {
201
204
  const cached = this.requireCache.get(filename);
202
205
  if (cached) return cached.exports;
203
- const extension = this.findLongestRegisteredExtension(filename);
204
- const loader = this.extensions[extension] || this.extensions[".js"];
205
- loader(module, filename);
206
- return module.exports;
206
+ const extension = this.findLongestRegisteredExtension(filename), loader = this.extensions[extension] || this.extensions[".js"];
207
+ return loader(module, filename), module.exports;
207
208
  }
208
209
  findLongestRegisteredExtension(filename) {
209
210
  const name = basename(filename);
210
- let currentExtension;
211
- let index;
212
- let startIndex = 0;
211
+ let currentExtension, index, startIndex = 0;
213
212
  // eslint-disable-next-line no-cond-assign
214
213
  while ((index = name.indexOf(".", startIndex)) !== -1) {
215
- startIndex = index + 1;
216
- if (index === 0) continue;
217
- currentExtension = name.slice(index);
218
- if (this.extensions[currentExtension]) return currentExtension;
214
+ if (startIndex = index + 1, index === 0) continue;
215
+ if (currentExtension = name.slice(index), this.extensions[currentExtension]) return currentExtension;
219
216
  }
220
217
  return ".js";
221
218
  }
222
219
  getCoreSyntheticModule(identifier) {
223
220
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
224
- const exports = this.require(identifier);
225
- const keys = Object.keys(exports);
226
- const module = new SyntheticModule([...keys, "default"], () => {
221
+ const exports = this.require(identifier), keys = Object.keys(exports), module = new SyntheticModule([...keys, "default"], () => {
227
222
  for (const key of keys) module.setExport(key, exports[key]);
228
223
  module.setExport("default", exports);
229
224
  }, {
230
225
  context: this.context,
231
226
  identifier
232
227
  });
233
- this.moduleCache.set(identifier, module);
234
- return module;
228
+ return this.moduleCache.set(identifier, module), module;
235
229
  }
236
230
  getCjsSyntheticModule(path, identifier) {
237
231
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
238
- const exports = this.require(path);
239
- // TODO: technically module should be parsed to find static exports, implement for strict mode in #2854
240
- const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports);
241
- const module = new SyntheticModule([...keys, "default"], function() {
232
+ const exports = this.require(path), { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports), module = new SyntheticModule([...keys, "default"], function() {
242
233
  for (const key of keys) this.setExport(key, moduleExports[key]);
243
234
  this.setExport("default", defaultExport);
244
235
  }, {
245
236
  context: this.context,
246
237
  identifier
247
238
  });
248
- this.moduleCache.set(identifier, module);
249
- return module;
239
+ return this.moduleCache.set(identifier, module), module;
250
240
  }
251
241
  // TODO: use this in strict mode, when available in #2854
252
242
  // private _getNamedCjsExports(path: string): Set<string> {
@@ -286,7 +276,7 @@ class CommonjsExecutor {
286
276
  // }
287
277
  require(identifier) {
288
278
  const ext = extname(identifier);
289
- if (ext === ".node" || isNodeBuiltin(identifier)) return this.requireCoreModule(identifier);
279
+ if (ext === ".node" || isBuiltin(identifier)) return this.requireCoreModule(identifier);
290
280
  const module = new this.Module(identifier);
291
281
  return this.loadCommonJSModule(module, identifier);
292
282
  }
@@ -296,13 +286,10 @@ class CommonjsExecutor {
296
286
  const moduleExports = _require(identifier);
297
287
  if (identifier === "node:module" || identifier === "module") {
298
288
  const module = new this.Module("/module.js");
299
- module.exports = this.Module;
300
- this.builtinCache[normalized] = module;
301
- return module.exports;
289
+ return module.exports = this.Module, this.builtinCache[normalized] = module, module.exports;
302
290
  }
303
- this.builtinCache[normalized] = _require.cache[normalized];
304
291
  // TODO: should we wrap module to rethrow context errors?
305
- return moduleExports;
292
+ return this.builtinCache[normalized] = _require.cache[normalized], moduleExports;
306
293
  }
307
294
  }
308
295
 
@@ -313,21 +300,18 @@ class EsmExecutor {
313
300
  context;
314
301
  #httpIp = IPnumber("127.0.0.0");
315
302
  constructor(executor, options) {
316
- this.executor = executor;
317
- this.context = options.context;
303
+ this.executor = executor, this.context = options.context;
318
304
  }
319
305
  async evaluateModule(m) {
320
306
  if (m.status === "unlinked") this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)));
321
- await this.esmLinkMap.get(m);
322
- if (m.status === "linked") await m.evaluate();
307
+ if (await this.esmLinkMap.get(m), m.status === "linked") await m.evaluate();
323
308
  return m;
324
309
  }
325
310
  async createEsModule(fileURL, getCode) {
326
311
  const cached = this.moduleCache.get(fileURL);
327
312
  if (cached) return cached;
328
313
  const promise = this.loadEsModule(fileURL, getCode);
329
- this.moduleCache.set(fileURL, promise);
330
- return promise;
314
+ return this.moduleCache.set(fileURL, promise), promise;
331
315
  }
332
316
  async loadEsModule(fileURL, getCode) {
333
317
  const code = await getCode();
@@ -337,34 +321,29 @@ class EsmExecutor {
337
321
  const result = JSON.parse(code);
338
322
  this.setExport("default", result);
339
323
  });
340
- this.moduleCache.set(fileURL, m);
341
- return m;
324
+ return this.moduleCache.set(fileURL, m), m;
342
325
  }
343
326
  const m = new SourceTextModule(code, {
344
327
  identifier: fileURL,
345
328
  context: this.context,
346
329
  importModuleDynamically: this.executor.importModuleDynamically,
347
330
  initializeImportMeta: (meta, mod) => {
348
- meta.url = mod.identifier;
349
- if (mod.identifier.startsWith("file:")) {
331
+ if (meta.url = mod.identifier, mod.identifier.startsWith("file:")) {
350
332
  const filename = fileURLToPath(mod.identifier);
351
- meta.filename = filename;
352
- meta.dirname = dirname$1(filename);
333
+ meta.filename = filename, meta.dirname = dirname$1(filename);
353
334
  }
354
335
  meta.resolve = (specifier, importer) => {
355
336
  return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier);
356
337
  };
357
338
  }
358
339
  });
359
- this.moduleCache.set(fileURL, m);
360
- return m;
340
+ return this.moduleCache.set(fileURL, m), m;
361
341
  }
362
342
  async createWebAssemblyModule(fileUrl, getCode) {
363
343
  const cached = this.moduleCache.get(fileUrl);
364
344
  if (cached) return cached;
365
345
  const m = this.loadWebAssemblyModule(getCode(), fileUrl);
366
- this.moduleCache.set(fileUrl, m);
367
- return m;
346
+ return this.moduleCache.set(fileUrl, m), m;
368
347
  }
369
348
  async createNetworkModule(fileUrl) {
370
349
  // https://nodejs.org/api/esm.html#https-and-http-imports
@@ -380,18 +359,13 @@ class EsmExecutor {
380
359
  async loadWebAssemblyModule(source, identifier) {
381
360
  const cached = this.moduleCache.get(identifier);
382
361
  if (cached) return cached;
383
- const wasmModule = await WebAssembly.compile(source);
384
- const exports = WebAssembly.Module.exports(wasmModule);
385
- const imports = WebAssembly.Module.imports(wasmModule);
386
- const moduleLookup = {};
362
+ const wasmModule = await WebAssembly.compile(source), exports = WebAssembly.Module.exports(wasmModule), imports = WebAssembly.Module.imports(wasmModule), moduleLookup = {};
387
363
  for (const { module } of imports) if (moduleLookup[module] === void 0) moduleLookup[module] = await this.executor.resolveModule(module, identifier);
388
- const evaluateModule = (module) => this.evaluateModule(module);
389
- const syntheticModule = new SyntheticModule(exports.map(({ name }) => name), async function() {
364
+ const evaluateModule = (module) => this.evaluateModule(module), syntheticModule = new SyntheticModule(exports.map(({ name }) => name), async function() {
390
365
  const importsObject = {};
391
366
  for (const { module, name } of imports) {
392
367
  if (!importsObject[module]) importsObject[module] = {};
393
- await evaluateModule(moduleLookup[module]);
394
- importsObject[module][name] = moduleLookup[module].namespace[name];
368
+ await evaluateModule(moduleLookup[module]), importsObject[module][name] = moduleLookup[module].namespace[name];
395
369
  }
396
370
  const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject);
397
371
  for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]);
@@ -412,14 +386,12 @@ class EsmExecutor {
412
386
  if (cached) return cached;
413
387
  const match = identifier.match(dataURIRegex);
414
388
  if (!match || !match.groups) throw new Error("Invalid data URI");
415
- const mime = match.groups.mime;
416
- const encoding = match.groups.encoding;
389
+ const mime = match.groups.mime, encoding = match.groups.encoding;
417
390
  if (mime === "application/wasm") {
418
391
  if (!encoding) throw new Error("Missing data URI encoding");
419
392
  if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`);
420
393
  const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier);
421
- this.moduleCache.set(identifier, module);
422
- return module;
394
+ return this.moduleCache.set(identifier, module), module;
423
395
  }
424
396
  let code = match.groups.code;
425
397
  if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code);
@@ -433,8 +405,7 @@ class EsmExecutor {
433
405
  context: this.context,
434
406
  identifier
435
407
  });
436
- this.moduleCache.set(identifier, module);
437
- return module;
408
+ return this.moduleCache.set(identifier, module), module;
438
409
  }
439
410
  return this.createEsModule(identifier, () => code);
440
411
  }
@@ -448,57 +419,39 @@ function IPmask(maskSize) {
448
419
  return -1 << 32 - maskSize;
449
420
  }
450
421
 
451
- const CLIENT_ID = "/@vite/client";
452
- const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
422
+ const CLIENT_ID = "/@vite/client", CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
453
423
  class ViteExecutor {
454
424
  esm;
455
425
  constructor(options) {
456
- this.options = options;
457
- this.esm = options.esmExecutor;
458
- }
459
- resolve = (identifier, parent) => {
460
- if (identifier === CLIENT_ID) {
461
- if (this.workerState.environment.transformMode === "web") return identifier;
462
- const packageName = this.getPackageName(parent);
463
- throw new Error(`[vitest] Vitest cannot handle ${CLIENT_ID} imported in ${parent} when running in SSR environment. Add "${packageName}" to "ssr.noExternal" if you are using Vite SSR, or to "server.deps.inline" if you are using Vite Node.`);
464
- }
426
+ this.options = options, this.esm = options.esmExecutor;
427
+ }
428
+ resolve = (identifier) => {
429
+ if (identifier === CLIENT_ID) return identifier;
465
430
  };
466
431
  get workerState() {
467
432
  return this.options.context.__vitest_worker__;
468
433
  }
469
- getPackageName(modulePath) {
470
- const path = normalize(modulePath);
471
- let name = path.split("/node_modules/").pop() || "";
472
- if (name?.startsWith("@")) name = name.split("/").slice(0, 2).join("/");
473
- else name = name.split("/")[0];
474
- return name;
475
- }
476
434
  async createViteModule(fileUrl) {
477
- if (fileUrl === CLIENT_FILE) return this.createViteClientModule();
435
+ if (fileUrl === CLIENT_FILE || fileUrl === CLIENT_ID) return this.createViteClientModule();
478
436
  const cached = this.esm.resolveCachedModule(fileUrl);
479
- if (cached) return cached;
480
- return this.esm.createEsModule(fileUrl, async () => {
437
+ return cached || this.esm.createEsModule(fileUrl, async () => {
481
438
  try {
482
- const result = await this.options.transform(fileUrl, "web");
439
+ const result = await this.options.transform(fileUrl);
483
440
  if (result.code) return result.code;
484
441
  } catch (cause) {
485
442
  // rethrow vite error if it cannot load the module because it's not resolved
486
443
  if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) {
487
444
  const error = new Error(`Cannot find module '${fileUrl}'`, { cause });
488
- error.code = "ERR_MODULE_NOT_FOUND";
489
- throw error;
445
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
490
446
  }
491
447
  }
492
448
  throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
493
449
  });
494
450
  }
495
451
  createViteClientModule() {
496
- const identifier = CLIENT_ID;
497
- const cached = this.esm.resolveCachedModule(identifier);
452
+ const identifier = CLIENT_ID, cached = this.esm.resolveCachedModule(identifier);
498
453
  if (cached) return cached;
499
- const stub = this.options.viteClientModule;
500
- const moduleKeys = Object.keys(stub);
501
- const module = new SyntheticModule(moduleKeys, function() {
454
+ const stub = this.options.viteClientModule, moduleKeys = Object.keys(stub), module = new SyntheticModule(moduleKeys, function() {
502
455
  moduleKeys.forEach((key) => {
503
456
  this.setExport(key, stub[key]);
504
457
  });
@@ -506,25 +459,16 @@ class ViteExecutor {
506
459
  context: this.options.context,
507
460
  identifier
508
461
  });
509
- this.esm.cacheModule(identifier, module);
510
- return module;
462
+ return this.esm.cacheModule(identifier, module), module;
511
463
  }
512
464
  canResolve = (fileUrl) => {
513
- const transformMode = this.workerState.environment.transformMode;
514
- if (transformMode !== "web") return false;
515
465
  if (fileUrl === CLIENT_FILE) return true;
516
- const config = this.workerState.config.deps?.web || {};
517
- const [modulePath] = fileUrl.split("?");
518
- if (config.transformCss && CSS_LANGS_RE.test(modulePath)) return true;
519
- if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) return true;
520
- if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) return true;
521
- return false;
466
+ const config = this.workerState.config.deps?.web || {}, [modulePath] = fileUrl.split("?");
467
+ return !!(config.transformCss && CSS_LANGS_RE.test(modulePath) || config.transformAssets && KNOWN_ASSET_RE.test(modulePath) || toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath)));
522
468
  };
523
469
  }
524
470
 
525
- const { existsSync, statSync } = fs;
526
- // always defined when we use vm pool
527
- const nativeResolve = import.meta.resolve;
471
+ const { existsSync } = fs, nativeResolve = import.meta.resolve;
528
472
  // TODO: improve Node.js strict mode support in #2854
529
473
  class ExternalModulesExecutor {
530
474
  cjs;
@@ -535,28 +479,21 @@ class ExternalModulesExecutor {
535
479
  resolvers = [];
536
480
  #networkSupported = null;
537
481
  constructor(options) {
538
- this.options = options;
539
- this.context = options.context;
540
- this.fs = options.fileMap;
541
- this.esm = new EsmExecutor(this, { context: this.context });
542
- this.cjs = new CommonjsExecutor({
482
+ this.options = options, this.context = options.context, this.fs = options.fileMap, this.esm = new EsmExecutor(this, { context: this.context }), this.cjs = new CommonjsExecutor({
543
483
  context: this.context,
544
484
  importModuleDynamically: this.importModuleDynamically,
545
485
  fileMap: options.fileMap,
546
486
  interopDefault: options.interopDefault
547
- });
548
- this.vite = new ViteExecutor({
487
+ }), this.vite = new ViteExecutor({
549
488
  esmExecutor: this.esm,
550
489
  context: this.context,
551
490
  transform: options.transform,
552
491
  viteClientModule: options.viteClientModule
553
- });
554
- this.resolvers = [this.vite.resolve];
492
+ }), this.resolvers = [this.vite.resolve];
555
493
  }
556
494
  async import(identifier) {
557
495
  const module = await this.createModule(identifier);
558
- await this.esm.evaluateModule(module);
559
- return module.namespace;
496
+ return await this.esm.evaluateModule(module), module.namespace;
560
497
  }
561
498
  require(identifier) {
562
499
  return this.cjs.require(identifier);
@@ -582,26 +519,6 @@ class ExternalModulesExecutor {
582
519
  // import.meta.resolve can be asynchronous in older +18 Node versions
583
520
  return nativeResolve(specifier, parent);
584
521
  }
585
- findNearestPackageData(basedir) {
586
- const originalBasedir = basedir;
587
- const packageCache = this.options.packageCache;
588
- while (basedir) {
589
- const cached = getCachedData(packageCache, basedir, originalBasedir);
590
- if (cached) return cached;
591
- const pkgPath = join(basedir, "package.json");
592
- try {
593
- if (statSync(pkgPath, { throwIfNoEntry: false })?.isFile()) {
594
- const pkgData = JSON.parse(this.fs.readFile(pkgPath));
595
- if (packageCache) setCacheData(packageCache, pkgData, basedir, originalBasedir);
596
- return pkgData;
597
- }
598
- } catch {}
599
- const nextBasedir = dirname$1(basedir);
600
- if (nextBasedir === basedir) break;
601
- basedir = nextBasedir;
602
- }
603
- return {};
604
- }
605
522
  getModuleInformation(identifier) {
606
523
  if (identifier.startsWith("data:")) return {
607
524
  type: "data",
@@ -609,7 +526,7 @@ class ExternalModulesExecutor {
609
526
  path: identifier
610
527
  };
611
528
  const extension = extname(identifier);
612
- if (extension === ".node" || isNodeBuiltin(identifier)) return {
529
+ if (extension === ".node" || isBuiltin(identifier)) return {
613
530
  type: "builtin",
614
531
  url: identifier,
615
532
  path: identifier
@@ -619,9 +536,7 @@ class ExternalModulesExecutor {
619
536
  url: identifier,
620
537
  path: identifier
621
538
  };
622
- const isFileUrl = identifier.startsWith("file://");
623
- const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
624
- const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
539
+ const isFileUrl = identifier.startsWith("file://"), pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier, fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
625
540
  let type;
626
541
  if (this.vite.canResolve(fileUrl)) type = "vite";
627
542
  else if (extension === ".mjs") type = "module";
@@ -631,7 +546,7 @@ class ExternalModulesExecutor {
631
546
  // cf. ESM_FILE_FORMAT(url) in https://nodejs.org/docs/latest-v20.x/api/esm.html#resolution-algorithm
632
547
  type = "wasm";
633
548
  else {
634
- const pkgData = this.findNearestPackageData(normalize(pathUrl));
549
+ const pkgData = findNearestPackageData(normalize(pathUrl));
635
550
  type = pkgData.type === "module" ? "module" : "commonjs";
636
551
  }
637
552
  return {
@@ -645,9 +560,8 @@ class ExternalModulesExecutor {
645
560
  // create ERR_MODULE_NOT_FOUND on our own since latest NodeJS's import.meta.resolve doesn't throw on non-existing namespace or path
646
561
  // https://github.com/nodejs/node/pull/49038
647
562
  if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) {
648
- const error = new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
649
- error.code = "ERR_MODULE_NOT_FOUND";
650
- throw error;
563
+ const error = /* @__PURE__ */ new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
564
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
651
565
  }
652
566
  switch (type) {
653
567
  case "data": return this.esm.createDataModule(identifier);
@@ -679,78 +593,115 @@ class FileMap {
679
593
  const cached = this.fsCache.get(path);
680
594
  if (cached != null) return cached;
681
595
  const source = await promises.readFile(path, "utf-8");
682
- this.fsCache.set(path, source);
683
- return source;
596
+ return this.fsCache.set(path, source), source;
684
597
  }
685
598
  readFile(path) {
686
599
  const cached = this.fsCache.get(path);
687
600
  if (cached != null) return cached;
688
601
  const source = readFileSync(path, "utf-8");
689
- this.fsCache.set(path, source);
690
- return source;
602
+ return this.fsCache.set(path, source), source;
691
603
  }
692
604
  readBuffer(path) {
693
605
  const cached = this.fsBufferCache.get(path);
694
606
  if (cached != null) return cached;
695
607
  const buffer = readFileSync(path);
696
- this.fsBufferCache.set(path, buffer);
697
- return buffer;
608
+ return this.fsBufferCache.set(path, buffer), buffer;
698
609
  }
699
610
  }
700
611
 
701
- const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
702
- const fileMap = new FileMap();
703
- const packageCache = /* @__PURE__ */ new Map();
612
+ const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href, fileMap = new FileMap(), packageCache = /* @__PURE__ */ new Map();
704
613
  async function runVmTests(method, state) {
705
614
  const { environment, ctx, rpc } = state;
706
615
  if (!environment.setupVM) {
707
- const envName = ctx.environment.name;
708
- const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
616
+ const envName = ctx.environment.name, packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
709
617
  throw new TypeError(`Environment "${ctx.environment.name}" is not a valid environment. Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`);
710
618
  }
711
619
  const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {});
712
- state.durations.environment = performance.now() - state.durations.environment;
713
- process.env.VITEST_VM_POOL = "1";
714
- if (!vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
620
+ if (state.durations.environment = performance.now() - state.durations.environment, process.env.VITEST_VM_POOL = "1", !vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
715
621
  const context = vm.getVmContext();
716
622
  if (!isContext(context)) throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
717
- provideWorkerState(context, state);
718
- // this is unfortunately needed for our own dependencies
719
- // we need to find a way to not rely on this by default
720
- // because browser doesn't provide these globals
721
- context.process = process;
722
- context.global = context;
723
- context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state);
724
- // TODO: don't hardcode setImmediate in fake timers defaults
725
- context.setImmediate = setImmediate;
726
- context.clearImmediate = clearImmediate;
727
- const stubs = getDefaultRequestStubs(context);
728
- const externalModulesExecutor = new ExternalModulesExecutor({
623
+ provideWorkerState(context, state), context.process = process, context.global = context, context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state), context.setImmediate = setImmediate, context.clearImmediate = clearImmediate;
624
+ const stubs = getDefaultRequestStubs(context), externalModulesExecutor = new ExternalModulesExecutor({
729
625
  context,
730
626
  fileMap,
731
627
  packageCache,
732
628
  transform: rpc.transform,
733
629
  viteClientModule: stubs["/@vite/client"]
734
- });
735
- const executor = await startVitestExecutor({
630
+ }), moduleRunner = startVitestModuleRunner({
736
631
  context,
737
- moduleCache: state.moduleCache,
632
+ evaluatedModules: state.evaluatedModules,
738
633
  state,
739
634
  externalModulesExecutor,
740
- requestStubs: stubs
635
+ createImportMeta: createNodeImportMeta
741
636
  });
742
- context.__vitest_mocker__ = executor.mocker;
743
- const { run } = await executor.importExternalModule(entryFile);
744
- const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
637
+ if (Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
638
+ value: {
639
+ context,
640
+ externalModulesExecutor
641
+ },
642
+ configurable: true,
643
+ enumerable: false,
644
+ writable: false
645
+ }), context.__vitest_mocker__ = moduleRunner.mocker, ctx.config.serializedDefines) try {
646
+ runInContext(ctx.config.serializedDefines, context, { filename: "virtual:load-defines.js" });
647
+ } catch (error) {
648
+ throw new Error(`Failed to load custom "defines": ${error.message}`);
649
+ }
650
+ await moduleRunner.mocker.initializeSpyModule();
651
+ const { run } = await moduleRunner.import(entryFile), fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
745
652
  filepath: f,
746
653
  testLocations: void 0
747
654
  } : f);
748
655
  try {
749
- await run(method, fileSpecs, ctx.config, executor);
656
+ await run(method, fileSpecs, ctx.config, moduleRunner);
750
657
  } finally {
751
- await vm.teardown?.();
752
- state.environmentTeardownRun = true;
658
+ await vm.teardown?.(), state.environmentTeardownRun = true;
659
+ }
660
+ }
661
+
662
+ class ForksVmWorker {
663
+ getRpcOptions() {
664
+ return createForksRpcOptions(v8);
665
+ }
666
+ async executeTests(method, state) {
667
+ const exit = process.exit;
668
+ state.ctx.config = unwrapSerializableConfig(state.ctx.config);
669
+ try {
670
+ await runVmTests(method, state);
671
+ } finally {
672
+ process.exit = exit;
673
+ }
674
+ }
675
+ runTests(state) {
676
+ return this.executeTests("run", state);
677
+ }
678
+ collectTests(state) {
679
+ return this.executeTests("collect", state);
753
680
  }
754
681
  }
682
+ const worker$1 = new ForksVmWorker();
683
+
684
+ class ThreadsVmWorker {
685
+ getRpcOptions(ctx) {
686
+ return createThreadsRpcOptions(ctx);
687
+ }
688
+ runTests(state) {
689
+ return runVmTests("run", state);
690
+ }
691
+ collectTests(state) {
692
+ return runVmTests("collect", state);
693
+ }
694
+ }
695
+ const worker = new ThreadsVmWorker();
696
+
697
+ async function run(ctx) {
698
+ await execute("run", ctx, ctx.pool === "vmForks" ? worker$1 : worker);
699
+ }
700
+ async function collect(ctx) {
701
+ await execute("collect", ctx, ctx.pool === "vmForks" ? worker$1 : worker);
702
+ }
703
+ async function teardown() {
704
+ await teardown$1();
705
+ }
755
706
 
756
- export { runVmTests as r };
707
+ export { collect, run, teardown };