vitest 3.2.3 → 4.0.0-beta.1

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 (50) hide show
  1. package/dist/browser.d.ts +3 -5
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{base.Cg0miDlQ.js → base.Bj3pWTr1.js} +1 -1
  4. package/dist/chunks/browser.d.q8Z0P0q1.d.ts +18 -0
  5. package/dist/chunks/{cac.Cs_fZ7zn.js → cac.D3EzDDZd.js} +11 -19
  6. package/dist/chunks/{cli-api.C37Ou0i1.js → cli-api.Dn5gKePv.js} +15 -13
  7. package/dist/chunks/{config.d.D2ROskhv.d.ts → config.d.HJdfX-8k.d.ts} +1 -2
  8. package/dist/chunks/{coverage.D1a3dTnj.js → coverage.Cwa-XhJt.js} +68 -26
  9. package/dist/chunks/{defaults.B7q_naMc.js → defaults.CXFFjsi8.js} +2 -42
  10. package/dist/chunks/environment.d.CUq4cUgQ.d.ts +44 -0
  11. package/dist/chunks/{global.d.MAmajcmJ.d.ts → global.d.CVbXEflG.d.ts} +7 -29
  12. package/dist/chunks/{globals.DEHgCU4V.js → globals.Cxal6MLI.js} +1 -1
  13. package/dist/chunks/{index.CJ0plNrh.js → index.B521nVV-.js} +4 -2
  14. package/dist/chunks/{index.CdQS2e2Q.js → index.BWf_gE5n.js} +0 -2
  15. package/dist/chunks/{index.CX5aIIXH.js → index.CZI_8rVt.js} +231 -240
  16. package/dist/chunks/{index.BbB8_kAK.js → index.D-VkfKhf.js} +2 -2
  17. package/dist/chunks/{index.CSxmp_dI.js → index.TfbsX-3I.js} +1 -1
  18. package/dist/chunks/plugin.d.C2EcJUjo.d.ts +9 -0
  19. package/dist/chunks/{reporters.d.DL9pg5DB.d.ts → reporters.d.DxZg19fy.d.ts} +2213 -2207
  20. package/dist/chunks/{rpc.Iovn4oWe.js → rpc.CsFtxqeq.js} +5 -5
  21. package/dist/chunks/{runBaseTests.Dd85QTll.js → runBaseTests.BC7ZIH5L.js} +5 -5
  22. package/dist/chunks/{setup-common.Dd054P77.js → setup-common.D7ZqXFx-.js} +1 -1
  23. package/dist/chunks/{worker.d.DvqK5Vmu.d.ts → worker.d.CmvJfRGs.d.ts} +1 -1
  24. package/dist/chunks/{worker.d.tQu2eJQy.d.ts → worker.d.DoNjFAiv.d.ts} +7 -13
  25. package/dist/cli.js +9 -9
  26. package/dist/config.cjs +2 -49
  27. package/dist/config.d.ts +36 -30
  28. package/dist/config.js +2 -8
  29. package/dist/coverage.d.ts +15 -9
  30. package/dist/coverage.js +7 -6
  31. package/dist/environments.d.ts +2 -3
  32. package/dist/execute.d.ts +3 -5
  33. package/dist/index.d.ts +23 -177
  34. package/dist/index.js +1 -1
  35. package/dist/node.d.ts +38 -26
  36. package/dist/node.js +15 -21
  37. package/dist/reporters.d.ts +9 -9
  38. package/dist/reporters.js +12 -12
  39. package/dist/runners.d.ts +1 -2
  40. package/dist/runners.js +3 -2
  41. package/dist/worker.js +2 -2
  42. package/dist/workers/forks.js +1 -1
  43. package/dist/workers/runVmTests.js +5 -5
  44. package/dist/workers/threads.js +1 -1
  45. package/dist/workers.d.ts +4 -7
  46. package/dist/workers.js +3 -3
  47. package/package.json +16 -16
  48. package/dist/chunks/environment.d.cL3nLXbE.d.ts +0 -119
  49. package/dist/chunks/vite.d.CtvOcEqC.d.ts +0 -25
  50. package/dist/chunks/{typechecker.DRKU1-1g.js → typechecker.CVytUJuF.js} +26 -26
@@ -29,8 +29,10 @@ function createBirpc(functions, options) {
29
29
  return functions;
30
30
  if (method === "$close")
31
31
  return close;
32
+ if (method === "$closed")
33
+ return closed;
32
34
  if (method === "then" && !eventNames.includes("then") && !("then" in functions))
33
- return void 0;
35
+ return undefined;
34
36
  const sendEvent = (...args) => {
35
37
  post(serialize({ m: method, a: args, t: TYPE_REQUEST }));
36
38
  };
@@ -45,7 +47,7 @@ function createBirpc(functions, options) {
45
47
  try {
46
48
  await _promise;
47
49
  } finally {
48
- _promise = void 0;
50
+ _promise = undefined;
49
51
  }
50
52
  }
51
53
  return new Promise((resolve, reject) => {
@@ -7,8 +7,6 @@ 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
-
12
10
  var VitestIndex = /*#__PURE__*/Object.freeze({
13
11
  __proto__: null,
14
12
  afterAll: afterAll,
@@ -1,19 +1,230 @@
1
+ import { existsSync, readFileSync, promises } from 'node:fs';
2
+ import { mkdir, writeFile, readdir, stat, readFile } from 'node:fs/promises';
3
+ import { resolve, dirname, isAbsolute, relative, basename, normalize } from 'pathe';
4
+ import { g as getOutputFile, h as hasFailedSnapshot, T as TypeCheckError } from './typechecker.CVytUJuF.js';
1
5
  import { performance as performance$1 } from 'node:perf_hooks';
2
- import { getTestName, hasFailed, getFullName, getTests, getSuites, getTasks } from '@vitest/runner/utils';
6
+ import { getTestName, getFullName, hasFailed, getTests, getSuites, getTasks } from '@vitest/runner/utils';
3
7
  import { slash, toArray, isPrimitive, inspect, positionToOffset, lineSplitRE } from '@vitest/utils';
4
8
  import { parseStacktrace, parseErrorStacktrace } from '@vitest/utils/source-map';
5
- import { isAbsolute, relative, dirname, basename, resolve, normalize } from 'pathe';
6
9
  import c from 'tinyrainbow';
7
10
  import { i as isTTY } from './env.D4Lgay0q.js';
8
- import { h as hasFailedSnapshot, g as getOutputFile, T as TypeCheckError } from './typechecker.DRKU1-1g.js';
9
11
  import { stripVTControlCharacters } from 'node:util';
10
- import { existsSync, readFileSync, promises } from 'node:fs';
11
- import { mkdir, writeFile, readdir, stat, readFile } from 'node:fs/promises';
12
12
  import { Console } from 'node:console';
13
13
  import { Writable } from 'node:stream';
14
14
  import { createRequire } from 'node:module';
15
15
  import { hostname } from 'node:os';
16
16
 
17
+ /// <reference types="../types/index.d.ts" />
18
+
19
+ // (c) 2020-present Andrea Giammarchi
20
+
21
+ const {parse: $parse, stringify: $stringify} = JSON;
22
+ const {keys} = Object;
23
+
24
+ const Primitive = String; // it could be Number
25
+ const primitive = 'string'; // it could be 'number'
26
+
27
+ const ignore = {};
28
+ const object = 'object';
29
+
30
+ const noop = (_, value) => value;
31
+
32
+ const primitives = value => (
33
+ value instanceof Primitive ? Primitive(value) : value
34
+ );
35
+
36
+ const Primitives = (_, value) => (
37
+ typeof value === primitive ? new Primitive(value) : value
38
+ );
39
+
40
+ const revive = (input, parsed, output, $) => {
41
+ const lazy = [];
42
+ for (let ke = keys(output), {length} = ke, y = 0; y < length; y++) {
43
+ const k = ke[y];
44
+ const value = output[k];
45
+ if (value instanceof Primitive) {
46
+ const tmp = input[value];
47
+ if (typeof tmp === object && !parsed.has(tmp)) {
48
+ parsed.add(tmp);
49
+ output[k] = ignore;
50
+ lazy.push({k, a: [input, parsed, tmp, $]});
51
+ }
52
+ else
53
+ output[k] = $.call(output, k, tmp);
54
+ }
55
+ else if (output[k] !== ignore)
56
+ output[k] = $.call(output, k, value);
57
+ }
58
+ for (let {length} = lazy, i = 0; i < length; i++) {
59
+ const {k, a} = lazy[i];
60
+ output[k] = $.call(output, k, revive.apply(null, a));
61
+ }
62
+ return output;
63
+ };
64
+
65
+ const set = (known, input, value) => {
66
+ const index = Primitive(input.push(value) - 1);
67
+ known.set(value, index);
68
+ return index;
69
+ };
70
+
71
+ /**
72
+ * Converts a specialized flatted string into a JS value.
73
+ * @param {string} text
74
+ * @param {(this: any, key: string, value: any) => any} [reviver]
75
+ * @returns {any}
76
+ */
77
+ const parse = (text, reviver) => {
78
+ const input = $parse(text, Primitives).map(primitives);
79
+ const value = input[0];
80
+ const $ = reviver || noop;
81
+ const tmp = typeof value === object && value ?
82
+ revive(input, new Set, value, $) :
83
+ value;
84
+ return $.call({'': tmp}, '', tmp);
85
+ };
86
+
87
+ /**
88
+ * Converts a JS value into a specialized flatted string.
89
+ * @param {any} value
90
+ * @param {((this: any, key: string, value: any) => any) | (string | number)[] | null | undefined} [replacer]
91
+ * @param {string | number | undefined} [space]
92
+ * @returns {string}
93
+ */
94
+ const stringify = (value, replacer, space) => {
95
+ const $ = replacer && typeof replacer === object ?
96
+ (k, v) => (k === '' || -1 < replacer.indexOf(k) ? v : void 0) :
97
+ (replacer || noop);
98
+ const known = new Map;
99
+ const input = [];
100
+ const output = [];
101
+ let i = +set(known, input, $.call({'': value}, '', value));
102
+ let firstRun = !i;
103
+ while (i < input.length) {
104
+ firstRun = true;
105
+ output[i] = $stringify(input[i++], replace, space);
106
+ }
107
+ return '[' + output.join(',') + ']';
108
+ function replace(key, value) {
109
+ if (firstRun) {
110
+ firstRun = !firstRun;
111
+ return value;
112
+ }
113
+ const after = $.call(this, key, value);
114
+ switch (typeof after) {
115
+ case object:
116
+ if (after === null) return after;
117
+ case primitive:
118
+ return known.get(after) || set(known, input, after);
119
+ }
120
+ return after;
121
+ }
122
+ };
123
+
124
+ class BlobReporter {
125
+ start = 0;
126
+ ctx;
127
+ options;
128
+ constructor(options) {
129
+ this.options = options;
130
+ }
131
+ onInit(ctx) {
132
+ if (ctx.config.watch) throw new Error("Blob reporter is not supported in watch mode");
133
+ this.ctx = ctx;
134
+ this.start = performance.now();
135
+ }
136
+ async onFinished(files = [], errors = [], coverage) {
137
+ const executionTime = performance.now() - this.start;
138
+ let outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "blob");
139
+ if (!outputFile) {
140
+ const shard = this.ctx.config.shard;
141
+ outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json";
142
+ }
143
+ const modules = this.ctx.projects.map((project) => {
144
+ return [project.name, [...project.vite.moduleGraph.idToModuleMap.entries()].map((mod) => {
145
+ if (!mod[1].file) return null;
146
+ return [
147
+ mod[0],
148
+ mod[1].file,
149
+ mod[1].url
150
+ ];
151
+ }).filter((x) => x != null)];
152
+ });
153
+ const report = [
154
+ this.ctx.version,
155
+ files,
156
+ errors,
157
+ modules,
158
+ coverage,
159
+ executionTime
160
+ ];
161
+ const reportFile = resolve(this.ctx.config.root, outputFile);
162
+ await writeBlob(report, reportFile);
163
+ this.ctx.logger.log("blob report written to", reportFile);
164
+ }
165
+ }
166
+ async function writeBlob(content, filename) {
167
+ const report = stringify(content);
168
+ const dir = dirname(filename);
169
+ if (!existsSync(dir)) await mkdir(dir, { recursive: true });
170
+ await writeFile(filename, report, "utf-8");
171
+ }
172
+ async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
173
+ // using process.cwd() because --merge-reports can only be used in CLI
174
+ const resolvedDir = resolve(process.cwd(), blobsDirectory);
175
+ const blobsFiles = await readdir(resolvedDir);
176
+ const promises = blobsFiles.map(async (filename) => {
177
+ const fullPath = resolve(resolvedDir, filename);
178
+ const stats = await stat(fullPath);
179
+ if (!stats.isFile()) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file`);
180
+ const content = await readFile(fullPath, "utf-8");
181
+ const [version, files, errors, moduleKeys, coverage, executionTime] = parse(content);
182
+ if (!version) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a valid blob file`);
183
+ return {
184
+ version,
185
+ files,
186
+ errors,
187
+ moduleKeys,
188
+ coverage,
189
+ file: filename,
190
+ executionTime
191
+ };
192
+ });
193
+ const blobs = await Promise.all(promises);
194
+ if (!blobs.length) throw new Error(`vitest.mergeReports() requires at least one blob file in "${blobsDirectory}" directory, but none were found`);
195
+ const versions = new Set(blobs.map((blob) => blob.version));
196
+ if (versions.size > 1) throw new Error(`vitest.mergeReports() requires all blob files to be generated by the same Vitest version, received\n\n${blobs.map((b) => `- "${b.file}" uses v${b.version}`).join("\n")}`);
197
+ if (!versions.has(currentVersion)) throw new Error(`the blobs in "${blobsDirectory}" were generated by a different version of Vitest. Expected v${currentVersion}, but received v${blobs[0].version}`);
198
+ // fake module graph - it is used to check if module is imported, but we don't use values inside
199
+ const projects = Object.fromEntries(projectsArray.map((p) => [p.name, p]));
200
+ blobs.forEach((blob) => {
201
+ blob.moduleKeys.forEach(([projectName, moduleIds]) => {
202
+ const project = projects[projectName];
203
+ if (!project) return;
204
+ moduleIds.forEach(([moduleId, file, url]) => {
205
+ const moduleNode = project.vite.moduleGraph.createFileOnlyEntry(file);
206
+ moduleNode.url = url;
207
+ moduleNode.id = moduleId;
208
+ project.vite.moduleGraph.idToModuleMap.set(moduleId, moduleNode);
209
+ });
210
+ });
211
+ });
212
+ const files = blobs.flatMap((blob) => blob.files).sort((f1, f2) => {
213
+ const time1 = f1.result?.startTime || 0;
214
+ const time2 = f2.result?.startTime || 0;
215
+ return time1 - time2;
216
+ });
217
+ const errors = blobs.flatMap((blob) => blob.errors);
218
+ const coverages = blobs.map((blob) => blob.coverage);
219
+ const executionTimes = blobs.map((blob) => blob.executionTime);
220
+ return {
221
+ files,
222
+ errors,
223
+ coverages,
224
+ executionTimes
225
+ };
226
+ }
227
+
17
228
  const F_RIGHT = "→";
18
229
  const F_DOWN = "↓";
19
230
  const F_DOWN_RIGHT = "↳";
@@ -299,6 +510,9 @@ class BaseReporter {
299
510
  getTestName(test, separator) {
300
511
  return getTestName(test, separator);
301
512
  }
513
+ getFullName(test, separator) {
514
+ return getFullName(test, separator);
515
+ }
302
516
  formatShortError(error) {
303
517
  return `${F_RIGHT} ${error.message}`;
304
518
  }
@@ -361,7 +575,7 @@ class BaseReporter {
361
575
  const write = (msg) => output.write(msg);
362
576
  let headerText = "unknown test";
363
577
  const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0;
364
- if (task) headerText = getFullName(task, c.dim(" > "));
578
+ if (task) headerText = this.getFullName(task, c.dim(" > "));
365
579
  else if (log.taskId && log.taskId !== "__vitest__unknown_test__") headerText = log.taskId;
366
580
  write(c.gray(log.type + c.dim(` | ${headerText}\n`)) + log.content);
367
581
  if (log.origin) {
@@ -385,8 +599,12 @@ class BaseReporter {
385
599
  shouldLog(log, taskState) {
386
600
  if (this.ctx.config.silent === true) return false;
387
601
  if (this.ctx.config.silent === "passed-only" && taskState !== "failed") return false;
388
- const shouldLog = this.ctx.config.onConsoleLog?.(log.content, log.type);
389
- if (shouldLog === false) return shouldLog;
602
+ if (this.ctx.config.onConsoleLog) {
603
+ const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0;
604
+ const entity = task && this.ctx.state.getReportedEntity(task);
605
+ const shouldLog = this.ctx.config.onConsoleLog(log.content, log.type, entity);
606
+ if (shouldLog === false) return shouldLog;
607
+ }
390
608
  return true;
391
609
  }
392
610
  onServerRestart(reason) {
@@ -469,7 +687,7 @@ class BaseReporter {
469
687
  for (const bench of topBenches) {
470
688
  const group = bench.suite || bench.file;
471
689
  if (!group) continue;
472
- const groupName = getFullName(group, c.dim(" > "));
690
+ const groupName = this.getFullName(group, c.dim(" > "));
473
691
  const project = this.ctx.projects.find((p) => p.name === bench.file.projectName);
474
692
  this.log(` ${formatProjectName(project)}${bench.name}${c.dim(` - ${groupName}`)}`);
475
693
  const siblings = group.tasks.filter((i) => i.meta.benchmark && i.result?.benchmark && i !== bench).sort((a, b) => a.result.benchmark.rank - b.result.benchmark.rank);
@@ -502,7 +720,7 @@ class BaseReporter {
502
720
  const filepath = task?.filepath || "";
503
721
  const projectName = task?.projectName || task.file?.projectName || "";
504
722
  const project = this.ctx.projects.find((p) => p.name === projectName);
505
- let name = getFullName(task, c.dim(" > "));
723
+ let name = this.getFullName(task, c.dim(" > "));
506
724
  if (filepath) name += c.dim(` [ ${this.relative(filepath)} ]`);
507
725
  this.ctx.logger.error(`${c.bgRed(c.bold(" FAIL "))} ${formatProjectName(project)}${name}`);
508
726
  }
@@ -537,233 +755,6 @@ function sum(items, cb) {
537
755
  }, 0);
538
756
  }
539
757
 
540
- class BasicReporter extends BaseReporter {
541
- constructor() {
542
- super();
543
- this.isTTY = false;
544
- }
545
- onInit(ctx) {
546
- super.onInit(ctx);
547
- ctx.logger.deprecate(`'basic' reporter is deprecated and will be removed in Vitest v3.\nRemove 'basic' from 'reporters' option. To match 'basic' reporter 100%, use configuration:\n${JSON.stringify({ test: { reporters: [["default", { summary: false }]] } }, null, 2)}`);
548
- }
549
- reportSummary(files, errors) {
550
- // non-tty mode doesn't add a new line
551
- this.ctx.logger.log();
552
- return super.reportSummary(files, errors);
553
- }
554
- }
555
-
556
- /// <reference types="../types/index.d.ts" />
557
-
558
- // (c) 2020-present Andrea Giammarchi
559
-
560
- const {parse: $parse, stringify: $stringify} = JSON;
561
- const {keys} = Object;
562
-
563
- const Primitive = String; // it could be Number
564
- const primitive = 'string'; // it could be 'number'
565
-
566
- const ignore = {};
567
- const object = 'object';
568
-
569
- const noop = (_, value) => value;
570
-
571
- const primitives = value => (
572
- value instanceof Primitive ? Primitive(value) : value
573
- );
574
-
575
- const Primitives = (_, value) => (
576
- typeof value === primitive ? new Primitive(value) : value
577
- );
578
-
579
- const revive = (input, parsed, output, $) => {
580
- const lazy = [];
581
- for (let ke = keys(output), {length} = ke, y = 0; y < length; y++) {
582
- const k = ke[y];
583
- const value = output[k];
584
- if (value instanceof Primitive) {
585
- const tmp = input[value];
586
- if (typeof tmp === object && !parsed.has(tmp)) {
587
- parsed.add(tmp);
588
- output[k] = ignore;
589
- lazy.push({k, a: [input, parsed, tmp, $]});
590
- }
591
- else
592
- output[k] = $.call(output, k, tmp);
593
- }
594
- else if (output[k] !== ignore)
595
- output[k] = $.call(output, k, value);
596
- }
597
- for (let {length} = lazy, i = 0; i < length; i++) {
598
- const {k, a} = lazy[i];
599
- output[k] = $.call(output, k, revive.apply(null, a));
600
- }
601
- return output;
602
- };
603
-
604
- const set = (known, input, value) => {
605
- const index = Primitive(input.push(value) - 1);
606
- known.set(value, index);
607
- return index;
608
- };
609
-
610
- /**
611
- * Converts a specialized flatted string into a JS value.
612
- * @param {string} text
613
- * @param {(this: any, key: string, value: any) => any} [reviver]
614
- * @returns {any}
615
- */
616
- const parse = (text, reviver) => {
617
- const input = $parse(text, Primitives).map(primitives);
618
- const value = input[0];
619
- const $ = reviver || noop;
620
- const tmp = typeof value === object && value ?
621
- revive(input, new Set, value, $) :
622
- value;
623
- return $.call({'': tmp}, '', tmp);
624
- };
625
-
626
- /**
627
- * Converts a JS value into a specialized flatted string.
628
- * @param {any} value
629
- * @param {((this: any, key: string, value: any) => any) | (string | number)[] | null | undefined} [replacer]
630
- * @param {string | number | undefined} [space]
631
- * @returns {string}
632
- */
633
- const stringify = (value, replacer, space) => {
634
- const $ = replacer && typeof replacer === object ?
635
- (k, v) => (k === '' || -1 < replacer.indexOf(k) ? v : void 0) :
636
- (replacer || noop);
637
- const known = new Map;
638
- const input = [];
639
- const output = [];
640
- let i = +set(known, input, $.call({'': value}, '', value));
641
- let firstRun = !i;
642
- while (i < input.length) {
643
- firstRun = true;
644
- output[i] = $stringify(input[i++], replace, space);
645
- }
646
- return '[' + output.join(',') + ']';
647
- function replace(key, value) {
648
- if (firstRun) {
649
- firstRun = !firstRun;
650
- return value;
651
- }
652
- const after = $.call(this, key, value);
653
- switch (typeof after) {
654
- case object:
655
- if (after === null) return after;
656
- case primitive:
657
- return known.get(after) || set(known, input, after);
658
- }
659
- return after;
660
- }
661
- };
662
-
663
- class BlobReporter {
664
- start = 0;
665
- ctx;
666
- options;
667
- constructor(options) {
668
- this.options = options;
669
- }
670
- onInit(ctx) {
671
- if (ctx.config.watch) throw new Error("Blob reporter is not supported in watch mode");
672
- this.ctx = ctx;
673
- this.start = performance.now();
674
- }
675
- async onFinished(files = [], errors = [], coverage) {
676
- const executionTime = performance.now() - this.start;
677
- let outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "blob");
678
- if (!outputFile) {
679
- const shard = this.ctx.config.shard;
680
- outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json";
681
- }
682
- const modules = this.ctx.projects.map((project) => {
683
- return [project.name, [...project.vite.moduleGraph.idToModuleMap.entries()].map((mod) => {
684
- if (!mod[1].file) return null;
685
- return [
686
- mod[0],
687
- mod[1].file,
688
- mod[1].url
689
- ];
690
- }).filter((x) => x != null)];
691
- });
692
- const report = [
693
- this.ctx.version,
694
- files,
695
- errors,
696
- modules,
697
- coverage,
698
- executionTime
699
- ];
700
- const reportFile = resolve(this.ctx.config.root, outputFile);
701
- await writeBlob(report, reportFile);
702
- this.ctx.logger.log("blob report written to", reportFile);
703
- }
704
- }
705
- async function writeBlob(content, filename) {
706
- const report = stringify(content);
707
- const dir = dirname(filename);
708
- if (!existsSync(dir)) await mkdir(dir, { recursive: true });
709
- await writeFile(filename, report, "utf-8");
710
- }
711
- async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
712
- // using process.cwd() because --merge-reports can only be used in CLI
713
- const resolvedDir = resolve(process.cwd(), blobsDirectory);
714
- const blobsFiles = await readdir(resolvedDir);
715
- const promises = blobsFiles.map(async (filename) => {
716
- const fullPath = resolve(resolvedDir, filename);
717
- const stats = await stat(fullPath);
718
- if (!stats.isFile()) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file`);
719
- const content = await readFile(fullPath, "utf-8");
720
- const [version, files, errors, moduleKeys, coverage, executionTime] = parse(content);
721
- if (!version) throw new TypeError(`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a valid blob file`);
722
- return {
723
- version,
724
- files,
725
- errors,
726
- moduleKeys,
727
- coverage,
728
- file: filename,
729
- executionTime
730
- };
731
- });
732
- const blobs = await Promise.all(promises);
733
- if (!blobs.length) throw new Error(`vitest.mergeReports() requires at least one blob file in "${blobsDirectory}" directory, but none were found`);
734
- const versions = new Set(blobs.map((blob) => blob.version));
735
- if (versions.size > 1) throw new Error(`vitest.mergeReports() requires all blob files to be generated by the same Vitest version, received\n\n${blobs.map((b) => `- "${b.file}" uses v${b.version}`).join("\n")}`);
736
- if (!versions.has(currentVersion)) throw new Error(`the blobs in "${blobsDirectory}" were generated by a different version of Vitest. Expected v${currentVersion}, but received v${blobs[0].version}`);
737
- // fake module graph - it is used to check if module is imported, but we don't use values inside
738
- const projects = Object.fromEntries(projectsArray.map((p) => [p.name, p]));
739
- blobs.forEach((blob) => {
740
- blob.moduleKeys.forEach(([projectName, moduleIds]) => {
741
- const project = projects[projectName];
742
- if (!project) return;
743
- moduleIds.forEach(([moduleId, file, url]) => {
744
- const moduleNode = project.vite.moduleGraph.createFileOnlyEntry(file);
745
- moduleNode.url = url;
746
- moduleNode.id = moduleId;
747
- project.vite.moduleGraph.idToModuleMap.set(moduleId, moduleNode);
748
- });
749
- });
750
- });
751
- const files = blobs.flatMap((blob) => blob.files).sort((f1, f2) => {
752
- const time1 = f1.result?.startTime || 0;
753
- const time2 = f2.result?.startTime || 0;
754
- return time1 - time2;
755
- });
756
- const errors = blobs.flatMap((blob) => blob.errors);
757
- const coverages = blobs.map((blob) => blob.coverage);
758
- const executionTimes = blobs.map((blob) => blob.executionTime);
759
- return {
760
- files,
761
- errors,
762
- coverages,
763
- executionTimes
764
- };
765
- }
766
-
767
758
  const DEFAULT_RENDER_INTERVAL_MS = 1e3;
768
759
  const ESC = "\x1B[";
769
760
  const CLEAR_LINE = `${ESC}K`;
@@ -1364,7 +1355,7 @@ function printErrorInner(error, project, options) {
1364
1355
  const stacks = options.parseErrorStacktrace(e);
1365
1356
  const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => {
1366
1357
  try {
1367
- return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
1358
+ return project._vite && project.getModuleById(stack.file) && existsSync(stack.file);
1368
1359
  } catch {
1369
1360
  return false;
1370
1361
  }
@@ -2014,6 +2005,7 @@ class JUnitReporter {
2014
2005
  }
2015
2006
 
2016
2007
  function yamlString(str) {
2008
+ if (!str) return "";
2017
2009
  return `"${str.replace(/"/g, "\\\"")}"`;
2018
2010
  }
2019
2011
  function tapString(str) {
@@ -2165,7 +2157,6 @@ function getIndentation(suite, level = 1) {
2165
2157
 
2166
2158
  const ReportersMap = {
2167
2159
  "default": DefaultReporter,
2168
- "basic": BasicReporter,
2169
2160
  "blob": BlobReporter,
2170
2161
  "verbose": VerboseReporter,
2171
2162
  "dot": DotReporter,
@@ -2177,4 +2168,4 @@ const ReportersMap = {
2177
2168
  "github-actions": GithubActionsReporter
2178
2169
  };
2179
2170
 
2180
- export { BasicReporter as B, DefaultReporter as D, F_RIGHT as F, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, ReportersMap as R, TapFlatReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapReporter as c, printError as d, errorBanner as e, formatProjectName as f, getStateSymbol as g, divider as h, generateCodeFrame as i, BlobReporter as j, parse as p, readBlobs as r, stringify as s, truncateString as t, utils as u, withLabel as w };
2171
+ export { BlobReporter as B, DefaultReporter as D, F_RIGHT as F, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, ReportersMap as R, TapFlatReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapReporter as c, printError as d, errorBanner as e, formatProjectName as f, getStateSymbol as g, divider as h, generateCodeFrame as i, parse as p, readBlobs as r, stringify as s, truncateString as t, utils as u, withLabel as w };
@@ -1,8 +1,8 @@
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.Dd054P77.js';
3
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.D7ZqXFx-.js';
4
4
  import { distDir } from '../path.js';
5
- import { r as rpc } from './rpc.Iovn4oWe.js';
5
+ import { r as rpc } from './rpc.CsFtxqeq.js';
6
6
  import { g as getWorkerState } from './utils.XdZDrNZV.js';
7
7
 
8
8
  function setupChaiConfig(config) {
@@ -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.CX5aIIXH.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName } from './index.CZI_8rVt.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils';
8
8
 
@@ -0,0 +1,9 @@
1
+ import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.DxZg19fy.js';
2
+
3
+ interface VitestPluginContext {
4
+ vitest: Vitest;
5
+ project: TestProject;
6
+ injectTestProjects: (config: TestProjectConfiguration | TestProjectConfiguration[]) => Promise<TestProject[]>;
7
+ }
8
+
9
+ export type { VitestPluginContext as V };