@vitest/browser 2.1.0-beta.6 → 2.1.0

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.
@@ -1,16 +1,496 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { a as getConfig, e as executor, i as importId, b as extname, g as getBrowserState, _ as __vitePreload, j as join, c as getWorkerState } from "./preload-helper-YsBSwBkS.js";
4
+ import { M as MockerRegistry, R as RedirectedModule, A as AutomockedModule, _ as __vitePreload, b as getConfig, e as executor, g as getBrowserState, c as getWorkerState } from "./preload-helper-D-WYp1PK.js";
5
5
  import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker, setupCommonEnv, startCoverageInsideWorker, startTests, collectTests, stopCoverageInsideWorker, SpyModule } from "vitest/browser";
6
6
  import { page } from "@vitest/browser/context";
7
- import { globalChannel, channel, waitForChannel, client, onCancel } from "@vitest/browser/client";
7
+ import { globalChannel, channel, client, onCancel, waitForChannel } from "@vitest/browser/client";
8
8
  import { getSafeTimers, stringify, format, TraceMap, originalPositionFor } from "vitest/utils";
9
9
  import { VitestTestRunner, NodeBenchmarkRunner } from "vitest/runners";
10
10
  import { expect } from "vitest";
11
+ function mockObject(options, object, mockExports = {}) {
12
+ const finalizers = new Array();
13
+ const refs = new RefTracker();
14
+ const define = (container, key, value) => {
15
+ try {
16
+ container[key] = value;
17
+ return true;
18
+ } catch {
19
+ return false;
20
+ }
21
+ };
22
+ const mockPropertiesOf = (container, newContainer) => {
23
+ const containerType = getType(container);
24
+ const isModule = containerType === "Module" || !!container.__esModule;
25
+ for (const { key: property, descriptor } of getAllMockableProperties(
26
+ container,
27
+ isModule,
28
+ options.globalConstructors
29
+ )) {
30
+ if (!isModule && descriptor.get) {
31
+ try {
32
+ Object.defineProperty(newContainer, property, descriptor);
33
+ } catch {
34
+ }
35
+ continue;
36
+ }
37
+ if (isSpecialProp(property, containerType)) {
38
+ continue;
39
+ }
40
+ const value = container[property];
41
+ const refId = refs.getId(value);
42
+ if (refId !== void 0) {
43
+ finalizers.push(
44
+ () => define(newContainer, property, refs.getMockedValue(refId))
45
+ );
46
+ continue;
47
+ }
48
+ const type = getType(value);
49
+ if (Array.isArray(value)) {
50
+ define(newContainer, property, []);
51
+ continue;
52
+ }
53
+ const isFunction2 = type.includes("Function") && typeof value === "function";
54
+ if ((!isFunction2 || value.__isMockFunction) && type !== "Object" && type !== "Module") {
55
+ define(newContainer, property, value);
56
+ continue;
57
+ }
58
+ if (!define(newContainer, property, isFunction2 ? value : {})) {
59
+ continue;
60
+ }
61
+ if (isFunction2) {
62
+ let mockFunction2 = function() {
63
+ if (this instanceof newContainer[property]) {
64
+ for (const { key, descriptor: descriptor2 } of getAllMockableProperties(
65
+ this,
66
+ false,
67
+ options.globalConstructors
68
+ )) {
69
+ if (descriptor2.get) {
70
+ continue;
71
+ }
72
+ const value2 = this[key];
73
+ const type2 = getType(value2);
74
+ const isFunction22 = type2.includes("Function") && typeof value2 === "function";
75
+ if (isFunction22) {
76
+ const original = this[key];
77
+ const mock2 = spyOn(this, key).mockImplementation(original);
78
+ mock2.mockRestore = () => {
79
+ mock2.mockReset();
80
+ mock2.mockImplementation(original);
81
+ return mock2;
82
+ };
83
+ }
84
+ }
85
+ }
86
+ };
87
+ if (!options.spyOn) {
88
+ throw new Error(
89
+ "[@vitest/mocker] `spyOn` is not defined. This is a Vitest error. Please open a new issue with reproduction."
90
+ );
91
+ }
92
+ const spyOn = options.spyOn;
93
+ const mock = spyOn(newContainer, property);
94
+ if (options.type === "automock") {
95
+ mock.mockImplementation(mockFunction2);
96
+ mock.mockRestore = () => {
97
+ mock.mockReset();
98
+ mock.mockImplementation(mockFunction2);
99
+ return mock;
100
+ };
101
+ }
102
+ Object.defineProperty(newContainer[property], "length", { value: 0 });
103
+ }
104
+ refs.track(value, newContainer[property]);
105
+ mockPropertiesOf(value, newContainer[property]);
106
+ }
107
+ };
108
+ const mockedObject = mockExports;
109
+ mockPropertiesOf(object, mockedObject);
110
+ for (const finalizer of finalizers) {
111
+ finalizer();
112
+ }
113
+ return mockedObject;
114
+ }
115
+ class RefTracker {
116
+ constructor() {
117
+ __publicField(this, "idMap", /* @__PURE__ */ new Map());
118
+ __publicField(this, "mockedValueMap", /* @__PURE__ */ new Map());
119
+ }
120
+ getId(value) {
121
+ return this.idMap.get(value);
122
+ }
123
+ getMockedValue(id) {
124
+ return this.mockedValueMap.get(id);
125
+ }
126
+ track(originalValue, mockedValue) {
127
+ const newId = this.idMap.size;
128
+ this.idMap.set(originalValue, newId);
129
+ this.mockedValueMap.set(newId, mockedValue);
130
+ return newId;
131
+ }
132
+ }
11
133
  function getType(value) {
12
134
  return Object.prototype.toString.apply(value).slice(8, -1);
13
135
  }
136
+ function isSpecialProp(prop, parentType) {
137
+ return parentType.includes("Function") && typeof prop === "string" && ["arguments", "callee", "caller", "length", "name"].includes(prop);
138
+ }
139
+ function getAllMockableProperties(obj, isModule, constructors) {
140
+ const { Map: Map2, Object: Object2, Function: Function2, RegExp: RegExp2, Array: Array2 } = constructors;
141
+ const allProps = new Map2();
142
+ let curr = obj;
143
+ do {
144
+ if (curr === Object2.prototype || curr === Function2.prototype || curr === RegExp2.prototype) {
145
+ break;
146
+ }
147
+ collectOwnProperties(curr, (key) => {
148
+ const descriptor = Object2.getOwnPropertyDescriptor(curr, key);
149
+ if (descriptor) {
150
+ allProps.set(key, { key, descriptor });
151
+ }
152
+ });
153
+ } while (curr = Object2.getPrototypeOf(curr));
154
+ if (isModule && !allProps.has("default") && "default" in obj) {
155
+ const descriptor = Object2.getOwnPropertyDescriptor(obj, "default");
156
+ if (descriptor) {
157
+ allProps.set("default", { key: "default", descriptor });
158
+ }
159
+ }
160
+ return Array2.from(allProps.values());
161
+ }
162
+ function collectOwnProperties(obj, collector) {
163
+ const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
164
+ Object.getOwnPropertyNames(obj).forEach(collect);
165
+ Object.getOwnPropertySymbols(obj).forEach(collect);
166
+ }
167
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
168
+ function normalizeWindowsPath(input = "") {
169
+ if (!input) {
170
+ return input;
171
+ }
172
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
173
+ }
174
+ const _UNC_REGEX = /^[/\\]{2}/;
175
+ const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
176
+ const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
177
+ const normalize$1 = function(path) {
178
+ if (path.length === 0) {
179
+ return ".";
180
+ }
181
+ path = normalizeWindowsPath(path);
182
+ const isUNCPath = path.match(_UNC_REGEX);
183
+ const isPathAbsolute = isAbsolute(path);
184
+ const trailingSeparator = path[path.length - 1] === "/";
185
+ path = normalizeString(path, !isPathAbsolute);
186
+ if (path.length === 0) {
187
+ if (isPathAbsolute) {
188
+ return "/";
189
+ }
190
+ return trailingSeparator ? "./" : ".";
191
+ }
192
+ if (trailingSeparator) {
193
+ path += "/";
194
+ }
195
+ if (_DRIVE_LETTER_RE.test(path)) {
196
+ path += "/";
197
+ }
198
+ if (isUNCPath) {
199
+ if (!isPathAbsolute) {
200
+ return `//./${path}`;
201
+ }
202
+ return `//${path}`;
203
+ }
204
+ return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
205
+ };
206
+ const join = function(...arguments_) {
207
+ if (arguments_.length === 0) {
208
+ return ".";
209
+ }
210
+ let joined;
211
+ for (const argument of arguments_) {
212
+ if (argument && argument.length > 0) {
213
+ if (joined === void 0) {
214
+ joined = argument;
215
+ } else {
216
+ joined += `/${argument}`;
217
+ }
218
+ }
219
+ }
220
+ if (joined === void 0) {
221
+ return ".";
222
+ }
223
+ return normalize$1(joined.replace(/\/\/+/g, "/"));
224
+ };
225
+ function normalizeString(path, allowAboveRoot) {
226
+ let res = "";
227
+ let lastSegmentLength = 0;
228
+ let lastSlash = -1;
229
+ let dots = 0;
230
+ let char = null;
231
+ for (let index = 0; index <= path.length; ++index) {
232
+ if (index < path.length) {
233
+ char = path[index];
234
+ } else if (char === "/") {
235
+ break;
236
+ } else {
237
+ char = "/";
238
+ }
239
+ if (char === "/") {
240
+ if (lastSlash === index - 1 || dots === 1) ;
241
+ else if (dots === 2) {
242
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
243
+ if (res.length > 2) {
244
+ const lastSlashIndex = res.lastIndexOf("/");
245
+ if (lastSlashIndex === -1) {
246
+ res = "";
247
+ lastSegmentLength = 0;
248
+ } else {
249
+ res = res.slice(0, lastSlashIndex);
250
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
251
+ }
252
+ lastSlash = index;
253
+ dots = 0;
254
+ continue;
255
+ } else if (res.length > 0) {
256
+ res = "";
257
+ lastSegmentLength = 0;
258
+ lastSlash = index;
259
+ dots = 0;
260
+ continue;
261
+ }
262
+ }
263
+ if (allowAboveRoot) {
264
+ res += res.length > 0 ? "/.." : "..";
265
+ lastSegmentLength = 2;
266
+ }
267
+ } else {
268
+ if (res.length > 0) {
269
+ res += `/${path.slice(lastSlash + 1, index)}`;
270
+ } else {
271
+ res = path.slice(lastSlash + 1, index);
272
+ }
273
+ lastSegmentLength = index - lastSlash - 1;
274
+ }
275
+ lastSlash = index;
276
+ dots = 0;
277
+ } else if (char === "." && dots !== -1) {
278
+ ++dots;
279
+ } else {
280
+ dots = -1;
281
+ }
282
+ }
283
+ return res;
284
+ }
285
+ const isAbsolute = function(p) {
286
+ return _IS_ABSOLUTE_RE.test(p);
287
+ };
288
+ const _EXTNAME_RE = /.(\.[^./]+)$/;
289
+ const extname = function(p) {
290
+ const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
291
+ return match && match[1] || "";
292
+ };
293
+ const { now } = Date;
294
+ class ModuleMocker {
295
+ constructor(interceptor, rpc2, spyOn, config) {
296
+ __publicField(this, "registry", new MockerRegistry());
297
+ __publicField(this, "queue", /* @__PURE__ */ new Set());
298
+ __publicField(this, "mockedIds", /* @__PURE__ */ new Set());
299
+ this.interceptor = interceptor;
300
+ this.rpc = rpc2;
301
+ this.spyOn = spyOn;
302
+ this.config = config;
303
+ }
304
+ async prepare() {
305
+ if (!this.queue.size) {
306
+ return;
307
+ }
308
+ await Promise.all([...this.queue.values()]);
309
+ }
310
+ async resolveFactoryModule(id) {
311
+ const mock = this.registry.get(id);
312
+ if (!mock || mock.type !== "manual") {
313
+ throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`);
314
+ }
315
+ const result = await mock.resolve();
316
+ return result;
317
+ }
318
+ getFactoryModule(id) {
319
+ const mock = this.registry.get(id);
320
+ if (!mock || mock.type !== "manual") {
321
+ throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`);
322
+ }
323
+ if (!mock.cache) {
324
+ throw new Error(`Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.`);
325
+ }
326
+ return mock.cache;
327
+ }
328
+ async invalidate() {
329
+ const ids = Array.from(this.mockedIds);
330
+ if (!ids.length) {
331
+ return;
332
+ }
333
+ await this.rpc.invalidate(ids);
334
+ this.interceptor.invalidate();
335
+ this.registry.clear();
336
+ }
337
+ async importActual(id, importer) {
338
+ const resolved = await this.rpc.resolveId(id, importer);
339
+ if (resolved == null) {
340
+ throw new Error(
341
+ `[vitest] Cannot resolve ${id} imported from ${importer}`
342
+ );
343
+ }
344
+ const ext = extname(resolved.id);
345
+ const url2 = new URL(resolved.url, location.href);
346
+ const query = `_vitest_original&ext${ext}`;
347
+ const actualUrl = `${url2.pathname}${url2.search ? `${url2.search}&${query}` : `?${query}`}${url2.hash}`;
348
+ return this.wrapDynamicImport(() => import(
349
+ /* @vite-ignore */
350
+ actualUrl
351
+ )).then((mod) => {
352
+ if (!resolved.optimized || typeof mod.default === "undefined") {
353
+ return mod;
354
+ }
355
+ const m = mod.default;
356
+ return (m == null ? void 0 : m.__esModule) ? m : { ...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {}, default: m };
357
+ });
358
+ }
359
+ async importMock(rawId, importer) {
360
+ await this.prepare();
361
+ const { resolvedId, redirectUrl } = await this.rpc.resolveMock(
362
+ rawId,
363
+ importer,
364
+ { mock: "auto" }
365
+ );
366
+ const mockUrl = this.resolveMockPath(cleanVersion(resolvedId));
367
+ let mock = this.registry.get(mockUrl);
368
+ if (!mock) {
369
+ if (redirectUrl) {
370
+ const resolvedRedirect = new URL(this.resolveMockPath(cleanVersion(redirectUrl)), location.href).toString();
371
+ mock = new RedirectedModule(rawId, mockUrl, resolvedRedirect);
372
+ } else {
373
+ mock = new AutomockedModule(rawId, mockUrl);
374
+ }
375
+ }
376
+ if (mock.type === "manual") {
377
+ return await mock.resolve();
378
+ }
379
+ if (mock.type === "automock" || mock.type === "autospy") {
380
+ const url2 = new URL(`/@id/${resolvedId}`, location.href);
381
+ const query = url2.search ? `${url2.search}&t=${now()}` : `?t=${now()}`;
382
+ const moduleObject = await __vitePreload(() => import(
383
+ /* @vite-ignore */
384
+ `${url2.pathname}${query}&mock=${mock.type}${url2.hash}`
385
+ ), true ? [] : void 0);
386
+ return this.mockObject(moduleObject, mock.type);
387
+ }
388
+ return import(
389
+ /* @vite-ignore */
390
+ mock.redirect
391
+ );
392
+ }
393
+ mockObject(object, moduleType = "automock") {
394
+ return mockObject({
395
+ globalConstructors: {
396
+ Object,
397
+ Function,
398
+ Array,
399
+ Map,
400
+ RegExp
401
+ },
402
+ spyOn: this.spyOn,
403
+ type: moduleType
404
+ }, object);
405
+ }
406
+ queueMock(rawId, importer, factoryOrOptions) {
407
+ const promise = this.rpc.resolveMock(rawId, importer, {
408
+ mock: typeof factoryOrOptions === "function" ? "factory" : (factoryOrOptions == null ? void 0 : factoryOrOptions.spy) ? "spy" : "auto"
409
+ }).then(async ({ redirectUrl, resolvedId, needsInterop, mockType }) => {
410
+ const mockUrl = this.resolveMockPath(cleanVersion(resolvedId));
411
+ this.mockedIds.add(resolvedId);
412
+ const factory = typeof factoryOrOptions === "function" ? async () => {
413
+ const data = await factoryOrOptions();
414
+ return needsInterop ? { default: data } : data;
415
+ } : void 0;
416
+ const mockRedirect = typeof redirectUrl === "string" ? new URL(this.resolveMockPath(cleanVersion(redirectUrl)), location.href).toString() : null;
417
+ let module;
418
+ if (mockType === "manual") {
419
+ module = this.registry.register("manual", rawId, mockUrl, factory);
420
+ } else if (mockType === "autospy") {
421
+ module = this.registry.register("autospy", rawId, mockUrl);
422
+ } else if (mockType === "redirect") {
423
+ module = this.registry.register("redirect", rawId, mockUrl, mockRedirect);
424
+ } else {
425
+ module = this.registry.register("automock", rawId, mockUrl);
426
+ }
427
+ await this.interceptor.register(module);
428
+ }).finally(() => {
429
+ this.queue.delete(promise);
430
+ });
431
+ this.queue.add(promise);
432
+ }
433
+ queueUnmock(id, importer) {
434
+ const promise = this.rpc.resolveId(id, importer).then(async (resolved) => {
435
+ if (!resolved) {
436
+ return;
437
+ }
438
+ const mockUrl = this.resolveMockPath(cleanVersion(resolved.id));
439
+ this.mockedIds.add(resolved.id);
440
+ this.registry.delete(mockUrl);
441
+ await this.interceptor.delete(mockUrl);
442
+ }).finally(() => {
443
+ this.queue.delete(promise);
444
+ });
445
+ this.queue.add(promise);
446
+ }
447
+ // We need to await mock registration before importing the actual module
448
+ // In case there is a mocked module in the import chain
449
+ wrapDynamicImport(moduleFactory) {
450
+ if (typeof moduleFactory === "function") {
451
+ const promise = new Promise((resolve, reject) => {
452
+ this.prepare().finally(() => {
453
+ moduleFactory().then(resolve, reject);
454
+ });
455
+ });
456
+ return promise;
457
+ }
458
+ return moduleFactory;
459
+ }
460
+ resolveMockPath(path) {
461
+ const config = this.config;
462
+ const fsRoot = join("/@fs/", config.root);
463
+ if (path.startsWith(config.root)) {
464
+ return path.slice(config.root.length);
465
+ }
466
+ if (path.startsWith(fsRoot)) {
467
+ return path.slice(fsRoot.length);
468
+ }
469
+ return path;
470
+ }
471
+ }
472
+ const versionRegexp = /(\?|&)v=\w{8}/;
473
+ function cleanVersion(url2) {
474
+ return url2.replace(versionRegexp, "");
475
+ }
476
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
477
+ const intToChar = new Uint8Array(64);
478
+ const charToInt = new Uint8Array(128);
479
+ for (let i = 0; i < chars.length; i++) {
480
+ const c = chars.charCodeAt(i);
481
+ intToChar[i] = c;
482
+ charToInt[c] = i;
483
+ }
484
+ var UrlType;
485
+ (function(UrlType2) {
486
+ UrlType2[UrlType2["Empty"] = 1] = "Empty";
487
+ UrlType2[UrlType2["Hash"] = 2] = "Hash";
488
+ UrlType2[UrlType2["Query"] = 3] = "Query";
489
+ UrlType2[UrlType2["RelativePath"] = 4] = "RelativePath";
490
+ UrlType2[UrlType2["AbsolutePath"] = 5] = "AbsolutePath";
491
+ UrlType2[UrlType2["SchemeRelative"] = 6] = "SchemeRelative";
492
+ UrlType2[UrlType2["Absolute"] = 7] = "Absolute";
493
+ })(UrlType || (UrlType = {}));
14
494
  function showPopupWarning(name, value, defaultValue) {
15
495
  return (...params) => {
16
496
  const formatedParams = params.map((p) => JSON.stringify(p)).join(", ");
@@ -95,42 +575,6 @@ function setupConsoleLogSpy() {
95
575
  count,
96
576
  countReset
97
577
  } = console$1;
98
- const formatInput = (input) => {
99
- if (typeof input === "object") {
100
- return stringify(input, void 0, {
101
- printBasicPrototype: false,
102
- escapeString: false
103
- });
104
- }
105
- return format(input);
106
- };
107
- const processLog = (args) => args.map(formatInput).join(" ");
108
- const sendLog = (type, content, disableStack) => {
109
- var _a, _b, _c;
110
- if (content.startsWith("[vite]")) {
111
- return;
112
- }
113
- const unknownTestId = "__vitest__unknown_test__";
114
- const taskId = ((_b = (_a = globalThis.__vitest_worker__) == null ? void 0 : _a.current) == null ? void 0 : _b.id) ?? unknownTestId;
115
- const origin = getConfig().printConsoleTrace && !disableStack ? (_c = new Error("STACK_TRACE").stack) == null ? void 0 : _c.split("\n").slice(1).join("\n") : void 0;
116
- rpc$1().sendLog({
117
- origin,
118
- content,
119
- browser: true,
120
- time: Date$1.now(),
121
- taskId,
122
- type,
123
- size: content.length
124
- });
125
- };
126
- const stdout = (base) => (...args) => {
127
- base(...args);
128
- sendLog("stdout", processLog(args));
129
- };
130
- const stderr = (base) => (...args) => {
131
- base(...args);
132
- sendLog("stderr", processLog(args));
133
- };
134
578
  console$1.log = stdout(log);
135
579
  console$1.debug = stdout(debug2);
136
580
  console$1.info = stdout(info);
@@ -190,6 +634,48 @@ ${stack}`, true);
190
634
  countLabels[label] = 0;
191
635
  };
192
636
  }
637
+ function stdout(base) {
638
+ return (...args) => {
639
+ base(...args);
640
+ sendLog("stdout", processLog(args));
641
+ };
642
+ }
643
+ function stderr(base) {
644
+ return (...args) => {
645
+ base(...args);
646
+ sendLog("stderr", processLog(args));
647
+ };
648
+ }
649
+ function formatInput(input) {
650
+ if (typeof input === "object") {
651
+ return stringify(input, void 0, {
652
+ printBasicPrototype: false,
653
+ escapeString: false
654
+ });
655
+ }
656
+ return format(input);
657
+ }
658
+ function processLog(args) {
659
+ return args.map(formatInput).join(" ");
660
+ }
661
+ function sendLog(type, content, disableStack) {
662
+ var _a, _b, _c;
663
+ if (content.startsWith("[vite]")) {
664
+ return;
665
+ }
666
+ const unknownTestId = "__vitest__unknown_test__";
667
+ const taskId = ((_b = (_a = globalThis.__vitest_worker__) == null ? void 0 : _a.current) == null ? void 0 : _b.id) ?? unknownTestId;
668
+ const origin = getConfig().printConsoleTrace && !disableStack ? (_c = new Error("STACK_TRACE").stack) == null ? void 0 : _c.split("\n").slice(1).join("\n") : void 0;
669
+ rpc$1().sendLog({
670
+ origin,
671
+ content,
672
+ browser: true,
673
+ time: Date$1.now(),
674
+ taskId,
675
+ type,
676
+ size: content.length
677
+ });
678
+ }
193
679
  class VitestBrowserSnapshotEnvironment {
194
680
  constructor() {
195
681
  __publicField(this, "sourceMaps", /* @__PURE__ */ new Map());
@@ -383,354 +869,40 @@ async function updateFilesLocations(files, sourceMaps) {
383
869
  });
384
870
  await Promise.all(promises2);
385
871
  }
386
- const now = Date.now;
387
- class VitestBrowserClientMocker {
388
- constructor() {
389
- __publicField(this, "queue", /* @__PURE__ */ new Set());
390
- __publicField(this, "mocks", {});
391
- __publicField(this, "mockObjects", {});
392
- __publicField(this, "factories", {});
393
- __publicField(this, "ids", /* @__PURE__ */ new Set());
394
- __publicField(this, "spyModule");
395
- }
872
+ class VitestBrowserClientMocker extends ModuleMocker {
396
873
  setupWorker() {
397
874
  channel.addEventListener(
398
875
  "message",
399
876
  async (e) => {
400
877
  if (e.data.type === "mock-factory:request") {
401
878
  try {
402
- const module = await this.resolve(e.data.id);
879
+ const module = await this.resolveFactoryModule(e.data.id);
403
880
  const exports = Object.keys(module);
404
881
  channel.postMessage({
405
882
  type: "mock-factory:response",
406
883
  exports
407
884
  });
408
885
  } catch (err) {
409
- const { processError } = await importId(
410
- "vitest/browser"
411
- );
412
886
  channel.postMessage({
413
887
  type: "mock-factory:error",
414
- error: processError(err)
888
+ error: {
889
+ name: err.name,
890
+ message: err.message,
891
+ stack: err.stack
892
+ }
415
893
  });
416
894
  }
417
895
  }
418
896
  }
419
897
  );
420
898
  }
421
- setSpyModule(mod) {
422
- this.spyModule = mod;
423
- }
424
- async importActual(id, importer) {
425
- const resolved = await rpc$1().resolveId(id, importer);
426
- if (resolved == null) {
427
- throw new Error(
428
- `[vitest] Cannot resolve ${id} imported from ${importer}`
429
- );
430
- }
431
- const ext = extname(resolved.id);
432
- const url2 = new URL(resolved.url, location.href);
433
- const query = `_vitest_original&ext${ext}`;
434
- const actualUrl = `${url2.pathname}${url2.search ? `${url2.search}&${query}` : `?${query}`}${url2.hash}`;
435
- return getBrowserState().wrapModule(() => import(
436
- /* @vite-ignore */
437
- actualUrl
438
- )).then((mod) => {
439
- if (!resolved.optimized || typeof mod.default === "undefined") {
440
- return mod;
441
- }
442
- const m = mod.default;
443
- return (m == null ? void 0 : m.__esModule) ? m : { ...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {}, default: m };
444
- });
445
- }
446
- async importMock(rawId, importer) {
447
- await this.prepare();
448
- const { resolvedId, type, mockPath } = await rpc$1().resolveMock(
449
- rawId,
450
- importer,
451
- false
452
- );
453
- const factoryReturn = this.get(resolvedId);
454
- if (factoryReturn) {
455
- return factoryReturn;
456
- }
457
- if (this.factories[resolvedId]) {
458
- return await this.resolve(resolvedId);
459
- }
460
- if (type === "redirect") {
461
- const url22 = new URL(`/@id/${mockPath}`, location.href);
462
- return import(
463
- /* @vite-ignore */
464
- url22.toString()
465
- );
466
- }
467
- const url2 = new URL(`/@id/${resolvedId}`, location.href);
468
- const query = url2.search ? `${url2.search}&t=${now()}` : `?t=${now()}`;
469
- const moduleObject = await __vitePreload(() => import(
470
- /* @vite-ignore */
471
- `${url2.pathname}${query}${url2.hash}`
472
- ), true ? [] : void 0);
473
- return this.mockObject(moduleObject);
474
- }
899
+ // default "vi" utility tries to access mock context to avoid circular dependencies
475
900
  getMockContext() {
476
901
  return { callstack: null };
477
902
  }
478
- get(id) {
479
- return this.mockObjects[id];
903
+ wrapDynamicImport(moduleFactory) {
904
+ return getBrowserState().wrapModule(moduleFactory);
480
905
  }
481
- async invalidate() {
482
- const ids = Array.from(this.ids);
483
- if (!ids.length) {
484
- return;
485
- }
486
- await rpc$1().invalidate(ids);
487
- channel.postMessage({ type: "mock:invalidate" });
488
- this.ids.clear();
489
- this.mocks = {};
490
- this.mockObjects = {};
491
- this.factories = {};
492
- }
493
- async resolve(id) {
494
- const factory = this.factories[id];
495
- if (!factory) {
496
- throw new Error(`Cannot resolve ${id} mock: no factory provided`);
497
- }
498
- try {
499
- this.mockObjects[id] = await factory();
500
- return this.mockObjects[id];
501
- } catch (err) {
502
- const vitestError = new Error(
503
- '[vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock'
504
- );
505
- vitestError.cause = err;
506
- throw vitestError;
507
- }
508
- }
509
- queueMock(id, importer, factory) {
510
- const promise = rpc$1().resolveMock(id, importer, !!factory).then(async ({ mockPath, resolvedId, needsInterop }) => {
511
- this.ids.add(resolvedId);
512
- const urlPaths = resolveMockPaths(cleanVersion(resolvedId));
513
- const resolvedMock = typeof mockPath === "string" ? new URL(resolvedMockedPath(cleanVersion(mockPath)), location.href).toString() : mockPath;
514
- const _factory = factory && needsInterop ? async () => {
515
- const data = await factory();
516
- return { default: data };
517
- } : factory;
518
- urlPaths.forEach((url2) => {
519
- this.mocks[url2] = resolvedMock;
520
- if (_factory) {
521
- this.factories[url2] = _factory;
522
- }
523
- });
524
- channel.postMessage({
525
- type: "mock",
526
- paths: urlPaths,
527
- mock: resolvedMock
528
- });
529
- await waitForChannel("mock:done");
530
- }).finally(() => {
531
- this.queue.delete(promise);
532
- });
533
- this.queue.add(promise);
534
- }
535
- queueUnmock(id, importer) {
536
- const promise = rpc$1().resolveId(id, importer).then(async (resolved) => {
537
- if (!resolved) {
538
- return;
539
- }
540
- this.ids.delete(resolved.id);
541
- const urlPaths = resolveMockPaths(cleanVersion(resolved.id));
542
- urlPaths.forEach((url2) => {
543
- delete this.mocks[url2];
544
- delete this.factories[url2];
545
- delete this.mockObjects[url2];
546
- });
547
- channel.postMessage({
548
- type: "unmock",
549
- paths: urlPaths
550
- });
551
- await waitForChannel("unmock:done");
552
- }).finally(() => {
553
- this.queue.delete(promise);
554
- });
555
- this.queue.add(promise);
556
- }
557
- async prepare() {
558
- if (!this.queue.size) {
559
- return;
560
- }
561
- await Promise.all([...this.queue.values()]);
562
- }
563
- // TODO: move this logic into a util(?)
564
- mockObject(object, mockExports = {}) {
565
- const finalizers = new Array();
566
- const refs = new RefTracker();
567
- const define = (container, key, value) => {
568
- try {
569
- container[key] = value;
570
- return true;
571
- } catch {
572
- return false;
573
- }
574
- };
575
- const mockPropertiesOf = (container, newContainer) => {
576
- const containerType = /* @__PURE__ */ getType(container);
577
- const isModule = containerType === "Module" || !!container.__esModule;
578
- for (const { key: property, descriptor } of getAllMockableProperties(
579
- container,
580
- isModule
581
- )) {
582
- if (!isModule && descriptor.get) {
583
- try {
584
- Object.defineProperty(newContainer, property, descriptor);
585
- } catch {
586
- }
587
- continue;
588
- }
589
- if (isSpecialProp(property, containerType)) {
590
- continue;
591
- }
592
- const value = container[property];
593
- const refId = refs.getId(value);
594
- if (refId !== void 0) {
595
- finalizers.push(
596
- () => define(newContainer, property, refs.getMockedValue(refId))
597
- );
598
- continue;
599
- }
600
- const type = /* @__PURE__ */ getType(value);
601
- if (Array.isArray(value)) {
602
- define(newContainer, property, []);
603
- continue;
604
- }
605
- const isFunction2 = type.includes("Function") && typeof value === "function";
606
- if ((!isFunction2 || value.__isMockFunction) && type !== "Object" && type !== "Module") {
607
- define(newContainer, property, value);
608
- continue;
609
- }
610
- if (!define(newContainer, property, isFunction2 ? value : {})) {
611
- continue;
612
- }
613
- if (isFunction2) {
614
- let mockFunction = function() {
615
- if (this instanceof newContainer[property]) {
616
- for (const { key, descriptor: descriptor2 } of getAllMockableProperties(
617
- this,
618
- false
619
- )) {
620
- if (descriptor2.get) {
621
- continue;
622
- }
623
- const value2 = this[key];
624
- const type2 = /* @__PURE__ */ getType(value2);
625
- const isFunction22 = type2.includes("Function") && typeof value2 === "function";
626
- if (isFunction22) {
627
- const original = this[key];
628
- const mock2 = spyModule.spyOn(this, key).mockImplementation(original);
629
- mock2.mockRestore = () => {
630
- mock2.mockReset();
631
- mock2.mockImplementation(original);
632
- return mock2;
633
- };
634
- }
635
- }
636
- }
637
- };
638
- const spyModule = this.spyModule;
639
- if (!spyModule) {
640
- throw new Error(
641
- "[vitest] `spyModule` is not defined. This is Vitest error. Please open a new issue with reproduction."
642
- );
643
- }
644
- const mock = spyModule.spyOn(newContainer, property).mockImplementation(mockFunction);
645
- mock.mockRestore = () => {
646
- mock.mockReset();
647
- mock.mockImplementation(mockFunction);
648
- return mock;
649
- };
650
- Object.defineProperty(newContainer[property], "length", { value: 0 });
651
- }
652
- refs.track(value, newContainer[property]);
653
- mockPropertiesOf(value, newContainer[property]);
654
- }
655
- };
656
- const mockedObject = mockExports;
657
- mockPropertiesOf(object, mockedObject);
658
- for (const finalizer of finalizers) {
659
- finalizer();
660
- }
661
- return mockedObject;
662
- }
663
- }
664
- function isSpecialProp(prop, parentType) {
665
- return parentType.includes("Function") && typeof prop === "string" && ["arguments", "callee", "caller", "length", "name"].includes(prop);
666
- }
667
- class RefTracker {
668
- constructor() {
669
- __publicField(this, "idMap", /* @__PURE__ */ new Map());
670
- __publicField(this, "mockedValueMap", /* @__PURE__ */ new Map());
671
- }
672
- getId(value) {
673
- return this.idMap.get(value);
674
- }
675
- getMockedValue(id) {
676
- return this.mockedValueMap.get(id);
677
- }
678
- track(originalValue, mockedValue) {
679
- const newId = this.idMap.size;
680
- this.idMap.set(originalValue, newId);
681
- this.mockedValueMap.set(newId, mockedValue);
682
- return newId;
683
- }
684
- }
685
- function getAllMockableProperties(obj, isModule) {
686
- const allProps = /* @__PURE__ */ new Map();
687
- let curr = obj;
688
- do {
689
- if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype) {
690
- break;
691
- }
692
- collectOwnProperties(curr, (key) => {
693
- const descriptor = Object.getOwnPropertyDescriptor(curr, key);
694
- if (descriptor) {
695
- allProps.set(key, { key, descriptor });
696
- }
697
- });
698
- } while (curr = Object.getPrototypeOf(curr));
699
- if (isModule && !allProps.has("default") && "default" in obj) {
700
- const descriptor = Object.getOwnPropertyDescriptor(obj, "default");
701
- if (descriptor) {
702
- allProps.set("default", { key: "default", descriptor });
703
- }
704
- }
705
- return Array.from(allProps.values());
706
- }
707
- function collectOwnProperties(obj, collector) {
708
- const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
709
- Object.getOwnPropertyNames(obj).forEach(collect);
710
- Object.getOwnPropertySymbols(obj).forEach(collect);
711
- }
712
- function resolvedMockedPath(path) {
713
- const config = getBrowserState().viteConfig;
714
- if (path.startsWith(config.root)) {
715
- return path.slice(config.root.length);
716
- }
717
- return path;
718
- }
719
- function resolveMockPaths(path) {
720
- const config = getBrowserState().viteConfig;
721
- const fsRoot = join("/@fs/", config.root);
722
- const paths = [path, join("/@fs/", path)];
723
- if (path.startsWith(config.root)) {
724
- paths.push(path.slice(config.root.length));
725
- }
726
- if (path.startsWith(fsRoot)) {
727
- paths.push(path.slice(fsRoot.length));
728
- }
729
- return paths;
730
- }
731
- const versionRegexp = /(\?|&)v=\w{8}/;
732
- function cleanVersion(url2) {
733
- return url2.replace(versionRegexp, "");
734
906
  }
735
907
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
736
908
  function getDefaultExportFromCjs(x) {
@@ -10064,8 +10236,8 @@ function equalArrays$2(array, other, bitmask, customizer, equalFunc, stack) {
10064
10236
  }
10065
10237
  var _equalArrays = equalArrays$2;
10066
10238
  var root$4 = _root;
10067
- var Uint8Array$1 = root$4.Uint8Array;
10068
- var _Uint8Array = Uint8Array$1;
10239
+ var Uint8Array$2 = root$4.Uint8Array;
10240
+ var _Uint8Array = Uint8Array$2;
10069
10241
  function mapToArray$1(map) {
10070
10242
  var index = -1, result = Array(map.size);
10071
10243
  map.forEach(function(value, key) {
@@ -10082,7 +10254,7 @@ function setToArray$1(set) {
10082
10254
  return result;
10083
10255
  }
10084
10256
  var _setToArray = setToArray$1;
10085
- var Symbol$1 = _Symbol, Uint8Array2 = _Uint8Array, eq = eq_1, equalArrays$1 = _equalArrays, mapToArray = _mapToArray, setToArray = _setToArray;
10257
+ var Symbol$1 = _Symbol, Uint8Array$1 = _Uint8Array, eq = eq_1, equalArrays$1 = _equalArrays, mapToArray = _mapToArray, setToArray = _setToArray;
10086
10258
  var COMPARE_PARTIAL_FLAG$2 = 1, COMPARE_UNORDERED_FLAG = 2;
10087
10259
  var boolTag$1 = "[object Boolean]", dateTag$1 = "[object Date]", errorTag$1 = "[object Error]", mapTag$2 = "[object Map]", numberTag$1 = "[object Number]", regexpTag$1 = "[object RegExp]", setTag$2 = "[object Set]", stringTag$1 = "[object String]", symbolTag = "[object Symbol]";
10088
10260
  var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$2 = "[object DataView]";
@@ -10096,7 +10268,7 @@ function equalByTag$1(object, other, tag, bitmask, customizer, equalFunc, stack)
10096
10268
  object = object.buffer;
10097
10269
  other = other.buffer;
10098
10270
  case arrayBufferTag$1:
10099
- if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object), new Uint8Array2(other))) {
10271
+ if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) {
10100
10272
  return false;
10101
10273
  }
10102
10274
  return true;
@@ -11902,7 +12074,34 @@ async function prepareTestEnvironment(files) {
11902
12074
  state.ctx.files = files;
11903
12075
  state.onCancel = onCancel;
11904
12076
  state.rpc = rpc2;
11905
- const mocker = new VitestBrowserClientMocker();
12077
+ const mocker = new VitestBrowserClientMocker(
12078
+ {
12079
+ async delete(url2) {
12080
+ channel.postMessage({
12081
+ type: "unmock",
12082
+ url: url2
12083
+ });
12084
+ await waitForChannel("unmock:done");
12085
+ },
12086
+ async register(module) {
12087
+ channel.postMessage({
12088
+ type: "mock",
12089
+ module: module.toJSON()
12090
+ });
12091
+ await waitForChannel("mock:done");
12092
+ },
12093
+ invalidate() {
12094
+ channel.postMessage({
12095
+ type: "mock:invalidate"
12096
+ });
12097
+ }
12098
+ },
12099
+ rpc2,
12100
+ SpyModule.spyOn,
12101
+ {
12102
+ root: getBrowserState().viteConfig.root
12103
+ }
12104
+ );
11906
12105
  globalThis.__vitest_mocker__ = mocker;
11907
12106
  setupConsoleLogSpy();
11908
12107
  setupDialogsSpy();
@@ -11915,7 +12114,6 @@ async function prepareTestEnvironment(files) {
11915
12114
  browserHashMap.set(filename, [true, version]);
11916
12115
  }
11917
12116
  });
11918
- mocker.setSpyModule(SpyModule);
11919
12117
  mocker.setupWorker();
11920
12118
  onCancel.then((reason) => {
11921
12119
  var _a;
@@ -11959,8 +12157,17 @@ async function executeTests(method, files) {
11959
12157
  state.durations.prepare = performance.now() - state.durations.prepare;
11960
12158
  debug("prepare time", state.durations.prepare, "ms");
11961
12159
  try {
11962
- await setupCommonEnv(config);
11963
- await startCoverageInsideWorker(config.coverage, executor);
12160
+ await Promise.all([
12161
+ setupCommonEnv(config),
12162
+ startCoverageInsideWorker(config.coverage, executor),
12163
+ (async () => {
12164
+ const VitestIndex = await __vitePreload(() => import("vitest"), true ? [] : void 0);
12165
+ Object.defineProperty(window, "__vitest_index__", {
12166
+ value: VitestIndex,
12167
+ enumerable: false
12168
+ });
12169
+ })()
12170
+ ]);
11964
12171
  for (const file of files) {
11965
12172
  state.filepath = file;
11966
12173
  if (method === "run") {
@@ -11982,7 +12189,14 @@ async function executeTests(method, files) {
11982
12189
  }, "Cleanup Error");
11983
12190
  }
11984
12191
  state.environmentTeardownRun = true;
11985
- await stopCoverageInsideWorker(config.coverage, executor);
12192
+ await stopCoverageInsideWorker(config.coverage, executor).catch((error) => {
12193
+ client.rpc.onUnhandledError({
12194
+ name: error.name,
12195
+ message: error.message,
12196
+ stack: String(error.stack)
12197
+ }, "Coverage Error").catch(() => {
12198
+ });
12199
+ });
11986
12200
  debug("finished running tests");
11987
12201
  done(files);
11988
12202
  }