vitest 4.0.0-beta.5 → 4.0.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.
Files changed (64) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{base.DMfOuRWD.js → base.BXI97p6t.js} +7 -16
  5. package/dist/chunks/{benchmark.CtuRzf-i.js → benchmark.UW6Ezvxy.js} +4 -9
  6. package/dist/chunks/{browser.d.Cawq_X_N.d.ts → browser.d.DOMmqJQx.d.ts} +1 -1
  7. package/dist/chunks/{cac.CKnbxhn2.js → cac.Dsn7ixFt.js} +38 -113
  8. package/dist/chunks/{cli-api.COn58yrl.js → cli-api.DfGJyldU.js} +829 -1232
  9. package/dist/chunks/{config.d.CKNVOKm0.d.ts → config.d._GBBbReY.d.ts} +1 -0
  10. package/dist/chunks/{console.Duv2dVIC.js → console.B0quX7yH.js} +32 -68
  11. package/dist/chunks/{coverage.B6cReEn1.js → coverage.Dvxug1RM.js} +210 -579
  12. package/dist/chunks/{creator.DUVZ6rfm.js → creator.KEg6n5IC.js} +28 -74
  13. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  14. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  15. package/dist/chunks/{globals.CJQ63oO0.js → globals.lgsmH00r.js} +5 -5
  16. package/dist/chunks/{index.QZr3S3vQ.js → index.AR8aAkCC.js} +2 -2
  17. package/dist/chunks/{index.DQhAfQQU.js → index.C3EbxYwt.js} +276 -607
  18. package/dist/chunks/{index.oWRWx-nj.js → index.CsFXYRkW.js} +17 -36
  19. package/dist/chunks/{index.DgN0Zk9a.js → index.D2B6d2vv.js} +14 -24
  20. package/dist/chunks/{index.BRtIe7r8.js → index.DfviD7lX.js} +55 -110
  21. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  22. package/dist/chunks/{moduleRunner.d.mmOmOGrW.d.ts → moduleRunner.d.CX4DuqOx.d.ts} +2 -2
  23. package/dist/chunks/{node.4JV5OXkt.js → node.BOqcT2jW.js} +1 -1
  24. package/dist/chunks/{plugin.d.CvOlgjxK.d.ts → plugin.d.vcD4xbMS.d.ts} +1 -1
  25. package/dist/chunks/{reporters.d.CYE9sT5z.d.ts → reporters.d.BC86JJdB.d.ts} +799 -758
  26. package/dist/chunks/{resolver.D5bG4zy5.js → resolver.Bx6lE0iq.js} +21 -64
  27. package/dist/chunks/{rpc.DGoW_Vl-.js → rpc.RpPylpp0.js} +7 -21
  28. package/dist/chunks/{runBaseTests.B3KcKqlF.js → runBaseTests.D6sfuWBM.js} +25 -54
  29. package/dist/chunks/{setup-common.lgPs-bYv.js → setup-common.hLGRxhC8.js} +9 -22
  30. package/dist/chunks/{startModuleRunner.C8FtT_BY.js → startModuleRunner.C8TW8zTN.js} +83 -205
  31. package/dist/chunks/{typechecker.BgoW4nTA.js → typechecker.DSo_maXz.js} +97 -209
  32. package/dist/chunks/{utils.CcGm2cd1.js → utils.C2YI6McM.js} +4 -13
  33. package/dist/chunks/{utils.B9FY3b73.js → utils.C7__0Iv5.js} +5 -14
  34. package/dist/chunks/{vi.DGAfBY4R.js → vi.BfdOiD4j.js} +110 -267
  35. package/dist/chunks/{vm.BKfKvaKl.js → vm.BHBje7cC.js} +73 -177
  36. package/dist/chunks/{worker.d.Db-UVmXc.d.ts → worker.d.BKu8cnnX.d.ts} +1 -1
  37. package/dist/chunks/{worker.d.D9QWnzAe.d.ts → worker.d.DYlqbejz.d.ts} +1 -1
  38. package/dist/cli.js +3 -3
  39. package/dist/config.d.ts +7 -7
  40. package/dist/coverage.d.ts +4 -4
  41. package/dist/coverage.js +2 -2
  42. package/dist/environments.js +1 -1
  43. package/dist/index.d.ts +6 -6
  44. package/dist/index.js +5 -5
  45. package/dist/module-evaluator.d.ts +3 -3
  46. package/dist/module-evaluator.js +33 -84
  47. package/dist/module-runner.js +2 -2
  48. package/dist/node.d.ts +11 -9
  49. package/dist/node.js +16 -27
  50. package/dist/reporters.d.ts +5 -5
  51. package/dist/reporters.js +3 -3
  52. package/dist/runners.d.ts +1 -1
  53. package/dist/runners.js +23 -51
  54. package/dist/snapshot.js +2 -2
  55. package/dist/suite.js +2 -2
  56. package/dist/worker.js +18 -34
  57. package/dist/workers/forks.js +4 -4
  58. package/dist/workers/runVmTests.js +19 -37
  59. package/dist/workers/threads.js +4 -4
  60. package/dist/workers/vmForks.js +7 -7
  61. package/dist/workers/vmThreads.js +7 -7
  62. package/dist/workers.d.ts +3 -3
  63. package/dist/workers.js +11 -11
  64. package/package.json +11 -11
@@ -1,9 +1,9 @@
1
1
  import * as chai from 'chai';
2
2
  import { resolve, join } from 'node:path';
3
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.lgPs-bYv.js';
3
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.hLGRxhC8.js';
4
4
  import { distDir } from '../path.js';
5
- import { r as rpc } from './rpc.DGoW_Vl-.js';
6
- import { g as getWorkerState } from './utils.B9FY3b73.js';
5
+ import { r as rpc } from './rpc.RpPylpp0.js';
6
+ import { g as getWorkerState } from './utils.C7__0Iv5.js';
7
7
 
8
8
  function setupChaiConfig(config) {
9
9
  Object.assign(chai.config, config);
@@ -11,7 +11,7 @@ function setupChaiConfig(config) {
11
11
 
12
12
  async function resolveSnapshotEnvironment(config, executor) {
13
13
  if (!config.snapshotEnvironment) {
14
- const { VitestNodeSnapshotEnvironment } = await import('./node.4JV5OXkt.js');
14
+ const { VitestNodeSnapshotEnvironment } = await import('./node.BOqcT2jW.js');
15
15
  return new VitestNodeSnapshotEnvironment();
16
16
  }
17
17
  const mod = await executor.import(config.snapshotEnvironment);
@@ -30,15 +30,12 @@ async function getTestRunnerConstructor(config, moduleRunner) {
30
30
  return mod.default;
31
31
  }
32
32
  async function resolveTestRunner(config, moduleRunner) {
33
- const TestRunner = await getTestRunnerConstructor(config, moduleRunner);
34
- const testRunner = new TestRunner(config);
35
- // inject private executor to every runner
36
- Object.defineProperty(testRunner, "moduleRunner", {
33
+ const TestRunner = await getTestRunnerConstructor(config, moduleRunner), testRunner = new TestRunner(config);
34
+ if (Object.defineProperty(testRunner, "moduleRunner", {
37
35
  value: moduleRunner,
38
36
  enumerable: false,
39
37
  configurable: false
40
- });
41
- if (!testRunner.config) testRunner.config = config;
38
+ }), !testRunner.config) testRunner.config = config;
42
39
  if (!testRunner.importFile) throw new Error("Runner must implement \"importFile\" method.");
43
40
  const [diffOptions] = await Promise.all([loadDiffConfig(config, moduleRunner), loadSnapshotSerializers(config, moduleRunner)]);
44
41
  testRunner.config.diffOptions = diffOptions;
@@ -46,39 +43,28 @@ async function resolveTestRunner(config, moduleRunner) {
46
43
  const originalOnTaskUpdate = testRunner.onTaskUpdate;
47
44
  testRunner.onTaskUpdate = async (task, events) => {
48
45
  const p = rpc().onTaskUpdate(task, events);
49
- await originalOnTaskUpdate?.call(testRunner, task, events);
50
- return p;
46
+ return await originalOnTaskUpdate?.call(testRunner, task, events), p;
51
47
  };
52
48
  // patch some methods, so custom runners don't need to call RPC
53
49
  const originalOnTestAnnotate = testRunner.onTestAnnotate;
54
50
  testRunner.onTestAnnotate = async (test, annotation) => {
55
- const p = rpc().onTaskAnnotate(test.id, annotation);
56
- const overriddenResult = await originalOnTestAnnotate?.call(testRunner, test, annotation);
57
- const vitestResult = await p;
51
+ const p = rpc().onTaskAnnotate(test.id, annotation), overriddenResult = await originalOnTestAnnotate?.call(testRunner, test, annotation), vitestResult = await p;
58
52
  return overriddenResult || vitestResult;
59
53
  };
60
54
  const originalOnCollectStart = testRunner.onCollectStart;
61
55
  testRunner.onCollectStart = async (file) => {
62
- await rpc().onQueued(file);
63
- await originalOnCollectStart?.call(testRunner, file);
56
+ await rpc().onQueued(file), await originalOnCollectStart?.call(testRunner, file);
64
57
  };
65
58
  const originalOnCollected = testRunner.onCollected;
66
59
  testRunner.onCollected = async (files) => {
67
60
  const state = getWorkerState();
68
61
  files.forEach((file) => {
69
- file.prepareDuration = state.durations.prepare;
70
- file.environmentLoad = state.durations.environment;
71
- // should be collected only for a single test file in a batch
72
- state.durations.prepare = 0;
73
- state.durations.environment = 0;
74
- });
75
- rpc().onCollected(files);
76
- await originalOnCollected?.call(testRunner, files);
62
+ file.prepareDuration = state.durations.prepare, file.environmentLoad = state.durations.environment, state.durations.prepare = 0, state.durations.environment = 0;
63
+ }), rpc().onCollected(files), await originalOnCollected?.call(testRunner, files);
77
64
  };
78
65
  const originalOnAfterRun = testRunner.onAfterRunFiles;
79
66
  testRunner.onAfterRunFiles = async (files) => {
80
- const state = getWorkerState();
81
- const coverage = await takeCoverageInsideWorker(config.coverage, moduleRunner);
67
+ const state = getWorkerState(), coverage = await takeCoverageInsideWorker(config.coverage, moduleRunner);
82
68
  if (coverage) rpc().onAfterSuiteRun({
83
69
  coverage,
84
70
  testFiles: files.map((file) => file.name).sort(),
@@ -88,18 +74,13 @@ async function resolveTestRunner(config, moduleRunner) {
88
74
  await originalOnAfterRun?.call(testRunner, files);
89
75
  };
90
76
  const originalOnAfterRunTask = testRunner.onAfterRunTask;
91
- testRunner.onAfterRunTask = async (test) => {
77
+ return testRunner.onAfterRunTask = async (test) => {
92
78
  if (config.bail && test.result?.state === "fail") {
93
- const previousFailures = await rpc().getCountOfFailedTests();
94
- const currentFailures = 1 + previousFailures;
95
- if (currentFailures >= config.bail) {
96
- rpc().onCancel("test-failure");
97
- testRunner.cancel?.("test-failure");
98
- }
79
+ const previousFailures = await rpc().getCountOfFailedTests(), currentFailures = 1 + previousFailures;
80
+ if (currentFailures >= config.bail) rpc().onCancel("test-failure"), testRunner.cancel?.("test-failure");
99
81
  }
100
82
  await originalOnAfterRunTask?.call(testRunner, test);
101
- };
102
- return testRunner;
83
+ }, testRunner;
103
84
  }
104
85
 
105
86
  export { resolveSnapshotEnvironment as a, resolveTestRunner as r, setupChaiConfig as s };
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import { getTasks, getFullName, getTests } from '@vitest/runner/utils';
3
3
  import * as pathe from 'pathe';
4
4
  import c from 'tinyrainbow';
5
- import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName } from './index.DQhAfQQU.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName } from './index.C3EbxYwt.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils';
8
8
 
@@ -98,19 +98,16 @@ function renderBenchmark(result, widths) {
98
98
  ].join(" ");
99
99
  }
100
100
  function renderTable(options) {
101
- const output = [];
102
- const benchMap = {};
101
+ const output = [], benchMap = {};
103
102
  for (const task of options.tasks) if (task.meta.benchmark && task.result?.benchmark) benchMap[task.id] = {
104
103
  current: task.result.benchmark,
105
104
  baseline: options.compare?.[task.id]
106
105
  };
107
- const benchCount = Object.entries(benchMap).length;
108
- const columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish));
106
+ const benchCount = Object.entries(benchMap).length, columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish));
109
107
  let idx = 0;
110
108
  const padding = " ".repeat(1 );
111
109
  for (const task of options.tasks) {
112
- const duration = task.result?.duration;
113
- const bench = benchMap[task.id];
110
+ const duration = task.result?.duration, bench = benchMap[task.id];
114
111
  let prefix = "";
115
112
  if (idx === 0 && task.meta?.benchmark) prefix += `${renderTableHead(columnWidths)}\n${padding}`;
116
113
  prefix += ` ${getStateSymbol(task)} `;
@@ -126,8 +123,7 @@ function renderTable(options) {
126
123
  let body = renderBenchmark(bench.current, columnWidths);
127
124
  if (options.compare && bench.baseline) {
128
125
  if (bench.current.hz) {
129
- const diff = bench.current.hz / bench.baseline.hz;
130
- const diffFixed = diff.toFixed(2);
126
+ const diff = bench.current.hz / bench.baseline.hz, diffFixed = diff.toFixed(2);
131
127
  if (diffFixed === "1.0.0") body += c.gray(` [${diffFixed}x]`);
132
128
  if (diff > 1) body += c.blue(` [${diffFixed}x] ⇑`);
133
129
  else body += c.red(` [${diffFixed}x] ⇓`);
@@ -144,8 +140,7 @@ function renderTable(options) {
144
140
  if (task.result?.state !== "pass" && outputMap.get(task) != null) {
145
141
  let data = outputMap.get(task);
146
142
  if (typeof data === "string") {
147
- data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop());
148
- if (data === "") data = void 0;
143
+ if (data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop()), data === "") data = void 0;
149
144
  }
150
145
  if (data != null) {
151
146
  const out = ` ${" ".repeat(options.level)}${F_RIGHT} ${data}`;
@@ -160,8 +155,7 @@ function renderTable(options) {
160
155
  class BenchmarkReporter extends DefaultReporter {
161
156
  compare;
162
157
  async onInit(ctx) {
163
- super.onInit(ctx);
164
- if (this.ctx.config.benchmark?.compare) {
158
+ if (super.onInit(ctx), this.ctx.config.benchmark?.compare) {
165
159
  const compareFile = pathe.resolve(this.ctx.config.root, this.ctx.config.benchmark?.compare);
166
160
  try {
167
161
  this.compare = flattenFormattedBenchmarkReport(JSON.parse(await fs.promises.readFile(compareFile, "utf-8")));
@@ -179,8 +173,7 @@ class BenchmarkReporter extends DefaultReporter {
179
173
  }
180
174
  }
181
175
  onTestSuiteResult(testSuite) {
182
- super.onTestSuiteResult(testSuite);
183
- this.printSuiteTable(testSuite);
176
+ super.onTestSuiteResult(testSuite), this.printSuiteTable(testSuite);
184
177
  }
185
178
  printTestModule(testModule) {
186
179
  this.printSuiteTable(testModule);
@@ -188,13 +181,11 @@ class BenchmarkReporter extends DefaultReporter {
188
181
  printSuiteTable(testTask) {
189
182
  const state = testTask.state();
190
183
  if (state === "pending" || state === "queued") return;
191
- const benches = testTask.task.tasks.filter((t) => t.meta.benchmark);
192
- const duration = testTask.task.result?.duration || 0;
184
+ const benches = testTask.task.tasks.filter((t) => t.meta.benchmark), duration = testTask.task.result?.duration || 0;
193
185
  if (benches.length > 0 && benches.every((t) => t.result?.state !== "run" && t.result?.state !== "queued")) {
194
186
  let title = `\n ${getStateSymbol(testTask.task)} ${formatProjectName(testTask.project)}${getFullName(testTask.task, c.dim(" > "))}`;
195
187
  if (duration != null && duration > this.ctx.config.slowTestThreshold) title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
196
- this.log(title);
197
- this.log(renderTable({
188
+ this.log(title), this.log(renderTable({
198
189
  tasks: benches,
199
190
  level: 1,
200
191
  columns: this.ctx.logger.getColumns(),
@@ -204,17 +195,16 @@ class BenchmarkReporter extends DefaultReporter {
204
195
  }));
205
196
  }
206
197
  }
207
- async onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
208
- super.onFinished(files, errors);
198
+ async onTestRunEnd(testModules, unhandledErrors, reason) {
199
+ super.onTestRunEnd(testModules, unhandledErrors, reason);
209
200
  // write output for future comparison
210
201
  let outputFile = this.ctx.config.benchmark?.outputJson;
211
202
  if (outputFile) {
212
203
  outputFile = pathe.resolve(this.ctx.config.root, outputFile);
213
204
  const outputDirectory = pathe.dirname(outputFile);
214
205
  if (!fs.existsSync(outputDirectory)) await fs.promises.mkdir(outputDirectory, { recursive: true });
215
- const output = createBenchmarkJsonReport(files);
216
- await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
217
- this.log(`Benchmark report written to ${outputFile}`);
206
+ const files = testModules.map((t) => t.task.file), output = createBenchmarkJsonReport(files);
207
+ await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2)), this.log(`Benchmark report written to ${outputFile}`);
218
208
  }
219
209
  }
220
210
  }
@@ -3,8 +3,6 @@ import { Console } from 'node:console';
3
3
  // SEE https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/interfaces.js
4
4
  const LIVING_KEYS = [
5
5
  "DOMException",
6
- "URL",
7
- "URLSearchParams",
8
6
  "EventTarget",
9
7
  "NamedNodeMap",
10
8
  "Node",
@@ -161,9 +159,6 @@ const LIVING_KEYS = [
161
159
  "ShadowRoot",
162
160
  "MutationObserver",
163
161
  "MutationRecord",
164
- "Headers",
165
- "AbortController",
166
- "AbortSignal",
167
162
  "Uint8Array",
168
163
  "Uint16Array",
169
164
  "Uint32Array",
@@ -180,8 +175,7 @@ const LIVING_KEYS = [
180
175
  "Audio",
181
176
  "Option",
182
177
  "CSS"
183
- ];
184
- const OTHER_KEYS = [
178
+ ], OTHER_KEYS = [
185
179
  "addEventListener",
186
180
  "alert",
187
181
  "blur",
@@ -244,11 +238,8 @@ const skipKeys = [
244
238
  "parent"
245
239
  ];
246
240
  function getWindowKeys(global, win, additionalKeys = []) {
247
- const keysArray = [...additionalKeys, ...KEYS];
248
- const keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
249
- if (skipKeys.includes(k)) return false;
250
- if (k in global) return keysArray.includes(k);
251
- return true;
241
+ const keysArray = [...additionalKeys, ...KEYS], keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
242
+ return skipKeys.includes(k) ? false : k in global ? keysArray.includes(k) : true;
252
243
  }));
253
244
  return keys;
254
245
  }
@@ -256,18 +247,13 @@ function isClassLikeName(name) {
256
247
  return name[0] === name[0].toUpperCase();
257
248
  }
258
249
  function populateGlobal(global, win, options = {}) {
259
- const { bindFunctions = false } = options;
260
- const keys = getWindowKeys(global, win, options.additionalKeys);
261
- const originals = /* @__PURE__ */ new Map();
262
- const overrideObject = /* @__PURE__ */ new Map();
250
+ const { bindFunctions = false } = options, keys = getWindowKeys(global, win, options.additionalKeys), originals = /* @__PURE__ */ new Map(), overrideObject = /* @__PURE__ */ new Map();
263
251
  for (const key of keys) {
264
252
  const boundFunction = bindFunctions && typeof win[key] === "function" && !isClassLikeName(key) && win[key].bind(win);
265
253
  if (KEYS.includes(key) && key in global) originals.set(key, global[key]);
266
254
  Object.defineProperty(global, key, {
267
255
  get() {
268
- if (overrideObject.has(key)) return overrideObject.get(key);
269
- if (boundFunction) return boundFunction;
270
- return win[key];
256
+ return overrideObject.has(key) ? overrideObject.get(key) : boundFunction || win[key];
271
257
  },
272
258
  set(v) {
273
259
  overrideObject.set(key, v);
@@ -275,19 +261,14 @@ function populateGlobal(global, win, options = {}) {
275
261
  configurable: true
276
262
  });
277
263
  }
278
- global.window = global;
279
- global.self = global;
280
- global.top = global;
281
- global.parent = global;
282
- if (global.global) global.global = global;
264
+ if (global.window = global, global.self = global, global.top = global, global.parent = global, global.global) global.global = global;
283
265
  // rewrite defaultView to reference the same global context
284
266
  if (global.document && global.document.defaultView) Object.defineProperty(global.document, "defaultView", {
285
267
  get: () => global,
286
268
  enumerable: true,
287
269
  configurable: true
288
270
  });
289
- skipKeys.forEach((k) => keys.add(k));
290
- return {
271
+ return skipKeys.forEach((k) => keys.add(k)), {
291
272
  keys,
292
273
  skipKeys,
293
274
  originals
@@ -298,11 +279,8 @@ var edge = {
298
279
  name: "edge-runtime",
299
280
  viteEnvironment: "ssr",
300
281
  async setupVM() {
301
- const { EdgeVM } = await import('@edge-runtime/vm');
302
- const vm = new EdgeVM({ extend: (context) => {
303
- context.global = context;
304
- context.Buffer = Buffer;
305
- return context;
282
+ const { EdgeVM } = await import('@edge-runtime/vm'), vm = new EdgeVM({ extend: (context) => {
283
+ return context.global = context, context.Buffer = Buffer, context;
306
284
  } });
307
285
  return {
308
286
  getVmContext() {
@@ -314,28 +292,20 @@ var edge = {
314
292
  };
315
293
  },
316
294
  async setup(global) {
317
- const { EdgeVM } = await import('@edge-runtime/vm');
318
- const vm = new EdgeVM({ extend: (context) => {
319
- context.global = context;
320
- context.Buffer = Buffer;
321
- KEYS.forEach((key) => {
295
+ const { EdgeVM } = await import('@edge-runtime/vm'), vm = new EdgeVM({ extend: (context) => {
296
+ return context.global = context, context.Buffer = Buffer, KEYS.forEach((key) => {
322
297
  if (key in global) context[key] = global[key];
323
- });
324
- return context;
325
- } });
326
- const { keys, originals } = populateGlobal(global, vm.context, { bindFunctions: true });
298
+ }), context;
299
+ } }), { keys, originals } = populateGlobal(global, vm.context, { bindFunctions: true });
327
300
  return { teardown(global) {
328
- keys.forEach((key) => delete global[key]);
329
- originals.forEach((v, k) => global[k] = v);
301
+ keys.forEach((key) => delete global[key]), originals.forEach((v, k) => global[k] = v);
330
302
  } };
331
303
  }
332
304
  };
333
305
 
334
306
  async function teardownWindow(win) {
335
- if (win.close && win.happyDOM.abort) {
336
- await win.happyDOM.abort();
337
- win.close();
338
- } else win.happyDOM.cancelAsync();
307
+ if (win.close && win.happyDOM.abort) await win.happyDOM.abort(), win.close();
308
+ else win.happyDOM.cancelAsync();
339
309
  }
340
310
  var happy = {
341
311
  name: "happy-dom",
@@ -351,25 +321,21 @@ var happy = {
351
321
  disableErrorCapturing: true
352
322
  }
353
323
  });
354
- // TODO: browser doesn't expose Buffer, but a lot of dependencies use it
355
- win.Buffer = Buffer;
356
324
  // inject structuredClone if it exists
357
- if (typeof structuredClone !== "undefined" && !win.structuredClone) win.structuredClone = structuredClone;
325
+ if (win.Buffer = Buffer, typeof structuredClone !== "undefined" && !win.structuredClone) win.structuredClone = structuredClone;
358
326
  return {
359
327
  getVmContext() {
360
328
  return win;
361
329
  },
362
330
  async teardown() {
363
- await teardownWindow(win);
364
- win = void 0;
331
+ await teardownWindow(win), win = void 0;
365
332
  }
366
333
  };
367
334
  },
368
335
  async setup(global, { happyDOM = {} }) {
369
336
  // happy-dom v3 introduced a breaking change to Window, but
370
337
  // provides GlobalWindow as a way to use previous behaviour
371
- const { Window, GlobalWindow } = await import('happy-dom');
372
- const win = new (GlobalWindow || Window)({
338
+ const { Window, GlobalWindow } = await import('happy-dom'), win = new (GlobalWindow || Window)({
373
339
  ...happyDOM,
374
340
  console: console && global.console ? global.console : void 0,
375
341
  url: happyDOM.url || "http://localhost:3000",
@@ -377,8 +343,7 @@ var happy = {
377
343
  ...happyDOM.settings,
378
344
  disableErrorCapturing: true
379
345
  }
380
- });
381
- const { keys, originals } = populateGlobal(global, win, {
346
+ }), { keys, originals } = populateGlobal(global, win, {
382
347
  bindFunctions: true,
383
348
  additionalKeys: [
384
349
  "Request",
@@ -388,9 +353,7 @@ var happy = {
388
353
  ]
389
354
  });
390
355
  return { async teardown(global) {
391
- await teardownWindow(win);
392
- keys.forEach((key) => delete global[key]);
393
- originals.forEach((v, k) => global[k] = v);
356
+ await teardownWindow(win), keys.forEach((key) => delete global[key]), originals.forEach((v, k) => global[k] = v);
394
357
  } };
395
358
  }
396
359
  };
@@ -400,18 +363,14 @@ function catchWindowErrors(window) {
400
363
  function throwUnhandlerError(e) {
401
364
  if (userErrorListenerCount === 0 && e.error != null) process.emit("uncaughtException", e.error);
402
365
  }
403
- const addEventListener = window.addEventListener.bind(window);
404
- const removeEventListener = window.removeEventListener.bind(window);
405
- window.addEventListener("error", throwUnhandlerError);
406
- window.addEventListener = function(...args) {
366
+ const addEventListener = window.addEventListener.bind(window), removeEventListener = window.removeEventListener.bind(window);
367
+ return window.addEventListener("error", throwUnhandlerError), window.addEventListener = function(...args) {
407
368
  if (args[0] === "error") userErrorListenerCount++;
408
369
  return addEventListener.apply(this, args);
409
- };
410
- window.removeEventListener = function(...args) {
370
+ }, window.removeEventListener = function(...args) {
411
371
  if (args[0] === "error" && userErrorListenerCount) userErrorListenerCount--;
412
372
  return removeEventListener.apply(this, args);
413
- };
414
- return function clearErrorHandlers() {
373
+ }, function clearErrorHandlers() {
415
374
  window.removeEventListener("error", throwUnhandlerError);
416
375
  };
417
376
  }
@@ -419,8 +378,7 @@ var jsdom = {
419
378
  name: "jsdom",
420
379
  viteEnvironment: "client",
421
380
  async setupVM({ jsdom = {} }) {
422
- const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom');
423
- const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
381
+ const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom'), { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
424
382
  let dom = new JSDOM(html, {
425
383
  pretendToBeVisual,
426
384
  resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
@@ -434,16 +392,11 @@ var jsdom = {
434
392
  ...restOptions
435
393
  });
436
394
  const clearWindowErrors = catchWindowErrors(dom.window);
437
- // TODO: browser doesn't expose Buffer, but a lot of dependencies use it
438
- dom.window.Buffer = Buffer;
439
- dom.window.jsdom = dom;
395
+ dom.window.Buffer = Buffer, dom.window.jsdom = dom;
440
396
  // inject web globals if they missing in JSDOM but otherwise available in Nodejs
441
397
  // https://nodejs.org/dist/latest/docs/api/globals.html
442
398
  const globalNames = [
443
399
  "structuredClone",
444
- "fetch",
445
- "Request",
446
- "Response",
447
400
  "BroadcastChannel",
448
401
  "MessageChannel",
449
402
  "MessagePort",
@@ -454,21 +407,33 @@ var jsdom = {
454
407
  const value = globalThis[name];
455
408
  if (typeof value !== "undefined" && typeof dom.window[name] === "undefined") dom.window[name] = value;
456
409
  }
410
+ // since we are providing Node.js's Fetch API,
411
+ // we also should override other APIs they use
412
+ const overrideGlobals = [
413
+ "fetch",
414
+ "Request",
415
+ "Response",
416
+ "Headers",
417
+ "AbortController",
418
+ "AbortSignal",
419
+ "URL",
420
+ "URLSearchParams"
421
+ ];
422
+ for (const name of overrideGlobals) {
423
+ const value = globalThis[name];
424
+ if (typeof value !== "undefined") dom.window[name] = value;
425
+ }
457
426
  return {
458
427
  getVmContext() {
459
428
  return dom.getInternalVMContext();
460
429
  },
461
430
  teardown() {
462
- clearWindowErrors();
463
- dom.window.close();
464
- dom = void 0;
431
+ clearWindowErrors(), dom.window.close(), dom = void 0;
465
432
  }
466
433
  };
467
434
  },
468
435
  async setup(global, { jsdom = {} }) {
469
- const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom');
470
- const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
471
- const dom = new JSDOM(html, {
436
+ const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom'), { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom, dom = new JSDOM(html, {
472
437
  pretendToBeVisual,
473
438
  resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
474
439
  runScripts,
@@ -479,16 +444,9 @@ var jsdom = {
479
444
  contentType,
480
445
  userAgent,
481
446
  ...restOptions
482
- });
483
- const { keys, originals } = populateGlobal(global, dom.window, { bindFunctions: true });
484
- const clearWindowErrors = catchWindowErrors(global);
485
- global.jsdom = dom;
486
- return { teardown(global) {
487
- clearWindowErrors();
488
- dom.window.close();
489
- delete global.jsdom;
490
- keys.forEach((key) => delete global[key]);
491
- originals.forEach((v, k) => global[k] = v);
447
+ }), { keys, originals } = populateGlobal(global, dom.window, { bindFunctions: true }), clearWindowErrors = catchWindowErrors(global);
448
+ return global.jsdom = dom, { teardown(global) {
449
+ clearWindowErrors(), dom.window.close(), delete global.jsdom, keys.forEach((key) => delete global[key]), originals.forEach((v, k) => global[k] = v);
492
450
  } };
493
451
  }
494
452
  };
@@ -501,8 +459,7 @@ const denyList = new Set([
501
459
  "Buffer",
502
460
  "ArrayBuffer",
503
461
  "Uint8Array"
504
- ]);
505
- const nodeGlobals = new Map(Object.getOwnPropertyNames(globalThis).filter((global) => !denyList.has(global)).map((nodeGlobalsKey) => {
462
+ ]), nodeGlobals = new Map(Object.getOwnPropertyNames(globalThis).filter((global) => !denyList.has(global)).map((nodeGlobalsKey) => {
506
463
  const descriptor = Object.getOwnPropertyDescriptor(globalThis, nodeGlobalsKey);
507
464
  if (!descriptor) throw new Error(`No property descriptor for ${nodeGlobalsKey}, this is a bug in Vitest.`);
508
465
  return [nodeGlobalsKey, descriptor];
@@ -512,8 +469,7 @@ var node = {
512
469
  viteEnvironment: "ssr",
513
470
  async setupVM() {
514
471
  const vm = await import('node:vm');
515
- let context = vm.createContext();
516
- let global = vm.runInContext("this", context);
472
+ let context = vm.createContext(), global = vm.runInContext("this", context);
517
473
  const contextGlobals = new Set(Object.getOwnPropertyNames(global));
518
474
  for (const [nodeGlobalsKey, descriptor] of nodeGlobals) if (!contextGlobals.has(nodeGlobalsKey)) if (descriptor.configurable) Object.defineProperty(global, nodeGlobalsKey, {
519
475
  configurable: true,
@@ -521,14 +477,12 @@ var node = {
521
477
  get() {
522
478
  // @ts-expect-error: no index signature
523
479
  const val = globalThis[nodeGlobalsKey];
524
- // override lazy getter
525
- Object.defineProperty(global, nodeGlobalsKey, {
480
+ return Object.defineProperty(global, nodeGlobalsKey, {
526
481
  configurable: true,
527
482
  enumerable: descriptor.enumerable,
528
483
  value: val,
529
484
  writable: descriptor.writable === true || nodeGlobalsKey === "performance"
530
- });
531
- return val;
485
+ }), val;
532
486
  },
533
487
  set(val) {
534
488
  // override lazy getter
@@ -552,26 +506,17 @@ var node = {
552
506
  get: descriptor.get,
553
507
  set: descriptor.set
554
508
  });
555
- global.global = global;
556
- global.Buffer = Buffer;
557
- global.ArrayBuffer = ArrayBuffer;
558
- // TextEncoder (global or via 'util') references a Uint8Array constructor
559
- // different than the global one used by users in tests. This makes sure the
560
- // same constructor is referenced by both.
561
- global.Uint8Array = Uint8Array;
562
- return {
509
+ return global.global = global, global.Buffer = Buffer, global.ArrayBuffer = ArrayBuffer, global.Uint8Array = Uint8Array, {
563
510
  getVmContext() {
564
511
  return context;
565
512
  },
566
513
  teardown() {
567
- context = void 0;
568
- global = void 0;
514
+ context = void 0, global = void 0;
569
515
  }
570
516
  };
571
517
  },
572
518
  async setup(global) {
573
- global.console.Console = Console;
574
- return { teardown(global) {
519
+ return global.console.Console = Console, { teardown(global) {
575
520
  delete global.console.Console;
576
521
  } };
577
522
  }
@@ -2,55 +2,40 @@ import { createRequire } from 'node:module';
2
2
  import { pathToFileURL } from 'node:url';
3
3
 
4
4
  const __require = createRequire(import.meta.url);
5
- let inspector;
6
- let session;
5
+ let inspector, session;
7
6
  /**
8
7
  * Enables debugging inside `worker_threads` and `child_process`.
9
8
  * Should be called as early as possible when worker/process has been set up.
10
9
  */
11
10
  function setupInspect(ctx) {
12
- const config = ctx.config;
13
- const isEnabled = config.inspector.enabled;
11
+ const config = ctx.config, isEnabled = config.inspector.enabled;
14
12
  if (isEnabled) {
15
13
  inspector = __require("node:inspector");
16
14
  // Inspector may be open already if "isolate: false" is used
17
15
  const isOpen = inspector.url() !== void 0;
18
16
  if (!isOpen) {
19
- inspector.open(config.inspector.port, config.inspector.host, config.inspector.waitForDebugger);
20
- if (config.inspectBrk) {
17
+ if (inspector.open(config.inspector.port, config.inspector.host, config.inspector.waitForDebugger), config.inspectBrk) {
21
18
  const firstTestFile = typeof ctx.files[0] === "string" ? ctx.files[0] : ctx.files[0].filepath;
22
19
  // Stop at first test file
23
- if (firstTestFile) {
24
- session = new inspector.Session();
25
- session.connect();
26
- session.post("Debugger.enable");
27
- session.post("Debugger.setBreakpointByUrl", {
28
- lineNumber: 0,
29
- url: pathToFileURL(firstTestFile)
30
- });
31
- }
20
+ if (firstTestFile) session = new inspector.Session(), session.connect(), session.post("Debugger.enable"), session.post("Debugger.setBreakpointByUrl", {
21
+ lineNumber: 0,
22
+ url: pathToFileURL(firstTestFile)
23
+ });
32
24
  }
33
25
  }
34
26
  }
35
27
  const keepOpen = shouldKeepOpen(config);
36
28
  return function cleanup() {
37
- if (isEnabled && !keepOpen && inspector) {
38
- inspector.close();
39
- session?.disconnect();
40
- }
29
+ if (isEnabled && !keepOpen && inspector) inspector.close(), session?.disconnect();
41
30
  };
42
31
  }
43
32
  function closeInspector(config) {
44
33
  const keepOpen = shouldKeepOpen(config);
45
- if (inspector && !keepOpen) {
46
- inspector.close();
47
- session?.disconnect();
48
- }
34
+ if (inspector && !keepOpen) inspector.close(), session?.disconnect();
49
35
  }
50
36
  function shouldKeepOpen(config) {
51
37
  // In watch mode the inspector can persist re-runs if isolation is disabled and a single worker is used
52
- const isIsolatedSingleThread = config.pool === "threads" && config.poolOptions?.threads?.isolate === false && config.poolOptions?.threads?.singleThread;
53
- const isIsolatedSingleFork = config.pool === "forks" && config.poolOptions?.forks?.isolate === false && config.poolOptions?.forks?.singleFork;
38
+ const isIsolatedSingleThread = config.pool === "threads" && config.poolOptions?.threads?.isolate === false && config.poolOptions?.threads?.singleThread, isIsolatedSingleFork = config.pool === "forks" && config.poolOptions?.forks?.isolate === false && config.poolOptions?.forks?.singleFork;
54
39
  return config.watch && (isIsolatedSingleFork || isIsolatedSingleThread);
55
40
  }
56
41
 
@@ -1,6 +1,6 @@
1
1
  import vm from 'node:vm';
2
2
  import { ModuleEvaluator, ModuleRunnerImportMeta, ModuleRunnerContext, EvaluatedModuleNode, FetchFunction, ModuleRunner, EvaluatedModules } from 'vite/module-runner';
3
- import { R as RuntimeRPC, W as WorkerGlobalState } from './worker.d.D9QWnzAe.js';
3
+ import { R as RuntimeRPC, W as WorkerGlobalState } from './worker.d.DYlqbejz.js';
4
4
  import { R as ResolveFunctionResult } from './environment.d.2fYMoz3o.js';
5
5
  import { MockedModule, MockedModuleType } from '@vitest/mocker';
6
6
  import { P as PendingSuiteMock, b as MockFactory, a as MockOptions } from './mocker.d.BE_2ls6u.js';
@@ -159,7 +159,7 @@ declare class VitestMocker {
159
159
  getMockPath(dep: string): string;
160
160
  getDependencyMock(id: string): MockedModule | undefined;
161
161
  findMockRedirect(mockPath: string, external: string | null): string | null;
162
- mockObject(object: Record<string | symbol, any>, mockExports?: Record<string | symbol, any>, behavior?: MockedModuleType): Record<string | symbol, any>;
162
+ mockObject(object: Record<string | symbol, any>, mockExports?: Record<string | symbol, any>, behavior?: "automock" | "autospy"): Record<string | symbol, any>;
163
163
  unmockPath(id: string): void;
164
164
  mockPath(originalId: string, id: string, url: string, external: string | null, mockType: MockedModuleType | undefined, factory: MockFactory | undefined): void;
165
165
  importActual<T>(rawId: string, importer: string, callstack?: string[] | null): Promise<T>;
@@ -1,5 +1,5 @@
1
1
  import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
2
- import { g as getWorkerState } from './utils.B9FY3b73.js';
2
+ import { g as getWorkerState } from './utils.C7__0Iv5.js';
3
3
  import '@vitest/utils';
4
4
 
5
5
  class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {