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
@@ -0,0 +1,682 @@
1
+ import fs from 'node:fs';
2
+ import nodeModule, { isBuiltin } from 'node:module';
3
+ import { isBareImport } from '@vitest/utils/helpers';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { normalize as normalize$1, join as join$1 } from 'pathe';
6
+ import { distDir } from '../path.js';
7
+ import { serializeValue } from '@vitest/utils/serialize';
8
+ import { VitestModuleEvaluator, unwrapId } from '../module-evaluator.js';
9
+ import { resolve as resolve$1, isAbsolute as isAbsolute$1 } from 'node:path';
10
+ import vm from 'node:vm';
11
+ import { MockerRegistry, mockObject, RedirectedModule, AutomockedModule } from '@vitest/mocker';
12
+ import * as viteModuleRunner from 'vite/module-runner';
13
+
14
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
15
+ function normalizeWindowsPath(input = "") {
16
+ return input && input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
17
+ }
18
+ const _UNC_REGEX = /^[/\\]{2}/, _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/, _DRIVE_LETTER_RE = /^[A-Za-z]:$/, _EXTNAME_RE = /.(\.[^./]+|\.)$/, normalize = function(path) {
19
+ if (path.length === 0) return ".";
20
+ path = normalizeWindowsPath(path);
21
+ const isUNCPath = path.match(_UNC_REGEX), isPathAbsolute = isAbsolute(path), trailingSeparator = path[path.length - 1] === "/";
22
+ if (path = normalizeString(path, !isPathAbsolute), path.length === 0) return isPathAbsolute ? "/" : trailingSeparator ? "./" : ".";
23
+ if (trailingSeparator) path += "/";
24
+ if (_DRIVE_LETTER_RE.test(path)) path += "/";
25
+ return isUNCPath ? isPathAbsolute ? `//${path}` : `//./${path}` : isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
26
+ }, join = function(...segments) {
27
+ let path = "";
28
+ for (const seg of segments) {
29
+ if (!seg) continue;
30
+ if (path.length > 0) {
31
+ const pathTrailing = path[path.length - 1] === "/", segLeading = seg[0] === "/", both = pathTrailing && segLeading;
32
+ if (both) path += seg.slice(1);
33
+ else path += pathTrailing || segLeading ? seg : `/${seg}`;
34
+ } else path += seg;
35
+ }
36
+ return normalize(path);
37
+ };
38
+ function cwd$1() {
39
+ return typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd().replace(/\\/g, "/") : "/";
40
+ }
41
+ const resolve = function(...arguments_) {
42
+ arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
43
+ let resolvedPath = "", resolvedAbsolute = false;
44
+ for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
45
+ const path = index >= 0 ? arguments_[index] : cwd$1();
46
+ !path || path.length === 0 || (resolvedPath = `${path}/${resolvedPath}`, resolvedAbsolute = isAbsolute(path));
47
+ }
48
+ return resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute), resolvedAbsolute && !isAbsolute(resolvedPath) ? `/${resolvedPath}` : resolvedPath.length > 0 ? resolvedPath : ".";
49
+ };
50
+ function normalizeString(path, allowAboveRoot) {
51
+ let res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, char = null;
52
+ for (let index = 0; index <= path.length; ++index) {
53
+ if (index < path.length) char = path[index];
54
+ else if (char === "/") break;
55
+ else char = "/";
56
+ if (char === "/") {
57
+ if (lastSlash === index - 1 || dots === 1);
58
+ else if (dots === 2) {
59
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
60
+ if (res.length > 2) {
61
+ const lastSlashIndex = res.lastIndexOf("/");
62
+ if (lastSlashIndex === -1) res = "", lastSegmentLength = 0;
63
+ else res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
64
+ lastSlash = index, dots = 0;
65
+ continue;
66
+ } else if (res.length > 0) {
67
+ res = "", lastSegmentLength = 0, lastSlash = index, dots = 0;
68
+ continue;
69
+ }
70
+ }
71
+ if (allowAboveRoot) res += res.length > 0 ? "/.." : "..", lastSegmentLength = 2;
72
+ } else {
73
+ if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`;
74
+ else res = path.slice(lastSlash + 1, index);
75
+ lastSegmentLength = index - lastSlash - 1;
76
+ }
77
+ lastSlash = index, dots = 0;
78
+ } else if (char === "." && dots !== -1) ++dots;
79
+ else dots = -1;
80
+ }
81
+ return res;
82
+ }
83
+ const isAbsolute = function(p) {
84
+ return _IS_ABSOLUTE_RE.test(p);
85
+ }, extname = function(p) {
86
+ if (p === "..") return "";
87
+ const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
88
+ return match && match[1] || "";
89
+ }, dirname = function(p) {
90
+ const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
91
+ if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) segments[0] += "/";
92
+ return segments.join("/") || (isAbsolute(p) ? "/" : ".");
93
+ }, basename = function(p, extension) {
94
+ const segments = normalizeWindowsPath(p).split("/");
95
+ let lastSegment = "";
96
+ for (let i = segments.length - 1; i >= 0; i--) {
97
+ const val = segments[i];
98
+ if (val) {
99
+ lastSegment = val;
100
+ break;
101
+ }
102
+ }
103
+ return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
104
+ };
105
+
106
+ const { existsSync, readdirSync, statSync } = fs;
107
+ function findMockRedirect(root, mockPath, external) {
108
+ const path = external || mockPath;
109
+ // it's a node_module alias
110
+ // all mocks should be inside <root>/__mocks__
111
+ if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
112
+ const mockDirname = dirname(path), mockFolder = join(root, "__mocks__", mockDirname);
113
+ if (!existsSync(mockFolder)) return null;
114
+ const baseOriginal = basename(path);
115
+ function findFile(mockFolder, baseOriginal) {
116
+ const files = readdirSync(mockFolder);
117
+ for (const file of files) {
118
+ const baseFile = basename(file, extname(file));
119
+ if (baseFile === baseOriginal) {
120
+ const path = resolve(mockFolder, file);
121
+ // if the same name, return the file
122
+ if (statSync(path).isFile()) return path;
123
+ {
124
+ // find folder/index.{js,ts}
125
+ const indexFile = findFile(path, "index");
126
+ if (indexFile) return indexFile;
127
+ }
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ return findFile(mockFolder, baseOriginal);
133
+ }
134
+ const dir = dirname(path), baseId = basename(path), fullPath = resolve(dir, "__mocks__", baseId);
135
+ return existsSync(fullPath) ? fullPath : null;
136
+ }
137
+ const builtins = new Set([
138
+ ...nodeModule.builtinModules,
139
+ "assert/strict",
140
+ "diagnostics_channel",
141
+ "dns/promises",
142
+ "fs/promises",
143
+ "path/posix",
144
+ "path/win32",
145
+ "readline/promises",
146
+ "stream/consumers",
147
+ "stream/promises",
148
+ "stream/web",
149
+ "timers/promises",
150
+ "util/types",
151
+ "wasi"
152
+ ]), prefixedBuiltins$1 = new Set([
153
+ "node:sea",
154
+ "node:sqlite",
155
+ "node:test",
156
+ "node:test/reporters"
157
+ ]), NODE_BUILTIN_NAMESPACE = "node:";
158
+ function isNodeBuiltin(id) {
159
+ return nodeModule.isBuiltin ? nodeModule.isBuiltin(id) : prefixedBuiltins$1.has(id) ? true : builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(5) : id);
160
+ }
161
+
162
+ const spyModulePath = resolve$1(distDir, "spy.js");
163
+ class VitestMocker {
164
+ static pendingIds = [];
165
+ spyModule;
166
+ primitives;
167
+ filterPublicKeys;
168
+ registries = /* @__PURE__ */ new Map();
169
+ mockContext = { callstack: null };
170
+ constructor(moduleRunner, options) {
171
+ this.moduleRunner = moduleRunner, this.options = options;
172
+ const context = this.options.context;
173
+ if (context) this.primitives = vm.runInContext("({ Object, Error, Function, RegExp, Symbol, Array, Map })", context);
174
+ else this.primitives = {
175
+ Object,
176
+ Error,
177
+ Function,
178
+ RegExp,
179
+ Symbol: globalThis.Symbol,
180
+ Array,
181
+ Map
182
+ };
183
+ if (options.spyModule) this.spyModule = options.spyModule;
184
+ const Symbol = this.primitives.Symbol;
185
+ this.filterPublicKeys = [
186
+ "__esModule",
187
+ Symbol.asyncIterator,
188
+ Symbol.hasInstance,
189
+ Symbol.isConcatSpreadable,
190
+ Symbol.iterator,
191
+ Symbol.match,
192
+ Symbol.matchAll,
193
+ Symbol.replace,
194
+ Symbol.search,
195
+ Symbol.split,
196
+ Symbol.species,
197
+ Symbol.toPrimitive,
198
+ Symbol.toStringTag,
199
+ Symbol.unscopables
200
+ ];
201
+ }
202
+ get root() {
203
+ return this.options.root;
204
+ }
205
+ get evaluatedModules() {
206
+ return this.moduleRunner.evaluatedModules;
207
+ }
208
+ get moduleDirectories() {
209
+ return this.options.moduleDirectories || [];
210
+ }
211
+ async initializeSpyModule() {
212
+ this.spyModule ||= await this.moduleRunner.import(spyModulePath);
213
+ }
214
+ getMockerRegistry() {
215
+ const suite = this.getSuiteFilepath();
216
+ if (!this.registries.has(suite)) this.registries.set(suite, new MockerRegistry());
217
+ return this.registries.get(suite);
218
+ }
219
+ reset() {
220
+ this.registries.clear();
221
+ }
222
+ invalidateModuleById(id) {
223
+ const mockId = this.getMockPath(id), node = this.evaluatedModules.getModuleById(mockId);
224
+ if (node) this.evaluatedModules.invalidateModule(node), node.mockedExports = void 0;
225
+ }
226
+ isModuleDirectory(path) {
227
+ return this.moduleDirectories.some((dir) => path.includes(dir));
228
+ }
229
+ getSuiteFilepath() {
230
+ return this.options.getCurrentTestFilepath() || "global";
231
+ }
232
+ createError(message, codeFrame) {
233
+ const Error = this.primitives.Error, error = new Error(message);
234
+ return Object.assign(error, { codeFrame }), error;
235
+ }
236
+ async resolveId(rawId, importer) {
237
+ const result = await this.options.resolveId(rawId, importer);
238
+ if (!result) {
239
+ const id = normalizeModuleId(rawId);
240
+ return {
241
+ id,
242
+ url: rawId,
243
+ external: id
244
+ };
245
+ }
246
+ // external is node_module or unresolved module
247
+ // for example, some people mock "vscode" and don't have it installed
248
+ const external = !isAbsolute$1(result.file) || this.isModuleDirectory(result.file) ? normalizeModuleId(rawId) : null;
249
+ return {
250
+ ...result,
251
+ id: normalizeModuleId(result.id),
252
+ external
253
+ };
254
+ }
255
+ async resolveMocks() {
256
+ VitestMocker.pendingIds.length && (await Promise.all(VitestMocker.pendingIds.map(async (mock) => {
257
+ const { id, url, external } = await this.resolveId(mock.id, mock.importer);
258
+ if (mock.action === "unmock") this.unmockPath(id);
259
+ if (mock.action === "mock") this.mockPath(mock.id, id, url, external, mock.type, mock.factory);
260
+ })), VitestMocker.pendingIds = []);
261
+ }
262
+ ensureModule(id, url) {
263
+ const node = this.evaluatedModules.ensureModule(id, url);
264
+ return node.meta = {
265
+ id,
266
+ url,
267
+ code: "",
268
+ file: null,
269
+ invalidate: false
270
+ }, node;
271
+ }
272
+ async callFunctionMock(id, url, mock) {
273
+ const node = this.ensureModule(id, url);
274
+ if (node.exports) return node.exports;
275
+ const exports = await mock.resolve(), moduleExports = new Proxy(exports, { get: (target, prop) => {
276
+ const val = target[prop];
277
+ // 'then' can exist on non-Promise objects, need nested instanceof check for logic to work
278
+ if (prop === "then") {
279
+ if (target instanceof Promise) return target.then.bind(target);
280
+ } else if (!(prop in target)) {
281
+ if (this.filterPublicKeys.includes(prop)) return void 0;
282
+ throw this.createError(`[vitest] No "${String(prop)}" export is defined on the "${mock.raw}" mock. Did you forget to return it from "vi.mock"?
283
+ If you need to partially mock a module, you can use "importOriginal" helper inside:
284
+ `, `vi.mock(import("${mock.raw}"), async (importOriginal) => {
285
+ const actual = await importOriginal()
286
+ return {
287
+ ...actual,
288
+ // your mocked methods
289
+ }
290
+ })`);
291
+ }
292
+ return val;
293
+ } });
294
+ return node.exports = moduleExports, moduleExports;
295
+ }
296
+ // public method to avoid circular dependency
297
+ getMockContext() {
298
+ return this.mockContext;
299
+ }
300
+ // path used to store mocked dependencies
301
+ getMockPath(dep) {
302
+ return `mock:${dep}`;
303
+ }
304
+ getDependencyMock(id) {
305
+ const registry = this.getMockerRegistry();
306
+ return registry.getById(fixLeadingSlashes(id));
307
+ }
308
+ findMockRedirect(mockPath, external) {
309
+ return findMockRedirect(this.root, mockPath, external);
310
+ }
311
+ mockObject(object, mockExports = {}, behavior = "automock") {
312
+ const createMockInstance = this.spyModule?.createMockInstance;
313
+ if (!createMockInstance) throw this.createError("[vitest] `spyModule` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
314
+ return mockObject({
315
+ globalConstructors: this.primitives,
316
+ createMockInstance,
317
+ type: behavior
318
+ }, object, mockExports);
319
+ }
320
+ unmockPath(id) {
321
+ const registry = this.getMockerRegistry();
322
+ registry.deleteById(id), this.invalidateModuleById(id);
323
+ }
324
+ mockPath(originalId, id, url, external, mockType, factory) {
325
+ const registry = this.getMockerRegistry();
326
+ if (mockType === "manual") registry.register("manual", originalId, id, url, factory);
327
+ else if (mockType === "autospy") registry.register("autospy", originalId, id, url);
328
+ else {
329
+ const redirect = this.findMockRedirect(id, external);
330
+ if (redirect) registry.register("redirect", originalId, id, url, redirect);
331
+ else registry.register("automock", originalId, id, url);
332
+ }
333
+ // every time the mock is registered, we remove the previous one from the cache
334
+ this.invalidateModuleById(id);
335
+ }
336
+ async importActual(rawId, importer, callstack) {
337
+ const { url } = await this.resolveId(rawId, importer), node = await this.moduleRunner.fetchModule(url, importer), result = await this.moduleRunner.cachedRequest(node.url, node, callstack || [importer], void 0, true);
338
+ return result;
339
+ }
340
+ async importMock(rawId, importer) {
341
+ const { id, url, external } = await this.resolveId(rawId, importer);
342
+ let mock = this.getDependencyMock(id);
343
+ if (!mock) {
344
+ const redirect = this.findMockRedirect(id, external);
345
+ if (redirect) mock = new RedirectedModule(rawId, id, rawId, redirect);
346
+ else mock = new AutomockedModule(rawId, id, rawId);
347
+ }
348
+ if (mock.type === "automock" || mock.type === "autospy") {
349
+ const node = await this.moduleRunner.fetchModule(url, importer), mod = await this.moduleRunner.cachedRequest(url, node, [importer], void 0, true), Object = this.primitives.Object;
350
+ return this.mockObject(mod, Object.create(Object.prototype), mock.type);
351
+ }
352
+ if (mock.type === "manual") return this.callFunctionMock(id, url, mock);
353
+ const node = await this.moduleRunner.fetchModule(mock.redirect);
354
+ return this.moduleRunner.cachedRequest(mock.redirect, node, [importer], void 0, true);
355
+ }
356
+ async requestWithMockedModule(url, evaluatedNode, callstack, mock) {
357
+ const mockId = this.getMockPath(evaluatedNode.id);
358
+ if (mock.type === "automock" || mock.type === "autospy") {
359
+ const cache = this.evaluatedModules.getModuleById(mockId);
360
+ if (cache && cache.mockedExports) return cache.mockedExports;
361
+ const Object = this.primitives.Object, exports = Object.create(null);
362
+ Object.defineProperty(exports, Symbol.toStringTag, {
363
+ value: "Module",
364
+ configurable: true,
365
+ writable: true
366
+ });
367
+ const node = this.ensureModule(mockId, this.getMockPath(evaluatedNode.url));
368
+ node.meta = evaluatedNode.meta, node.file = evaluatedNode.file, node.mockedExports = exports;
369
+ const mod = await this.moduleRunner.cachedRequest(url, node, callstack, void 0, true);
370
+ return this.mockObject(mod, exports, mock.type), exports;
371
+ }
372
+ if (mock.type === "manual" && !callstack.includes(mockId) && !callstack.includes(url)) try {
373
+ return callstack.push(mockId), this.mockContext.callstack = callstack, await this.callFunctionMock(mockId, this.getMockPath(url), mock);
374
+ } finally {
375
+ this.mockContext.callstack = null;
376
+ const indexMock = callstack.indexOf(mockId);
377
+ callstack.splice(indexMock, 1);
378
+ }
379
+ else if (mock.type === "redirect" && !callstack.includes(mock.redirect)) return mock.redirect;
380
+ }
381
+ async mockedRequest(url, evaluatedNode, callstack) {
382
+ const mock = this.getDependencyMock(evaluatedNode.id);
383
+ if (mock) return this.requestWithMockedModule(url, evaluatedNode, callstack, mock);
384
+ }
385
+ queueMock(id, importer, factoryOrOptions) {
386
+ const mockType = getMockType(factoryOrOptions);
387
+ VitestMocker.pendingIds.push({
388
+ action: "mock",
389
+ id,
390
+ importer,
391
+ factory: typeof factoryOrOptions === "function" ? factoryOrOptions : void 0,
392
+ type: mockType
393
+ });
394
+ }
395
+ queueUnmock(id, importer) {
396
+ VitestMocker.pendingIds.push({
397
+ action: "unmock",
398
+ id,
399
+ importer
400
+ });
401
+ }
402
+ }
403
+ function getMockType(factoryOrOptions) {
404
+ return factoryOrOptions ? typeof factoryOrOptions === "function" ? "manual" : factoryOrOptions.spy ? "autospy" : "automock" : "automock";
405
+ }
406
+ // unique id that is not available as "$bare_import" like "test"
407
+ // https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix
408
+ const prefixedBuiltins = new Set([
409
+ "node:sea",
410
+ "node:sqlite",
411
+ "node:test",
412
+ "node:test/reporters"
413
+ ]), isWindows$1 = process.platform === "win32";
414
+ // transform file url to id
415
+ // virtual:custom -> virtual:custom
416
+ // \0custom -> \0custom
417
+ // /root/id -> /id
418
+ // /root/id.js -> /id.js
419
+ // C:/root/id.js -> /id.js
420
+ // C:\root\id.js -> /id.js
421
+ // TODO: expose this in vite/module-runner
422
+ function normalizeModuleId(file) {
423
+ if (prefixedBuiltins.has(file)) return file;
424
+ // unix style, but Windows path still starts with the drive letter to check the root
425
+ const unixFile = slash(file).replace(/^\/@fs\//, isWindows$1 ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/");
426
+ // if it's not in the root, keep it as a path, not a URL
427
+ return unixFile.replace(/^file:\//, "/");
428
+ }
429
+ const windowsSlashRE = /\\/g;
430
+ function slash(p) {
431
+ return p.replace(windowsSlashRE, "/");
432
+ }
433
+ const multipleSlashRe = /^\/+/;
434
+ // module-runner incorrectly replaces file:///path with `///path`
435
+ function fixLeadingSlashes(id) {
436
+ return id.startsWith("//") ? id.replace(multipleSlashRe, "/") : id;
437
+ }
438
+
439
+ class VitestTransport {
440
+ constructor(options) {
441
+ this.options = options;
442
+ }
443
+ async invoke(event) {
444
+ if (event.type !== "custom") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support Vite HMR events.`) };
445
+ if (event.event !== "vite:invoke") return { error: /* @__PURE__ */ new Error(`Vitest Module Runner doesn't support ${event.event} event.`) };
446
+ const { name, data } = event.data;
447
+ if (name !== "fetchModule") return { error: /* @__PURE__ */ new Error(`Unknown method: ${name}. Expected "fetchModule".`) };
448
+ try {
449
+ const result = await this.options.fetchModule(...data);
450
+ return { result };
451
+ } catch (error) {
452
+ return { error };
453
+ }
454
+ }
455
+ }
456
+
457
+ // eslint-disable-next-line ts/ban-ts-comment
458
+ // @ts-ignore
459
+ const createNodeImportMeta = viteModuleRunner.createNodeImportMeta;
460
+ // @ts-expect-error overriding private method
461
+ class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
462
+ mocker;
463
+ moduleExecutionInfo;
464
+ constructor(vitestOptions) {
465
+ const options = vitestOptions, transport = new VitestTransport(options.transport), evaluatedModules = options.evaluatedModules;
466
+ if (super({
467
+ transport,
468
+ hmr: false,
469
+ evaluatedModules,
470
+ sourcemapInterceptor: "prepareStackTrace",
471
+ createImportMeta: vitestOptions.createImportMeta
472
+ }, options.evaluator), this.vitestOptions = vitestOptions, this.moduleExecutionInfo = options.getWorkerState().moduleExecutionInfo, this.mocker = options.mocker || new VitestMocker(this, {
473
+ spyModule: options.spyModule,
474
+ context: options.vm?.context,
475
+ resolveId: options.transport.resolveId,
476
+ get root() {
477
+ return options.getWorkerState().config.root;
478
+ },
479
+ get moduleDirectories() {
480
+ return options.getWorkerState().config.deps.moduleDirectories || [];
481
+ },
482
+ getCurrentTestFilepath() {
483
+ return options.getWorkerState().filepath;
484
+ }
485
+ }), options.vm) options.vm.context.__vitest_mocker__ = this.mocker;
486
+ else Object.defineProperty(globalThis, "__vitest_mocker__", {
487
+ configurable: true,
488
+ writable: true,
489
+ value: this.mocker
490
+ });
491
+ }
492
+ async import(rawId) {
493
+ const resolved = await this.vitestOptions.transport.resolveId(rawId);
494
+ return resolved ? super.import(resolved.url) : super.import(rawId);
495
+ }
496
+ async fetchModule(url, importer) {
497
+ const module = await this.cachedModule(url, importer);
498
+ return module;
499
+ }
500
+ _cachedRequest(url, module, callstack = [], metadata) {
501
+ // @ts-expect-error "cachedRequest" is private
502
+ return super.cachedRequest(url, module, callstack, metadata);
503
+ }
504
+ /**
505
+ * @internal
506
+ */
507
+ async cachedRequest(url, mod, callstack = [], metadata, ignoreMock = false) {
508
+ if (ignoreMock) return this._cachedRequest(url, mod, callstack, metadata);
509
+ let mocked;
510
+ if (mod.meta && "mockedModule" in mod.meta) mocked = await this.mocker.requestWithMockedModule(url, mod, callstack, mod.meta.mockedModule);
511
+ else mocked = await this.mocker.mockedRequest(url, mod, callstack);
512
+ if (typeof mocked === "string") {
513
+ const node = await this.fetchModule(mocked);
514
+ return this._cachedRequest(mocked, node, callstack, metadata);
515
+ }
516
+ return mocked != null && typeof mocked === "object" ? mocked : this._cachedRequest(url, mod, callstack, metadata);
517
+ }
518
+ /** @internal */
519
+ _invalidateSubTreeById(ids, invalidated = /* @__PURE__ */ new Set()) {
520
+ for (const id of ids) {
521
+ if (invalidated.has(id)) continue;
522
+ const node = this.evaluatedModules.getModuleById(id);
523
+ if (!node) continue;
524
+ invalidated.add(id);
525
+ const subIds = Array.from(this.evaluatedModules.idToModuleMap).filter(([, mod]) => mod.importers.has(id)).map(([key]) => key);
526
+ if (subIds.length) this._invalidateSubTreeById(subIds, invalidated);
527
+ this.evaluatedModules.invalidateModule(node);
528
+ }
529
+ }
530
+ }
531
+
532
+ const bareVitestRegexp = /^@?vitest(?:\/|$)/, normalizedDistDir = normalize$1(distDir), relativeIds = {}, externalizeMap = /* @__PURE__ */ new Map();
533
+ // all Vitest imports always need to be externalized
534
+ function getCachedVitestImport(id, state) {
535
+ if (id.startsWith("/@fs/") || id.startsWith("\\@fs\\")) id = id.slice(process.platform === "win32" ? 5 : 4);
536
+ if (externalizeMap.has(id)) return {
537
+ externalize: externalizeMap.get(id),
538
+ type: "module"
539
+ };
540
+ // always externalize Vitest because we import from there before running tests
541
+ // so we already have it cached by Node.js
542
+ const root = state().config.root, relativeRoot = relativeIds[root] ?? (relativeIds[root] = normalizedDistDir.slice(root.length));
543
+ if (id.includes(distDir) || id.includes(normalizedDistDir)) {
544
+ const externalize = id.startsWith("file://") ? id : pathToFileURL(id).toString();
545
+ return externalizeMap.set(id, externalize), {
546
+ externalize,
547
+ type: "module"
548
+ };
549
+ }
550
+ if (relativeRoot && relativeRoot !== "/" && id.startsWith(relativeRoot)) {
551
+ const path = join$1(root, id), externalize = pathToFileURL(path).toString();
552
+ return externalizeMap.set(id, externalize), {
553
+ externalize,
554
+ type: "module"
555
+ };
556
+ }
557
+ return bareVitestRegexp.test(id) ? (externalizeMap.set(id, id), {
558
+ externalize: id,
559
+ type: "module"
560
+ }) : null;
561
+ }
562
+
563
+ const dispose = [];
564
+ function listenForErrors(state) {
565
+ dispose.forEach((fn) => fn()), dispose.length = 0;
566
+ function catchError(err, type, event) {
567
+ const worker = state(), listeners = process.listeners(event);
568
+ // if there is another listener, assume that it's handled by user code
569
+ // one is Vitest's own listener
570
+ if (listeners.length > 1) return;
571
+ const error = serializeValue(err);
572
+ if (typeof error === "object" && error != null) {
573
+ if (error.VITEST_TEST_NAME = worker.current?.type === "test" ? worker.current.name : void 0, worker.filepath) error.VITEST_TEST_PATH = worker.filepath;
574
+ error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun;
575
+ }
576
+ state().rpc.onUnhandledError(error, type);
577
+ }
578
+ const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException"), unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
579
+ process.on("uncaughtException", uncaughtException), process.on("unhandledRejection", unhandledRejection), dispose.push(() => {
580
+ process.off("uncaughtException", uncaughtException), process.off("unhandledRejection", unhandledRejection);
581
+ });
582
+ }
583
+
584
+ const { readFileSync } = fs, browserExternalId = "__vite-browser-external", browserExternalLength = 24;
585
+ const VITEST_VM_CONTEXT_SYMBOL = "__vitest_vm_context__";
586
+ const cwd = process.cwd(), isWindows = process.platform === "win32";
587
+ function startVitestModuleRunner(options) {
588
+ const state = () => globalThis.__vitest_worker__ || options.state, rpc = () => state().rpc;
589
+ process.exit = (code = process.exitCode || 0) => {
590
+ throw new Error(`process.exit unexpectedly called with "${code}"`);
591
+ }, listenForErrors(state);
592
+ const environment = () => {
593
+ const environment = state().environment;
594
+ return environment.viteEnvironment || environment.name;
595
+ }, vm = options.context && options.externalModulesExecutor ? {
596
+ context: options.context,
597
+ externalModulesExecutor: options.externalModulesExecutor
598
+ } : void 0, evaluator = options.evaluator || new VitestModuleEvaluator(vm, {
599
+ get moduleExecutionInfo() {
600
+ return state().moduleExecutionInfo;
601
+ },
602
+ get interopDefault() {
603
+ return state().config.deps.interopDefault;
604
+ },
605
+ getCurrentTestFilepath: () => state().filepath
606
+ }), moduleRunner = new VitestModuleRunner({
607
+ spyModule: options.spyModule,
608
+ evaluatedModules: options.evaluatedModules,
609
+ evaluator,
610
+ mocker: options.mocker,
611
+ transport: {
612
+ async fetchModule(id, importer, options) {
613
+ const resolvingModules = state().resolvingModules;
614
+ if (isWindows) {
615
+ if (id[1] === ":") {
616
+ // The drive letter is different for whatever reason, we need to normalize it to CWD
617
+ if (id[0] !== cwd[0] && id[0].toUpperCase() === cwd[0].toUpperCase()) {
618
+ const isUpperCase = cwd[0].toUpperCase() === cwd[0];
619
+ id = (isUpperCase ? id[0].toUpperCase() : id[0].toLowerCase()) + id.slice(1);
620
+ }
621
+ // always mark absolute windows paths, otherwise Vite will externalize it
622
+ id = `/@id/${id}`;
623
+ }
624
+ }
625
+ const vitest = getCachedVitestImport(id, state);
626
+ if (vitest) return vitest;
627
+ const rawId = unwrapId(id);
628
+ resolvingModules.add(rawId);
629
+ try {
630
+ if (VitestMocker.pendingIds.length) await moduleRunner.mocker.resolveMocks();
631
+ const resolvedMock = moduleRunner.mocker.getDependencyMock(rawId);
632
+ if (resolvedMock?.type === "manual" || resolvedMock?.type === "redirect") return {
633
+ code: "",
634
+ file: null,
635
+ id,
636
+ url: id,
637
+ invalidate: false,
638
+ mockedModule: resolvedMock
639
+ };
640
+ if (isBuiltin(rawId) || rawId.startsWith(browserExternalId)) return {
641
+ externalize: toBuiltin(rawId),
642
+ type: "builtin"
643
+ };
644
+ const result = await rpc().fetch(id, importer, environment(), options);
645
+ if ("cached" in result) {
646
+ const code = readFileSync(result.tmp, "utf-8");
647
+ return {
648
+ code,
649
+ ...result
650
+ };
651
+ }
652
+ return result;
653
+ } catch (cause) {
654
+ // rethrow vite error if it cannot load the module because it's not resolved
655
+ if (typeof cause === "object" && cause != null && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url") || typeof cause?.message === "string" && cause.message.startsWith("Cannot find module '")) {
656
+ const error = new Error(`Cannot find ${isBareImport(id) ? "package" : "module"} '${id}'${importer ? ` imported from '${importer}'` : ""}`, { cause });
657
+ throw error.code = "ERR_MODULE_NOT_FOUND", error;
658
+ }
659
+ throw cause;
660
+ } finally {
661
+ resolvingModules.delete(rawId);
662
+ }
663
+ },
664
+ resolveId(id, importer) {
665
+ return rpc().resolve(id, importer, environment());
666
+ }
667
+ },
668
+ getWorkerState: state,
669
+ vm,
670
+ createImportMeta: options.createImportMeta
671
+ });
672
+ // await moduleRunner.import('/@vite/env')
673
+ // await moduleRunner.mocker.initializeSpyModule()
674
+ return moduleRunner;
675
+ }
676
+ function toBuiltin(id) {
677
+ if (id.startsWith(browserExternalId)) id = id.slice(browserExternalLength);
678
+ if (!id.startsWith("node:")) id = `node:${id}`;
679
+ return id;
680
+ }
681
+
682
+ export { VitestModuleRunner as V, VITEST_VM_CONTEXT_SYMBOL as a, VitestTransport as b, createNodeImportMeta as c, startVitestModuleRunner as s };
@@ -1,5 +1,5 @@
1
1
  import { Test } from '@vitest/runner';
2
- import { c as BenchmarkAPI, a as BenchFunction } from './benchmark.d.BwvBVTda.js';
2
+ import { c as BenchmarkAPI, a as BenchFunction } from './benchmark.d.DAaHLpsq.js';
3
3
  import { Options } from 'tinybench';
4
4
  import '@vitest/runner/utils';
5
5