vitest 3.2.0-beta.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE.md +29 -0
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{base.DwtwORaC.js → base.Cg0miDlQ.js} +11 -14
  5. package/dist/chunks/{benchmark.BoF7jW0Q.js → benchmark.CYdenmiT.js} +4 -6
  6. package/dist/chunks/{cac.I9MLYfT-.js → cac.6rXCxFY1.js} +76 -143
  7. package/dist/chunks/{cli-api.d6IK1pnk.js → cli-api.Cej3MBjA.js} +1460 -1344
  8. package/dist/chunks/{config.d.UqE-KR0o.d.ts → config.d.D2ROskhv.d.ts} +2 -0
  9. package/dist/chunks/{console.K1NMVOSc.js → console.CtFJOzRO.js} +25 -45
  10. package/dist/chunks/{constants.BZZyIeIE.js → constants.DnKduX2e.js} +1 -0
  11. package/dist/chunks/{coverage.0iPg4Wrz.js → coverage.DVF1vEu8.js} +4 -12
  12. package/dist/chunks/{coverage.OGU09Jbh.js → coverage.EIiagJJP.js} +578 -993
  13. package/dist/chunks/{creator.DGAdZ4Hj.js → creator.GK6I-cL4.js} +39 -83
  14. package/dist/chunks/date.Bq6ZW5rf.js +73 -0
  15. package/dist/chunks/{defaults.DSxsTG0h.js → defaults.B7q_naMc.js} +2 -1
  16. package/dist/chunks/{env.Dq0hM4Xv.js → env.D4Lgay0q.js} +1 -1
  17. package/dist/chunks/{environment.d.D8YDy2v5.d.ts → environment.d.cL3nLXbE.d.ts} +1 -0
  18. package/dist/chunks/{execute.JlGHLJZT.js → execute.B7h3T_Hc.js} +126 -217
  19. package/dist/chunks/{git.DXfdBEfR.js → git.BVQ8w_Sw.js} +1 -3
  20. package/dist/chunks/{global.d.BPa1eL3O.d.ts → global.d.MAmajcmJ.d.ts} +5 -1
  21. package/dist/chunks/{globals.CpxW8ccg.js → globals.DEHgCU4V.js} +7 -6
  22. package/dist/chunks/{index.CV36oG_L.js → index.BZ0g1JD2.js} +430 -625
  23. package/dist/chunks/{index.DswW_LEs.js → index.BbB8_kAK.js} +25 -24
  24. package/dist/chunks/{index.CmC5OK9L.js → index.CIyJn3t1.js} +38 -82
  25. package/dist/chunks/{index.CfXMNXHg.js → index.CdQS2e2Q.js} +4 -2
  26. package/dist/chunks/{index.DFXFpH3w.js → index.CmSc2RE5.js} +85 -105
  27. package/dist/chunks/index.D3XRDfWc.js +213 -0
  28. package/dist/chunks/{inspector.DbDkSkFn.js → inspector.C914Efll.js} +4 -1
  29. package/dist/chunks/{node.3xsWotC9.js → node.fjCdwEIl.js} +1 -1
  30. package/dist/chunks/{reporters.d.CLC9rhKy.d.ts → reporters.d.C1ogPriE.d.ts} +47 -9
  31. package/dist/chunks/{rpc.D9_013TY.js → rpc.Iovn4oWe.js} +10 -19
  32. package/dist/chunks/{runBaseTests.Dn2vyej_.js → runBaseTests.Dd85QTll.js} +27 -31
  33. package/dist/chunks/{setup-common.CYo3Y0dD.js → setup-common.Dd054P77.js} +16 -42
  34. package/dist/chunks/{typechecker.DnTrplSJ.js → typechecker.DRKU1-1g.js} +163 -186
  35. package/dist/chunks/{utils.BfxieIyZ.js → utils.CAioKnHs.js} +9 -14
  36. package/dist/chunks/{utils.CgTj3MsC.js → utils.XdZDrNZV.js} +6 -13
  37. package/dist/chunks/{vi.BFR5YIgu.js → vi.bdSIJ99Y.js} +137 -263
  38. package/dist/chunks/{vite.d.CBZ3M_ru.d.ts → vite.d.DqE4-hhK.d.ts} +3 -1
  39. package/dist/chunks/{vm.C1HHjtNS.js → vm.BThCzidc.js} +164 -212
  40. package/dist/chunks/{worker.d.D5Xdi-Zr.d.ts → worker.d.DvqK5Vmu.d.ts} +1 -1
  41. package/dist/chunks/{worker.d.CoCI7hzP.d.ts → worker.d.tQu2eJQy.d.ts} +5 -3
  42. package/dist/cli.js +5 -5
  43. package/dist/config.cjs +3 -1
  44. package/dist/config.d.ts +7 -6
  45. package/dist/config.js +3 -3
  46. package/dist/coverage.d.ts +4 -4
  47. package/dist/coverage.js +7 -7
  48. package/dist/environments.d.ts +6 -2
  49. package/dist/environments.js +1 -1
  50. package/dist/execute.d.ts +9 -3
  51. package/dist/execute.js +1 -1
  52. package/dist/index.d.ts +28 -15
  53. package/dist/index.js +5 -5
  54. package/dist/node.d.ts +18 -10
  55. package/dist/node.js +17 -17
  56. package/dist/reporters.d.ts +4 -4
  57. package/dist/reporters.js +4 -4
  58. package/dist/runners.d.ts +6 -3
  59. package/dist/runners.js +59 -80
  60. package/dist/snapshot.js +2 -2
  61. package/dist/suite.js +2 -2
  62. package/dist/worker.js +39 -41
  63. package/dist/workers/forks.js +6 -4
  64. package/dist/workers/runVmTests.js +20 -21
  65. package/dist/workers/threads.js +4 -4
  66. package/dist/workers/vmForks.js +6 -6
  67. package/dist/workers/vmThreads.js +6 -6
  68. package/dist/workers.d.ts +4 -4
  69. package/dist/workers.js +10 -10
  70. package/package.json +21 -19
  71. package/dist/chunks/date.CDOsz-HY.js +0 -53
  72. package/dist/chunks/index.CK1YOQaa.js +0 -143
@@ -1,9 +1,9 @@
1
1
  import * as chai from 'chai';
2
2
  import { resolve } from 'node:path';
3
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.CYo3Y0dD.js';
3
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.Dd054P77.js';
4
4
  import { distDir } from '../path.js';
5
- import { r as rpc } from './rpc.D9_013TY.js';
6
- import { g as getWorkerState } from './utils.CgTj3MsC.js';
5
+ import { r as rpc } from './rpc.Iovn4oWe.js';
6
+ import { g as getWorkerState } from './utils.XdZDrNZV.js';
7
7
 
8
8
  function setupChaiConfig(config) {
9
9
  Object.assign(chai.config, config);
@@ -11,13 +11,11 @@ function setupChaiConfig(config) {
11
11
 
12
12
  async function resolveSnapshotEnvironment(config, executor) {
13
13
  if (!config.snapshotEnvironment) {
14
- const { VitestNodeSnapshotEnvironment } = await import('./node.3xsWotC9.js');
14
+ const { VitestNodeSnapshotEnvironment } = await import('./node.fjCdwEIl.js');
15
15
  return new VitestNodeSnapshotEnvironment();
16
16
  }
17
17
  const mod = await executor.executeId(config.snapshotEnvironment);
18
- if (typeof mod.default !== "object" || !mod.default) {
19
- throw new Error("Snapshot environment module must have a default export object with a shape of `SnapshotEnvironment`");
20
- }
18
+ if (typeof mod.default !== "object" || !mod.default) throw new Error("Snapshot environment module must have a default export object with a shape of `SnapshotEnvironment`");
21
19
  return mod.default;
22
20
  }
23
21
 
@@ -28,33 +26,37 @@ async function getTestRunnerConstructor(config, executor) {
28
26
  return config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner;
29
27
  }
30
28
  const mod = await executor.executeId(config.runner);
31
- if (!mod.default && typeof mod.default !== "function") {
32
- throw new Error(`Runner must export a default function, but got ${typeof mod.default} imported from ${config.runner}`);
33
- }
29
+ if (!mod.default && typeof mod.default !== "function") throw new Error(`Runner must export a default function, but got ${typeof mod.default} imported from ${config.runner}`);
34
30
  return mod.default;
35
31
  }
36
32
  async function resolveTestRunner(config, executor) {
37
33
  const TestRunner = await getTestRunnerConstructor(config, executor);
38
34
  const testRunner = new TestRunner(config);
35
+ // inject private executor to every runner
39
36
  Object.defineProperty(testRunner, "__vitest_executor", {
40
37
  value: executor,
41
38
  enumerable: false,
42
39
  configurable: false
43
40
  });
44
- if (!testRunner.config) {
45
- testRunner.config = config;
46
- }
47
- if (!testRunner.importFile) {
48
- throw new Error("Runner must implement \"importFile\" method.");
49
- }
41
+ if (!testRunner.config) testRunner.config = config;
42
+ if (!testRunner.importFile) throw new Error("Runner must implement \"importFile\" method.");
50
43
  const [diffOptions] = await Promise.all([loadDiffConfig(config, executor), loadSnapshotSerializers(config, executor)]);
51
44
  testRunner.config.diffOptions = diffOptions;
45
+ // patch some methods, so custom runners don't need to call RPC
52
46
  const originalOnTaskUpdate = testRunner.onTaskUpdate;
53
47
  testRunner.onTaskUpdate = async (task, events) => {
54
48
  const p = rpc().onTaskUpdate(task, events);
55
49
  await originalOnTaskUpdate?.call(testRunner, task, events);
56
50
  return p;
57
51
  };
52
+ // patch some methods, so custom runners don't need to call RPC
53
+ const originalOnTestAnnotate = testRunner.onTestAnnotate;
54
+ testRunner.onTestAnnotate = async (test, annotation) => {
55
+ const p = rpc().onTaskAnnotate(test.id, annotation);
56
+ const overridenResult = await originalOnTestAnnotate?.call(testRunner, test, annotation);
57
+ const vitestResult = await p;
58
+ return overridenResult || vitestResult;
59
+ };
58
60
  const originalOnCollectStart = testRunner.onCollectStart;
59
61
  testRunner.onCollectStart = async (file) => {
60
62
  await rpc().onQueued(file);
@@ -66,6 +68,7 @@ async function resolveTestRunner(config, executor) {
66
68
  files.forEach((file) => {
67
69
  file.prepareDuration = state.durations.prepare;
68
70
  file.environmentLoad = state.durations.environment;
71
+ // should be collected only for a single test file in a batch
69
72
  state.durations.prepare = 0;
70
73
  state.durations.environment = 0;
71
74
  });
@@ -76,14 +79,12 @@ async function resolveTestRunner(config, executor) {
76
79
  testRunner.onAfterRunFiles = async (files) => {
77
80
  const state = getWorkerState();
78
81
  const coverage = await takeCoverageInsideWorker(config.coverage, executor);
79
- if (coverage) {
80
- rpc().onAfterSuiteRun({
81
- coverage,
82
- testFiles: files.map((file) => file.name).sort(),
83
- transformMode: state.environment.transformMode,
84
- projectName: state.ctx.projectName
85
- });
86
- }
82
+ if (coverage) rpc().onAfterSuiteRun({
83
+ coverage,
84
+ testFiles: files.map((file) => file.name).sort(),
85
+ transformMode: state.environment.transformMode,
86
+ projectName: state.ctx.projectName
87
+ });
87
88
  await originalOnAfterRun?.call(testRunner, files);
88
89
  };
89
90
  const originalOnAfterRunTask = testRunner.onAfterRunTask;
@@ -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.CV36oG_L.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName } from './index.BZ0g1JD2.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils';
8
8
 
@@ -10,26 +10,20 @@ function createBenchmarkJsonReport(files) {
10
10
  const report = { files: [] };
11
11
  for (const file of files) {
12
12
  const groups = [];
13
- for (const task of getTasks(file)) {
14
- if (task?.type === "suite") {
15
- const benchmarks = [];
16
- for (const t of task.tasks) {
17
- const benchmark = t.meta.benchmark && t.result?.benchmark;
18
- if (benchmark) {
19
- benchmarks.push({
20
- id: t.id,
21
- ...benchmark,
22
- samples: []
23
- });
24
- }
25
- }
26
- if (benchmarks.length) {
27
- groups.push({
28
- fullName: getFullName(task, " > "),
29
- benchmarks
30
- });
31
- }
13
+ for (const task of getTasks(file)) if (task?.type === "suite") {
14
+ const benchmarks = [];
15
+ for (const t of task.tasks) {
16
+ const benchmark = t.meta.benchmark && t.result?.benchmark;
17
+ if (benchmark) benchmarks.push({
18
+ id: t.id,
19
+ ...benchmark,
20
+ samples: []
21
+ });
32
22
  }
23
+ if (benchmarks.length) groups.push({
24
+ fullName: getFullName(task, " > "),
25
+ benchmarks
26
+ });
33
27
  }
34
28
  report.files.push({
35
29
  filepath: file.filepath,
@@ -40,17 +34,11 @@ function createBenchmarkJsonReport(files) {
40
34
  }
41
35
  function flattenFormattedBenchmarkReport(report) {
42
36
  const flat = {};
43
- for (const file of report.files) {
44
- for (const group of file.groups) {
45
- for (const t of group.benchmarks) {
46
- flat[t.id] = t;
47
- }
48
- }
49
- }
37
+ for (const file of report.files) for (const group of file.groups) for (const t of group.benchmarks) flat[t.id] = t;
50
38
  return flat;
51
39
  }
52
40
 
53
- const outputMap = new WeakMap();
41
+ const outputMap = /* @__PURE__ */ new WeakMap();
54
42
  function formatNumber(number) {
55
43
  const res = String(number.toFixed(number < 100 ? 4 : 2)).split(".");
56
44
  return res[0].replace(/(?=(?:\d{3})+$)\B/g, ",") + (res[1] ? `.${res[1]}` : "");
@@ -112,14 +100,10 @@ function renderBenchmark(result, widths) {
112
100
  function renderTable(options) {
113
101
  const output = [];
114
102
  const benchMap = {};
115
- for (const task of options.tasks) {
116
- if (task.meta.benchmark && task.result?.benchmark) {
117
- benchMap[task.id] = {
118
- current: task.result.benchmark,
119
- baseline: options.compare?.[task.id]
120
- };
121
- }
122
- }
103
+ for (const task of options.tasks) if (task.meta.benchmark && task.result?.benchmark) benchMap[task.id] = {
104
+ current: task.result.benchmark,
105
+ baseline: options.compare?.[task.id]
106
+ };
123
107
  const benchCount = Object.entries(benchMap).length;
124
108
  const columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish));
125
109
  let idx = 0;
@@ -128,61 +112,40 @@ function renderTable(options) {
128
112
  const duration = task.result?.duration;
129
113
  const bench = benchMap[task.id];
130
114
  let prefix = "";
131
- if (idx === 0 && task.meta?.benchmark) {
132
- prefix += `${renderTableHead(columnWidths)}\n${padding}`;
133
- }
115
+ if (idx === 0 && task.meta?.benchmark) prefix += `${renderTableHead(columnWidths)}\n${padding}`;
134
116
  prefix += ` ${getStateSymbol(task)} `;
135
117
  let suffix = "";
136
- if (task.type === "suite") {
137
- suffix += c.dim(` (${getTests(task).length})`);
138
- }
139
- if (task.mode === "skip" || task.mode === "todo") {
140
- suffix += c.dim(c.gray(" [skipped]"));
141
- }
118
+ if (task.type === "suite") suffix += c.dim(` (${getTests(task).length})`);
119
+ if (task.mode === "skip" || task.mode === "todo") suffix += c.dim(c.gray(" [skipped]"));
142
120
  if (duration != null) {
143
121
  const color = duration > options.slowTestThreshold ? c.yellow : c.green;
144
122
  suffix += color(` ${Math.round(duration)}${c.dim("ms")}`);
145
123
  }
146
- if (options.showHeap && task.result?.heap != null) {
147
- suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
148
- }
124
+ if (options.showHeap && task.result?.heap != null) suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
149
125
  if (bench) {
150
126
  let body = renderBenchmark(bench.current, columnWidths);
151
127
  if (options.compare && bench.baseline) {
152
128
  if (bench.current.hz) {
153
129
  const diff = bench.current.hz / bench.baseline.hz;
154
130
  const diffFixed = diff.toFixed(2);
155
- if (diffFixed === "1.0.0") {
156
- body += c.gray(` [${diffFixed}x]`);
157
- }
158
- if (diff > 1) {
159
- body += c.blue(` [${diffFixed}x] ⇑`);
160
- } else {
161
- body += c.red(` [${diffFixed}x] ⇓`);
162
- }
131
+ if (diffFixed === "1.0.0") body += c.gray(` [${diffFixed}x]`);
132
+ if (diff > 1) body += c.blue(` [${diffFixed}x] ⇑`);
133
+ else body += c.red(` [${diffFixed}x] ⇓`);
163
134
  }
164
135
  output.push(padding + prefix + body + suffix);
165
136
  const bodyBaseline = renderBenchmark(bench.baseline, columnWidths);
166
137
  output.push(`${padding} ${bodyBaseline} ${c.dim("(baseline)")}`);
167
138
  } else {
168
- if (bench.current.rank === 1 && benchCount > 1) {
169
- body += c.bold(c.green(" fastest"));
170
- }
171
- if (bench.current.rank === benchCount && benchCount > 2) {
172
- body += c.bold(c.gray(" slowest"));
173
- }
139
+ if (bench.current.rank === 1 && benchCount > 1) body += c.bold(c.green(" fastest"));
140
+ if (bench.current.rank === benchCount && benchCount > 2) body += c.bold(c.gray(" slowest"));
174
141
  output.push(padding + prefix + body + suffix);
175
142
  }
176
- } else {
177
- output.push(padding + prefix + task.name + suffix);
178
- }
143
+ } else output.push(padding + prefix + task.name + suffix);
179
144
  if (task.result?.state !== "pass" && outputMap.get(task) != null) {
180
145
  let data = outputMap.get(task);
181
146
  if (typeof data === "string") {
182
147
  data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop());
183
- if (data === "") {
184
- data = undefined;
185
- }
148
+ if (data === "") data = void 0;
186
149
  }
187
150
  if (data != null) {
188
151
  const out = ` ${" ".repeat(options.level)}${F_RIGHT} ${data}`;
@@ -210,11 +173,9 @@ class BenchmarkReporter extends DefaultReporter {
210
173
  onTaskUpdate(packs) {
211
174
  for (const pack of packs) {
212
175
  const task = this.ctx.state.idMap.get(pack[0]);
213
- if (task?.type === "suite" && task.result?.state !== "run") {
214
- task.tasks.filter((task) => task.result?.benchmark).sort((benchA, benchB) => benchA.result.benchmark.mean - benchB.result.benchmark.mean).forEach((bench, idx) => {
215
- bench.result.benchmark.rank = Number(idx) + 1;
216
- });
217
- }
176
+ if (task?.type === "suite" && task.result?.state !== "run") task.tasks.filter((task) => task.result?.benchmark).sort((benchA, benchB) => benchA.result.benchmark.mean - benchB.result.benchmark.mean).forEach((bench, idx) => {
177
+ bench.result.benchmark.rank = Number(idx) + 1;
178
+ });
218
179
  }
219
180
  }
220
181
  onTestSuiteResult(testSuite) {
@@ -226,16 +187,12 @@ class BenchmarkReporter extends DefaultReporter {
226
187
  }
227
188
  printSuiteTable(testTask) {
228
189
  const state = testTask.state();
229
- if (state === "pending" || state === "queued") {
230
- return;
231
- }
190
+ if (state === "pending" || state === "queued") return;
232
191
  const benches = testTask.task.tasks.filter((t) => t.meta.benchmark);
233
192
  const duration = testTask.task.result?.duration || 0;
234
193
  if (benches.length > 0 && benches.every((t) => t.result?.state !== "run" && t.result?.state !== "queued")) {
235
194
  let title = `\n ${getStateSymbol(testTask.task)} ${formatProjectName(testTask.project)}${getFullName(testTask.task, c.dim(" > "))}`;
236
- if (duration != null && duration > this.ctx.config.slowTestThreshold) {
237
- title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
238
- }
195
+ if (duration != null && duration > this.ctx.config.slowTestThreshold) title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
239
196
  this.log(title);
240
197
  this.log(renderTable({
241
198
  tasks: benches,
@@ -249,13 +206,12 @@ class BenchmarkReporter extends DefaultReporter {
249
206
  }
250
207
  async onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
251
208
  super.onFinished(files, errors);
209
+ // write output for future comparison
252
210
  let outputFile = this.ctx.config.benchmark?.outputJson;
253
211
  if (outputFile) {
254
212
  outputFile = pathe.resolve(this.ctx.config.root, outputFile);
255
213
  const outputDirectory = pathe.dirname(outputFile);
256
- if (!fs.existsSync(outputDirectory)) {
257
- await fs.promises.mkdir(outputDirectory, { recursive: true });
258
- }
214
+ if (!fs.existsSync(outputDirectory)) await fs.promises.mkdir(outputDirectory, { recursive: true });
259
215
  const output = createBenchmarkJsonReport(files);
260
216
  await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
261
217
  this.log(`Benchmark report written to ${outputFile}`);
@@ -1,5 +1,5 @@
1
- import { c as createExpect, a as globalExpect, i as inject, v as vi, b as vitest } from './vi.BFR5YIgu.js';
2
- import { b as bench } from './benchmark.BoF7jW0Q.js';
1
+ import { c as createExpect, a as globalExpect, i as inject, v as vi, b as vitest } from './vi.bdSIJ99Y.js';
2
+ import { b as bench } from './benchmark.CYdenmiT.js';
3
3
  import { expectTypeOf } from 'expect-type';
4
4
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
5
5
  import * as chai from 'chai';
@@ -7,6 +7,8 @@ import { assert, should } from 'chai';
7
7
 
8
8
  const assertType = function assertType() {};
9
9
 
10
+ // TODO: deprecate <reference types="vitest" /> in favor of `<reference types="vitest/config" />`
11
+
10
12
  var VitestIndex = /*#__PURE__*/Object.freeze({
11
13
  __proto__: null,
12
14
  afterAll: afterAll,