vitest 3.2.4 → 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 (49) hide show
  1. package/dist/browser.d.ts +3 -5
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{base.DfmxU-tU.js → base.Bj3pWTr1.js} +1 -1
  4. package/dist/chunks/browser.d.q8Z0P0q1.d.ts +18 -0
  5. package/dist/chunks/{cac.Cb-PYCCB.js → cac.D3EzDDZd.js} +8 -17
  6. package/dist/chunks/{cli-api.BkDphVBG.js → cli-api.Dn5gKePv.js} +7 -7
  7. package/dist/chunks/{config.d.D2ROskhv.d.ts → config.d.HJdfX-8k.d.ts} +1 -2
  8. package/dist/chunks/{coverage.DL5VHqXY.js → coverage.Cwa-XhJt.js} +56 -17
  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.CdQS2e2Q.js → index.BWf_gE5n.js} +0 -2
  14. package/dist/chunks/{index.VByaPkjc.js → index.CZI_8rVt.js} +223 -235
  15. package/dist/chunks/{index.CwejwG0H.js → index.D-VkfKhf.js} +2 -2
  16. package/dist/chunks/{index.BCWujgDG.js → index.TfbsX-3I.js} +1 -1
  17. package/dist/chunks/plugin.d.C2EcJUjo.d.ts +9 -0
  18. package/dist/chunks/{reporters.d.BFLkQcL6.d.ts → reporters.d.DxZg19fy.d.ts} +2213 -2208
  19. package/dist/chunks/{rpc.-pEldfrD.js → rpc.CsFtxqeq.js} +4 -4
  20. package/dist/chunks/{runBaseTests.9Ij9_de-.js → runBaseTests.BC7ZIH5L.js} +4 -4
  21. package/dist/chunks/{setup-common.Dd054P77.js → setup-common.D7ZqXFx-.js} +1 -1
  22. package/dist/chunks/{worker.d.CKwWzBSj.d.ts → worker.d.CmvJfRGs.d.ts} +1 -1
  23. package/dist/chunks/{worker.d.1GmBbd7G.d.ts → worker.d.DoNjFAiv.d.ts} +6 -13
  24. package/dist/cli.js +9 -9
  25. package/dist/config.cjs +2 -49
  26. package/dist/config.d.ts +36 -30
  27. package/dist/config.js +2 -8
  28. package/dist/coverage.d.ts +15 -9
  29. package/dist/coverage.js +6 -5
  30. package/dist/environments.d.ts +2 -3
  31. package/dist/execute.d.ts +3 -5
  32. package/dist/index.d.ts +23 -177
  33. package/dist/index.js +1 -1
  34. package/dist/node.d.ts +37 -25
  35. package/dist/node.js +13 -19
  36. package/dist/reporters.d.ts +9 -9
  37. package/dist/reporters.js +12 -12
  38. package/dist/runners.d.ts +1 -2
  39. package/dist/runners.js +2 -1
  40. package/dist/worker.js +1 -1
  41. package/dist/workers/forks.js +1 -1
  42. package/dist/workers/runVmTests.js +4 -4
  43. package/dist/workers/threads.js +1 -1
  44. package/dist/workers.d.ts +4 -7
  45. package/dist/workers.js +2 -2
  46. package/package.json +11 -11
  47. package/dist/chunks/environment.d.cL3nLXbE.d.ts +0 -119
  48. package/dist/chunks/vite.d.CMLlLIFP.d.ts +0 -25
  49. package/dist/chunks/{typechecker.DRKU1-1g.js → typechecker.CVytUJuF.js} +26 -26
@@ -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
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 = "↳";
@@ -388,8 +599,12 @@ class BaseReporter {
388
599
  shouldLog(log, taskState) {
389
600
  if (this.ctx.config.silent === true) return false;
390
601
  if (this.ctx.config.silent === "passed-only" && taskState !== "failed") return false;
391
- const shouldLog = this.ctx.config.onConsoleLog?.(log.content, log.type);
392
- 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
+ }
393
608
  return true;
394
609
  }
395
610
  onServerRestart(reason) {
@@ -540,233 +755,6 @@ function sum(items, cb) {
540
755
  }, 0);
541
756
  }
542
757
 
543
- class BasicReporter extends BaseReporter {
544
- constructor() {
545
- super();
546
- this.isTTY = false;
547
- }
548
- onInit(ctx) {
549
- super.onInit(ctx);
550
- 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)}`);
551
- }
552
- reportSummary(files, errors) {
553
- // non-tty mode doesn't add a new line
554
- this.ctx.logger.log();
555
- return super.reportSummary(files, errors);
556
- }
557
- }
558
-
559
- /// <reference types="../types/index.d.ts" />
560
-
561
- // (c) 2020-present Andrea Giammarchi
562
-
563
- const {parse: $parse, stringify: $stringify} = JSON;
564
- const {keys} = Object;
565
-
566
- const Primitive = String; // it could be Number
567
- const primitive = 'string'; // it could be 'number'
568
-
569
- const ignore = {};
570
- const object = 'object';
571
-
572
- const noop = (_, value) => value;
573
-
574
- const primitives = value => (
575
- value instanceof Primitive ? Primitive(value) : value
576
- );
577
-
578
- const Primitives = (_, value) => (
579
- typeof value === primitive ? new Primitive(value) : value
580
- );
581
-
582
- const revive = (input, parsed, output, $) => {
583
- const lazy = [];
584
- for (let ke = keys(output), {length} = ke, y = 0; y < length; y++) {
585
- const k = ke[y];
586
- const value = output[k];
587
- if (value instanceof Primitive) {
588
- const tmp = input[value];
589
- if (typeof tmp === object && !parsed.has(tmp)) {
590
- parsed.add(tmp);
591
- output[k] = ignore;
592
- lazy.push({k, a: [input, parsed, tmp, $]});
593
- }
594
- else
595
- output[k] = $.call(output, k, tmp);
596
- }
597
- else if (output[k] !== ignore)
598
- output[k] = $.call(output, k, value);
599
- }
600
- for (let {length} = lazy, i = 0; i < length; i++) {
601
- const {k, a} = lazy[i];
602
- output[k] = $.call(output, k, revive.apply(null, a));
603
- }
604
- return output;
605
- };
606
-
607
- const set = (known, input, value) => {
608
- const index = Primitive(input.push(value) - 1);
609
- known.set(value, index);
610
- return index;
611
- };
612
-
613
- /**
614
- * Converts a specialized flatted string into a JS value.
615
- * @param {string} text
616
- * @param {(this: any, key: string, value: any) => any} [reviver]
617
- * @returns {any}
618
- */
619
- const parse = (text, reviver) => {
620
- const input = $parse(text, Primitives).map(primitives);
621
- const value = input[0];
622
- const $ = reviver || noop;
623
- const tmp = typeof value === object && value ?
624
- revive(input, new Set, value, $) :
625
- value;
626
- return $.call({'': tmp}, '', tmp);
627
- };
628
-
629
- /**
630
- * Converts a JS value into a specialized flatted string.
631
- * @param {any} value
632
- * @param {((this: any, key: string, value: any) => any) | (string | number)[] | null | undefined} [replacer]
633
- * @param {string | number | undefined} [space]
634
- * @returns {string}
635
- */
636
- const stringify = (value, replacer, space) => {
637
- const $ = replacer && typeof replacer === object ?
638
- (k, v) => (k === '' || -1 < replacer.indexOf(k) ? v : void 0) :
639
- (replacer || noop);
640
- const known = new Map;
641
- const input = [];
642
- const output = [];
643
- let i = +set(known, input, $.call({'': value}, '', value));
644
- let firstRun = !i;
645
- while (i < input.length) {
646
- firstRun = true;
647
- output[i] = $stringify(input[i++], replace, space);
648
- }
649
- return '[' + output.join(',') + ']';
650
- function replace(key, value) {
651
- if (firstRun) {
652
- firstRun = !firstRun;
653
- return value;
654
- }
655
- const after = $.call(this, key, value);
656
- switch (typeof after) {
657
- case object:
658
- if (after === null) return after;
659
- case primitive:
660
- return known.get(after) || set(known, input, after);
661
- }
662
- return after;
663
- }
664
- };
665
-
666
- class BlobReporter {
667
- start = 0;
668
- ctx;
669
- options;
670
- constructor(options) {
671
- this.options = options;
672
- }
673
- onInit(ctx) {
674
- if (ctx.config.watch) throw new Error("Blob reporter is not supported in watch mode");
675
- this.ctx = ctx;
676
- this.start = performance.now();
677
- }
678
- async onFinished(files = [], errors = [], coverage) {
679
- const executionTime = performance.now() - this.start;
680
- let outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, "blob");
681
- if (!outputFile) {
682
- const shard = this.ctx.config.shard;
683
- outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json";
684
- }
685
- const modules = this.ctx.projects.map((project) => {
686
- return [project.name, [...project.vite.moduleGraph.idToModuleMap.entries()].map((mod) => {
687
- if (!mod[1].file) return null;
688
- return [
689
- mod[0],
690
- mod[1].file,
691
- mod[1].url
692
- ];
693
- }).filter((x) => x != null)];
694
- });
695
- const report = [
696
- this.ctx.version,
697
- files,
698
- errors,
699
- modules,
700
- coverage,
701
- executionTime
702
- ];
703
- const reportFile = resolve(this.ctx.config.root, outputFile);
704
- await writeBlob(report, reportFile);
705
- this.ctx.logger.log("blob report written to", reportFile);
706
- }
707
- }
708
- async function writeBlob(content, filename) {
709
- const report = stringify(content);
710
- const dir = dirname(filename);
711
- if (!existsSync(dir)) await mkdir(dir, { recursive: true });
712
- await writeFile(filename, report, "utf-8");
713
- }
714
- async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
715
- // using process.cwd() because --merge-reports can only be used in CLI
716
- const resolvedDir = resolve(process.cwd(), blobsDirectory);
717
- const blobsFiles = await readdir(resolvedDir);
718
- const promises = blobsFiles.map(async (filename) => {
719
- const fullPath = resolve(resolvedDir, filename);
720
- const stats = await stat(fullPath);
721
- 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`);
722
- const content = await readFile(fullPath, "utf-8");
723
- const [version, files, errors, moduleKeys, coverage, executionTime] = parse(content);
724
- 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`);
725
- return {
726
- version,
727
- files,
728
- errors,
729
- moduleKeys,
730
- coverage,
731
- file: filename,
732
- executionTime
733
- };
734
- });
735
- const blobs = await Promise.all(promises);
736
- if (!blobs.length) throw new Error(`vitest.mergeReports() requires at least one blob file in "${blobsDirectory}" directory, but none were found`);
737
- const versions = new Set(blobs.map((blob) => blob.version));
738
- 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")}`);
739
- 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}`);
740
- // fake module graph - it is used to check if module is imported, but we don't use values inside
741
- const projects = Object.fromEntries(projectsArray.map((p) => [p.name, p]));
742
- blobs.forEach((blob) => {
743
- blob.moduleKeys.forEach(([projectName, moduleIds]) => {
744
- const project = projects[projectName];
745
- if (!project) return;
746
- moduleIds.forEach(([moduleId, file, url]) => {
747
- const moduleNode = project.vite.moduleGraph.createFileOnlyEntry(file);
748
- moduleNode.url = url;
749
- moduleNode.id = moduleId;
750
- project.vite.moduleGraph.idToModuleMap.set(moduleId, moduleNode);
751
- });
752
- });
753
- });
754
- const files = blobs.flatMap((blob) => blob.files).sort((f1, f2) => {
755
- const time1 = f1.result?.startTime || 0;
756
- const time2 = f2.result?.startTime || 0;
757
- return time1 - time2;
758
- });
759
- const errors = blobs.flatMap((blob) => blob.errors);
760
- const coverages = blobs.map((blob) => blob.coverage);
761
- const executionTimes = blobs.map((blob) => blob.executionTime);
762
- return {
763
- files,
764
- errors,
765
- coverages,
766
- executionTimes
767
- };
768
- }
769
-
770
758
  const DEFAULT_RENDER_INTERVAL_MS = 1e3;
771
759
  const ESC = "\x1B[";
772
760
  const CLEAR_LINE = `${ESC}K`;
@@ -2017,6 +2005,7 @@ class JUnitReporter {
2017
2005
  }
2018
2006
 
2019
2007
  function yamlString(str) {
2008
+ if (!str) return "";
2020
2009
  return `"${str.replace(/"/g, "\\\"")}"`;
2021
2010
  }
2022
2011
  function tapString(str) {
@@ -2168,7 +2157,6 @@ function getIndentation(suite, level = 1) {
2168
2157
 
2169
2158
  const ReportersMap = {
2170
2159
  "default": DefaultReporter,
2171
- "basic": BasicReporter,
2172
2160
  "blob": BlobReporter,
2173
2161
  "verbose": VerboseReporter,
2174
2162
  "dot": DotReporter,
@@ -2180,4 +2168,4 @@ const ReportersMap = {
2180
2168
  "github-actions": GithubActionsReporter
2181
2169
  };
2182
2170
 
2183
- 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.-pEldfrD.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.VByaPkjc.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 };