@vitest/browser 2.1.0-beta.6 → 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.
@@ -23,7 +23,7 @@
23
23
  })();
24
24
  </script>
25
25
  <!-- !LOAD_METADATA! -->
26
- <script type="module" crossorigin src="./assets/index-D7jfm8wn.js"></script>
26
+ <script type="module" crossorigin src="./assets/index-CEU6kzsk.js"></script>
27
27
  <link rel="stylesheet" crossorigin href="./assets/index-BevOiAy-.css">
28
28
  </head>
29
29
  <body>
@@ -1,8 +1,120 @@
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 { _ as __vitePreload, g as getBrowserState, a as getConfig, r as relative } from "./preload-helper-YsBSwBkS.js";
4
+ import { M as MockerRegistry, _ as __vitePreload, a as ManualMockedModule, g as getBrowserState, b as getConfig } from "./preload-helper-D-WYp1PK.js";
5
5
  import { channel, client, globalChannel } from "@vitest/browser/client";
6
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
7
+ function normalizeWindowsPath(input = "") {
8
+ if (!input) {
9
+ return input;
10
+ }
11
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
12
+ }
13
+ const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
14
+ const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
15
+ function cwd() {
16
+ if (typeof process !== "undefined" && typeof process.cwd === "function") {
17
+ return process.cwd().replace(/\\/g, "/");
18
+ }
19
+ return "/";
20
+ }
21
+ const resolve = function(...arguments_) {
22
+ arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
23
+ let resolvedPath = "";
24
+ let resolvedAbsolute = false;
25
+ for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
26
+ const path = index >= 0 ? arguments_[index] : cwd();
27
+ if (!path || path.length === 0) {
28
+ continue;
29
+ }
30
+ resolvedPath = `${path}/${resolvedPath}`;
31
+ resolvedAbsolute = isAbsolute(path);
32
+ }
33
+ resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
34
+ if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
35
+ return `/${resolvedPath}`;
36
+ }
37
+ return resolvedPath.length > 0 ? resolvedPath : ".";
38
+ };
39
+ function normalizeString(path, allowAboveRoot) {
40
+ let res = "";
41
+ let lastSegmentLength = 0;
42
+ let lastSlash = -1;
43
+ let dots = 0;
44
+ let char = null;
45
+ for (let index = 0; index <= path.length; ++index) {
46
+ if (index < path.length) {
47
+ char = path[index];
48
+ } else if (char === "/") {
49
+ break;
50
+ } else {
51
+ char = "/";
52
+ }
53
+ if (char === "/") {
54
+ if (lastSlash === index - 1 || dots === 1) ;
55
+ else if (dots === 2) {
56
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
57
+ if (res.length > 2) {
58
+ const lastSlashIndex = res.lastIndexOf("/");
59
+ if (lastSlashIndex === -1) {
60
+ res = "";
61
+ lastSegmentLength = 0;
62
+ } else {
63
+ res = res.slice(0, lastSlashIndex);
64
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
65
+ }
66
+ lastSlash = index;
67
+ dots = 0;
68
+ continue;
69
+ } else if (res.length > 0) {
70
+ res = "";
71
+ lastSegmentLength = 0;
72
+ lastSlash = index;
73
+ dots = 0;
74
+ continue;
75
+ }
76
+ }
77
+ if (allowAboveRoot) {
78
+ res += res.length > 0 ? "/.." : "..";
79
+ lastSegmentLength = 2;
80
+ }
81
+ } else {
82
+ if (res.length > 0) {
83
+ res += `/${path.slice(lastSlash + 1, index)}`;
84
+ } else {
85
+ res = path.slice(lastSlash + 1, index);
86
+ }
87
+ lastSegmentLength = index - lastSlash - 1;
88
+ }
89
+ lastSlash = index;
90
+ dots = 0;
91
+ } else if (char === "." && dots !== -1) {
92
+ ++dots;
93
+ } else {
94
+ dots = -1;
95
+ }
96
+ }
97
+ return res;
98
+ }
99
+ const isAbsolute = function(p) {
100
+ return _IS_ABSOLUTE_RE.test(p);
101
+ };
102
+ const relative = function(from, to) {
103
+ const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
104
+ const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
105
+ if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
106
+ return _to.join("/");
107
+ }
108
+ const _fromCopy = [..._from];
109
+ for (const segment of _fromCopy) {
110
+ if (_to[0] !== segment) {
111
+ break;
112
+ }
113
+ _from.shift();
114
+ _to.shift();
115
+ }
116
+ return [..._from.map(() => ".."), ..._to].join("/");
117
+ };
6
118
  function generateHash(str) {
7
119
  let hash = 0;
8
120
  if (str.length === 0) {
@@ -18,102 +130,95 @@ function generateHash(str) {
18
130
  function getUiAPI() {
19
131
  return window.__vitest_ui_api__;
20
132
  }
21
- function createModuleMocker() {
22
- const mocks = /* @__PURE__ */ new Map();
23
- let started = false;
24
- let startPromise;
25
- async function init() {
26
- if (started) {
133
+ const postfixRE = /[?#].*$/;
134
+ function cleanUrl(url2) {
135
+ return url2.replace(postfixRE, "");
136
+ }
137
+ class ModuleMockerMSWInterceptor {
138
+ constructor(options = {}) {
139
+ __publicField(this, "mocks", new MockerRegistry());
140
+ __publicField(this, "started", false);
141
+ __publicField(this, "startPromise");
142
+ this.options = options;
143
+ if (!options.globalThisAccessor) {
144
+ options.globalThisAccessor = '"__vitest_mocker__"';
145
+ }
146
+ }
147
+ async register(module) {
148
+ await this.init();
149
+ this.mocks.add(module);
150
+ }
151
+ async delete(url2) {
152
+ await this.init();
153
+ this.mocks.delete(url2);
154
+ }
155
+ invalidate() {
156
+ this.mocks.clear();
157
+ }
158
+ async resolveManualMock(mock) {
159
+ const exports = Object.keys(await mock.resolve());
160
+ const module = `const module = globalThis[${this.options.globalThisAccessor}].getFactoryModule("${mock.url}");`;
161
+ const keys = exports.map((name) => {
162
+ if (name === "default") {
163
+ return `export default module["default"];`;
164
+ }
165
+ return `export const ${name} = module["${name}"];`;
166
+ }).join("\n");
167
+ const text = `${module}
168
+ ${keys}`;
169
+ return new Response(text, {
170
+ headers: {
171
+ "Content-Type": "application/javascript"
172
+ }
173
+ });
174
+ }
175
+ async init() {
176
+ if (this.started) {
27
177
  return;
28
178
  }
29
- if (startPromise) {
30
- return startPromise;
179
+ if (this.startPromise) {
180
+ return this.startPromise;
31
181
  }
32
- startPromise = Promise.all([
33
- __vitePreload(() => import("msw/browser"), true ? [] : void 0),
182
+ const worker = this.options.mswWorker;
183
+ this.startPromise = Promise.all([
184
+ worker ? {
185
+ setupWorker(handler) {
186
+ worker.use(handler);
187
+ return worker;
188
+ }
189
+ } : __vitePreload(() => import("msw/browser"), true ? [] : void 0),
34
190
  __vitePreload(() => import("msw/core/http"), true ? [] : void 0)
35
191
  ]).then(([{ setupWorker }, { http }]) => {
36
- const worker = setupWorker(
192
+ const worker2 = setupWorker(
37
193
  http.get(/.+/, async ({ request }) => {
38
194
  const path = cleanQuery(request.url.slice(location.origin.length));
39
- if (!mocks.has(path)) {
195
+ if (!this.mocks.has(path)) {
40
196
  if (path.includes("/deps/")) {
41
197
  return fetch(bypass(request));
42
198
  }
43
199
  return passthrough();
44
200
  }
45
- const mock = mocks.get(path);
46
- if (mock === void 0) {
47
- const exports = await getFactoryExports(path);
48
- const module = `const module = __vitest_mocker__.get('${path}');`;
49
- const keys = exports.map((name) => {
50
- if (name === "default") {
51
- return `export default module['default'];`;
52
- }
53
- return `export const ${name} = module['${name}'];`;
54
- }).join("\n");
55
- const text = `${module}
56
- ${keys}`;
57
- return new Response(text, {
58
- headers: {
59
- "Content-Type": "application/javascript"
60
- }
61
- });
62
- }
63
- if (typeof mock === "string") {
64
- return Response.redirect(mock);
201
+ const mock = this.mocks.get(path);
202
+ switch (mock.type) {
203
+ case "manual":
204
+ return this.resolveManualMock(mock);
205
+ case "automock":
206
+ case "autospy":
207
+ return Response.redirect(injectQuery(path, `mock=${mock.type}`));
208
+ case "redirect":
209
+ return Response.redirect(mock.redirect);
210
+ default:
211
+ throw new Error(`Unknown mock type: ${mock.type}`);
65
212
  }
66
- return Response.redirect(injectQuery(path, "mock=auto"));
67
213
  })
68
214
  );
69
- return worker.start({
70
- serviceWorker: {
71
- url: "/__vitest_msw__"
72
- },
73
- quiet: true
74
- });
215
+ return worker2.start(this.options.mswOptions);
75
216
  }).finally(() => {
76
- started = true;
77
- startPromise = void 0;
217
+ this.started = true;
218
+ this.startPromise = void 0;
78
219
  });
79
- await startPromise;
220
+ await this.startPromise;
80
221
  }
81
- return {
82
- async mock(event) {
83
- await init();
84
- event.paths.forEach((path) => mocks.set(path, event.mock));
85
- channel.postMessage({ type: "mock:done" });
86
- },
87
- async unmock(event) {
88
- await init();
89
- event.paths.forEach((path) => mocks.delete(path));
90
- channel.postMessage({ type: "unmock:done" });
91
- },
92
- invalidate() {
93
- mocks.clear();
94
- }
95
- };
96
- }
97
- function getFactoryExports(id) {
98
- channel.postMessage({
99
- type: "mock-factory:request",
100
- id
101
- });
102
- return new Promise((resolve, reject) => {
103
- channel.addEventListener(
104
- "message",
105
- function onMessage(e) {
106
- if (e.data.type === "mock-factory:response") {
107
- resolve(e.data.exports);
108
- channel.removeEventListener("message", onMessage);
109
- }
110
- if (e.data.type === "mock-factory:error") {
111
- reject(e.data.error);
112
- channel.removeEventListener("message", onMessage);
113
- }
114
- }
115
- );
116
- });
117
222
  }
118
223
  const timestampRegexp = /(\?|&)t=\d{13}/;
119
224
  const versionRegexp = /(\?|&)v=\w{8}/;
@@ -142,10 +247,6 @@ function bypass(request) {
142
247
  }
143
248
  return clonedRequest;
144
249
  }
145
- const postfixRE = /[?#].*$/;
146
- function cleanUrl(url2) {
147
- return url2.replace(postfixRE, "");
148
- }
149
250
  const replacePercentageRE = /%/g;
150
251
  function injectQuery(url2, queryToInject) {
151
252
  const resolvedUrl = new URL(
@@ -156,13 +257,64 @@ function injectQuery(url2, queryToInject) {
156
257
  const pathname = cleanUrl(url2);
157
258
  return `${pathname}?${queryToInject}${search ? `&${search.slice(1)}` : ""}${hash ?? ""}`;
158
259
  }
260
+ class VitestBrowserModuleMockerInterceptor extends ModuleMockerMSWInterceptor {
261
+ async register(event) {
262
+ if (event.type === "manual") {
263
+ const module = ManualMockedModule.fromJSON(event, async () => {
264
+ const keys = await getFactoryExports(event.url);
265
+ return Object.fromEntries(keys.map((key) => [key, null]));
266
+ });
267
+ await super.register(module);
268
+ } else {
269
+ await this.init();
270
+ this.mocks.register(event);
271
+ }
272
+ channel.postMessage({ type: "mock:done" });
273
+ }
274
+ async delete(url2) {
275
+ await super.delete(url2);
276
+ channel.postMessage({ type: "unmock:done" });
277
+ }
278
+ }
279
+ function createModuleMockerInterceptor() {
280
+ return new VitestBrowserModuleMockerInterceptor({
281
+ globalThisAccessor: '"__vitest_mocker__"',
282
+ mswOptions: {
283
+ serviceWorker: {
284
+ url: "/__vitest_msw__"
285
+ },
286
+ quiet: true
287
+ }
288
+ });
289
+ }
290
+ function getFactoryExports(id) {
291
+ channel.postMessage({
292
+ type: "mock-factory:request",
293
+ id
294
+ });
295
+ return new Promise((resolve2, reject) => {
296
+ channel.addEventListener(
297
+ "message",
298
+ function onMessage(e) {
299
+ if (e.data.type === "mock-factory:response") {
300
+ resolve2(e.data.exports);
301
+ channel.removeEventListener("message", onMessage);
302
+ }
303
+ if (e.data.type === "mock-factory:error") {
304
+ reject(e.data.error);
305
+ channel.removeEventListener("message", onMessage);
306
+ }
307
+ }
308
+ );
309
+ });
310
+ }
159
311
  const url = new URL(location.href);
160
312
  const ID_ALL = "__vitest_all__";
161
313
  class IframeOrchestrator {
162
314
  constructor() {
163
315
  __publicField(this, "cancelled", false);
164
316
  __publicField(this, "runningFiles", /* @__PURE__ */ new Set());
165
- __publicField(this, "mocker", createModuleMocker());
317
+ __publicField(this, "interceptor", createModuleMockerInterceptor());
166
318
  __publicField(this, "iframes", /* @__PURE__ */ new Map());
167
319
  }
168
320
  async init() {
@@ -205,13 +357,13 @@ class IframeOrchestrator {
205
357
  }
206
358
  const iframe = this.createIframe(container, file);
207
359
  await setIframeViewport(iframe, width, height);
208
- await new Promise((resolve) => {
360
+ await new Promise((resolve2) => {
209
361
  channel.addEventListener(
210
362
  "message",
211
363
  function handler(e) {
212
364
  if (e.data.type === "done" || e.data.type === "error") {
213
365
  channel.removeEventListener("message", handler);
214
- resolve();
366
+ resolve2();
215
367
  }
216
368
  }
217
369
  );
@@ -308,13 +460,13 @@ class IframeOrchestrator {
308
460
  break;
309
461
  }
310
462
  case "mock:invalidate":
311
- this.mocker.invalidate();
463
+ this.interceptor.invalidate();
312
464
  break;
313
465
  case "unmock":
314
- await this.mocker.unmock(e.data);
466
+ await this.interceptor.delete(e.data.url);
315
467
  break;
316
468
  case "mock":
317
- await this.mocker.mock(e.data);
469
+ await this.interceptor.register(e.data.module);
318
470
  break;
319
471
  case "mock-factory:error":
320
472
  case "mock-factory:response":
@@ -349,9 +501,9 @@ async function getContainer(config) {
349
501
  if (config.browser.ui) {
350
502
  const element = document.querySelector("#tester-ui");
351
503
  if (!element) {
352
- return new Promise((resolve) => {
504
+ return new Promise((resolve2) => {
353
505
  setTimeout(() => {
354
- resolve(getContainer(config));
506
+ resolve2(getContainer(config));
355
507
  }, 30);
356
508
  });
357
509
  }