vitest 4.0.0-beta.1 → 4.0.0-beta.10

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 (85) hide show
  1. package/LICENSE.md +2 -2
  2. package/dist/browser.d.ts +13 -14
  3. package/dist/browser.js +6 -5
  4. package/dist/chunks/base.Cjha6usc.js +129 -0
  5. package/dist/chunks/{benchmark.CYdenmiT.js → benchmark.CJUa-Hsa.js} +6 -8
  6. package/dist/chunks/{benchmark.d.BwvBVTda.d.ts → benchmark.d.DAaHLpsq.d.ts} +4 -4
  7. package/dist/chunks/{browser.d.q8Z0P0q1.d.ts → browser.d.yFAklsD1.d.ts} +5 -5
  8. package/dist/chunks/{cac.D3EzDDZd.js → cac.DCxo_nSu.js} +70 -152
  9. package/dist/chunks/{cli-api.Dn5gKePv.js → cli-api.BJJXh9BV.js} +1330 -1677
  10. package/dist/chunks/{config.d.HJdfX-8k.d.ts → config.d.B_LthbQq.d.ts} +58 -63
  11. package/dist/chunks/{console.CtFJOzRO.js → console.7h5kHUIf.js} +34 -70
  12. package/dist/chunks/{constants.DnKduX2e.js → constants.D_Q9UYh-.js} +1 -9
  13. package/dist/chunks/{coverage.Cwa-XhJt.js → coverage.BCU-r2QL.js} +515 -781
  14. package/dist/chunks/{coverage.DVF1vEu8.js → coverage.D_JHT54q.js} +2 -2
  15. package/dist/chunks/{coverage.d.S9RMNXIe.d.ts → coverage.d.BZtK59WP.d.ts} +10 -8
  16. package/dist/chunks/{creator.GK6I-cL4.js → creator.08Gi-vCA.js} +93 -77
  17. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  18. package/dist/chunks/{environment.d.CUq4cUgQ.d.ts → environment.d.BsToaxti.d.ts} +27 -6
  19. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  20. package/dist/chunks/{global.d.CVbXEflG.d.ts → global.d.BK3X7FW1.d.ts} +2 -5
  21. package/dist/chunks/{globals.Cxal6MLI.js → globals.DG-S3xFe.js} +8 -8
  22. package/dist/chunks/{index.CZI_8rVt.js → index.BIP7prJq.js} +289 -608
  23. package/dist/chunks/{index.B521nVV-.js → index.Bgo3tNWt.js} +23 -4
  24. package/dist/chunks/{index.TfbsX-3I.js → index.BjKEiSn0.js} +14 -24
  25. package/dist/chunks/{index.BWf_gE5n.js → index.CMfqw92x.js} +7 -6
  26. package/dist/chunks/{index.CmSc2RE5.js → index.DIWhzsUh.js} +72 -118
  27. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  28. package/dist/chunks/moduleRunner.d.D9nBoC4p.d.ts +201 -0
  29. package/dist/chunks/moduleTransport.I-bgQy0S.js +19 -0
  30. package/dist/chunks/{node.fjCdwEIl.js → node.CyipiPvJ.js} +1 -1
  31. package/dist/chunks/{plugin.d.C2EcJUjo.d.ts → plugin.d.BMVSnsGV.d.ts} +1 -1
  32. package/dist/chunks/{reporters.d.DxZg19fy.d.ts → reporters.d.BUWjmRYq.d.ts} +1226 -1291
  33. package/dist/chunks/resolveSnapshotEnvironment.Bkht6Yor.js +81 -0
  34. package/dist/chunks/resolver.Bx6lE0iq.js +119 -0
  35. package/dist/chunks/rpc.BKr6mtxz.js +65 -0
  36. package/dist/chunks/{setup-common.D7ZqXFx-.js → setup-common.uiMcU3cv.js} +17 -29
  37. package/dist/chunks/startModuleRunner.p67gbNo9.js +665 -0
  38. package/dist/chunks/{suite.d.FvehnV49.d.ts → suite.d.BJWk38HB.d.ts} +1 -1
  39. package/dist/chunks/test.BiqSKISg.js +214 -0
  40. package/dist/chunks/{typechecker.CVytUJuF.js → typechecker.DB-fIMaH.js} +144 -213
  41. package/dist/chunks/{utils.CAioKnHs.js → utils.C2YI6McM.js} +5 -14
  42. package/dist/chunks/{utils.XdZDrNZV.js → utils.D2R2NiOH.js} +8 -27
  43. package/dist/chunks/{vi.bdSIJ99Y.js → vi.ZPgvtBao.js} +156 -305
  44. package/dist/chunks/{vm.BThCzidc.js → vm.Ca0Y0W5f.js} +116 -226
  45. package/dist/chunks/{worker.d.DoNjFAiv.d.ts → worker.d.BDsXGkwh.d.ts} +28 -22
  46. package/dist/chunks/{worker.d.CmvJfRGs.d.ts → worker.d.BNcX_2mH.d.ts} +1 -1
  47. package/dist/cli.js +4 -4
  48. package/dist/config.cjs +3 -9
  49. package/dist/config.d.ts +49 -54
  50. package/dist/config.js +1 -1
  51. package/dist/coverage.d.ts +27 -26
  52. package/dist/coverage.js +6 -7
  53. package/dist/environments.d.ts +9 -13
  54. package/dist/environments.js +1 -1
  55. package/dist/index.d.ts +38 -45
  56. package/dist/index.js +7 -9
  57. package/dist/module-evaluator.d.ts +13 -0
  58. package/dist/module-evaluator.js +276 -0
  59. package/dist/module-runner.js +15 -0
  60. package/dist/node.d.ts +40 -41
  61. package/dist/node.js +23 -33
  62. package/dist/reporters.d.ts +12 -13
  63. package/dist/reporters.js +3 -3
  64. package/dist/runners.d.ts +3 -3
  65. package/dist/runners.js +13 -232
  66. package/dist/snapshot.js +2 -2
  67. package/dist/suite.d.ts +2 -2
  68. package/dist/suite.js +2 -2
  69. package/dist/worker.js +90 -47
  70. package/dist/workers/forks.js +34 -10
  71. package/dist/workers/runVmTests.js +36 -56
  72. package/dist/workers/threads.js +34 -10
  73. package/dist/workers/vmForks.js +11 -10
  74. package/dist/workers/vmThreads.js +11 -10
  75. package/dist/workers.d.ts +5 -4
  76. package/dist/workers.js +35 -17
  77. package/globals.d.ts +17 -17
  78. package/package.json +32 -31
  79. package/dist/chunks/base.Bj3pWTr1.js +0 -38
  80. package/dist/chunks/execute.B7h3T_Hc.js +0 -708
  81. package/dist/chunks/index.D-VkfKhf.js +0 -105
  82. package/dist/chunks/rpc.CsFtxqeq.js +0 -83
  83. package/dist/chunks/runBaseTests.BC7ZIH5L.js +0 -129
  84. package/dist/execute.d.ts +0 -148
  85. package/dist/execute.js +0 -13
@@ -1,15 +1,16 @@
1
1
  import { fileURLToPath, pathToFileURL } from 'node:url';
2
- import vm, { isContext } from 'node:vm';
3
- import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
2
+ import vm, { isContext, runInContext } from 'node:vm';
3
+ import { dirname, basename, extname, normalize, resolve } from 'pathe';
4
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';
5
+ import { createCustomConsole } from './console.7h5kHUIf.js';
7
6
  import fs from 'node:fs';
7
+ import { createRequire, Module, isBuiltin } from 'node:module';
8
+ import { CSS_LANGS_RE, KNOWN_ASSET_RE, toArray, isBareImport } from '@vitest/utils';
9
+ import { f as findNearestPackageData } from './resolver.Bx6lE0iq.js';
8
10
  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';
11
+ import { getDefaultRequestStubs } from '../module-evaluator.js';
12
+ import { s as startVitestModuleRunner, a as VITEST_VM_CONTEXT_SYMBOL, c as createNodeImportMeta } from './startModuleRunner.p67gbNo9.js';
13
+ import { p as provideWorkerState } from './utils.D2R2NiOH.js';
13
14
 
14
15
  function interopCommonJsModule(interopDefault, mod) {
15
16
  if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) return {
@@ -18,11 +19,8 @@ function interopCommonJsModule(interopDefault, mod) {
18
19
  defaultExport: mod
19
20
  };
20
21
  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 {
22
+ const defaultKets = Object.keys(mod.default), moduleKeys = Object.keys(mod), allKeys = new Set([...defaultKets, ...moduleKeys]);
23
+ return allKeys.delete("default"), {
26
24
  keys: Array.from(allKeys),
27
25
  moduleExports: new Proxy(mod, { get(mod, prop) {
28
26
  return mod[prop] ?? mod.default?.[prop];
@@ -36,11 +34,14 @@ function interopCommonJsModule(interopDefault, mod) {
36
34
  defaultExport: mod
37
35
  };
38
36
  }
37
+ function isPrimitive(obj) {
38
+ const isObject = obj != null && (typeof obj === "object" || typeof obj === "function");
39
+ return !isObject;
40
+ }
39
41
  const SyntheticModule = vm.SyntheticModule;
40
42
  const SourceTextModule = vm.SourceTextModule;
41
43
 
42
- const _require = createRequire(import.meta.url);
43
- const requiresCache = /* @__PURE__ */ new WeakMap();
44
+ const _require = createRequire(import.meta.url), requiresCache = /* @__PURE__ */ new WeakMap();
44
45
  class CommonjsExecutor {
45
46
  context;
46
47
  requireCache = /* @__PURE__ */ new Map();
@@ -52,12 +53,8 @@ class CommonjsExecutor {
52
53
  Module;
53
54
  interopDefault;
54
55
  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;
56
+ this.context = options.context, this.fs = options.fileMap, this.interopDefault = options.interopDefault;
57
+ const primitives = vm.runInContext("({ Object, Array, Error })", this.context), executor = this;
61
58
  this.Module = class Module$1 {
62
59
  exports;
63
60
  isPreloading = false;
@@ -69,21 +66,22 @@ class CommonjsExecutor {
69
66
  path;
70
67
  paths = [];
71
68
  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;
69
+ this.exports = primitives.Object.create(Object.prototype), this.path = dirname(id), this.id = id, this.filename = id, this.loaded = false, this.parent = parent;
79
70
  }
80
71
  get require() {
81
72
  const require = requiresCache.get(this);
82
73
  if (require) return require;
83
74
  const _require = Module$1.createRequire(this.id);
84
- requiresCache.set(this, _require);
85
- return _require;
75
+ return requiresCache.set(this, _require), _require;
86
76
  }
77
+ static getSourceMapsSupport = () => ({
78
+ enabled: false,
79
+ nodeModules: false,
80
+ generatedCode: false
81
+ });
82
+ static setSourceMapsSupport = () => {
83
+ // noop
84
+ };
87
85
  static register = () => {
88
86
  throw new Error(`[vitest] "register" is not available when running in Vitest.`);
89
87
  };
@@ -91,19 +89,16 @@ class CommonjsExecutor {
91
89
  throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`);
92
90
  };
93
91
  _compile(code, filename) {
94
- const cjsModule = Module$1.wrap(code);
95
- const script = new vm.Script(cjsModule, {
92
+ const cjsModule = Module$1.wrap(code), script = new vm.Script(cjsModule, {
96
93
  filename,
97
94
  importModuleDynamically: options.importModuleDynamically
98
95
  });
99
96
  // @ts-expect-error mark script with current identifier
100
97
  script.identifier = filename;
101
- const fn = script.runInContext(executor.context);
102
- const __dirname = dirname(filename);
98
+ const fn = script.runInContext(executor.context), __dirname = dirname(filename);
103
99
  executor.requireCache.set(filename, this);
104
100
  try {
105
- fn(this.exports, this.require, this, filename, __dirname);
106
- return this.exports;
101
+ return fn(this.exports, this.require, this, filename, __dirname), this.exports;
107
102
  } finally {
108
103
  this.loaded = true;
109
104
  }
@@ -149,9 +144,7 @@ class CommonjsExecutor {
149
144
  static stripTypeScriptTypes = Module.stripTypeScriptTypes;
150
145
  static findPackageJSON = Module.findPackageJSON;
151
146
  static Module = Module$1;
152
- };
153
- this.extensions[".js"] = this.requireJs;
154
- this.extensions[".json"] = this.requireJson;
147
+ }, this.extensions[".js"] = this.requireJs, this.extensions[".json"] = this.requireJson;
155
148
  }
156
149
  requireJs = (m, filename) => {
157
150
  const content = this.fs.readFile(filename);
@@ -162,23 +155,17 @@ class CommonjsExecutor {
162
155
  m.exports = JSON.parse(code);
163
156
  };
164
157
  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);
158
+ const _require = createRequire(filename), require = ((id) => {
159
+ const resolved = _require.resolve(id), ext = extname(resolved);
160
+ if (ext === ".node" || isBuiltin(resolved)) return this.requireCoreModule(resolved);
170
161
  const module = new this.Module(resolved);
171
162
  return this.loadCommonJSModule(module, resolved);
172
- };
173
- require.resolve = _require.resolve;
174
- Object.defineProperty(require, "extensions", {
163
+ });
164
+ return require.resolve = _require.resolve, Object.defineProperty(require, "extensions", {
175
165
  get: () => this.extensions,
176
166
  set: () => {},
177
167
  configurable: true
178
- });
179
- require.main = void 0;
180
- require.cache = this.publicRequireCache;
181
- return require;
168
+ }), require.main = void 0, require.cache = this.publicRequireCache, require;
182
169
  };
183
170
  createProxyCache() {
184
171
  return new Proxy(Object.create(null), {
@@ -200,53 +187,40 @@ class CommonjsExecutor {
200
187
  loadCommonJSModule(module, filename) {
201
188
  const cached = this.requireCache.get(filename);
202
189
  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;
190
+ const extension = this.findLongestRegisteredExtension(filename), loader = this.extensions[extension] || this.extensions[".js"];
191
+ return loader(module, filename), module.exports;
207
192
  }
208
193
  findLongestRegisteredExtension(filename) {
209
194
  const name = basename(filename);
210
- let currentExtension;
211
- let index;
212
- let startIndex = 0;
195
+ let currentExtension, index, startIndex = 0;
213
196
  // eslint-disable-next-line no-cond-assign
214
197
  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;
198
+ if (startIndex = index + 1, index === 0) continue;
199
+ if (currentExtension = name.slice(index), this.extensions[currentExtension]) return currentExtension;
219
200
  }
220
201
  return ".js";
221
202
  }
222
203
  getCoreSyntheticModule(identifier) {
223
204
  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"], () => {
205
+ const exports = this.require(identifier), keys = Object.keys(exports), module = new SyntheticModule([...keys, "default"], () => {
227
206
  for (const key of keys) module.setExport(key, exports[key]);
228
207
  module.setExport("default", exports);
229
208
  }, {
230
209
  context: this.context,
231
210
  identifier
232
211
  });
233
- this.moduleCache.set(identifier, module);
234
- return module;
212
+ return this.moduleCache.set(identifier, module), module;
235
213
  }
236
214
  getCjsSyntheticModule(path, identifier) {
237
215
  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() {
216
+ const exports = this.require(path), { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports), module = new SyntheticModule([...keys, "default"], function() {
242
217
  for (const key of keys) this.setExport(key, moduleExports[key]);
243
218
  this.setExport("default", defaultExport);
244
219
  }, {
245
220
  context: this.context,
246
221
  identifier
247
222
  });
248
- this.moduleCache.set(identifier, module);
249
- return module;
223
+ return this.moduleCache.set(identifier, module), module;
250
224
  }
251
225
  // TODO: use this in strict mode, when available in #2854
252
226
  // private _getNamedCjsExports(path: string): Set<string> {
@@ -286,7 +260,7 @@ class CommonjsExecutor {
286
260
  // }
287
261
  require(identifier) {
288
262
  const ext = extname(identifier);
289
- if (ext === ".node" || isNodeBuiltin(identifier)) return this.requireCoreModule(identifier);
263
+ if (ext === ".node" || isBuiltin(identifier)) return this.requireCoreModule(identifier);
290
264
  const module = new this.Module(identifier);
291
265
  return this.loadCommonJSModule(module, identifier);
292
266
  }
@@ -296,13 +270,10 @@ class CommonjsExecutor {
296
270
  const moduleExports = _require(identifier);
297
271
  if (identifier === "node:module" || identifier === "module") {
298
272
  const module = new this.Module("/module.js");
299
- module.exports = this.Module;
300
- this.builtinCache[normalized] = module;
301
- return module.exports;
273
+ return module.exports = this.Module, this.builtinCache[normalized] = module, module.exports;
302
274
  }
303
- this.builtinCache[normalized] = _require.cache[normalized];
304
275
  // TODO: should we wrap module to rethrow context errors?
305
- return moduleExports;
276
+ return this.builtinCache[normalized] = _require.cache[normalized], moduleExports;
306
277
  }
307
278
  }
308
279
 
@@ -313,21 +284,18 @@ class EsmExecutor {
313
284
  context;
314
285
  #httpIp = IPnumber("127.0.0.0");
315
286
  constructor(executor, options) {
316
- this.executor = executor;
317
- this.context = options.context;
287
+ this.executor = executor, this.context = options.context;
318
288
  }
319
289
  async evaluateModule(m) {
320
290
  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();
291
+ if (await this.esmLinkMap.get(m), m.status === "linked") await m.evaluate();
323
292
  return m;
324
293
  }
325
294
  async createEsModule(fileURL, getCode) {
326
295
  const cached = this.moduleCache.get(fileURL);
327
296
  if (cached) return cached;
328
297
  const promise = this.loadEsModule(fileURL, getCode);
329
- this.moduleCache.set(fileURL, promise);
330
- return promise;
298
+ return this.moduleCache.set(fileURL, promise), promise;
331
299
  }
332
300
  async loadEsModule(fileURL, getCode) {
333
301
  const code = await getCode();
@@ -337,34 +305,29 @@ class EsmExecutor {
337
305
  const result = JSON.parse(code);
338
306
  this.setExport("default", result);
339
307
  });
340
- this.moduleCache.set(fileURL, m);
341
- return m;
308
+ return this.moduleCache.set(fileURL, m), m;
342
309
  }
343
310
  const m = new SourceTextModule(code, {
344
311
  identifier: fileURL,
345
312
  context: this.context,
346
313
  importModuleDynamically: this.executor.importModuleDynamically,
347
314
  initializeImportMeta: (meta, mod) => {
348
- meta.url = mod.identifier;
349
- if (mod.identifier.startsWith("file:")) {
315
+ if (meta.url = mod.identifier, mod.identifier.startsWith("file:")) {
350
316
  const filename = fileURLToPath(mod.identifier);
351
- meta.filename = filename;
352
- meta.dirname = dirname$1(filename);
317
+ meta.filename = filename, meta.dirname = dirname$1(filename);
353
318
  }
354
319
  meta.resolve = (specifier, importer) => {
355
320
  return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier);
356
321
  };
357
322
  }
358
323
  });
359
- this.moduleCache.set(fileURL, m);
360
- return m;
324
+ return this.moduleCache.set(fileURL, m), m;
361
325
  }
362
326
  async createWebAssemblyModule(fileUrl, getCode) {
363
327
  const cached = this.moduleCache.get(fileUrl);
364
328
  if (cached) return cached;
365
329
  const m = this.loadWebAssemblyModule(getCode(), fileUrl);
366
- this.moduleCache.set(fileUrl, m);
367
- return m;
330
+ return this.moduleCache.set(fileUrl, m), m;
368
331
  }
369
332
  async createNetworkModule(fileUrl) {
370
333
  // https://nodejs.org/api/esm.html#https-and-http-imports
@@ -380,18 +343,13 @@ class EsmExecutor {
380
343
  async loadWebAssemblyModule(source, identifier) {
381
344
  const cached = this.moduleCache.get(identifier);
382
345
  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 = {};
346
+ const wasmModule = await WebAssembly.compile(source), exports = WebAssembly.Module.exports(wasmModule), imports = WebAssembly.Module.imports(wasmModule), moduleLookup = {};
387
347
  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() {
348
+ const evaluateModule = (module) => this.evaluateModule(module), syntheticModule = new SyntheticModule(exports.map(({ name }) => name), async function() {
390
349
  const importsObject = {};
391
350
  for (const { module, name } of imports) {
392
351
  if (!importsObject[module]) importsObject[module] = {};
393
- await evaluateModule(moduleLookup[module]);
394
- importsObject[module][name] = moduleLookup[module].namespace[name];
352
+ await evaluateModule(moduleLookup[module]), importsObject[module][name] = moduleLookup[module].namespace[name];
395
353
  }
396
354
  const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject);
397
355
  for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]);
@@ -412,14 +370,12 @@ class EsmExecutor {
412
370
  if (cached) return cached;
413
371
  const match = identifier.match(dataURIRegex);
414
372
  if (!match || !match.groups) throw new Error("Invalid data URI");
415
- const mime = match.groups.mime;
416
- const encoding = match.groups.encoding;
373
+ const mime = match.groups.mime, encoding = match.groups.encoding;
417
374
  if (mime === "application/wasm") {
418
375
  if (!encoding) throw new Error("Missing data URI encoding");
419
376
  if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`);
420
377
  const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier);
421
- this.moduleCache.set(identifier, module);
422
- return module;
378
+ return this.moduleCache.set(identifier, module), module;
423
379
  }
424
380
  let code = match.groups.code;
425
381
  if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code);
@@ -433,8 +389,7 @@ class EsmExecutor {
433
389
  context: this.context,
434
390
  identifier
435
391
  });
436
- this.moduleCache.set(identifier, module);
437
- return module;
392
+ return this.moduleCache.set(identifier, module), module;
438
393
  }
439
394
  return this.createEsModule(identifier, () => code);
440
395
  }
@@ -448,57 +403,39 @@ function IPmask(maskSize) {
448
403
  return -1 << 32 - maskSize;
449
404
  }
450
405
 
451
- const CLIENT_ID = "/@vite/client";
452
- const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
406
+ const CLIENT_ID = "/@vite/client", CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
453
407
  class ViteExecutor {
454
408
  esm;
455
409
  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
- }
410
+ this.options = options, this.esm = options.esmExecutor;
411
+ }
412
+ resolve = (identifier) => {
413
+ if (identifier === CLIENT_ID) return identifier;
465
414
  };
466
415
  get workerState() {
467
416
  return this.options.context.__vitest_worker__;
468
417
  }
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
418
  async createViteModule(fileUrl) {
477
- if (fileUrl === CLIENT_FILE) return this.createViteClientModule();
419
+ if (fileUrl === CLIENT_FILE || fileUrl === CLIENT_ID) return this.createViteClientModule();
478
420
  const cached = this.esm.resolveCachedModule(fileUrl);
479
- if (cached) return cached;
480
- return this.esm.createEsModule(fileUrl, async () => {
421
+ return cached || this.esm.createEsModule(fileUrl, async () => {
481
422
  try {
482
- const result = await this.options.transform(fileUrl, "web");
423
+ const result = await this.options.transform(fileUrl);
483
424
  if (result.code) return result.code;
484
425
  } catch (cause) {
485
426
  // rethrow vite error if it cannot load the module because it's not resolved
486
427
  if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) {
487
428
  const error = new Error(`Cannot find module '${fileUrl}'`, { cause });
488
- error.code = "ERR_MODULE_NOT_FOUND";
489
- throw error;
429
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
490
430
  }
491
431
  }
492
432
  throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
493
433
  });
494
434
  }
495
435
  createViteClientModule() {
496
- const identifier = CLIENT_ID;
497
- const cached = this.esm.resolveCachedModule(identifier);
436
+ const identifier = CLIENT_ID, cached = this.esm.resolveCachedModule(identifier);
498
437
  if (cached) return cached;
499
- const stub = this.options.viteClientModule;
500
- const moduleKeys = Object.keys(stub);
501
- const module = new SyntheticModule(moduleKeys, function() {
438
+ const stub = this.options.viteClientModule, moduleKeys = Object.keys(stub), module = new SyntheticModule(moduleKeys, function() {
502
439
  moduleKeys.forEach((key) => {
503
440
  this.setExport(key, stub[key]);
504
441
  });
@@ -506,25 +443,16 @@ class ViteExecutor {
506
443
  context: this.options.context,
507
444
  identifier
508
445
  });
509
- this.esm.cacheModule(identifier, module);
510
- return module;
446
+ return this.esm.cacheModule(identifier, module), module;
511
447
  }
512
448
  canResolve = (fileUrl) => {
513
- const transformMode = this.workerState.environment.transformMode;
514
- if (transformMode !== "web") return false;
515
449
  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;
450
+ const config = this.workerState.config.deps?.web || {}, [modulePath] = fileUrl.split("?");
451
+ return !!(config.transformCss && CSS_LANGS_RE.test(modulePath) || config.transformAssets && KNOWN_ASSET_RE.test(modulePath) || toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath)));
522
452
  };
523
453
  }
524
454
 
525
- const { existsSync, statSync } = fs;
526
- // always defined when we use vm pool
527
- const nativeResolve = import.meta.resolve;
455
+ const { existsSync } = fs, nativeResolve = import.meta.resolve;
528
456
  // TODO: improve Node.js strict mode support in #2854
529
457
  class ExternalModulesExecutor {
530
458
  cjs;
@@ -535,28 +463,21 @@ class ExternalModulesExecutor {
535
463
  resolvers = [];
536
464
  #networkSupported = null;
537
465
  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({
466
+ this.options = options, this.context = options.context, this.fs = options.fileMap, this.esm = new EsmExecutor(this, { context: this.context }), this.cjs = new CommonjsExecutor({
543
467
  context: this.context,
544
468
  importModuleDynamically: this.importModuleDynamically,
545
469
  fileMap: options.fileMap,
546
470
  interopDefault: options.interopDefault
547
- });
548
- this.vite = new ViteExecutor({
471
+ }), this.vite = new ViteExecutor({
549
472
  esmExecutor: this.esm,
550
473
  context: this.context,
551
474
  transform: options.transform,
552
475
  viteClientModule: options.viteClientModule
553
- });
554
- this.resolvers = [this.vite.resolve];
476
+ }), this.resolvers = [this.vite.resolve];
555
477
  }
556
478
  async import(identifier) {
557
479
  const module = await this.createModule(identifier);
558
- await this.esm.evaluateModule(module);
559
- return module.namespace;
480
+ return await this.esm.evaluateModule(module), module.namespace;
560
481
  }
561
482
  require(identifier) {
562
483
  return this.cjs.require(identifier);
@@ -582,26 +503,6 @@ class ExternalModulesExecutor {
582
503
  // import.meta.resolve can be asynchronous in older +18 Node versions
583
504
  return nativeResolve(specifier, parent);
584
505
  }
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
506
  getModuleInformation(identifier) {
606
507
  if (identifier.startsWith("data:")) return {
607
508
  type: "data",
@@ -609,7 +510,7 @@ class ExternalModulesExecutor {
609
510
  path: identifier
610
511
  };
611
512
  const extension = extname(identifier);
612
- if (extension === ".node" || isNodeBuiltin(identifier)) return {
513
+ if (extension === ".node" || isBuiltin(identifier)) return {
613
514
  type: "builtin",
614
515
  url: identifier,
615
516
  path: identifier
@@ -619,9 +520,7 @@ class ExternalModulesExecutor {
619
520
  url: identifier,
620
521
  path: identifier
621
522
  };
622
- const isFileUrl = identifier.startsWith("file://");
623
- const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
624
- const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
523
+ const isFileUrl = identifier.startsWith("file://"), pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier, fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
625
524
  let type;
626
525
  if (this.vite.canResolve(fileUrl)) type = "vite";
627
526
  else if (extension === ".mjs") type = "module";
@@ -631,7 +530,7 @@ class ExternalModulesExecutor {
631
530
  // cf. ESM_FILE_FORMAT(url) in https://nodejs.org/docs/latest-v20.x/api/esm.html#resolution-algorithm
632
531
  type = "wasm";
633
532
  else {
634
- const pkgData = this.findNearestPackageData(normalize(pathUrl));
533
+ const pkgData = findNearestPackageData(normalize(pathUrl));
635
534
  type = pkgData.type === "module" ? "module" : "commonjs";
636
535
  }
637
536
  return {
@@ -645,9 +544,8 @@ class ExternalModulesExecutor {
645
544
  // 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
545
  // https://github.com/nodejs/node/pull/49038
647
546
  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;
547
+ const error = /* @__PURE__ */ new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
548
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
651
549
  }
652
550
  switch (type) {
653
551
  case "data": return this.esm.createDataModule(identifier);
@@ -679,77 +577,69 @@ class FileMap {
679
577
  const cached = this.fsCache.get(path);
680
578
  if (cached != null) return cached;
681
579
  const source = await promises.readFile(path, "utf-8");
682
- this.fsCache.set(path, source);
683
- return source;
580
+ return this.fsCache.set(path, source), source;
684
581
  }
685
582
  readFile(path) {
686
583
  const cached = this.fsCache.get(path);
687
584
  if (cached != null) return cached;
688
585
  const source = readFileSync(path, "utf-8");
689
- this.fsCache.set(path, source);
690
- return source;
586
+ return this.fsCache.set(path, source), source;
691
587
  }
692
588
  readBuffer(path) {
693
589
  const cached = this.fsBufferCache.get(path);
694
590
  if (cached != null) return cached;
695
591
  const buffer = readFileSync(path);
696
- this.fsBufferCache.set(path, buffer);
697
- return buffer;
592
+ return this.fsBufferCache.set(path, buffer), buffer;
698
593
  }
699
594
  }
700
595
 
701
- const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
702
- const fileMap = new FileMap();
703
- const packageCache = /* @__PURE__ */ new Map();
596
+ const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href, fileMap = new FileMap(), packageCache = /* @__PURE__ */ new Map();
704
597
  async function runVmTests(method, state) {
705
598
  const { environment, ctx, rpc } = state;
706
599
  if (!environment.setupVM) {
707
- const envName = ctx.environment.name;
708
- const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
600
+ const envName = ctx.environment.name, packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
709
601
  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
602
  }
711
603
  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.`);
604
+ 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
605
  const context = vm.getVmContext();
716
606
  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({
607
+ provideWorkerState(context, state), context.process = process, context.global = context, context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state), context.setImmediate = setImmediate, context.clearImmediate = clearImmediate;
608
+ const stubs = getDefaultRequestStubs(context), externalModulesExecutor = new ExternalModulesExecutor({
729
609
  context,
730
610
  fileMap,
731
611
  packageCache,
732
612
  transform: rpc.transform,
733
613
  viteClientModule: stubs["/@vite/client"]
734
- });
735
- const executor = await startVitestExecutor({
614
+ }), moduleRunner = startVitestModuleRunner({
736
615
  context,
737
- moduleCache: state.moduleCache,
616
+ evaluatedModules: state.evaluatedModules,
738
617
  state,
739
618
  externalModulesExecutor,
740
- requestStubs: stubs
619
+ createImportMeta: createNodeImportMeta
741
620
  });
742
- context.__vitest_mocker__ = executor.mocker;
743
- const { run } = await executor.importExternalModule(entryFile);
744
- const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
621
+ if (Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
622
+ value: {
623
+ context,
624
+ externalModulesExecutor
625
+ },
626
+ configurable: true,
627
+ enumerable: false,
628
+ writable: false
629
+ }), context.__vitest_mocker__ = moduleRunner.mocker, ctx.config.serializedDefines) try {
630
+ runInContext(ctx.config.serializedDefines, context, { filename: "virtual:load-defines.js" });
631
+ } catch (error) {
632
+ throw new Error(`Failed to load custom "defines": ${error.message}`);
633
+ }
634
+ await moduleRunner.mocker.initializeSpyModule();
635
+ const { run } = await moduleRunner.import(entryFile), fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
745
636
  filepath: f,
746
637
  testLocations: void 0
747
638
  } : f);
748
639
  try {
749
- await run(method, fileSpecs, ctx.config, executor);
640
+ await run(method, fileSpecs, ctx.config, moduleRunner);
750
641
  } finally {
751
- await vm.teardown?.();
752
- state.environmentTeardownRun = true;
642
+ await vm.teardown?.(), state.environmentTeardownRun = true;
753
643
  }
754
644
  }
755
645