vitest 4.0.0-beta.10 → 4.0.0-beta.12
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.
- package/LICENSE.md +85 -101
- package/dist/browser.d.ts +10 -6
- package/dist/browser.js +8 -5
- package/dist/chunks/{benchmark.CJUa-Hsa.js → benchmark.DHKMYAts.js} +2 -2
- package/dist/chunks/{browser.d.yFAklsD1.d.ts → browser.d.D9YV3JvA.d.ts} +1 -1
- package/dist/chunks/{cac.DCxo_nSu.js → cac.r1gel_VZ.js} +18 -11
- package/dist/chunks/{cli-api.BJJXh9BV.js → cli-api.CpywZzJV.js} +153 -176
- package/dist/chunks/{config.d.B_LthbQq.d.ts → config.d.DGazh2r6.d.ts} +3 -1
- package/dist/chunks/{console.7h5kHUIf.js → console.CTJL2nuH.js} +4 -6
- package/dist/chunks/{coverage.BCU-r2QL.js → coverage.CiB0fs_7.js} +57 -79
- package/dist/chunks/{creator.08Gi-vCA.js → creator.DfXDsUyL.js} +6 -8
- package/dist/chunks/{global.d.BK3X7FW1.d.ts → global.d.BcFPD2LN.d.ts} +0 -13
- package/dist/chunks/{globals.DG-S3xFe.js → globals.DC4ntO86.js} +8 -6
- package/dist/chunks/{index.DIWhzsUh.js → index.Bt-upxGS.js} +6 -12
- package/dist/chunks/{index.BIP7prJq.js → index.CHrBLuEH.js} +94 -103
- package/dist/chunks/{index.X0nbfr6-.js → index.Dc3xnDvT.js} +48 -289
- package/dist/chunks/{index.CMfqw92x.js → index.Dnl38iQ_.js} +2 -2
- package/dist/chunks/{index.BjKEiSn0.js → index.uLUz1RDt.js} +3 -3
- package/dist/chunks/{inspector.CvQD-Nie.js → inspector.Br76Q2Mb.js} +1 -4
- package/dist/chunks/{moduleRunner.d.D9nBoC4p.d.ts → moduleRunner.d.CeYc7nZ0.d.ts} +1 -1
- package/dist/chunks/{node.CyipiPvJ.js → node.BwAWWjHZ.js} +3 -4
- package/dist/chunks/{plugin.d.BMVSnsGV.d.ts → plugin.d.XreRXLXS.d.ts} +1 -1
- package/dist/chunks/{reporters.d.BUWjmRYq.d.ts → reporters.d.CJVTaaWb.d.ts} +54 -13
- package/dist/chunks/{resolveSnapshotEnvironment.Bkht6Yor.js → resolveSnapshotEnvironment.BsJpmVZR.js} +7 -8
- package/dist/chunks/{rpc.BKr6mtxz.js → rpc.cD77ENhU.js} +13 -14
- package/dist/chunks/{setup-common.uiMcU3cv.js → setup-common.BewgbkTd.js} +6 -6
- package/dist/chunks/{startModuleRunner.p67gbNo9.js → startModuleRunner.DPBo3mme.js} +65 -56
- package/dist/chunks/{test.BiqSKISg.js → test.CTuWuHYH.js} +7 -7
- package/dist/chunks/{typechecker.DB-fIMaH.js → typechecker.BfOQ86_a.js} +624 -14
- package/dist/chunks/{utils.D2R2NiOH.js → utils.CG9h5ccR.js} +2 -5
- package/dist/chunks/{vi.ZPgvtBao.js → vi.B2--mG9U.js} +38 -145
- package/dist/{worker.js → chunks/worker.DVTUM2IW.js} +71 -42
- package/dist/chunks/{worker.d.BDsXGkwh.d.ts → worker.d.buwuBpBt.d.ts} +2 -77
- package/dist/cli.js +7 -5
- package/dist/config.d.ts +6 -6
- package/dist/coverage.d.ts +5 -5
- package/dist/coverage.js +4 -5
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +8 -6
- package/dist/module-evaluator.d.ts +3 -3
- package/dist/module-evaluator.js +11 -13
- package/dist/module-runner.js +5 -5
- package/dist/node.d.ts +14 -11
- package/dist/node.js +18 -14
- package/dist/reporters.d.ts +5 -5
- package/dist/reporters.js +7 -5
- package/dist/runners.d.ts +1 -1
- package/dist/runners.js +9 -7
- package/dist/snapshot.js +3 -3
- package/dist/suite.js +4 -3
- package/dist/{chunks/base.Cjha6usc.js → worker-base.js} +104 -32
- package/dist/{chunks/vm.Ca0Y0W5f.js → worker-vm.js} +81 -31
- package/dist/workers/runVmTests.js +14 -11
- package/package.json +26 -26
- package/browser.d.ts +0 -1
- package/dist/chunks/moduleTransport.I-bgQy0S.js +0 -19
- package/dist/chunks/resolver.Bx6lE0iq.js +0 -119
- package/dist/chunks/utils.C2YI6McM.js +0 -52
- package/dist/chunks/worker.d.BNcX_2mH.d.ts +0 -8
- package/dist/workers/forks.js +0 -67
- package/dist/workers/threads.js +0 -55
- package/dist/workers/vmForks.js +0 -48
- package/dist/workers/vmThreads.js +0 -38
- package/dist/workers.d.ts +0 -38
- package/dist/workers.js +0 -48
- package/execute.d.ts +0 -1
- package/utils.d.ts +0 -1
- package/workers.d.ts +0 -1
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { existsSync, readFileSync, promises } from 'node:fs';
|
|
2
2
|
import { mkdir, writeFile, readdir, stat, readFile } from 'node:fs/promises';
|
|
3
3
|
import { resolve, dirname, isAbsolute, relative, basename, normalize } from 'pathe';
|
|
4
|
-
import { g as getOutputFile, h as hasFailedSnapshot, T as TypeCheckError } from './typechecker.
|
|
4
|
+
import { g as getOutputFile, h as hasFailedSnapshot, T as TypeCheckError } from './typechecker.BfOQ86_a.js';
|
|
5
5
|
import { performance as performance$1 } from 'node:perf_hooks';
|
|
6
|
-
import { getTestName,
|
|
7
|
-
import { slash, toArray, isPrimitive
|
|
6
|
+
import { getTestName, hasFailed, getTests, getSuites, getTasks, getFullName } from '@vitest/runner/utils';
|
|
7
|
+
import { slash, toArray, isPrimitive } from '@vitest/utils/helpers';
|
|
8
8
|
import { parseStacktrace, parseErrorStacktrace, defaultStackIgnorePatterns } from '@vitest/utils/source-map';
|
|
9
9
|
import c from 'tinyrainbow';
|
|
10
10
|
import { i as isTTY } from './env.D4Lgay0q.js';
|
|
11
11
|
import { stripVTControlCharacters } from 'node:util';
|
|
12
12
|
import { Console } from 'node:console';
|
|
13
13
|
import { Writable } from 'node:stream';
|
|
14
|
+
import { inspect } from '@vitest/utils/display';
|
|
15
|
+
import { positionToOffset, lineSplitRE } from '@vitest/utils/offset';
|
|
14
16
|
import { createRequire } from 'node:module';
|
|
15
17
|
import { hostname } from 'node:os';
|
|
16
18
|
|
|
@@ -169,9 +171,9 @@ async function writeBlob(content, filename) {
|
|
|
169
171
|
}
|
|
170
172
|
async function readBlobs(currentVersion, blobsDirectory, projectsArray) {
|
|
171
173
|
// using process.cwd() because --merge-reports can only be used in CLI
|
|
172
|
-
const resolvedDir = resolve(process.cwd(), blobsDirectory),
|
|
173
|
-
const fullPath = resolve(resolvedDir, filename)
|
|
174
|
-
if (!
|
|
174
|
+
const resolvedDir = resolve(process.cwd(), blobsDirectory), promises = (await readdir(resolvedDir)).map(async (filename) => {
|
|
175
|
+
const fullPath = resolve(resolvedDir, filename);
|
|
176
|
+
if (!(await stat(fullPath)).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`);
|
|
175
177
|
const content = await readFile(fullPath, "utf-8"), [version, files, errors, moduleKeys, coverage, executionTime] = parse(content);
|
|
176
178
|
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`);
|
|
177
179
|
return {
|
|
@@ -232,6 +234,7 @@ const testPass = c.green(F_CHECK);
|
|
|
232
234
|
const taskFail = c.red(F_CROSS);
|
|
233
235
|
const suiteFail = c.red(F_POINTER);
|
|
234
236
|
const pending$1 = c.gray("·");
|
|
237
|
+
const separator = c.dim(" > ");
|
|
235
238
|
const labelDefaultColors = [
|
|
236
239
|
c.bgYellow,
|
|
237
240
|
c.bgCyan,
|
|
@@ -351,6 +354,7 @@ var utils = /*#__PURE__*/Object.freeze({
|
|
|
351
354
|
pending: pending$1,
|
|
352
355
|
pointer: pointer,
|
|
353
356
|
renderSnapshotSummary: renderSnapshotSummary,
|
|
357
|
+
separator: separator,
|
|
354
358
|
skipped: skipped,
|
|
355
359
|
suiteFail: suiteFail,
|
|
356
360
|
taskFail: taskFail,
|
|
@@ -440,19 +444,10 @@ class BaseReporter {
|
|
|
440
444
|
})), logs.forEach((log) => this.log(log));
|
|
441
445
|
}
|
|
442
446
|
printTestCase(moduleState, test) {
|
|
443
|
-
const testResult = test.result(), { duration
|
|
444
|
-
|
|
445
|
-
if (
|
|
446
|
-
if (
|
|
447
|
-
if (testResult.state === "failed")
|
|
448
|
-
// print short errors, full errors will be at the end in summary
|
|
449
|
-
this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test.task, c.dim(" > "))}`) + suffix), testResult.errors.forEach((error) => {
|
|
450
|
-
const message = this.formatShortError(error);
|
|
451
|
-
if (message) this.log(c.red(` ${padding}${message}`));
|
|
452
|
-
});
|
|
453
|
-
else if (duration && duration > this.ctx.config.slowTestThreshold) this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, c.dim(" > "))} ${suffix}`);
|
|
454
|
-
else if (this.ctx.config.hideSkippedTests && testResult.state === "skipped") ; else if (testResult.state === "skipped" && testResult.note) this.log(` ${padding}${getStateSymbol(test.task)} ${this.getTestName(test.task, c.dim(" > "))}${c.dim(c.gray(` [${testResult.note}]`))}`);
|
|
455
|
-
else if (this.renderSucceed || moduleState === "failed") this.log(` ${padding}${getStateSymbol(test.task)} ${this.getTestName(test.task, c.dim(" > "))}${suffix}`);
|
|
447
|
+
const testResult = test.result(), { duration = 0 } = test.diagnostic() || {}, padding = this.getTestIndentation(test.task), suffix = this.getTestCaseSuffix(test);
|
|
448
|
+
if (testResult.state === "failed") this.log(c.red(` ${padding}${taskFail} ${this.getTestName(test.task, separator)}`) + suffix);
|
|
449
|
+
else if (duration > this.ctx.config.slowTestThreshold) this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, separator)} ${suffix}`);
|
|
450
|
+
else if (this.ctx.config.hideSkippedTests && testResult.state === "skipped") ; else if (this.renderSucceed || moduleState === "failed") this.log(` ${padding}${this.getStateSymbol(test)} ${this.getTestName(test.task, separator)}${suffix}`);
|
|
456
451
|
}
|
|
457
452
|
getModuleLog(testModule, counts) {
|
|
458
453
|
let state = c.dim(`${counts.tests} test${counts.tests > 1 ? "s" : ""}`);
|
|
@@ -461,46 +456,65 @@ class BaseReporter {
|
|
|
461
456
|
let suffix = c.dim("(") + state + c.dim(")") + this.getDurationPrefix(testModule.task);
|
|
462
457
|
const diagnostic = testModule.diagnostic();
|
|
463
458
|
if (diagnostic.heap != null) suffix += c.magenta(` ${Math.floor(diagnostic.heap / 1024 / 1024)} MB heap used`);
|
|
464
|
-
|
|
465
|
-
if (testModule.meta().typecheck) title += ` ${c.bgBlue(c.bold(" TS "))}`;
|
|
466
|
-
if (testModule.project.name) title += ` ${formatProjectName(testModule.project, "")}`;
|
|
467
|
-
return ` ${title} ${testModule.task.name} ${suffix}`;
|
|
459
|
+
return ` ${this.getEntityPrefix(testModule)} ${testModule.task.name} ${suffix}`;
|
|
468
460
|
}
|
|
469
|
-
printTestSuite(
|
|
470
|
-
|
|
461
|
+
printTestSuite(testSuite) {
|
|
462
|
+
if (!this.renderSucceed) return;
|
|
463
|
+
const indentation = " ".repeat(getIndentation(testSuite.task)), tests = Array.from(testSuite.children.allTests()), state = this.getStateSymbol(testSuite);
|
|
464
|
+
this.log(` ${indentation}${state} ${testSuite.name} ${c.dim(`(${tests.length})`)}`);
|
|
471
465
|
}
|
|
472
|
-
getTestName(test,
|
|
473
|
-
return
|
|
466
|
+
getTestName(test, _separator) {
|
|
467
|
+
return test.name;
|
|
474
468
|
}
|
|
475
469
|
getFullName(test, separator) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
return
|
|
470
|
+
if (test === test.file) return test.name;
|
|
471
|
+
let name = test.file.name;
|
|
472
|
+
if (test.location) name += c.dim(`:${test.location.line}:${test.location.column}`);
|
|
473
|
+
return name += separator, name += getTestName(test, separator), name;
|
|
480
474
|
}
|
|
481
|
-
getTestIndentation(
|
|
482
|
-
return " ";
|
|
475
|
+
getTestIndentation(test) {
|
|
476
|
+
return " ".repeat(getIndentation(test));
|
|
483
477
|
}
|
|
484
478
|
printAnnotations(test, console, padding = 0) {
|
|
485
479
|
const annotations = test.annotations();
|
|
486
480
|
if (!annotations.length) return;
|
|
487
|
-
const PADDING = " ".repeat(padding);
|
|
488
|
-
annotations.forEach((
|
|
481
|
+
const PADDING = " ".repeat(padding), groupedAnnotations = {};
|
|
482
|
+
for (const group in annotations.forEach((annotation) => {
|
|
483
|
+
const { location, type } = annotation;
|
|
484
|
+
let group;
|
|
489
485
|
if (location) {
|
|
490
486
|
const file = relative(test.project.config.root, location.file);
|
|
491
|
-
|
|
492
|
-
} else
|
|
487
|
+
group = `${c.gray(`${file}:${location.line}:${location.column}`)} ${c.bold(type)}`;
|
|
488
|
+
} else group = c.bold(type);
|
|
489
|
+
groupedAnnotations[group] ??= [], groupedAnnotations[group].push(annotation);
|
|
490
|
+
}), groupedAnnotations) this[console](`${PADDING}${c.blue(F_POINTER)} ${group}`), groupedAnnotations[group].forEach(({ message }) => {
|
|
493
491
|
this[console](`${PADDING} ${c.blue(F_DOWN_RIGHT)} ${message}`);
|
|
494
492
|
});
|
|
495
493
|
}
|
|
494
|
+
getEntityPrefix(entity) {
|
|
495
|
+
let title = this.getStateSymbol(entity);
|
|
496
|
+
if (entity.project.name) title += ` ${formatProjectName(entity.project, "")}`;
|
|
497
|
+
if (entity.meta().typecheck) title += ` ${c.bgBlue(c.bold(" TS "))}`;
|
|
498
|
+
return title;
|
|
499
|
+
}
|
|
500
|
+
getTestCaseSuffix(testCase) {
|
|
501
|
+
const { heap, retryCount, repeatCount } = testCase.diagnostic() || {}, testResult = testCase.result();
|
|
502
|
+
let suffix = this.getDurationPrefix(testCase.task);
|
|
503
|
+
if (retryCount != null && retryCount > 0) suffix += c.yellow(` (retry x${retryCount})`);
|
|
504
|
+
if (repeatCount != null && repeatCount > 0) suffix += c.yellow(` (repeat x${repeatCount})`);
|
|
505
|
+
if (heap != null) suffix += c.magenta(` ${Math.floor(heap / 1024 / 1024)} MB heap used`);
|
|
506
|
+
if (testResult.state === "skipped" && testResult.note) suffix += c.dim(c.gray(` [${testResult.note}]`));
|
|
507
|
+
return suffix;
|
|
508
|
+
}
|
|
509
|
+
getStateSymbol(test) {
|
|
510
|
+
return getStateSymbol(test.task);
|
|
511
|
+
}
|
|
496
512
|
getDurationPrefix(task) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
return color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
|
|
513
|
+
const duration = task.result?.duration && Math.round(task.result?.duration);
|
|
514
|
+
return duration == null ? "" : (duration > this.ctx.config.slowTestThreshold ? c.yellow : c.green)(` ${duration}${c.dim("ms")}`);
|
|
500
515
|
}
|
|
501
516
|
onWatcherStart(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
502
|
-
|
|
503
|
-
if (failed) this.log(withLabel("red", "FAIL", "Tests failed. Watching for file changes..."));
|
|
517
|
+
if (errors.length > 0 || hasFailed(files)) this.log(withLabel("red", "FAIL", "Tests failed. Watching for file changes..."));
|
|
504
518
|
else if (this.ctx.isCancelling) this.log(withLabel("red", "CANCELLED", "Test run cancelled. Watching for file changes..."));
|
|
505
519
|
else this.log(withLabel("green", "PASS", "Waiting for file changes..."));
|
|
506
520
|
const hints = [c.dim("press ") + c.bold("h") + c.dim(" to show help")];
|
|
@@ -531,7 +545,7 @@ class BaseReporter {
|
|
|
531
545
|
const output = log.type === "stdout" ? this.ctx.logger.outputStream : this.ctx.logger.errorStream, write = (msg) => output.write(msg);
|
|
532
546
|
let headerText = "unknown test";
|
|
533
547
|
const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0;
|
|
534
|
-
if (task) headerText = this.getFullName(task,
|
|
548
|
+
if (task) headerText = this.getFullName(task, separator);
|
|
535
549
|
else if (log.taskId && log.taskId !== "__vitest__unknown_test__") headerText = log.taskId;
|
|
536
550
|
if (write(c.gray(log.type + c.dim(` | ${headerText}\n`)) + log.content), log.origin) {
|
|
537
551
|
// browser logs don't have an extra end of line at the end like Node.js does
|
|
@@ -550,8 +564,8 @@ class BaseReporter {
|
|
|
550
564
|
shouldLog(log, taskState) {
|
|
551
565
|
if (this.ctx.config.silent === true || this.ctx.config.silent === "passed-only" && taskState !== "failed") return false;
|
|
552
566
|
if (this.ctx.config.onConsoleLog) {
|
|
553
|
-
const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0, entity = task && this.ctx.state.getReportedEntity(task)
|
|
554
|
-
if (
|
|
567
|
+
const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0, entity = task && this.ctx.state.getReportedEntity(task);
|
|
568
|
+
if (this.ctx.config.onConsoleLog(log.content, log.type, entity) === false) return false;
|
|
555
569
|
}
|
|
556
570
|
return true;
|
|
557
571
|
}
|
|
@@ -601,12 +615,12 @@ class BaseReporter {
|
|
|
601
615
|
if (errors.length) this.ctx.logger.printUnhandledErrors(errors), this.error();
|
|
602
616
|
}
|
|
603
617
|
reportBenchmarkSummary(files) {
|
|
604
|
-
const
|
|
618
|
+
const topBenches = getTests(files).filter((i) => i.result?.benchmark?.rank === 1);
|
|
605
619
|
this.log(`\n${withLabel("cyan", "BENCH", "Summary\n")}`);
|
|
606
620
|
for (const bench of topBenches) {
|
|
607
621
|
const group = bench.suite || bench.file;
|
|
608
622
|
if (!group) continue;
|
|
609
|
-
const groupName = this.getFullName(group,
|
|
623
|
+
const groupName = this.getFullName(group, separator), project = this.ctx.projects.find((p) => p.name === bench.file.projectName);
|
|
610
624
|
this.log(` ${formatProjectName(project)}${bench.name}${c.dim(` - ${groupName}`)}`);
|
|
611
625
|
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);
|
|
612
626
|
for (const sibling of siblings) {
|
|
@@ -633,7 +647,7 @@ class BaseReporter {
|
|
|
633
647
|
for (const [error, tasks] of errorsQueue) {
|
|
634
648
|
for (const task of tasks) {
|
|
635
649
|
const filepath = task?.filepath || "", projectName = task?.projectName || task.file?.projectName || "", project = this.ctx.projects.find((p) => p.name === projectName);
|
|
636
|
-
let name = this.getFullName(task,
|
|
650
|
+
let name = this.getFullName(task, separator);
|
|
637
651
|
if (filepath) name += c.dim(` [ ${this.relative(filepath)} ]`);
|
|
638
652
|
this.ctx.logger.error(`${c.bgRed(c.bold(" FAIL "))} ${formatProjectName(project)}${name}`);
|
|
639
653
|
}
|
|
@@ -664,6 +678,9 @@ function sum(items, cb) {
|
|
|
664
678
|
return total + Math.max(cb(next) || 0, 0);
|
|
665
679
|
}, 0);
|
|
666
680
|
}
|
|
681
|
+
function getIndentation(suite, level = 1) {
|
|
682
|
+
return suite.suite && !("filepath" in suite.suite) ? getIndentation(suite.suite, level + 1) : level;
|
|
683
|
+
}
|
|
667
684
|
|
|
668
685
|
const DEFAULT_RENDER_INTERVAL_MS = 1e3, ESC = "\x1B[", CLEAR_LINE = `${ESC}K`, MOVE_CURSOR_ONE_ROW_UP = `${ESC}1A`, SYNC_START = `${ESC}?2026h`, SYNC_END = `${ESC}?2026l`;
|
|
669
686
|
/**
|
|
@@ -876,11 +893,10 @@ class SummaryReporter {
|
|
|
876
893
|
else if (state === "failed") this.modules.failed++;
|
|
877
894
|
else if (module.task.mode === "todo" && state === "skipped") this.modules.todo++;
|
|
878
895
|
else if (state === "skipped") this.modules.skipped++;
|
|
879
|
-
const left = this.modules.total - this.modules.completed;
|
|
880
896
|
// Keep finished tests visible in summary for a while if there are more tests left.
|
|
881
897
|
// When a new test starts in onTestModuleQueued it will take this ones place.
|
|
882
898
|
// This reduces flickering by making summary more stable.
|
|
883
|
-
if (
|
|
899
|
+
if (this.modules.total - this.modules.completed > this.maxParallelTests) this.finishedModules.set(module.id, setTimeout(() => {
|
|
884
900
|
this.removeTestModule(module.id);
|
|
885
901
|
}, FINISHED_TEST_CLEANUP_TIME_MS).unref());
|
|
886
902
|
else
|
|
@@ -1105,12 +1121,12 @@ function capturePrintError(error, ctx, options) {
|
|
|
1105
1121
|
} }), console = new Console(writable), logger = {
|
|
1106
1122
|
error: console.error.bind(console),
|
|
1107
1123
|
highlight: ctx.logger.highlight.bind(ctx.logger)
|
|
1108
|
-
}
|
|
1109
|
-
showCodeFrame: false,
|
|
1110
|
-
...options
|
|
1111
|
-
});
|
|
1124
|
+
};
|
|
1112
1125
|
return {
|
|
1113
|
-
nearest:
|
|
1126
|
+
nearest: printError(error, ctx, logger, {
|
|
1127
|
+
showCodeFrame: false,
|
|
1128
|
+
...options
|
|
1129
|
+
})?.nearest,
|
|
1114
1130
|
output
|
|
1115
1131
|
};
|
|
1116
1132
|
}
|
|
@@ -1158,19 +1174,17 @@ function printErrorInner(error, project, options) {
|
|
|
1158
1174
|
const stacks = options.parseErrorStacktrace(e), nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => {
|
|
1159
1175
|
// we are checking that this module was processed by us at one point
|
|
1160
1176
|
try {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
});
|
|
1165
|
-
return hasResult && existsSync(stack.file);
|
|
1177
|
+
return [...Object.values(project._vite?.environments || {}), ...Object.values(project.browser?.vite.environments || {})].some((environment) => {
|
|
1178
|
+
return [...environment.moduleGraph.getModulesByFile(stack.file)?.values() || []].some((module) => !!module.transformResult);
|
|
1179
|
+
}) && existsSync(stack.file);
|
|
1166
1180
|
} catch {
|
|
1167
1181
|
return false;
|
|
1168
1182
|
}
|
|
1169
1183
|
});
|
|
1170
1184
|
if (type) printErrorType(type, project.vitest);
|
|
1171
1185
|
if (printErrorMessage(e, logger), options.screenshotPaths?.length) {
|
|
1172
|
-
const
|
|
1173
|
-
if (logger.error(`\nFailure screenshot${length > 1 ? "s" : ""}:`), logger.error(
|
|
1186
|
+
const uniqueScreenshots = Array.from(new Set(options.screenshotPaths)), length = uniqueScreenshots.length;
|
|
1187
|
+
if (logger.error(`\nFailure screenshot${length > 1 ? "s" : ""}:`), logger.error(uniqueScreenshots.map((p) => ` - ${c.dim(relative(process.cwd(), p))}`).join("\n")), !e.diff) logger.error();
|
|
1174
1188
|
}
|
|
1175
1189
|
if (e.codeFrame) logger.error(`${e.codeFrame}\n`);
|
|
1176
1190
|
if ("__vitest_rollup_error__" in e) {
|
|
@@ -1252,7 +1266,7 @@ function handleImportOutsideModuleError(stack, logger) {
|
|
|
1252
1266
|
if (!esmErrors.some((e) => stack.includes(e))) return;
|
|
1253
1267
|
const path = normalize(stack.split("\n")[0].trim());
|
|
1254
1268
|
let name = path.split("/node_modules/").pop() || "";
|
|
1255
|
-
if (name
|
|
1269
|
+
if (name[0] === "@") name = name.split("/").slice(0, 2).join("/");
|
|
1256
1270
|
else name = name.split("/")[0];
|
|
1257
1271
|
if (name) printModuleWarningForPackage(logger, path, name);
|
|
1258
1272
|
else printModuleWarningForSourceCode(logger, path);
|
|
@@ -1409,7 +1423,7 @@ const BUILT_IN_TYPES = [
|
|
|
1409
1423
|
"warning"
|
|
1410
1424
|
];
|
|
1411
1425
|
function getTitle(type) {
|
|
1412
|
-
|
|
1426
|
+
if (!BUILT_IN_TYPES.includes(type)) return type;
|
|
1413
1427
|
}
|
|
1414
1428
|
function getType(type) {
|
|
1415
1429
|
return BUILT_IN_TYPES.includes(type) ? type : "notice";
|
|
@@ -1436,8 +1450,7 @@ function escapeProperty(s) {
|
|
|
1436
1450
|
class HangingProcessReporter {
|
|
1437
1451
|
whyRunning;
|
|
1438
1452
|
onInit() {
|
|
1439
|
-
|
|
1440
|
-
this.whyRunning = _require("why-is-node-running");
|
|
1453
|
+
this.whyRunning = createRequire(import.meta.url)("why-is-node-running");
|
|
1441
1454
|
}
|
|
1442
1455
|
onProcessTimeout() {
|
|
1443
1456
|
this.whyRunning?.();
|
|
@@ -1597,8 +1610,7 @@ class JUnitReporter {
|
|
|
1597
1610
|
this.reportFile = resolve(this.ctx.config.root, outputFile);
|
|
1598
1611
|
const outputDirectory = dirname(this.reportFile);
|
|
1599
1612
|
if (!existsSync(outputDirectory)) await promises.mkdir(outputDirectory, { recursive: true });
|
|
1600
|
-
|
|
1601
|
-
this.fileFd = fileFd, this.baseLog = async (text) => {
|
|
1613
|
+
this.fileFd = await promises.open(this.reportFile, "w+"), this.baseLog = async (text) => {
|
|
1602
1614
|
if (!this.fileFd) this.fileFd = await promises.open(this.reportFile, "w+");
|
|
1603
1615
|
await promises.writeFile(this.fileFd, `${text}\n`);
|
|
1604
1616
|
};
|
|
@@ -1761,7 +1773,7 @@ class TapReporter {
|
|
|
1761
1773
|
this.logger.log(`# ${type}: ${message}`);
|
|
1762
1774
|
}), this.logger.unindent();
|
|
1763
1775
|
if (task.result?.state === "fail" && task.result.errors) this.logger.indent(), task.result.errors.forEach((error) => {
|
|
1764
|
-
const
|
|
1776
|
+
const stack = (task.file.pool === "browser" ? project.browser?.parseErrorStacktrace(error) || [] : parseErrorStacktrace(error, { frameFilter: this.ctx.config.onStackTrace }))[0];
|
|
1765
1777
|
if (this.logger.log("---"), this.logger.log("error:"), this.logger.indent(), this.logErrorDetails(error), this.logger.unindent(), stack) this.logger.log(`at: ${yamlString(`${stack.file}:${stack.line}:${stack.column}`)}`);
|
|
1766
1778
|
if (error.showDiff) this.logger.log(`actual: ${yamlString(error.actual)}`), this.logger.log(`expected: ${yamlString(error.expected)}`);
|
|
1767
1779
|
}), this.logger.log("..."), this.logger.unindent();
|
|
@@ -1792,48 +1804,26 @@ class TapFlatReporter extends TapReporter {
|
|
|
1792
1804
|
}
|
|
1793
1805
|
}
|
|
1794
1806
|
|
|
1807
|
+
class TreeReporter extends DefaultReporter {
|
|
1808
|
+
verbose = true;
|
|
1809
|
+
renderSucceed = true;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1795
1812
|
class VerboseReporter extends DefaultReporter {
|
|
1796
1813
|
verbose = true;
|
|
1797
1814
|
renderSucceed = true;
|
|
1798
|
-
printTestModule(
|
|
1799
|
-
//
|
|
1800
|
-
// but don't print it in the CLI because we
|
|
1801
|
-
// print all the tests when they finish
|
|
1802
|
-
// instead of printing them when the test file finishes
|
|
1803
|
-
if (this.isTTY) return super.printTestModule(module);
|
|
1815
|
+
printTestModule(_module) {
|
|
1816
|
+
// don't print test module, only print tests
|
|
1804
1817
|
}
|
|
1805
1818
|
onTestCaseResult(test) {
|
|
1806
|
-
|
|
1807
|
-
// in the CLI when they finish
|
|
1808
|
-
if (super.onTestCaseResult(test), this.isTTY) return;
|
|
1819
|
+
super.onTestCaseResult(test);
|
|
1809
1820
|
const testResult = test.result();
|
|
1810
1821
|
if (this.ctx.config.hideSkippedTests && testResult.state === "skipped") return;
|
|
1811
|
-
let title = ` ${
|
|
1812
|
-
if (test.
|
|
1813
|
-
title +=
|
|
1814
|
-
const diagnostic = test.diagnostic();
|
|
1815
|
-
if (diagnostic?.heap != null) title += c.magenta(` ${Math.floor(diagnostic.heap / 1024 / 1024)} MB heap used`);
|
|
1816
|
-
if (testResult.state === "skipped" && testResult.note) title += c.dim(c.gray(` [${testResult.note}]`));
|
|
1817
|
-
if (this.log(title), testResult.state === "failed") testResult.errors.forEach((error) => this.log(c.red(` ${F_RIGHT} ${error?.message}`)));
|
|
1822
|
+
let title = ` ${this.getEntityPrefix(test)} `;
|
|
1823
|
+
if (title += test.module.task.name, test.location) title += c.dim(`:${test.location.line}:${test.location.column}`);
|
|
1824
|
+
if (title += separator, title += getTestName(test.task, separator), title += this.getTestCaseSuffix(test), this.log(title), testResult.state === "failed") testResult.errors.forEach((error) => this.log(c.red(` ${F_RIGHT} ${error.message}`)));
|
|
1818
1825
|
if (test.annotations().length) this.log(), this.printAnnotations(test, "log", 3), this.log();
|
|
1819
1826
|
}
|
|
1820
|
-
printTestSuite(testSuite) {
|
|
1821
|
-
const indentation = " ".repeat(getIndentation(testSuite.task)), tests = Array.from(testSuite.children.allTests()), state = getStateSymbol(testSuite.task);
|
|
1822
|
-
this.log(` ${indentation}${state} ${testSuite.name} ${c.dim(`(${tests.length})`)}`);
|
|
1823
|
-
}
|
|
1824
|
-
getTestName(test) {
|
|
1825
|
-
return test.name;
|
|
1826
|
-
}
|
|
1827
|
-
getTestIndentation(test) {
|
|
1828
|
-
return " ".repeat(getIndentation(test));
|
|
1829
|
-
}
|
|
1830
|
-
formatShortError() {
|
|
1831
|
-
// Short errors are not shown in tree-view
|
|
1832
|
-
return "";
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
function getIndentation(suite, level = 1) {
|
|
1836
|
-
return suite.suite && !("filepath" in suite.suite) ? getIndentation(suite.suite, level + 1) : level;
|
|
1837
1827
|
}
|
|
1838
1828
|
|
|
1839
1829
|
const ReportersMap = {
|
|
@@ -1845,8 +1835,9 @@ const ReportersMap = {
|
|
|
1845
1835
|
"tap": TapReporter,
|
|
1846
1836
|
"tap-flat": TapFlatReporter,
|
|
1847
1837
|
"junit": JUnitReporter,
|
|
1838
|
+
"tree": TreeReporter,
|
|
1848
1839
|
"hanging-process": HangingProcessReporter,
|
|
1849
1840
|
"github-actions": GithubActionsReporter
|
|
1850
1841
|
};
|
|
1851
1842
|
|
|
1852
|
-
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,
|
|
1843
|
+
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, stringify as d, printError as e, formatProjectName as f, getStateSymbol as g, errorBanner as h, divider as i, generateCodeFrame as j, parse as p, readBlobs as r, separator as s, truncateString as t, utils as u, withLabel as w };
|