vitest 4.0.0-beta.1 → 4.0.0-beta.10

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 (85) hide show
  1. package/LICENSE.md +2 -2
  2. package/dist/browser.d.ts +13 -14
  3. package/dist/browser.js +6 -5
  4. package/dist/chunks/base.Cjha6usc.js +129 -0
  5. package/dist/chunks/{benchmark.CYdenmiT.js → benchmark.CJUa-Hsa.js} +6 -8
  6. package/dist/chunks/{benchmark.d.BwvBVTda.d.ts → benchmark.d.DAaHLpsq.d.ts} +4 -4
  7. package/dist/chunks/{browser.d.q8Z0P0q1.d.ts → browser.d.yFAklsD1.d.ts} +5 -5
  8. package/dist/chunks/{cac.D3EzDDZd.js → cac.DCxo_nSu.js} +70 -152
  9. package/dist/chunks/{cli-api.Dn5gKePv.js → cli-api.BJJXh9BV.js} +1330 -1677
  10. package/dist/chunks/{config.d.HJdfX-8k.d.ts → config.d.B_LthbQq.d.ts} +58 -63
  11. package/dist/chunks/{console.CtFJOzRO.js → console.7h5kHUIf.js} +34 -70
  12. package/dist/chunks/{constants.DnKduX2e.js → constants.D_Q9UYh-.js} +1 -9
  13. package/dist/chunks/{coverage.Cwa-XhJt.js → coverage.BCU-r2QL.js} +515 -781
  14. package/dist/chunks/{coverage.DVF1vEu8.js → coverage.D_JHT54q.js} +2 -2
  15. package/dist/chunks/{coverage.d.S9RMNXIe.d.ts → coverage.d.BZtK59WP.d.ts} +10 -8
  16. package/dist/chunks/{creator.GK6I-cL4.js → creator.08Gi-vCA.js} +93 -77
  17. package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
  18. package/dist/chunks/{environment.d.CUq4cUgQ.d.ts → environment.d.BsToaxti.d.ts} +27 -6
  19. package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
  20. package/dist/chunks/{global.d.CVbXEflG.d.ts → global.d.BK3X7FW1.d.ts} +2 -5
  21. package/dist/chunks/{globals.Cxal6MLI.js → globals.DG-S3xFe.js} +8 -8
  22. package/dist/chunks/{index.CZI_8rVt.js → index.BIP7prJq.js} +289 -608
  23. package/dist/chunks/{index.B521nVV-.js → index.Bgo3tNWt.js} +23 -4
  24. package/dist/chunks/{index.TfbsX-3I.js → index.BjKEiSn0.js} +14 -24
  25. package/dist/chunks/{index.BWf_gE5n.js → index.CMfqw92x.js} +7 -6
  26. package/dist/chunks/{index.CmSc2RE5.js → index.DIWhzsUh.js} +72 -118
  27. package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
  28. package/dist/chunks/moduleRunner.d.D9nBoC4p.d.ts +201 -0
  29. package/dist/chunks/moduleTransport.I-bgQy0S.js +19 -0
  30. package/dist/chunks/{node.fjCdwEIl.js → node.CyipiPvJ.js} +1 -1
  31. package/dist/chunks/{plugin.d.C2EcJUjo.d.ts → plugin.d.BMVSnsGV.d.ts} +1 -1
  32. package/dist/chunks/{reporters.d.DxZg19fy.d.ts → reporters.d.BUWjmRYq.d.ts} +1226 -1291
  33. package/dist/chunks/resolveSnapshotEnvironment.Bkht6Yor.js +81 -0
  34. package/dist/chunks/resolver.Bx6lE0iq.js +119 -0
  35. package/dist/chunks/rpc.BKr6mtxz.js +65 -0
  36. package/dist/chunks/{setup-common.D7ZqXFx-.js → setup-common.uiMcU3cv.js} +17 -29
  37. package/dist/chunks/startModuleRunner.p67gbNo9.js +665 -0
  38. package/dist/chunks/{suite.d.FvehnV49.d.ts → suite.d.BJWk38HB.d.ts} +1 -1
  39. package/dist/chunks/test.BiqSKISg.js +214 -0
  40. package/dist/chunks/{typechecker.CVytUJuF.js → typechecker.DB-fIMaH.js} +144 -213
  41. package/dist/chunks/{utils.CAioKnHs.js → utils.C2YI6McM.js} +5 -14
  42. package/dist/chunks/{utils.XdZDrNZV.js → utils.D2R2NiOH.js} +8 -27
  43. package/dist/chunks/{vi.bdSIJ99Y.js → vi.ZPgvtBao.js} +156 -305
  44. package/dist/chunks/{vm.BThCzidc.js → vm.Ca0Y0W5f.js} +116 -226
  45. package/dist/chunks/{worker.d.DoNjFAiv.d.ts → worker.d.BDsXGkwh.d.ts} +28 -22
  46. package/dist/chunks/{worker.d.CmvJfRGs.d.ts → worker.d.BNcX_2mH.d.ts} +1 -1
  47. package/dist/cli.js +4 -4
  48. package/dist/config.cjs +3 -9
  49. package/dist/config.d.ts +49 -54
  50. package/dist/config.js +1 -1
  51. package/dist/coverage.d.ts +27 -26
  52. package/dist/coverage.js +6 -7
  53. package/dist/environments.d.ts +9 -13
  54. package/dist/environments.js +1 -1
  55. package/dist/index.d.ts +38 -45
  56. package/dist/index.js +7 -9
  57. package/dist/module-evaluator.d.ts +13 -0
  58. package/dist/module-evaluator.js +276 -0
  59. package/dist/module-runner.js +15 -0
  60. package/dist/node.d.ts +40 -41
  61. package/dist/node.js +23 -33
  62. package/dist/reporters.d.ts +12 -13
  63. package/dist/reporters.js +3 -3
  64. package/dist/runners.d.ts +3 -3
  65. package/dist/runners.js +13 -232
  66. package/dist/snapshot.js +2 -2
  67. package/dist/suite.d.ts +2 -2
  68. package/dist/suite.js +2 -2
  69. package/dist/worker.js +90 -47
  70. package/dist/workers/forks.js +34 -10
  71. package/dist/workers/runVmTests.js +36 -56
  72. package/dist/workers/threads.js +34 -10
  73. package/dist/workers/vmForks.js +11 -10
  74. package/dist/workers/vmThreads.js +11 -10
  75. package/dist/workers.d.ts +5 -4
  76. package/dist/workers.js +35 -17
  77. package/globals.d.ts +17 -17
  78. package/package.json +32 -31
  79. package/dist/chunks/base.Bj3pWTr1.js +0 -38
  80. package/dist/chunks/execute.B7h3T_Hc.js +0 -708
  81. package/dist/chunks/index.D-VkfKhf.js +0 -105
  82. package/dist/chunks/rpc.CsFtxqeq.js +0 -83
  83. package/dist/chunks/runBaseTests.BC7ZIH5L.js +0 -129
  84. package/dist/execute.d.ts +0 -148
  85. package/dist/execute.js +0 -13
@@ -10,16 +10,13 @@ import { parseAstAsync } from 'vite';
10
10
 
11
11
  const REGEXP_WRAP_PREFIX = "$$vitest:";
12
12
  function getOutputFile(config, reporter) {
13
- if (!config?.outputFile) return;
14
- if (typeof config.outputFile === "string") return config.outputFile;
15
- return config.outputFile[reporter];
13
+ if (config?.outputFile) return typeof config.outputFile === "string" ? config.outputFile : config.outputFile[reporter];
16
14
  }
17
15
  /**
18
16
  * Prepares `SerializedConfig` for serialization, e.g. `node:v8.serialize`
19
17
  */
20
18
  function wrapSerializableConfig(config) {
21
- let testNamePattern = config.testNamePattern;
22
- let defines = config.defines;
19
+ let testNamePattern = config.testNamePattern, defines = config.defines;
23
20
  // v8 serialize does not support regex
24
21
  if (testNamePattern && typeof testNamePattern !== "string") testNamePattern = `${REGEXP_WRAP_PREFIX}${testNamePattern.toString()}`;
25
22
  // v8 serialize drops properties with undefined value
@@ -33,6 +30,49 @@ function wrapSerializableConfig(config) {
33
30
  defines
34
31
  };
35
32
  }
33
+ function createDefinesScript(define) {
34
+ if (!define) return "";
35
+ const serializedDefine = serializeDefine(define);
36
+ return serializedDefine === "{}" ? "" : `
37
+ const defines = ${serializeDefine(define)}
38
+ Object.keys(defines).forEach((key) => {
39
+ const segments = key.split('.')
40
+ let target = globalThis
41
+ for (let i = 0; i < segments.length; i++) {
42
+ const segment = segments[i]
43
+ if (i === segments.length - 1) {
44
+ target[segment] = defines[key]
45
+ } else {
46
+ target = target[segment] || (target[segment] = {})
47
+ }
48
+ }
49
+ })
50
+ `;
51
+ }
52
+ /**
53
+ * Like `JSON.stringify` but keeps raw string values as a literal
54
+ * in the generated code. For example: `"window"` would refer to
55
+ * the global `window` object directly.
56
+ */
57
+ function serializeDefine(define) {
58
+ const userDefine = {};
59
+ for (const key in define) {
60
+ // vitest sets this to avoid vite:client-inject plugin
61
+ if (key === "process.env.NODE_ENV" && define[key] === "process.env.NODE_ENV") continue;
62
+ // import.meta.env.* is handled in `importAnalysis` plugin
63
+ if (!key.startsWith("import.meta.env.")) userDefine[key] = define[key];
64
+ }
65
+ let res = `{`;
66
+ const keys = Object.keys(userDefine).sort();
67
+ for (let i = 0; i < keys.length; i++) {
68
+ const key = keys[i], val = userDefine[key];
69
+ if (res += `${JSON.stringify(key)}: ${handleDefineValue(val)}`, i !== keys.length - 1) res += `, `;
70
+ }
71
+ return `${res}}`;
72
+ }
73
+ function handleDefineValue(value) {
74
+ return typeof value === "undefined" ? "undefined" : typeof value === "string" ? value : JSON.stringify(value);
75
+ }
36
76
 
37
77
  function hasFailedSnapshot(suite) {
38
78
  return getTests(suite).some((s) => {
@@ -40,58 +80,44 @@ function hasFailedSnapshot(suite) {
40
80
  });
41
81
  }
42
82
  function convertTasksToEvents(file, onTask) {
43
- const packs = [];
44
- const events = [];
83
+ const packs = [], events = [];
45
84
  function visit(suite) {
46
- onTask?.(suite);
47
- packs.push([
85
+ onTask?.(suite), packs.push([
48
86
  suite.id,
49
87
  suite.result,
50
88
  suite.meta
51
- ]);
52
- events.push([
89
+ ]), events.push([
53
90
  suite.id,
54
91
  "suite-prepare",
55
92
  void 0
56
- ]);
57
- suite.tasks.forEach((task) => {
93
+ ]), suite.tasks.forEach((task) => {
58
94
  if (task.type === "suite") visit(task);
59
- else {
60
- onTask?.(task);
61
- if (suite.mode !== "skip" && suite.mode !== "todo") {
62
- packs.push([
63
- task.id,
64
- task.result,
65
- task.meta
66
- ]);
67
- events.push([
68
- task.id,
69
- "test-prepare",
70
- void 0
71
- ]);
72
- task.annotations.forEach((annotation) => {
73
- events.push([
74
- task.id,
75
- "test-annotation",
76
- { annotation }
77
- ]);
78
- });
79
- events.push([
80
- task.id,
81
- "test-finished",
82
- void 0
83
- ]);
84
- }
85
- }
86
- });
87
- events.push([
95
+ else if (onTask?.(task), suite.mode !== "skip" && suite.mode !== "todo") packs.push([
96
+ task.id,
97
+ task.result,
98
+ task.meta
99
+ ]), events.push([
100
+ task.id,
101
+ "test-prepare",
102
+ void 0
103
+ ]), task.annotations.forEach((annotation) => {
104
+ events.push([
105
+ task.id,
106
+ "test-annotation",
107
+ { annotation }
108
+ ]);
109
+ }), events.push([
110
+ task.id,
111
+ "test-finished",
112
+ void 0
113
+ ]);
114
+ }), events.push([
88
115
  suite.id,
89
116
  "suite-finished",
90
117
  void 0
91
118
  ]);
92
119
  }
93
- visit(file);
94
- return {
120
+ return visit(file), {
95
121
  packs,
96
122
  events
97
123
  };
@@ -374,13 +400,9 @@ base.MethodDefinition = base.PropertyDefinition = base.Property = function (node
374
400
  };
375
401
 
376
402
  async function collectTests(ctx, filepath) {
377
- const request = await ctx.vitenode.transformRequest(filepath, filepath);
403
+ const request = await ctx.vite.environments.ssr.transformRequest(filepath);
378
404
  if (!request) return null;
379
- const ast = await parseAstAsync(request.code);
380
- const testFilepath = relative(ctx.config.root, filepath);
381
- const projectName = ctx.name;
382
- const typecheckSubprojectName = projectName ? `${projectName}:__typecheck__` : "__typecheck__";
383
- const file = {
405
+ const ast = await parseAstAsync(request.code), testFilepath = relative(ctx.config.root, filepath), projectName = ctx.name, typecheckSubprojectName = projectName ? `${projectName}:__typecheck__` : "__typecheck__", file = {
384
406
  filepath,
385
407
  type: "suite",
386
408
  id: generateHash(`${testFilepath}${typecheckSubprojectName}`),
@@ -394,24 +416,19 @@ async function collectTests(ctx, filepath) {
394
416
  file: null
395
417
  };
396
418
  file.file = file;
397
- const definitions = [];
398
- const getName = (callee) => {
419
+ const definitions = [], getName = (callee) => {
399
420
  if (!callee) return null;
400
421
  if (callee.type === "Identifier") return callee.name;
401
422
  if (callee.type === "CallExpression") return getName(callee.callee);
402
423
  if (callee.type === "TaggedTemplateExpression") return getName(callee.tag);
403
- if (callee.type === "MemberExpression") {
404
- if (callee.object?.type === "Identifier" && [
405
- "it",
406
- "test",
407
- "describe",
408
- "suite"
409
- ].includes(callee.object.name)) return callee.object?.name;
410
- // direct call as `__vite_ssr_exports_0__.test()`
411
- if (callee.object?.name?.startsWith("__vite_ssr_")) return getName(callee.property);
412
- // call as `__vite_ssr__.test.skip()`
413
- return getName(callee.object?.property);
414
- }
424
+ if (callee.type === "MemberExpression")
425
+ // call as `__vite_ssr__.test.skip()`
426
+ return callee.object?.type === "Identifier" && [
427
+ "it",
428
+ "test",
429
+ "describe",
430
+ "suite"
431
+ ].includes(callee.object.name) ? callee.object?.name : callee.object?.name?.startsWith("__vite_ssr_") ? getName(callee.property) : getName(callee.object?.property);
415
432
  // unwrap (0, ...)
416
433
  if (callee.type === "SequenceExpression" && callee.expressions.length === 2) {
417
434
  const [e0, e1] = callee.expressions;
@@ -420,10 +437,8 @@ async function collectTests(ctx, filepath) {
420
437
  return null;
421
438
  };
422
439
  ancestor(ast, { CallExpression(node) {
423
- const { callee } = node;
424
- const name = getName(callee);
425
- if (!name) return;
426
- if (![
440
+ const { callee } = node, name = getName(callee);
441
+ if (!name || ![
427
442
  "it",
428
443
  "test",
429
444
  "describe",
@@ -444,9 +459,7 @@ async function collectTests(ctx, filepath) {
444
459
  if (callee.type === "CallExpression") start = callee.end;
445
460
  else if (callee.type === "TaggedTemplateExpression") start = callee.end + 1;
446
461
  else start = node.start;
447
- const { arguments: [messageNode] } = node;
448
- const isQuoted = messageNode?.type === "Literal" || messageNode?.type === "TemplateLiteral";
449
- const message = isQuoted ? request.code.slice(messageNode.start + 1, messageNode.end - 1) : request.code.slice(messageNode.start, messageNode.end);
462
+ const { arguments: [messageNode] } = node, isQuoted = messageNode?.type === "Literal" || messageNode?.type === "TemplateLiteral", message = isQuoted ? request.code.slice(messageNode.start + 1, messageNode.end - 1) : request.code.slice(messageNode.start, messageNode.end);
450
463
  // cannot statically analyze, so we always skip it
451
464
  if (mode === "skipIf" || mode === "runIf") mode = "skip";
452
465
  definitions.push({
@@ -482,9 +495,7 @@ async function collectTests(ctx, filepath) {
482
495
  start: definition.start,
483
496
  meta: { typecheck: true }
484
497
  };
485
- definition.task = task;
486
- latestSuite.tasks.push(task);
487
- lastSuite = task;
498
+ definition.task = task, latestSuite.tasks.push(task), lastSuite = task;
488
499
  return;
489
500
  }
490
501
  const task = {
@@ -501,13 +512,10 @@ async function collectTests(ctx, filepath) {
501
512
  annotations: [],
502
513
  meta: { typecheck: true }
503
514
  };
504
- definition.task = task;
505
- latestSuite.tasks.push(task);
506
- });
507
- calculateSuiteHash(file);
515
+ definition.task = task, latestSuite.tasks.push(task);
516
+ }), calculateSuiteHash(file);
508
517
  const hasOnly = someTasksAreOnly(file);
509
- interpretTaskModes(file, ctx.config.testNamePattern, void 0, hasOnly, false, ctx.config.allowOnly);
510
- return {
518
+ return interpretTaskModes(file, ctx.config.testNamePattern, void 0, hasOnly, false, ctx.config.allowOnly), {
511
519
  file,
512
520
  parsed: request.code,
513
521
  filepath,
@@ -516,14 +524,11 @@ async function collectTests(ctx, filepath) {
516
524
  };
517
525
  }
518
526
 
519
- const newLineRegExp = /\r?\n/;
520
- const errCodeRegExp = /error TS(?<errCode>\d+)/;
527
+ const newLineRegExp = /\r?\n/, errCodeRegExp = /error TS(?<errCode>\d+)/;
521
528
  async function makeTscErrorInfo(errInfo) {
522
529
  const [errFilePathPos = "", ...errMsgRawArr] = errInfo.split(":");
523
530
  if (!errFilePathPos || errMsgRawArr.length === 0 || errMsgRawArr.join("").length === 0) return ["unknown filepath", null];
524
- const errMsgRaw = errMsgRawArr.join("").trim();
525
- // get filePath, line, col
526
- const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
531
+ const errMsgRaw = errMsgRawArr.join("").trim(), [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
527
532
  if (!errFilePath || !errPos) return ["unknown filepath", null];
528
533
  const [errLine, errCol] = errPos.split(",");
529
534
  if (!errLine || !errCol) return [errFilePath, null];
@@ -532,9 +537,7 @@ async function makeTscErrorInfo(errInfo) {
532
537
  if (!execArr) return [errFilePath, null];
533
538
  const errCodeStr = execArr.groups?.errCode ?? "";
534
539
  if (!errCodeStr) return [errFilePath, null];
535
- const line = Number(errLine);
536
- const col = Number(errCol);
537
- const errCode = Number(errCodeStr);
540
+ const line = Number(errLine), col = Number(errCol), errCode = Number(errCodeStr);
538
541
  return [errFilePath, {
539
542
  filePath: errFilePath,
540
543
  errCode,
@@ -544,43 +547,30 @@ async function makeTscErrorInfo(errInfo) {
544
547
  }];
545
548
  }
546
549
  async function getRawErrsMapFromTsCompile(tscErrorStdout) {
547
- const rawErrsMap = /* @__PURE__ */ new Map();
548
- // Merge details line with main line (i.e. which contains file path)
549
- const infos = await Promise.all(tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
550
+ const rawErrsMap = /* @__PURE__ */ new Map(), infos = await Promise.all(tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
550
551
  if (!next) return prev;
551
- else if (!next.startsWith(" ")) prev.push(next);
552
+ if (!next.startsWith(" ")) prev.push(next);
552
553
  else prev[prev.length - 1] += `\n${next}`;
553
554
  return prev;
554
555
  }, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine)));
555
- infos.forEach(([errFilePath, errInfo]) => {
556
- if (!errInfo) return;
557
- if (!rawErrsMap.has(errFilePath)) rawErrsMap.set(errFilePath, [errInfo]);
556
+ return infos.forEach(([errFilePath, errInfo]) => {
557
+ if (errInfo) if (!rawErrsMap.has(errFilePath)) rawErrsMap.set(errFilePath, [errInfo]);
558
558
  else rawErrsMap.get(errFilePath)?.push(errInfo);
559
- });
560
- return rawErrsMap;
559
+ }), rawErrsMap;
561
560
  }
562
561
 
563
562
  function createIndexMap(source) {
564
563
  const map = /* @__PURE__ */ new Map();
565
- let index = 0;
566
- let line = 1;
567
- let column = 1;
568
- for (const char of source) {
569
- map.set(`${line}:${column}`, index++);
570
- if (char === "\n" || char === "\r\n") {
571
- line++;
572
- column = 0;
573
- } else column++;
574
- }
564
+ let index = 0, line = 1, column = 1;
565
+ for (const char of source) if (map.set(`${line}:${column}`, index++), char === "\n" || char === "\r\n") line++, column = 0;
566
+ else column++;
575
567
  return map;
576
568
  }
577
569
 
578
570
  class TypeCheckError extends Error {
579
571
  name = "TypeCheckError";
580
572
  constructor(message, stacks) {
581
- super(message);
582
- this.message = message;
583
- this.stacks = stacks;
573
+ super(message), this.message = message, this.stacks = stacks;
584
574
  }
585
575
  }
586
576
  class Typechecker {
@@ -620,12 +610,9 @@ class Typechecker {
620
610
  }
621
611
  async collectTests() {
622
612
  const tests = (await Promise.all(this.getFiles().map((filepath) => this.collectFileTests(filepath)))).reduce((acc, data) => {
623
- if (!data) return acc;
624
- acc[data.filepath] = data;
625
- return acc;
613
+ return data && (acc[data.filepath] = data), acc;
626
614
  }, {});
627
- this._tests = tests;
628
- return tests;
615
+ return this._tests = tests, tests;
629
616
  }
630
617
  markPassed(file) {
631
618
  if (!file.result?.state) file.result = { state: "pass" };
@@ -638,26 +625,17 @@ class Typechecker {
638
625
  markTasks(file.tasks);
639
626
  }
640
627
  async prepareResults(output) {
641
- const typeErrors = await this.parseTscLikeOutput(output);
642
- const testFiles = new Set(this.getFiles());
628
+ const typeErrors = await this.parseTscLikeOutput(output), testFiles = new Set(this.getFiles());
643
629
  if (!this._tests) this._tests = await this.collectTests();
644
- const sourceErrors = [];
645
- const files = [];
646
- testFiles.forEach((path) => {
647
- const { file, definitions, map, parsed } = this._tests[path];
648
- const errors = typeErrors.get(path);
649
- files.push(file);
650
- if (!errors) {
630
+ const sourceErrors = [], files = [];
631
+ return testFiles.forEach((path) => {
632
+ const { file, definitions, map, parsed } = this._tests[path], errors = typeErrors.get(path);
633
+ if (files.push(file), !errors) {
651
634
  this.markPassed(file);
652
635
  return;
653
636
  }
654
- const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)];
655
- // has no map for ".js" files that use // @ts-check
656
- const traceMap = map && new TraceMap(map);
657
- const indexMap = createIndexMap(parsed);
658
- const markState = (task, state) => {
659
- task.result = { state: task.mode === "run" || task.mode === "only" ? state : task.mode };
660
- if (task.suite) markState(task.suite, state);
637
+ const sortedDefinitions = [...definitions.sort((a, b) => b.start - a.start)], traceMap = map && new TraceMap(map), indexMap = createIndexMap(parsed), markState = (task, state) => {
638
+ if (task.result = { state: task.mode === "run" || task.mode === "only" ? state : task.mode }, task.suite) markState(task.suite, state);
661
639
  else if (task.file && task !== task.file) markState(task.file, state);
662
640
  };
663
641
  errors.forEach(({ error, originalError }) => {
@@ -665,53 +643,37 @@ class Typechecker {
665
643
  line: originalError.line,
666
644
  column: originalError.column,
667
645
  source: basename(path)
668
- }) : originalError;
669
- const line = processedPos.line ?? originalError.line;
670
- const column = processedPos.column ?? originalError.column;
671
- const index = indexMap.get(`${line}:${column}`);
672
- const definition = index != null && sortedDefinitions.find((def) => def.start <= index && def.end >= index);
673
- const suite = definition ? definition.task : file;
674
- const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode;
675
- const errors = suite.result?.errors || [];
676
- suite.result = {
646
+ }) : originalError, line = processedPos.line ?? originalError.line, column = processedPos.column ?? originalError.column, index = indexMap.get(`${line}:${column}`), definition = index != null && sortedDefinitions.find((def) => def.start <= index && def.end >= index), suite = definition ? definition.task : file, state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode, errors = suite.result?.errors || [];
647
+ if (suite.result = {
677
648
  state,
678
649
  errors
679
- };
680
- errors.push(error);
681
- if (state === "fail") {
650
+ }, errors.push(error), state === "fail") {
682
651
  if (suite.suite) markState(suite.suite, "fail");
683
652
  else if (suite.file && suite !== suite.file) markState(suite.file, "fail");
684
653
  }
685
- });
686
- this.markPassed(file);
687
- });
688
- typeErrors.forEach((errors, path) => {
654
+ }), this.markPassed(file);
655
+ }), typeErrors.forEach((errors, path) => {
689
656
  if (!testFiles.has(path)) sourceErrors.push(...errors.map(({ error }) => error));
690
- });
691
- return {
657
+ }), {
692
658
  files,
693
659
  sourceErrors,
694
660
  time: performance.now() - this._startTime
695
661
  };
696
662
  }
697
663
  async parseTscLikeOutput(output) {
698
- const errorsMap = await getRawErrsMapFromTsCompile(output);
699
- const typesErrors = /* @__PURE__ */ new Map();
700
- errorsMap.forEach((errors, path) => {
701
- const filepath = resolve(this.project.config.root, path);
702
- const suiteErrors = errors.map((info) => {
664
+ const errorsMap = await getRawErrsMapFromTsCompile(output), typesErrors = /* @__PURE__ */ new Map();
665
+ return errorsMap.forEach((errors, path) => {
666
+ const filepath = resolve(this.project.config.root, path), suiteErrors = errors.map((info) => {
703
667
  const limit = Error.stackTraceLimit;
704
668
  Error.stackTraceLimit = 0;
705
669
  // Some expect-type errors have the most useful information on the second line e.g. `This expression is not callable.\n Type 'ExpectString<number>' has no call signatures.`
706
- const errMsg = info.errMsg.replace(/\r?\n\s*(Type .* has no call signatures)/g, " $1");
707
- const error = new TypeCheckError(errMsg, [{
670
+ const errMsg = info.errMsg.replace(/\r?\n\s*(Type .* has no call signatures)/g, " $1"), error = new TypeCheckError(errMsg, [{
708
671
  file: filepath,
709
672
  line: info.line,
710
673
  column: info.column,
711
674
  method: ""
712
675
  }]);
713
- Error.stackTraceLimit = limit;
714
- return {
676
+ return Error.stackTraceLimit = limit, {
715
677
  originalError: info,
716
678
  error: {
717
679
  name: error.name,
@@ -722,12 +684,10 @@ class Typechecker {
722
684
  };
723
685
  });
724
686
  typesErrors.set(filepath, suiteErrors);
725
- });
726
- return typesErrors;
687
+ }), typesErrors;
727
688
  }
728
689
  async stop() {
729
- this.process?.kill();
730
- this.process = void 0;
690
+ this.process?.kill(), this.process = void 0;
731
691
  }
732
692
  async ensurePackageInstalled(ctx, checker) {
733
693
  if (checker !== "tsc" && checker !== "vue-tsc") return;
@@ -741,8 +701,7 @@ class Typechecker {
741
701
  return this._output;
742
702
  }
743
703
  async spawn() {
744
- const { root, watch, typecheck } = this.project.config;
745
- const args = [
704
+ const { root, watch, typecheck } = this.project.config, args = [
746
705
  "--noEmit",
747
706
  "--pretty",
748
707
  "false",
@@ -754,8 +713,7 @@ class Typechecker {
754
713
  if (watch) args.push("--watch");
755
714
  if (typecheck.allowJs) args.push("--allowJs", "--checkJs");
756
715
  if (typecheck.tsconfig) args.push("-p", resolve(root, typecheck.tsconfig));
757
- this._output = "";
758
- this._startTime = performance.now();
716
+ this._output = "", this._startTime = performance.now();
759
717
  const child = x(typecheck.checker, args, {
760
718
  nodeOptions: {
761
719
  cwd: root,
@@ -764,44 +722,26 @@ class Typechecker {
764
722
  throwOnError: false
765
723
  });
766
724
  this.process = child.process;
767
- let rerunTriggered = false;
768
- let dataReceived = false;
725
+ let rerunTriggered = false, dataReceived = false;
769
726
  return new Promise((resolve, reject) => {
770
727
  if (!child.process || !child.process.stdout) {
771
- reject(new Error(`Failed to initialize ${typecheck.checker}. This is a bug in Vitest - please, open an issue with reproduction.`));
728
+ reject(/* @__PURE__ */ new Error(`Failed to initialize ${typecheck.checker}. This is a bug in Vitest - please, open an issue with reproduction.`));
772
729
  return;
773
730
  }
774
731
  child.process.stdout.on("data", (chunk) => {
775
- dataReceived = true;
776
- this._output += chunk;
777
- if (!watch) return;
778
- if (this._output.includes("File change detected") && !rerunTriggered) {
779
- this._onWatcherRerun?.();
780
- this._startTime = performance.now();
781
- this._result.sourceErrors = [];
782
- this._result.files = [];
783
- this._tests = null;
784
- rerunTriggered = true;
785
- }
786
- if (/Found \w+ errors*. Watching for/.test(this._output)) {
787
- rerunTriggered = false;
788
- this.prepareResults(this._output).then((result) => {
789
- this._result = result;
790
- this._onParseEnd?.(result);
791
- });
792
- this._output = "";
732
+ if (dataReceived = true, this._output += chunk, watch) {
733
+ if (this._output.includes("File change detected") && !rerunTriggered) this._onWatcherRerun?.(), this._startTime = performance.now(), this._result.sourceErrors = [], this._result.files = [], this._tests = null, rerunTriggered = true;
734
+ if (/Found \w+ errors*. Watching for/.test(this._output)) rerunTriggered = false, this.prepareResults(this._output).then((result) => {
735
+ this._result = result, this._onParseEnd?.(result);
736
+ }), this._output = "";
793
737
  }
794
738
  });
795
- const timeout = setTimeout(() => reject(new Error(`${typecheck.checker} spawn timed out`)), this.project.config.typecheck.spawnTimeout);
739
+ const timeout = setTimeout(() => reject(/* @__PURE__ */ new Error(`${typecheck.checker} spawn timed out`)), this.project.config.typecheck.spawnTimeout);
796
740
  function onError(cause) {
797
- clearTimeout(timeout);
798
- reject(new Error("Spawning typechecker failed - is typescript installed?", { cause }));
741
+ clearTimeout(timeout), reject(new Error("Spawning typechecker failed - is typescript installed?", { cause }));
799
742
  }
800
- child.process.once("spawn", () => {
801
- this._onParseStart?.();
802
- child.process?.off("error", onError);
803
- clearTimeout(timeout);
804
- if (process.platform === "win32")
743
+ if (child.process.once("spawn", () => {
744
+ if (this._onParseStart?.(), child.process?.off("error", onError), clearTimeout(timeout), process.platform === "win32")
805
745
  // on Windows, the process might be spawned but fail to start
806
746
  // we wait for a potential error here. if "close" event didn't trigger,
807
747
  // we resolve the promise
@@ -809,22 +749,16 @@ class Typechecker {
809
749
  resolve({ result: child });
810
750
  }, 200);
811
751
  else resolve({ result: child });
812
- });
813
- if (process.platform === "win32") child.process.once("close", (code) => {
814
- if (code != null && code !== 0 && !dataReceived) onError(new Error(`The ${typecheck.checker} command exited with code ${code}.`));
752
+ }), process.platform === "win32") child.process.once("close", (code) => {
753
+ if (code != null && code !== 0 && !dataReceived) onError(/* @__PURE__ */ new Error(`The ${typecheck.checker} command exited with code ${code}.`));
815
754
  });
816
755
  child.process.once("error", onError);
817
756
  });
818
757
  }
819
758
  async start() {
820
759
  if (this.process) return;
821
- const { watch } = this.project.config;
822
- const { result: child } = await this.spawn();
823
- if (!watch) {
824
- await child;
825
- this._result = await this.prepareResults(this._output);
826
- await this._onParseEnd?.(this._result);
827
- }
760
+ const { watch } = this.project.config, { result: child } = await this.spawn();
761
+ if (!watch) await child, this._result = await this.prepareResults(this._output), await this._onParseEnd?.(this._result);
828
762
  }
829
763
  getResult() {
830
764
  return this._result;
@@ -833,12 +767,10 @@ class Typechecker {
833
767
  return Object.values(this._tests || {}).map((i) => i.file);
834
768
  }
835
769
  getTestPacksAndEvents() {
836
- const packs = [];
837
- const events = [];
770
+ const packs = [], events = [];
838
771
  for (const { file } of Object.values(this._tests || {})) {
839
772
  const result = convertTasksToEvents(file);
840
- packs.push(...result.packs);
841
- events.push(...result.events);
773
+ packs.push(...result.packs), events.push(...result.events);
842
774
  }
843
775
  return {
844
776
  packs,
@@ -861,14 +793,13 @@ function findGeneratedPosition(traceMap, { line, column, source }) {
861
793
  if (m.source === source && m.originalLine !== null && m.originalColumn !== null && (line === m.originalLine ? column < m.originalColumn : line < m.originalLine)) mappings.push(m);
862
794
  });
863
795
  const next = mappings.sort((a, b) => a.originalLine === b.originalLine ? a.originalColumn - b.originalColumn : a.originalLine - b.originalLine).at(0);
864
- if (next) return {
796
+ return next ? {
865
797
  line: next.generatedLine,
866
798
  column: next.generatedColumn
867
- };
868
- return {
799
+ } : {
869
800
  line: null,
870
801
  column: null
871
802
  };
872
803
  }
873
804
 
874
- export { TypeCheckError as T, Typechecker as a, convertTasksToEvents as c, getOutputFile as g, hasFailedSnapshot as h, wrapSerializableConfig as w };
805
+ export { TypeCheckError as T, Typechecker as a, ancestor as b, createDefinesScript as c, convertTasksToEvents as d, getOutputFile as g, hasFailedSnapshot as h, wrapSerializableConfig as w };
@@ -1,11 +1,6 @@
1
1
  import { parseRegexp } from '@vitest/utils';
2
2
 
3
- const REGEXP_WRAP_PREFIX = "$$vitest:";
4
- // Store global APIs in case process is overwritten by tests
5
- const processSend = process.send?.bind(process);
6
- const processOn = process.on?.bind(process);
7
- const processOff = process.off?.bind(process);
8
- const dispose = [];
3
+ const REGEXP_WRAP_PREFIX = "$$vitest:", processSend = process.send?.bind(process), processOn = process.on?.bind(process), processOff = process.off?.bind(process), dispose = [];
9
4
  function createThreadsRpcOptions({ port }) {
10
5
  return {
11
6
  post: (v) => {
@@ -31,12 +26,9 @@ function createForksRpcOptions(nodeV8) {
31
26
  },
32
27
  on(fn) {
33
28
  const handler = (message, ...extras) => {
34
- // Do not react on Tinypool's internal messaging
35
- if (message?.__tinypool_worker_message__) return;
36
- return fn(message, ...extras);
29
+ if (!message?.__tinypool_worker_message__) return fn(message, ...extras);
37
30
  };
38
- processOn("message", handler);
39
- dispose.push(() => processOff("message", handler));
31
+ processOn("message", handler), dispose.push(() => processOff("message", handler));
40
32
  }
41
33
  };
42
34
  }
@@ -46,11 +38,10 @@ function createForksRpcOptions(nodeV8) {
46
38
  function unwrapSerializableConfig(config) {
47
39
  if (config.testNamePattern && typeof config.testNamePattern === "string") {
48
40
  const testNamePattern = config.testNamePattern;
49
- if (testNamePattern.startsWith(REGEXP_WRAP_PREFIX)) config.testNamePattern = parseRegexp(testNamePattern.slice(REGEXP_WRAP_PREFIX.length));
41
+ if (testNamePattern.startsWith(REGEXP_WRAP_PREFIX)) config.testNamePattern = parseRegexp(testNamePattern.slice(9));
50
42
  }
51
43
  if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) {
52
- const { keys, original } = config.defines;
53
- const defines = {};
44
+ const { keys, original } = config.defines, defines = {};
54
45
  // Apply all keys from the original. Entries which had undefined value are missing from original now
55
46
  for (const key of keys) defines[key] = original[key];
56
47
  config.defines = defines;