@vitest/browser 2.1.0-beta.5 → 2.1.0-beta.7

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, i as importFs, b as importId, e as extname, g as getBrowserState, _ as __vitePreload, j as join, c as getWorkerState } from "./preload-helper-BrGs795G.js";
5
- import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker, setupCommonEnv, startTests, collectTests, SpyModule } from "vitest/browser";
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
+ 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());
@@ -296,7 +782,7 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
296
782
  if (coverage) {
297
783
  await rpc$1().onAfterSuiteRun({
298
784
  coverage,
299
- transformMode: "web",
785
+ transformMode: "browser",
300
786
  projectName: this.config.name
301
787
  });
302
788
  }
@@ -343,14 +829,8 @@ async function initiateRunner(state, mocker, config) {
343
829
  return cachedRunner;
344
830
  }
345
831
  const runnerClass = config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner;
346
- const executeId = (id) => {
347
- if (id[0] === "/" || id[1] === ":") {
348
- return importFs(id);
349
- }
350
- return importId(id);
351
- };
352
832
  const BrowserRunner = createBrowserRunner(runnerClass, mocker, state, {
353
- takeCoverage: () => takeCoverageInsideWorker(config.coverage, { executeId })
833
+ takeCoverage: () => takeCoverageInsideWorker(config.coverage, executor)
354
834
  });
355
835
  if (!config.snapshotOptions.snapshotEnvironment) {
356
836
  config.snapshotOptions.snapshotEnvironment = new VitestBrowserSnapshotEnvironment();
@@ -358,7 +838,6 @@ async function initiateRunner(state, mocker, config) {
358
838
  const runner = new BrowserRunner({
359
839
  config
360
840
  });
361
- const executor = { executeId };
362
841
  const [diffOptions] = await Promise.all([
363
842
  loadDiffConfig(config, executor),
364
843
  loadSnapshotSerializers(config, executor)
@@ -390,355 +869,41 @@ async function updateFilesLocations(files, sourceMaps) {
390
869
  });
391
870
  await Promise.all(promises2);
392
871
  }
393
- const now = Date.now;
394
- class VitestBrowserClientMocker {
395
- constructor() {
396
- __publicField(this, "queue", /* @__PURE__ */ new Set());
397
- __publicField(this, "mocks", {});
398
- __publicField(this, "mockObjects", {});
399
- __publicField(this, "factories", {});
400
- __publicField(this, "ids", /* @__PURE__ */ new Set());
401
- __publicField(this, "spyModule");
402
- }
872
+ class VitestBrowserClientMocker extends ModuleMocker {
403
873
  setupWorker() {
404
874
  channel.addEventListener(
405
875
  "message",
406
876
  async (e) => {
407
877
  if (e.data.type === "mock-factory:request") {
408
878
  try {
409
- const module = await this.resolve(e.data.id);
879
+ const module = await this.resolveFactoryModule(e.data.id);
410
880
  const exports = Object.keys(module);
411
881
  channel.postMessage({
412
882
  type: "mock-factory:response",
413
883
  exports
414
884
  });
415
885
  } catch (err) {
416
- const { processError } = await importId(
417
- "vitest/browser"
418
- );
419
886
  channel.postMessage({
420
887
  type: "mock-factory:error",
421
- error: processError(err)
888
+ error: {
889
+ name: err.name,
890
+ message: err.message,
891
+ stack: err.stack
892
+ }
422
893
  });
423
894
  }
424
895
  }
425
896
  }
426
897
  );
427
898
  }
428
- setSpyModule(mod) {
429
- this.spyModule = mod;
430
- }
431
- async importActual(id, importer) {
432
- const resolved = await rpc$1().resolveId(id, importer);
433
- if (resolved == null) {
434
- throw new Error(
435
- `[vitest] Cannot resolve ${id} imported from ${importer}`
436
- );
437
- }
438
- const ext = extname(resolved.id);
439
- const url2 = new URL(resolved.url, location.href);
440
- const query = `_vitest_original&ext${ext}`;
441
- const actualUrl = `${url2.pathname}${url2.search ? `${url2.search}&${query}` : `?${query}`}${url2.hash}`;
442
- return getBrowserState().wrapModule(() => import(
443
- /* @vite-ignore */
444
- actualUrl
445
- )).then((mod) => {
446
- if (!resolved.optimized || typeof mod.default === "undefined") {
447
- return mod;
448
- }
449
- const m = mod.default;
450
- return (m == null ? void 0 : m.__esModule) ? m : { ...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {}, default: m };
451
- });
452
- }
453
- async importMock(rawId, importer) {
454
- await this.prepare();
455
- const { resolvedId, type, mockPath } = await rpc$1().resolveMock(
456
- rawId,
457
- importer,
458
- false
459
- );
460
- const factoryReturn = this.get(resolvedId);
461
- if (factoryReturn) {
462
- return factoryReturn;
463
- }
464
- if (this.factories[resolvedId]) {
465
- return await this.resolve(resolvedId);
466
- }
467
- if (type === "redirect") {
468
- const url22 = new URL(`/@id/${mockPath}`, location.href);
469
- return import(
470
- /* @vite-ignore */
471
- url22.toString()
472
- );
473
- }
474
- const url2 = new URL(`/@id/${resolvedId}`, location.href);
475
- const query = url2.search ? `${url2.search}&t=${now()}` : `?t=${now()}`;
476
- const moduleObject = await __vitePreload(() => import(
477
- /* @vite-ignore */
478
- `${url2.pathname}${query}${url2.hash}`
479
- ), true ? [] : void 0);
480
- return this.mockObject(moduleObject);
481
- }
899
+ // default "vi" utility tries to access mock context to avoid circular dependencies
482
900
  getMockContext() {
483
901
  return { callstack: null };
484
902
  }
485
- get(id) {
486
- return this.mockObjects[id];
487
- }
488
- async invalidate() {
489
- const ids = Array.from(this.ids);
490
- if (!ids.length) {
491
- return;
492
- }
493
- await rpc$1().invalidate(ids);
494
- channel.postMessage({ type: "mock:invalidate" });
495
- this.ids.clear();
496
- this.mocks = {};
497
- this.mockObjects = {};
498
- this.factories = {};
499
- }
500
- async resolve(id) {
501
- const factory = this.factories[id];
502
- if (!factory) {
503
- throw new Error(`Cannot resolve ${id} mock: no factory provided`);
504
- }
505
- try {
506
- this.mockObjects[id] = await factory();
507
- return this.mockObjects[id];
508
- } catch (err) {
509
- const vitestError = new Error(
510
- '[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'
511
- );
512
- vitestError.cause = err;
513
- throw vitestError;
514
- }
515
- }
516
- queueMock(id, importer, factory) {
517
- const promise = rpc$1().resolveMock(id, importer, !!factory).then(async ({ mockPath, resolvedId, needsInterop }) => {
518
- this.ids.add(resolvedId);
519
- const urlPaths = resolveMockPaths(cleanVersion(resolvedId));
520
- const resolvedMock = typeof mockPath === "string" ? new URL(resolvedMockedPath(cleanVersion(mockPath)), location.href).toString() : mockPath;
521
- const _factory = factory && needsInterop ? async () => {
522
- const data = await factory();
523
- return { default: data };
524
- } : factory;
525
- urlPaths.forEach((url2) => {
526
- this.mocks[url2] = resolvedMock;
527
- if (_factory) {
528
- this.factories[url2] = _factory;
529
- }
530
- });
531
- channel.postMessage({
532
- type: "mock",
533
- paths: urlPaths,
534
- mock: resolvedMock
535
- });
536
- await waitForChannel("mock:done");
537
- }).finally(() => {
538
- this.queue.delete(promise);
539
- });
540
- this.queue.add(promise);
541
- }
542
- queueUnmock(id, importer) {
543
- const promise = rpc$1().resolveId(id, importer).then(async (resolved) => {
544
- if (!resolved) {
545
- return;
546
- }
547
- this.ids.delete(resolved.id);
548
- const urlPaths = resolveMockPaths(cleanVersion(resolved.id));
549
- urlPaths.forEach((url2) => {
550
- delete this.mocks[url2];
551
- delete this.factories[url2];
552
- delete this.mockObjects[url2];
553
- });
554
- channel.postMessage({
555
- type: "unmock",
556
- paths: urlPaths
557
- });
558
- await waitForChannel("unmock:done");
559
- }).finally(() => {
560
- this.queue.delete(promise);
561
- });
562
- this.queue.add(promise);
563
- }
564
- async prepare() {
565
- if (!this.queue.size) {
566
- return;
567
- }
568
- await Promise.all([...this.queue.values()]);
569
- }
570
- // TODO: move this logic into a util(?)
571
- mockObject(object, mockExports = {}) {
572
- const finalizers = new Array();
573
- const refs = new RefTracker();
574
- const define = (container, key, value) => {
575
- try {
576
- container[key] = value;
577
- return true;
578
- } catch {
579
- return false;
580
- }
581
- };
582
- const mockPropertiesOf = (container, newContainer) => {
583
- const containerType = /* @__PURE__ */ getType(container);
584
- const isModule = containerType === "Module" || !!container.__esModule;
585
- for (const { key: property, descriptor } of getAllMockableProperties(
586
- container,
587
- isModule
588
- )) {
589
- if (!isModule && descriptor.get) {
590
- try {
591
- Object.defineProperty(newContainer, property, descriptor);
592
- } catch {
593
- }
594
- continue;
595
- }
596
- if (isSpecialProp(property, containerType)) {
597
- continue;
598
- }
599
- const value = container[property];
600
- const refId = refs.getId(value);
601
- if (refId !== void 0) {
602
- finalizers.push(
603
- () => define(newContainer, property, refs.getMockedValue(refId))
604
- );
605
- continue;
606
- }
607
- const type = /* @__PURE__ */ getType(value);
608
- if (Array.isArray(value)) {
609
- define(newContainer, property, []);
610
- continue;
611
- }
612
- const isFunction2 = type.includes("Function") && typeof value === "function";
613
- if ((!isFunction2 || value.__isMockFunction) && type !== "Object" && type !== "Module") {
614
- define(newContainer, property, value);
615
- continue;
616
- }
617
- if (!define(newContainer, property, isFunction2 ? value : {})) {
618
- continue;
619
- }
620
- if (isFunction2) {
621
- let mockFunction = function() {
622
- if (this instanceof newContainer[property]) {
623
- for (const { key, descriptor: descriptor2 } of getAllMockableProperties(
624
- this,
625
- false
626
- )) {
627
- if (descriptor2.get) {
628
- continue;
629
- }
630
- const value2 = this[key];
631
- const type2 = /* @__PURE__ */ getType(value2);
632
- const isFunction22 = type2.includes("Function") && typeof value2 === "function";
633
- if (isFunction22) {
634
- const original = this[key];
635
- const mock2 = spyModule.spyOn(this, key).mockImplementation(original);
636
- mock2.mockRestore = () => {
637
- mock2.mockReset();
638
- mock2.mockImplementation(original);
639
- return mock2;
640
- };
641
- }
642
- }
643
- }
644
- };
645
- const spyModule = this.spyModule;
646
- if (!spyModule) {
647
- throw new Error(
648
- "[vitest] `spyModule` is not defined. This is Vitest error. Please open a new issue with reproduction."
649
- );
650
- }
651
- const mock = spyModule.spyOn(newContainer, property).mockImplementation(mockFunction);
652
- mock.mockRestore = () => {
653
- mock.mockReset();
654
- mock.mockImplementation(mockFunction);
655
- return mock;
656
- };
657
- Object.defineProperty(newContainer[property], "length", { value: 0 });
658
- }
659
- refs.track(value, newContainer[property]);
660
- mockPropertiesOf(value, newContainer[property]);
661
- }
662
- };
663
- const mockedObject = mockExports;
664
- mockPropertiesOf(object, mockedObject);
665
- for (const finalizer of finalizers) {
666
- finalizer();
667
- }
668
- return mockedObject;
903
+ wrapDynamicImport(moduleFactory) {
904
+ return getBrowserState().wrapModule(moduleFactory);
669
905
  }
670
906
  }
671
- function isSpecialProp(prop, parentType) {
672
- return parentType.includes("Function") && typeof prop === "string" && ["arguments", "callee", "caller", "length", "name"].includes(prop);
673
- }
674
- class RefTracker {
675
- constructor() {
676
- __publicField(this, "idMap", /* @__PURE__ */ new Map());
677
- __publicField(this, "mockedValueMap", /* @__PURE__ */ new Map());
678
- }
679
- getId(value) {
680
- return this.idMap.get(value);
681
- }
682
- getMockedValue(id) {
683
- return this.mockedValueMap.get(id);
684
- }
685
- track(originalValue, mockedValue) {
686
- const newId = this.idMap.size;
687
- this.idMap.set(originalValue, newId);
688
- this.mockedValueMap.set(newId, mockedValue);
689
- return newId;
690
- }
691
- }
692
- function getAllMockableProperties(obj, isModule) {
693
- const allProps = /* @__PURE__ */ new Map();
694
- let curr = obj;
695
- do {
696
- if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype) {
697
- break;
698
- }
699
- collectOwnProperties(curr, (key) => {
700
- const descriptor = Object.getOwnPropertyDescriptor(curr, key);
701
- if (descriptor) {
702
- allProps.set(key, { key, descriptor });
703
- }
704
- });
705
- } while (curr = Object.getPrototypeOf(curr));
706
- if (isModule && !allProps.has("default") && "default" in obj) {
707
- const descriptor = Object.getOwnPropertyDescriptor(obj, "default");
708
- if (descriptor) {
709
- allProps.set("default", { key: "default", descriptor });
710
- }
711
- }
712
- return Array.from(allProps.values());
713
- }
714
- function collectOwnProperties(obj, collector) {
715
- const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
716
- Object.getOwnPropertyNames(obj).forEach(collect);
717
- Object.getOwnPropertySymbols(obj).forEach(collect);
718
- }
719
- function resolvedMockedPath(path) {
720
- const config = getBrowserState().viteConfig;
721
- if (path.startsWith(config.root)) {
722
- return path.slice(config.root.length);
723
- }
724
- return path;
725
- }
726
- function resolveMockPaths(path) {
727
- const config = getBrowserState().viteConfig;
728
- const fsRoot = join("/@fs/", config.root);
729
- const paths = [path, join("/@fs/", path)];
730
- if (path.startsWith(config.root)) {
731
- paths.push(path.slice(config.root.length));
732
- }
733
- if (path.startsWith(fsRoot)) {
734
- paths.push(path.slice(fsRoot.length));
735
- }
736
- return paths;
737
- }
738
- const versionRegexp = /(\?|&)v=\w{8}/;
739
- function cleanVersion(url2) {
740
- return url2.replace(versionRegexp, "");
741
- }
742
907
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
743
908
  function getDefaultExportFromCjs(x) {
744
909
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -10071,8 +10236,8 @@ function equalArrays$2(array, other, bitmask, customizer, equalFunc, stack) {
10071
10236
  }
10072
10237
  var _equalArrays = equalArrays$2;
10073
10238
  var root$4 = _root;
10074
- var Uint8Array$1 = root$4.Uint8Array;
10075
- var _Uint8Array = Uint8Array$1;
10239
+ var Uint8Array$2 = root$4.Uint8Array;
10240
+ var _Uint8Array = Uint8Array$2;
10076
10241
  function mapToArray$1(map) {
10077
10242
  var index = -1, result = Array(map.size);
10078
10243
  map.forEach(function(value, key) {
@@ -10089,7 +10254,7 @@ function setToArray$1(set) {
10089
10254
  return result;
10090
10255
  }
10091
10256
  var _setToArray = setToArray$1;
10092
- 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;
10093
10258
  var COMPARE_PARTIAL_FLAG$2 = 1, COMPARE_UNORDERED_FLAG = 2;
10094
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]";
10095
10260
  var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$2 = "[object DataView]";
@@ -10103,7 +10268,7 @@ function equalByTag$1(object, other, tag, bitmask, customizer, equalFunc, stack)
10103
10268
  object = object.buffer;
10104
10269
  other = other.buffer;
10105
10270
  case arrayBufferTag$1:
10106
- 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))) {
10107
10272
  return false;
10108
10273
  }
10109
10274
  return true;
@@ -11909,7 +12074,34 @@ async function prepareTestEnvironment(files) {
11909
12074
  state.ctx.files = files;
11910
12075
  state.onCancel = onCancel;
11911
12076
  state.rpc = rpc2;
11912
- 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
+ );
11913
12105
  globalThis.__vitest_mocker__ = mocker;
11914
12106
  setupConsoleLogSpy();
11915
12107
  setupDialogsSpy();
@@ -11922,7 +12114,6 @@ async function prepareTestEnvironment(files) {
11922
12114
  browserHashMap.set(filename, [true, version]);
11923
12115
  }
11924
12116
  });
11925
- mocker.setSpyModule(SpyModule);
11926
12117
  mocker.setupWorker();
11927
12118
  onCancel.then((reason) => {
11928
12119
  var _a;
@@ -11966,7 +12157,17 @@ async function executeTests(method, files) {
11966
12157
  state.durations.prepare = performance.now() - state.durations.prepare;
11967
12158
  debug("prepare time", state.durations.prepare, "ms");
11968
12159
  try {
11969
- await setupCommonEnv(config);
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
+ ]);
11970
12171
  for (const file of files) {
11971
12172
  state.filepath = file;
11972
12173
  if (method === "run") {
@@ -11988,6 +12189,14 @@ async function executeTests(method, files) {
11988
12189
  }, "Cleanup Error");
11989
12190
  }
11990
12191
  state.environmentTeardownRun = true;
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
+ });
11991
12200
  debug("finished running tests");
11992
12201
  done(files);
11993
12202
  }