vitest 4.0.0-beta.4 → 4.0.0-beta.6

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 (78) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/browser.d.ts +8 -9
  3. package/dist/browser.js +3 -2
  4. package/dist/chunks/base.BXI97p6t.js +39 -0
  5. package/dist/chunks/{benchmark.CYdenmiT.js → benchmark.UW6Ezvxy.js} +6 -8
  6. package/dist/chunks/{browser.d.BRP8scJf.d.ts → browser.d.Cawq_X_N.d.ts} +1 -1
  7. package/dist/chunks/{cac.CY0IAxC4.js → cac.WE-urWw5.js} +38 -115
  8. package/dist/chunks/{cli-api.B8xRY9Zt.js → cli-api.CZz3evYC.js} +931 -1439
  9. package/dist/chunks/{config.d.DZo8c7fw.d.ts → config.d.CKNVOKm0.d.ts} +3 -8
  10. package/dist/chunks/{console.DoJHFxmj.js → console.B0quX7yH.js} +32 -68
  11. package/dist/chunks/{constants.CXzqaLmq.js → constants.D_Q9UYh-.js} +1 -6
  12. package/dist/chunks/{coverage.C84l9G-M.js → coverage.BPRS6xgn.js} +395 -665
  13. package/dist/chunks/{coverage.DVF1vEu8.js → coverage.D_JHT54q.js} +2 -2
  14. package/dist/chunks/{coverage.d.CNYjU4GF.d.ts → coverage.d.BZtK59WP.d.ts} +7 -5
  15. package/dist/chunks/{creator.yfA2ExGt.js → creator.KEg6n5IC.js} +29 -75
  16. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  17. package/dist/chunks/{environment.d.Bhm9oc0v.d.ts → environment.d.2fYMoz3o.d.ts} +26 -4
  18. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  19. package/dist/chunks/{global.d.DAhT2emn.d.ts → global.d.K6uBQHzY.d.ts} +1 -1
  20. package/dist/chunks/{globals.Dgo-vS5G.js → globals.lgsmH00r.js} +7 -6
  21. package/dist/chunks/{index.D3SKT3tv.js → index.7w0eqmYM.js} +14 -24
  22. package/dist/chunks/{index.D1_MsKEt.js → index.AR8aAkCC.js} +4 -2
  23. package/dist/chunks/{index.CmSc2RE5.js → index.BG0gqZH-.js} +43 -106
  24. package/dist/chunks/{index.CtUvr1c8.js → index.CsFXYRkW.js} +27 -46
  25. package/dist/chunks/{index.Bz6b0Ib7.js → index.VNI-1z5c.js} +276 -604
  26. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  27. package/dist/chunks/moduleRunner.d.8kKUsuDg.d.ts +202 -0
  28. package/dist/chunks/moduleTransport.I-bgQy0S.js +19 -0
  29. package/dist/chunks/{node.fjCdwEIl.js → node.BOqcT2jW.js} +1 -1
  30. package/dist/chunks/{plugin.d.CLhMcYdD.d.ts → plugin.d.DuiQJfUL.d.ts} +1 -1
  31. package/dist/chunks/{reporters.d.DWg40D2B.d.ts → reporters.d.CqR9-CDJ.d.ts} +52 -101
  32. package/dist/chunks/resolver.Bx6lE0iq.js +119 -0
  33. package/dist/chunks/{rpc.jnQO9F8a.js → rpc.RpPylpp0.js} +7 -21
  34. package/dist/chunks/runBaseTests.D6sfuWBM.js +99 -0
  35. package/dist/chunks/{setup-common.Ebx5x0eP.js → setup-common.hLGRxhC8.js} +15 -27
  36. package/dist/chunks/startModuleRunner.C8TW8zTN.js +655 -0
  37. package/dist/chunks/{typechecker.CMNPqJOo.js → typechecker.Cd1wvxUM.js} +97 -209
  38. package/dist/chunks/{utils.CcGm2cd1.js → utils.C2YI6McM.js} +4 -13
  39. package/dist/chunks/{utils.XdZDrNZV.js → utils.C7__0Iv5.js} +7 -17
  40. package/dist/chunks/{vi.CA0EPI9Y.js → vi.BfdOiD4j.js} +116 -269
  41. package/dist/chunks/{vm.BUnLJt_P.js → vm.BHBje7cC.js} +101 -225
  42. package/dist/chunks/{worker.d.zjyR34Pb.d.ts → worker.d.D9QWnzAe.d.ts} +16 -13
  43. package/dist/chunks/{worker.d.C-1AbnVe.d.ts → worker.d.Db-UVmXc.d.ts} +1 -1
  44. package/dist/cli.js +4 -4
  45. package/dist/config.cjs +3 -9
  46. package/dist/config.d.ts +10 -12
  47. package/dist/config.js +1 -1
  48. package/dist/coverage.d.ts +10 -11
  49. package/dist/coverage.js +5 -6
  50. package/dist/environments.d.ts +2 -2
  51. package/dist/environments.js +1 -1
  52. package/dist/index.d.ts +10 -9
  53. package/dist/index.js +6 -5
  54. package/dist/module-evaluator.d.ts +12 -0
  55. package/dist/module-evaluator.js +276 -0
  56. package/dist/module-runner.js +15 -0
  57. package/dist/node.d.ts +12 -13
  58. package/dist/node.js +19 -24
  59. package/dist/reporters.d.ts +7 -8
  60. package/dist/reporters.js +3 -3
  61. package/dist/runners.d.ts +3 -3
  62. package/dist/runners.js +35 -57
  63. package/dist/snapshot.js +2 -2
  64. package/dist/suite.js +2 -2
  65. package/dist/worker.js +82 -45
  66. package/dist/workers/forks.js +11 -10
  67. package/dist/workers/runVmTests.js +27 -46
  68. package/dist/workers/threads.js +11 -10
  69. package/dist/workers/vmForks.js +11 -10
  70. package/dist/workers/vmThreads.js +11 -10
  71. package/dist/workers.d.ts +5 -4
  72. package/dist/workers.js +17 -16
  73. package/package.json +22 -17
  74. package/dist/chunks/base.BaCDDRPG.js +0 -38
  75. package/dist/chunks/execute.Dt-pCVcL.js +0 -708
  76. package/dist/chunks/runBaseTests.DBVVLMSb.js +0 -129
  77. package/dist/execute.d.ts +0 -148
  78. package/dist/execute.js +0 -13
@@ -1,15 +1,16 @@
1
1
  import { fileURLToPath, pathToFileURL } from 'node:url';
2
2
  import vm, { isContext } from 'node:vm';
3
- import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
3
+ import { dirname, basename, extname, normalize, resolve } from 'pathe';
4
4
  import { distDir } from '../path.js';
5
- import { createCustomConsole } from './console.DoJHFxmj.js';
6
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.Dt-pCVcL.js';
5
+ import { createCustomConsole } from './console.B0quX7yH.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 } from './startModuleRunner.C8TW8zTN.js';
13
+ import { p as provideWorkerState } from './utils.C7__0Iv5.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,20 +66,13 @@ 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
  }
87
77
  static getSourceMapsSupport = () => ({
88
78
  enabled: false,
@@ -99,19 +89,16 @@ class CommonjsExecutor {
99
89
  throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`);
100
90
  };
101
91
  _compile(code, filename) {
102
- const cjsModule = Module$1.wrap(code);
103
- const script = new vm.Script(cjsModule, {
92
+ const cjsModule = Module$1.wrap(code), script = new vm.Script(cjsModule, {
104
93
  filename,
105
94
  importModuleDynamically: options.importModuleDynamically
106
95
  });
107
96
  // @ts-expect-error mark script with current identifier
108
97
  script.identifier = filename;
109
- const fn = script.runInContext(executor.context);
110
- const __dirname = dirname(filename);
98
+ const fn = script.runInContext(executor.context), __dirname = dirname(filename);
111
99
  executor.requireCache.set(filename, this);
112
100
  try {
113
- fn(this.exports, this.require, this, filename, __dirname);
114
- return this.exports;
101
+ return fn(this.exports, this.require, this, filename, __dirname), this.exports;
115
102
  } finally {
116
103
  this.loaded = true;
117
104
  }
@@ -157,9 +144,7 @@ class CommonjsExecutor {
157
144
  static stripTypeScriptTypes = Module.stripTypeScriptTypes;
158
145
  static findPackageJSON = Module.findPackageJSON;
159
146
  static Module = Module$1;
160
- };
161
- this.extensions[".js"] = this.requireJs;
162
- this.extensions[".json"] = this.requireJson;
147
+ }, this.extensions[".js"] = this.requireJs, this.extensions[".json"] = this.requireJson;
163
148
  }
164
149
  requireJs = (m, filename) => {
165
150
  const content = this.fs.readFile(filename);
@@ -170,23 +155,17 @@ class CommonjsExecutor {
170
155
  m.exports = JSON.parse(code);
171
156
  };
172
157
  createRequire = (filename) => {
173
- const _require = createRequire(filename);
174
- const require = (id) => {
175
- const resolved = _require.resolve(id);
176
- const ext = extname(resolved);
177
- 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);
178
161
  const module = new this.Module(resolved);
179
162
  return this.loadCommonJSModule(module, resolved);
180
- };
181
- require.resolve = _require.resolve;
182
- Object.defineProperty(require, "extensions", {
163
+ });
164
+ return require.resolve = _require.resolve, Object.defineProperty(require, "extensions", {
183
165
  get: () => this.extensions,
184
166
  set: () => {},
185
167
  configurable: true
186
- });
187
- require.main = void 0;
188
- require.cache = this.publicRequireCache;
189
- return require;
168
+ }), require.main = void 0, require.cache = this.publicRequireCache, require;
190
169
  };
191
170
  createProxyCache() {
192
171
  return new Proxy(Object.create(null), {
@@ -208,53 +187,40 @@ class CommonjsExecutor {
208
187
  loadCommonJSModule(module, filename) {
209
188
  const cached = this.requireCache.get(filename);
210
189
  if (cached) return cached.exports;
211
- const extension = this.findLongestRegisteredExtension(filename);
212
- const loader = this.extensions[extension] || this.extensions[".js"];
213
- loader(module, filename);
214
- return module.exports;
190
+ const extension = this.findLongestRegisteredExtension(filename), loader = this.extensions[extension] || this.extensions[".js"];
191
+ return loader(module, filename), module.exports;
215
192
  }
216
193
  findLongestRegisteredExtension(filename) {
217
194
  const name = basename(filename);
218
- let currentExtension;
219
- let index;
220
- let startIndex = 0;
195
+ let currentExtension, index, startIndex = 0;
221
196
  // eslint-disable-next-line no-cond-assign
222
197
  while ((index = name.indexOf(".", startIndex)) !== -1) {
223
- startIndex = index + 1;
224
- if (index === 0) continue;
225
- currentExtension = name.slice(index);
226
- 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;
227
200
  }
228
201
  return ".js";
229
202
  }
230
203
  getCoreSyntheticModule(identifier) {
231
204
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
232
- const exports = this.require(identifier);
233
- const keys = Object.keys(exports);
234
- const module = new SyntheticModule([...keys, "default"], () => {
205
+ const exports = this.require(identifier), keys = Object.keys(exports), module = new SyntheticModule([...keys, "default"], () => {
235
206
  for (const key of keys) module.setExport(key, exports[key]);
236
207
  module.setExport("default", exports);
237
208
  }, {
238
209
  context: this.context,
239
210
  identifier
240
211
  });
241
- this.moduleCache.set(identifier, module);
242
- return module;
212
+ return this.moduleCache.set(identifier, module), module;
243
213
  }
244
214
  getCjsSyntheticModule(path, identifier) {
245
215
  if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
246
- const exports = this.require(path);
247
- // TODO: technically module should be parsed to find static exports, implement for strict mode in #2854
248
- const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports);
249
- 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() {
250
217
  for (const key of keys) this.setExport(key, moduleExports[key]);
251
218
  this.setExport("default", defaultExport);
252
219
  }, {
253
220
  context: this.context,
254
221
  identifier
255
222
  });
256
- this.moduleCache.set(identifier, module);
257
- return module;
223
+ return this.moduleCache.set(identifier, module), module;
258
224
  }
259
225
  // TODO: use this in strict mode, when available in #2854
260
226
  // private _getNamedCjsExports(path: string): Set<string> {
@@ -294,7 +260,7 @@ class CommonjsExecutor {
294
260
  // }
295
261
  require(identifier) {
296
262
  const ext = extname(identifier);
297
- if (ext === ".node" || isNodeBuiltin(identifier)) return this.requireCoreModule(identifier);
263
+ if (ext === ".node" || isBuiltin(identifier)) return this.requireCoreModule(identifier);
298
264
  const module = new this.Module(identifier);
299
265
  return this.loadCommonJSModule(module, identifier);
300
266
  }
@@ -304,13 +270,10 @@ class CommonjsExecutor {
304
270
  const moduleExports = _require(identifier);
305
271
  if (identifier === "node:module" || identifier === "module") {
306
272
  const module = new this.Module("/module.js");
307
- module.exports = this.Module;
308
- this.builtinCache[normalized] = module;
309
- return module.exports;
273
+ return module.exports = this.Module, this.builtinCache[normalized] = module, module.exports;
310
274
  }
311
- this.builtinCache[normalized] = _require.cache[normalized];
312
275
  // TODO: should we wrap module to rethrow context errors?
313
- return moduleExports;
276
+ return this.builtinCache[normalized] = _require.cache[normalized], moduleExports;
314
277
  }
315
278
  }
316
279
 
@@ -321,21 +284,18 @@ class EsmExecutor {
321
284
  context;
322
285
  #httpIp = IPnumber("127.0.0.0");
323
286
  constructor(executor, options) {
324
- this.executor = executor;
325
- this.context = options.context;
287
+ this.executor = executor, this.context = options.context;
326
288
  }
327
289
  async evaluateModule(m) {
328
290
  if (m.status === "unlinked") this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)));
329
- await this.esmLinkMap.get(m);
330
- if (m.status === "linked") await m.evaluate();
291
+ if (await this.esmLinkMap.get(m), m.status === "linked") await m.evaluate();
331
292
  return m;
332
293
  }
333
294
  async createEsModule(fileURL, getCode) {
334
295
  const cached = this.moduleCache.get(fileURL);
335
296
  if (cached) return cached;
336
297
  const promise = this.loadEsModule(fileURL, getCode);
337
- this.moduleCache.set(fileURL, promise);
338
- return promise;
298
+ return this.moduleCache.set(fileURL, promise), promise;
339
299
  }
340
300
  async loadEsModule(fileURL, getCode) {
341
301
  const code = await getCode();
@@ -345,34 +305,29 @@ class EsmExecutor {
345
305
  const result = JSON.parse(code);
346
306
  this.setExport("default", result);
347
307
  });
348
- this.moduleCache.set(fileURL, m);
349
- return m;
308
+ return this.moduleCache.set(fileURL, m), m;
350
309
  }
351
310
  const m = new SourceTextModule(code, {
352
311
  identifier: fileURL,
353
312
  context: this.context,
354
313
  importModuleDynamically: this.executor.importModuleDynamically,
355
314
  initializeImportMeta: (meta, mod) => {
356
- meta.url = mod.identifier;
357
- if (mod.identifier.startsWith("file:")) {
315
+ if (meta.url = mod.identifier, mod.identifier.startsWith("file:")) {
358
316
  const filename = fileURLToPath(mod.identifier);
359
- meta.filename = filename;
360
- meta.dirname = dirname$1(filename);
317
+ meta.filename = filename, meta.dirname = dirname$1(filename);
361
318
  }
362
319
  meta.resolve = (specifier, importer) => {
363
320
  return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier);
364
321
  };
365
322
  }
366
323
  });
367
- this.moduleCache.set(fileURL, m);
368
- return m;
324
+ return this.moduleCache.set(fileURL, m), m;
369
325
  }
370
326
  async createWebAssemblyModule(fileUrl, getCode) {
371
327
  const cached = this.moduleCache.get(fileUrl);
372
328
  if (cached) return cached;
373
329
  const m = this.loadWebAssemblyModule(getCode(), fileUrl);
374
- this.moduleCache.set(fileUrl, m);
375
- return m;
330
+ return this.moduleCache.set(fileUrl, m), m;
376
331
  }
377
332
  async createNetworkModule(fileUrl) {
378
333
  // https://nodejs.org/api/esm.html#https-and-http-imports
@@ -388,18 +343,13 @@ class EsmExecutor {
388
343
  async loadWebAssemblyModule(source, identifier) {
389
344
  const cached = this.moduleCache.get(identifier);
390
345
  if (cached) return cached;
391
- const wasmModule = await WebAssembly.compile(source);
392
- const exports = WebAssembly.Module.exports(wasmModule);
393
- const imports = WebAssembly.Module.imports(wasmModule);
394
- const moduleLookup = {};
346
+ const wasmModule = await WebAssembly.compile(source), exports = WebAssembly.Module.exports(wasmModule), imports = WebAssembly.Module.imports(wasmModule), moduleLookup = {};
395
347
  for (const { module } of imports) if (moduleLookup[module] === void 0) moduleLookup[module] = await this.executor.resolveModule(module, identifier);
396
- const evaluateModule = (module) => this.evaluateModule(module);
397
- 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() {
398
349
  const importsObject = {};
399
350
  for (const { module, name } of imports) {
400
351
  if (!importsObject[module]) importsObject[module] = {};
401
- await evaluateModule(moduleLookup[module]);
402
- importsObject[module][name] = moduleLookup[module].namespace[name];
352
+ await evaluateModule(moduleLookup[module]), importsObject[module][name] = moduleLookup[module].namespace[name];
403
353
  }
404
354
  const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject);
405
355
  for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]);
@@ -420,14 +370,12 @@ class EsmExecutor {
420
370
  if (cached) return cached;
421
371
  const match = identifier.match(dataURIRegex);
422
372
  if (!match || !match.groups) throw new Error("Invalid data URI");
423
- const mime = match.groups.mime;
424
- const encoding = match.groups.encoding;
373
+ const mime = match.groups.mime, encoding = match.groups.encoding;
425
374
  if (mime === "application/wasm") {
426
375
  if (!encoding) throw new Error("Missing data URI encoding");
427
376
  if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`);
428
377
  const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier);
429
- this.moduleCache.set(identifier, module);
430
- return module;
378
+ return this.moduleCache.set(identifier, module), module;
431
379
  }
432
380
  let code = match.groups.code;
433
381
  if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code);
@@ -441,8 +389,7 @@ class EsmExecutor {
441
389
  context: this.context,
442
390
  identifier
443
391
  });
444
- this.moduleCache.set(identifier, module);
445
- return module;
392
+ return this.moduleCache.set(identifier, module), module;
446
393
  }
447
394
  return this.createEsModule(identifier, () => code);
448
395
  }
@@ -456,57 +403,39 @@ function IPmask(maskSize) {
456
403
  return -1 << 32 - maskSize;
457
404
  }
458
405
 
459
- const CLIENT_ID = "/@vite/client";
460
- const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
406
+ const CLIENT_ID = "/@vite/client", CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
461
407
  class ViteExecutor {
462
408
  esm;
463
409
  constructor(options) {
464
- this.options = options;
465
- this.esm = options.esmExecutor;
466
- }
467
- resolve = (identifier, parent) => {
468
- if (identifier === CLIENT_ID) {
469
- if (this.workerState.environment.transformMode === "web") return identifier;
470
- const packageName = this.getPackageName(parent);
471
- 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.`);
472
- }
410
+ this.options = options, this.esm = options.esmExecutor;
411
+ }
412
+ resolve = (identifier) => {
413
+ if (identifier === CLIENT_ID) return identifier;
473
414
  };
474
415
  get workerState() {
475
416
  return this.options.context.__vitest_worker__;
476
417
  }
477
- getPackageName(modulePath) {
478
- const path = normalize(modulePath);
479
- let name = path.split("/node_modules/").pop() || "";
480
- if (name?.startsWith("@")) name = name.split("/").slice(0, 2).join("/");
481
- else name = name.split("/")[0];
482
- return name;
483
- }
484
418
  async createViteModule(fileUrl) {
485
- if (fileUrl === CLIENT_FILE) return this.createViteClientModule();
419
+ if (fileUrl === CLIENT_FILE || fileUrl === CLIENT_ID) return this.createViteClientModule();
486
420
  const cached = this.esm.resolveCachedModule(fileUrl);
487
- if (cached) return cached;
488
- return this.esm.createEsModule(fileUrl, async () => {
421
+ return cached || this.esm.createEsModule(fileUrl, async () => {
489
422
  try {
490
- const result = await this.options.transform(fileUrl, "web");
423
+ const result = await this.options.transform(fileUrl);
491
424
  if (result.code) return result.code;
492
425
  } catch (cause) {
493
426
  // rethrow vite error if it cannot load the module because it's not resolved
494
427
  if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) {
495
428
  const error = new Error(`Cannot find module '${fileUrl}'`, { cause });
496
- error.code = "ERR_MODULE_NOT_FOUND";
497
- throw error;
429
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
498
430
  }
499
431
  }
500
432
  throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
501
433
  });
502
434
  }
503
435
  createViteClientModule() {
504
- const identifier = CLIENT_ID;
505
- const cached = this.esm.resolveCachedModule(identifier);
436
+ const identifier = CLIENT_ID, cached = this.esm.resolveCachedModule(identifier);
506
437
  if (cached) return cached;
507
- const stub = this.options.viteClientModule;
508
- const moduleKeys = Object.keys(stub);
509
- const module = new SyntheticModule(moduleKeys, function() {
438
+ const stub = this.options.viteClientModule, moduleKeys = Object.keys(stub), module = new SyntheticModule(moduleKeys, function() {
510
439
  moduleKeys.forEach((key) => {
511
440
  this.setExport(key, stub[key]);
512
441
  });
@@ -514,25 +443,16 @@ class ViteExecutor {
514
443
  context: this.options.context,
515
444
  identifier
516
445
  });
517
- this.esm.cacheModule(identifier, module);
518
- return module;
446
+ return this.esm.cacheModule(identifier, module), module;
519
447
  }
520
448
  canResolve = (fileUrl) => {
521
- const transformMode = this.workerState.environment.transformMode;
522
- if (transformMode !== "web") return false;
523
449
  if (fileUrl === CLIENT_FILE) return true;
524
- const config = this.workerState.config.deps?.web || {};
525
- const [modulePath] = fileUrl.split("?");
526
- if (config.transformCss && CSS_LANGS_RE.test(modulePath)) return true;
527
- if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) return true;
528
- if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) return true;
529
- 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)));
530
452
  };
531
453
  }
532
454
 
533
- const { existsSync, statSync } = fs;
534
- // always defined when we use vm pool
535
- const nativeResolve = import.meta.resolve;
455
+ const { existsSync } = fs, nativeResolve = import.meta.resolve;
536
456
  // TODO: improve Node.js strict mode support in #2854
537
457
  class ExternalModulesExecutor {
538
458
  cjs;
@@ -543,28 +463,21 @@ class ExternalModulesExecutor {
543
463
  resolvers = [];
544
464
  #networkSupported = null;
545
465
  constructor(options) {
546
- this.options = options;
547
- this.context = options.context;
548
- this.fs = options.fileMap;
549
- this.esm = new EsmExecutor(this, { context: this.context });
550
- 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({
551
467
  context: this.context,
552
468
  importModuleDynamically: this.importModuleDynamically,
553
469
  fileMap: options.fileMap,
554
470
  interopDefault: options.interopDefault
555
- });
556
- this.vite = new ViteExecutor({
471
+ }), this.vite = new ViteExecutor({
557
472
  esmExecutor: this.esm,
558
473
  context: this.context,
559
474
  transform: options.transform,
560
475
  viteClientModule: options.viteClientModule
561
- });
562
- this.resolvers = [this.vite.resolve];
476
+ }), this.resolvers = [this.vite.resolve];
563
477
  }
564
478
  async import(identifier) {
565
479
  const module = await this.createModule(identifier);
566
- await this.esm.evaluateModule(module);
567
- return module.namespace;
480
+ return await this.esm.evaluateModule(module), module.namespace;
568
481
  }
569
482
  require(identifier) {
570
483
  return this.cjs.require(identifier);
@@ -590,26 +503,6 @@ class ExternalModulesExecutor {
590
503
  // import.meta.resolve can be asynchronous in older +18 Node versions
591
504
  return nativeResolve(specifier, parent);
592
505
  }
593
- findNearestPackageData(basedir) {
594
- const originalBasedir = basedir;
595
- const packageCache = this.options.packageCache;
596
- while (basedir) {
597
- const cached = getCachedData(packageCache, basedir, originalBasedir);
598
- if (cached) return cached;
599
- const pkgPath = join(basedir, "package.json");
600
- try {
601
- if (statSync(pkgPath, { throwIfNoEntry: false })?.isFile()) {
602
- const pkgData = JSON.parse(this.fs.readFile(pkgPath));
603
- if (packageCache) setCacheData(packageCache, pkgData, basedir, originalBasedir);
604
- return pkgData;
605
- }
606
- } catch {}
607
- const nextBasedir = dirname$1(basedir);
608
- if (nextBasedir === basedir) break;
609
- basedir = nextBasedir;
610
- }
611
- return {};
612
- }
613
506
  getModuleInformation(identifier) {
614
507
  if (identifier.startsWith("data:")) return {
615
508
  type: "data",
@@ -617,7 +510,7 @@ class ExternalModulesExecutor {
617
510
  path: identifier
618
511
  };
619
512
  const extension = extname(identifier);
620
- if (extension === ".node" || isNodeBuiltin(identifier)) return {
513
+ if (extension === ".node" || isBuiltin(identifier)) return {
621
514
  type: "builtin",
622
515
  url: identifier,
623
516
  path: identifier
@@ -627,9 +520,7 @@ class ExternalModulesExecutor {
627
520
  url: identifier,
628
521
  path: identifier
629
522
  };
630
- const isFileUrl = identifier.startsWith("file://");
631
- const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
632
- 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();
633
524
  let type;
634
525
  if (this.vite.canResolve(fileUrl)) type = "vite";
635
526
  else if (extension === ".mjs") type = "module";
@@ -639,7 +530,7 @@ class ExternalModulesExecutor {
639
530
  // cf. ESM_FILE_FORMAT(url) in https://nodejs.org/docs/latest-v20.x/api/esm.html#resolution-algorithm
640
531
  type = "wasm";
641
532
  else {
642
- const pkgData = this.findNearestPackageData(normalize(pathUrl));
533
+ const pkgData = findNearestPackageData(normalize(pathUrl));
643
534
  type = pkgData.type === "module" ? "module" : "commonjs";
644
535
  }
645
536
  return {
@@ -654,8 +545,7 @@ class ExternalModulesExecutor {
654
545
  // https://github.com/nodejs/node/pull/49038
655
546
  if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) {
656
547
  const error = /* @__PURE__ */ new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
657
- error.code = "ERR_MODULE_NOT_FOUND";
658
- throw error;
548
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
659
549
  }
660
550
  switch (type) {
661
551
  case "data": return this.esm.createDataModule(identifier);
@@ -687,77 +577,63 @@ class FileMap {
687
577
  const cached = this.fsCache.get(path);
688
578
  if (cached != null) return cached;
689
579
  const source = await promises.readFile(path, "utf-8");
690
- this.fsCache.set(path, source);
691
- return source;
580
+ return this.fsCache.set(path, source), source;
692
581
  }
693
582
  readFile(path) {
694
583
  const cached = this.fsCache.get(path);
695
584
  if (cached != null) return cached;
696
585
  const source = readFileSync(path, "utf-8");
697
- this.fsCache.set(path, source);
698
- return source;
586
+ return this.fsCache.set(path, source), source;
699
587
  }
700
588
  readBuffer(path) {
701
589
  const cached = this.fsBufferCache.get(path);
702
590
  if (cached != null) return cached;
703
591
  const buffer = readFileSync(path);
704
- this.fsBufferCache.set(path, buffer);
705
- return buffer;
592
+ return this.fsBufferCache.set(path, buffer), buffer;
706
593
  }
707
594
  }
708
595
 
709
- const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
710
- const fileMap = new FileMap();
711
- const packageCache = /* @__PURE__ */ new Map();
596
+ const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href, fileMap = new FileMap(), packageCache = /* @__PURE__ */ new Map();
712
597
  async function runVmTests(method, state) {
713
598
  const { environment, ctx, rpc } = state;
714
599
  if (!environment.setupVM) {
715
- const envName = ctx.environment.name;
716
- const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
600
+ const envName = ctx.environment.name, packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
717
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.`);
718
602
  }
719
603
  const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {});
720
- state.durations.environment = performance.now() - state.durations.environment;
721
- process.env.VITEST_VM_POOL = "1";
722
- 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.`);
723
605
  const context = vm.getVmContext();
724
606
  if (!isContext(context)) throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
725
- provideWorkerState(context, state);
726
- // this is unfortunately needed for our own dependencies
727
- // we need to find a way to not rely on this by default
728
- // because browser doesn't provide these globals
729
- context.process = process;
730
- context.global = context;
731
- context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state);
732
- // TODO: don't hardcode setImmediate in fake timers defaults
733
- context.setImmediate = setImmediate;
734
- context.clearImmediate = clearImmediate;
735
- const stubs = getDefaultRequestStubs(context);
736
- 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({
737
609
  context,
738
610
  fileMap,
739
611
  packageCache,
740
612
  transform: rpc.transform,
741
613
  viteClientModule: stubs["/@vite/client"]
742
- });
743
- const executor = await startVitestExecutor({
614
+ }), moduleRunner = await startVitestModuleRunner({
744
615
  context,
745
- moduleCache: state.moduleCache,
616
+ evaluatedModules: state.evaluatedModules,
746
617
  state,
747
- externalModulesExecutor,
748
- requestStubs: stubs
618
+ externalModulesExecutor
749
619
  });
750
- context.__vitest_mocker__ = executor.mocker;
751
- const { run } = await executor.importExternalModule(entryFile);
752
- const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
620
+ Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
621
+ value: {
622
+ context,
623
+ externalModulesExecutor
624
+ },
625
+ configurable: true,
626
+ enumerable: false,
627
+ writable: false
628
+ }), context.__vitest_mocker__ = moduleRunner.mocker;
629
+ const { run } = await moduleRunner.import(entryFile), fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
753
630
  filepath: f,
754
631
  testLocations: void 0
755
632
  } : f);
756
633
  try {
757
- await run(method, fileSpecs, ctx.config, executor);
634
+ await run(method, fileSpecs, ctx.config, moduleRunner);
758
635
  } finally {
759
- await vm.teardown?.();
760
- state.environmentTeardownRun = true;
636
+ await vm.teardown?.(), state.environmentTeardownRun = true;
761
637
  }
762
638
  }
763
639