vitest 2.0.0-beta.10 → 2.0.0-beta.11
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/dist/browser.d.ts +1 -1
- package/dist/browser.js +3 -3
- package/dist/chunks/{integrations-globals.C6Ah-pUW.js → integrations-globals.CC2ed6Py.js} +9 -9
- package/dist/chunks/{node-git.CCI8evVZ.js → node-git.ZtkbKc8u.js} +14 -15
- package/dist/chunks/{runtime-console.DiVMr5d4.js → runtime-console.Ckl0vEQr.js} +25 -10
- package/dist/chunks/{runtime-runBaseTests.Cukyr5-I.js → runtime-runBaseTests.BXW_BJeO.js} +40 -32
- package/dist/cli.js +3 -3
- package/dist/config.cjs +42 -19
- package/dist/config.d.ts +1 -1
- package/dist/config.js +42 -20
- package/dist/coverage.d.ts +4 -4
- package/dist/coverage.js +98 -36
- package/dist/environments.d.ts +1 -1
- package/dist/environments.js +1 -1
- package/dist/execute.d.ts +1 -1
- package/dist/execute.js +2 -2
- package/dist/index.d.ts +34 -8
- package/dist/index.js +9 -9
- package/dist/node.d.ts +19 -6
- package/dist/node.js +24 -16
- package/dist/path.js +4 -1
- package/dist/{reporters-CYVC6LOl.d.ts → reporters-fiIq_dT9.d.ts} +118 -179
- package/dist/reporters.d.ts +1 -1
- package/dist/reporters.js +7 -7
- package/dist/runners.d.ts +1 -1
- package/dist/runners.js +98 -60
- package/dist/{suite-Dpu9EC_k.d.ts → suite-D4aoU9rI.d.ts} +1 -1
- package/dist/suite.d.ts +2 -2
- package/dist/suite.js +2 -2
- package/dist/utils.d.ts +1 -5
- package/dist/utils.js +1 -6
- package/dist/vendor/{base.Dln9yllP.js → base.C2DbLEfT.js} +4 -3
- package/dist/vendor/{base._gnK9Slw.js → base.CTYV4Gnz.js} +24 -17
- package/dist/vendor/{benchmark.BNLebNi5.js → benchmark.CMp8QfyL.js} +13 -14
- package/dist/vendor/{cac.CtYFkoSJ.js → cac.BcJW7n2j.js} +71 -37
- package/dist/vendor/{cli-api.CUtJc4r3.js → cli-api.C8t8m4__.js} +4012 -4828
- package/dist/vendor/{constants.TCjCaw2D.js → constants.BWsVtsAj.js} +5 -22
- package/dist/vendor/{coverage.ChSqD-qS.js → coverage.BhYSDdTT.js} +27 -11
- package/dist/vendor/{date.BKM1wewY.js → date.W2xKR2qe.js} +5 -3
- package/dist/vendor/{execute.BHj6OMh4.js → execute.T3gg2ZK6.js} +174 -60
- package/dist/vendor/{index.B5SKBLvV.js → index.-dbR4KUi.js} +17 -9
- package/dist/vendor/{index.BOMEjpjj.js → index.BC5zhX9y.js} +960 -469
- package/dist/vendor/{index.CThipSqB.js → index.BMmMjLIQ.js} +2540 -2540
- package/dist/vendor/{index._7XLd8Kd.js → index.C9Thslzw.js} +2 -1
- package/dist/vendor/{index.D3hs2WiI.js → index.CQJ2m700.js} +3 -3
- package/dist/vendor/{index.kpsSqFiz.js → index.D4nqnQWz.js} +69 -73
- package/dist/vendor/{rpc.DRDE9Pu1.js → rpc.BGx7q_k2.js} +30 -19
- package/dist/vendor/{run-once.DLomgGUH.js → run-once.Db8Hgq9X.js} +2 -1
- package/dist/vendor/{setup-common.DAu7t7mY.js → setup-common.uqZOEWuR.js} +30 -15
- package/dist/vendor/{tasks.WC7M-K-v.js → tasks.DhVtQBtW.js} +3 -1
- package/dist/vendor/{utils.YuQ3LT2a.js → utils.DSO2UK15.js} +40 -25
- package/dist/vendor/{utils.CUjzkRH7.js → utils.DkxLWvS1.js} +12 -5
- package/dist/vendor/{vi.hATFzZbX.js → vi.BPjl8cAZ.js} +266 -137
- package/dist/vendor/{vm.Ow-X2mkS.js → vm.CycSoHnJ.js} +151 -86
- package/dist/worker.js +31 -15
- package/dist/workers/forks.js +4 -4
- package/dist/workers/runVmTests.js +14 -13
- package/dist/workers/threads.js +4 -4
- package/dist/workers/vmForks.js +6 -6
- package/dist/workers/vmThreads.js +6 -6
- package/dist/workers.d.ts +2 -2
- package/dist/workers.js +9 -9
- package/package.json +11 -11
- package/suppress-warnings.cjs +1 -4
|
@@ -2,16 +2,16 @@ import fs, { existsSync, promises, readFileSync } from 'node:fs';
|
|
|
2
2
|
import c from 'picocolors';
|
|
3
3
|
import * as pathe from 'pathe';
|
|
4
4
|
import { basename, dirname, resolve, join, relative, extname, normalize } from 'pathe';
|
|
5
|
-
import { a as getFullName, h as hasFailedSnapshot } from './tasks.
|
|
5
|
+
import { a as getFullName, h as hasFailedSnapshot } from './tasks.DhVtQBtW.js';
|
|
6
6
|
import { getSafeTimers, notNullish, highlight, shuffle, inspect, positionToOffset, lineSplitRE } from '@vitest/utils';
|
|
7
7
|
import { i as isNode } from './env.bmJgw1qP.js';
|
|
8
|
-
import { g as getStateSymbol, f as formatProjectName, p as pointer, F as F_RIGHT, a as F_POINTER, r as renderSnapshotSummary, b as getStateString, c as formatTimeString, d as countTestErrors, e as divider, s as stripAnsi, h as getCols, i as getHookStateSymbol } from './utils.
|
|
8
|
+
import { g as getStateSymbol, f as formatProjectName, p as pointer, F as F_RIGHT, a as F_POINTER, r as renderSnapshotSummary, b as getStateString, c as formatTimeString, d as countTestErrors, e as divider, s as stripAnsi, h as getCols, i as getHookStateSymbol } from './utils.DSO2UK15.js';
|
|
9
9
|
import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks, getTests, hasFailed, getSuites } from '@vitest/runner/utils';
|
|
10
10
|
import { performance } from 'node:perf_hooks';
|
|
11
11
|
import { TraceMap, generatedPositionFor, parseStacktrace, parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
12
|
-
import { r as relativePath } from './index.
|
|
13
|
-
import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.
|
|
14
|
-
import { t as toArray, b as isPrimitive } from './base.
|
|
12
|
+
import { r as relativePath } from './index.C9Thslzw.js';
|
|
13
|
+
import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.Ckl0vEQr.js';
|
|
14
|
+
import { t as toArray, b as isPrimitive } from './base.CTYV4Gnz.js';
|
|
15
15
|
import { isCI } from 'std-env';
|
|
16
16
|
import nodeos__default, { hostname } from 'node:os';
|
|
17
17
|
import { Writable } from 'node:stream';
|
|
@@ -140,19 +140,23 @@ const stringify = (value, replacer, space) => {
|
|
|
140
140
|
|
|
141
141
|
const REGEXP_WRAP_PREFIX = "$$vitest:";
|
|
142
142
|
function getOutputFile(config, reporter) {
|
|
143
|
-
if (!(config == null ? void 0 : config.outputFile))
|
|
143
|
+
if (!(config == null ? void 0 : config.outputFile)) {
|
|
144
144
|
return;
|
|
145
|
-
|
|
145
|
+
}
|
|
146
|
+
if (typeof config.outputFile === "string") {
|
|
146
147
|
return config.outputFile;
|
|
148
|
+
}
|
|
147
149
|
return config.outputFile[reporter];
|
|
148
150
|
}
|
|
149
151
|
function wrapSerializableConfig(config) {
|
|
150
152
|
let testNamePattern = config.testNamePattern;
|
|
151
153
|
let defines = config.defines;
|
|
152
|
-
if (testNamePattern && typeof testNamePattern !== "string")
|
|
154
|
+
if (testNamePattern && typeof testNamePattern !== "string") {
|
|
153
155
|
testNamePattern = `${REGEXP_WRAP_PREFIX}${testNamePattern.toString()}`;
|
|
154
|
-
|
|
156
|
+
}
|
|
157
|
+
if (defines) {
|
|
155
158
|
defines = { keys: Object.keys(defines), original: defines };
|
|
159
|
+
}
|
|
156
160
|
return {
|
|
157
161
|
...config,
|
|
158
162
|
testNamePattern,
|
|
@@ -181,17 +185,21 @@ async function makeTscErrorInfo(errInfo) {
|
|
|
181
185
|
}
|
|
182
186
|
const errMsgRaw = errMsgRawArr.join("").trim();
|
|
183
187
|
const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
|
|
184
|
-
if (!errFilePath || !errPos)
|
|
188
|
+
if (!errFilePath || !errPos) {
|
|
185
189
|
return ["unknown filepath", null];
|
|
190
|
+
}
|
|
186
191
|
const [errLine, errCol] = errPos.split(",");
|
|
187
|
-
if (!errLine || !errCol)
|
|
192
|
+
if (!errLine || !errCol) {
|
|
188
193
|
return [errFilePath, null];
|
|
194
|
+
}
|
|
189
195
|
const execArr = errCodeRegExp.exec(errMsgRaw);
|
|
190
|
-
if (!execArr)
|
|
196
|
+
if (!execArr) {
|
|
191
197
|
return [errFilePath, null];
|
|
198
|
+
}
|
|
192
199
|
const errCodeStr = ((_a = execArr.groups) == null ? void 0 : _a.errCode) ?? "";
|
|
193
|
-
if (!errCodeStr)
|
|
200
|
+
if (!errCodeStr) {
|
|
194
201
|
return [errFilePath, null];
|
|
202
|
+
}
|
|
195
203
|
const line = Number(errLine);
|
|
196
204
|
const col = Number(errCol);
|
|
197
205
|
const errCode = Number(errCodeStr);
|
|
@@ -210,9 +218,13 @@ async function getTsconfig(root, config) {
|
|
|
210
218
|
const configName = config.tsconfig ? basename(config.tsconfig) : void 0;
|
|
211
219
|
const configSearchPath = config.tsconfig ? dirname(resolve(root, config.tsconfig)) : root;
|
|
212
220
|
const tsconfig = $e(configSearchPath, configName);
|
|
213
|
-
if (!tsconfig)
|
|
221
|
+
if (!tsconfig) {
|
|
214
222
|
throw new Error("no tsconfig.json found");
|
|
215
|
-
|
|
223
|
+
}
|
|
224
|
+
const tempConfigPath = join(
|
|
225
|
+
dirname(tsconfig.path),
|
|
226
|
+
"tsconfig.vitest-temp.json"
|
|
227
|
+
);
|
|
216
228
|
try {
|
|
217
229
|
const tmpTsConfig = { ...tsconfig.config };
|
|
218
230
|
tmpTsConfig.compilerOptions = tmpTsConfig.compilerOptions || {};
|
|
@@ -233,24 +245,27 @@ async function getRawErrsMapFromTsCompile(tscErrorStdout) {
|
|
|
233
245
|
const rawErrsMap = /* @__PURE__ */ new Map();
|
|
234
246
|
const infos = await Promise.all(
|
|
235
247
|
tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
|
|
236
|
-
if (!next)
|
|
248
|
+
if (!next) {
|
|
237
249
|
return prev;
|
|
238
|
-
else if (!next.startsWith(" "))
|
|
250
|
+
} else if (!next.startsWith(" ")) {
|
|
239
251
|
prev.push(next);
|
|
240
|
-
else
|
|
252
|
+
} else {
|
|
241
253
|
prev[prev.length - 1] += `
|
|
242
254
|
${next}`;
|
|
255
|
+
}
|
|
243
256
|
return prev;
|
|
244
257
|
}, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine))
|
|
245
258
|
);
|
|
246
259
|
infos.forEach(([errFilePath, errInfo]) => {
|
|
247
260
|
var _a;
|
|
248
|
-
if (!errInfo)
|
|
261
|
+
if (!errInfo) {
|
|
249
262
|
return;
|
|
250
|
-
|
|
263
|
+
}
|
|
264
|
+
if (!rawErrsMap.has(errFilePath)) {
|
|
251
265
|
rawErrsMap.set(errFilePath, [errInfo]);
|
|
252
|
-
else
|
|
266
|
+
} else {
|
|
253
267
|
(_a = rawErrsMap.get(errFilePath)) == null ? void 0 : _a.push(errInfo);
|
|
268
|
+
}
|
|
254
269
|
});
|
|
255
270
|
return rawErrsMap;
|
|
256
271
|
}
|
|
@@ -585,8 +600,9 @@ base.MethodDefinition = base.PropertyDefinition = base.Property = function (node
|
|
|
585
600
|
|
|
586
601
|
async function collectTests(ctx, filepath) {
|
|
587
602
|
const request = await ctx.vitenode.transformRequest(filepath, filepath);
|
|
588
|
-
if (!request)
|
|
603
|
+
if (!request) {
|
|
589
604
|
return null;
|
|
605
|
+
}
|
|
590
606
|
const ast = await parseAstAsync(request.code);
|
|
591
607
|
const testFilepath = relative(ctx.config.root, filepath);
|
|
592
608
|
const file = {
|
|
@@ -606,13 +622,16 @@ async function collectTests(ctx, filepath) {
|
|
|
606
622
|
const definitions = [];
|
|
607
623
|
const getName = (callee) => {
|
|
608
624
|
var _a, _b, _c;
|
|
609
|
-
if (!callee)
|
|
625
|
+
if (!callee) {
|
|
610
626
|
return null;
|
|
611
|
-
|
|
627
|
+
}
|
|
628
|
+
if (callee.type === "Identifier") {
|
|
612
629
|
return callee.name;
|
|
630
|
+
}
|
|
613
631
|
if (callee.type === "MemberExpression") {
|
|
614
|
-
if ((_b = (_a = callee.object) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("__vite_ssr_"))
|
|
632
|
+
if ((_b = (_a = callee.object) == null ? void 0 : _a.name) == null ? void 0 : _b.startsWith("__vite_ssr_")) {
|
|
615
633
|
return getName(callee.property);
|
|
634
|
+
}
|
|
616
635
|
return getName((_c = callee.object) == null ? void 0 : _c.property);
|
|
617
636
|
}
|
|
618
637
|
return null;
|
|
@@ -622,17 +641,25 @@ async function collectTests(ctx, filepath) {
|
|
|
622
641
|
var _a;
|
|
623
642
|
const { callee } = node;
|
|
624
643
|
const name = getName(callee);
|
|
625
|
-
if (!name)
|
|
644
|
+
if (!name) {
|
|
626
645
|
return;
|
|
627
|
-
|
|
646
|
+
}
|
|
647
|
+
if (!["it", "test", "describe", "suite"].includes(name)) {
|
|
628
648
|
return;
|
|
629
|
-
|
|
649
|
+
}
|
|
650
|
+
const {
|
|
651
|
+
arguments: [{ value: message }]
|
|
652
|
+
} = node;
|
|
630
653
|
const property = (_a = callee == null ? void 0 : callee.property) == null ? void 0 : _a.name;
|
|
631
654
|
let mode = !property || property === name ? "run" : property;
|
|
632
|
-
if (!["run", "skip", "todo", "only", "skipIf", "runIf"].includes(mode))
|
|
633
|
-
throw new Error(
|
|
634
|
-
|
|
655
|
+
if (!["run", "skip", "todo", "only", "skipIf", "runIf"].includes(mode)) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
`${name}.${mode} syntax is not supported when testing types`
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
if (mode === "skipIf" || mode === "runIf") {
|
|
635
661
|
mode = "skip";
|
|
662
|
+
}
|
|
636
663
|
definitions.push({
|
|
637
664
|
start: node.start,
|
|
638
665
|
end: node.end,
|
|
@@ -644,15 +671,17 @@ async function collectTests(ctx, filepath) {
|
|
|
644
671
|
});
|
|
645
672
|
let lastSuite = file;
|
|
646
673
|
const updateLatestSuite = (index) => {
|
|
647
|
-
while (lastSuite.suite && lastSuite.end < index)
|
|
674
|
+
while (lastSuite.suite && lastSuite.end < index) {
|
|
648
675
|
lastSuite = lastSuite.suite;
|
|
676
|
+
}
|
|
649
677
|
return lastSuite;
|
|
650
678
|
};
|
|
651
679
|
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
|
|
652
680
|
const latestSuite = updateLatestSuite(definition.start);
|
|
653
681
|
let mode = definition.mode;
|
|
654
|
-
if (latestSuite.mode !== "run")
|
|
682
|
+
if (latestSuite.mode !== "run") {
|
|
655
683
|
mode = latestSuite.mode;
|
|
684
|
+
}
|
|
656
685
|
if (definition.type === "suite") {
|
|
657
686
|
const task2 = {
|
|
658
687
|
type: definition.type,
|
|
@@ -693,7 +722,13 @@ async function collectTests(ctx, filepath) {
|
|
|
693
722
|
});
|
|
694
723
|
calculateSuiteHash(file);
|
|
695
724
|
const hasOnly = someTasksAreOnly(file);
|
|
696
|
-
interpretTaskModes(
|
|
725
|
+
interpretTaskModes(
|
|
726
|
+
file,
|
|
727
|
+
ctx.config.testNamePattern,
|
|
728
|
+
hasOnly,
|
|
729
|
+
false,
|
|
730
|
+
ctx.config.allowOnly
|
|
731
|
+
);
|
|
697
732
|
return {
|
|
698
733
|
file,
|
|
699
734
|
parsed: request.code,
|
|
@@ -755,8 +790,9 @@ class Typechecker {
|
|
|
755
790
|
const tests = (await Promise.all(
|
|
756
791
|
this.getFiles().map((filepath) => this.collectFileTests(filepath))
|
|
757
792
|
)).reduce((acc, data) => {
|
|
758
|
-
if (!data)
|
|
793
|
+
if (!data) {
|
|
759
794
|
return acc;
|
|
795
|
+
}
|
|
760
796
|
acc[data.filepath] = data;
|
|
761
797
|
return acc;
|
|
762
798
|
}, {});
|
|
@@ -773,8 +809,9 @@ class Typechecker {
|
|
|
773
809
|
const markTasks = (tasks) => {
|
|
774
810
|
var _a2;
|
|
775
811
|
for (const task of tasks) {
|
|
776
|
-
if ("tasks" in task)
|
|
812
|
+
if ("tasks" in task) {
|
|
777
813
|
markTasks(task.tasks);
|
|
814
|
+
}
|
|
778
815
|
if (!((_a2 = task.result) == null ? void 0 : _a2.state) && task.mode === "run") {
|
|
779
816
|
task.result = {
|
|
780
817
|
state: "pass"
|
|
@@ -787,8 +824,9 @@ class Typechecker {
|
|
|
787
824
|
async prepareResults(output) {
|
|
788
825
|
const typeErrors = await this.parseTscLikeOutput(output);
|
|
789
826
|
const testFiles = new Set(this.getFiles());
|
|
790
|
-
if (!this._tests)
|
|
827
|
+
if (!this._tests) {
|
|
791
828
|
this._tests = await this.collectTests();
|
|
829
|
+
}
|
|
792
830
|
const sourceErrors = [];
|
|
793
831
|
const files = [];
|
|
794
832
|
testFiles.forEach((path) => {
|
|
@@ -799,17 +837,20 @@ class Typechecker {
|
|
|
799
837
|
this.markPassed(file);
|
|
800
838
|
return;
|
|
801
839
|
}
|
|
802
|
-
const sortedDefinitions = [
|
|
840
|
+
const sortedDefinitions = [
|
|
841
|
+
...definitions.sort((a, b) => b.start - a.start)
|
|
842
|
+
];
|
|
803
843
|
const traceMap = map && new TraceMap(map);
|
|
804
844
|
const indexMap = createIndexMap(parsed);
|
|
805
845
|
const markState = (task, state) => {
|
|
806
846
|
task.result = {
|
|
807
847
|
state: task.mode === "run" || task.mode === "only" ? state : task.mode
|
|
808
848
|
};
|
|
809
|
-
if (task.suite)
|
|
849
|
+
if (task.suite) {
|
|
810
850
|
markState(task.suite, state);
|
|
811
|
-
else if (task.file && task !== task.file)
|
|
851
|
+
} else if (task.file && task !== task.file) {
|
|
812
852
|
markState(task.file, state);
|
|
853
|
+
}
|
|
813
854
|
};
|
|
814
855
|
errors.forEach(({ error, originalError }) => {
|
|
815
856
|
var _a;
|
|
@@ -821,7 +862,9 @@ class Typechecker {
|
|
|
821
862
|
const line = processedPos.line ?? originalError.line;
|
|
822
863
|
const column = processedPos.column ?? originalError.column;
|
|
823
864
|
const index = indexMap.get(`${line}:${column}`);
|
|
824
|
-
const definition = index != null && sortedDefinitions.find(
|
|
865
|
+
const definition = index != null && sortedDefinitions.find(
|
|
866
|
+
(def) => def.start <= index && def.end >= index
|
|
867
|
+
);
|
|
825
868
|
const suite = definition ? definition.task : file;
|
|
826
869
|
const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode;
|
|
827
870
|
const errors2 = ((_a = suite.result) == null ? void 0 : _a.errors) || [];
|
|
@@ -831,17 +874,19 @@ class Typechecker {
|
|
|
831
874
|
};
|
|
832
875
|
errors2.push(error);
|
|
833
876
|
if (state === "fail") {
|
|
834
|
-
if (suite.suite)
|
|
877
|
+
if (suite.suite) {
|
|
835
878
|
markState(suite.suite, "fail");
|
|
836
|
-
else if (suite.file && suite !== suite.file)
|
|
879
|
+
} else if (suite.file && suite !== suite.file) {
|
|
837
880
|
markState(suite.file, "fail");
|
|
881
|
+
}
|
|
838
882
|
}
|
|
839
883
|
});
|
|
840
884
|
this.markPassed(file);
|
|
841
885
|
});
|
|
842
886
|
typeErrors.forEach((errors, path) => {
|
|
843
|
-
if (!testFiles.has(path))
|
|
887
|
+
if (!testFiles.has(path)) {
|
|
844
888
|
sourceErrors.push(...errors.map(({ error }) => error));
|
|
889
|
+
}
|
|
845
890
|
});
|
|
846
891
|
return {
|
|
847
892
|
files,
|
|
@@ -857,7 +902,10 @@ class Typechecker {
|
|
|
857
902
|
const suiteErrors = errors.map((info) => {
|
|
858
903
|
const limit = Error.stackTraceLimit;
|
|
859
904
|
Error.stackTraceLimit = 0;
|
|
860
|
-
const errMsg = info.errMsg.replace(
|
|
905
|
+
const errMsg = info.errMsg.replace(
|
|
906
|
+
/\r?\n\s*(Type .* has no call signatures)/g,
|
|
907
|
+
" $1"
|
|
908
|
+
);
|
|
861
909
|
const error = new TypeCheckError(errMsg, [
|
|
862
910
|
{
|
|
863
911
|
file: filepath,
|
|
@@ -884,8 +932,9 @@ class Typechecker {
|
|
|
884
932
|
return typesErrors;
|
|
885
933
|
}
|
|
886
934
|
async clear() {
|
|
887
|
-
if (this.tempConfigPath)
|
|
935
|
+
if (this.tempConfigPath) {
|
|
888
936
|
await rm(this.tempConfigPath, { force: true });
|
|
937
|
+
}
|
|
889
938
|
}
|
|
890
939
|
async stop() {
|
|
891
940
|
var _a;
|
|
@@ -893,8 +942,9 @@ class Typechecker {
|
|
|
893
942
|
(_a = this.process) == null ? void 0 : _a.kill();
|
|
894
943
|
}
|
|
895
944
|
async ensurePackageInstalled(ctx, checker) {
|
|
896
|
-
if (checker !== "tsc" && checker !== "vue-tsc")
|
|
945
|
+
if (checker !== "tsc" && checker !== "vue-tsc") {
|
|
897
946
|
return;
|
|
947
|
+
}
|
|
898
948
|
const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
|
|
899
949
|
await ctx.packageInstaller.ensureInstalled(packageName, ctx.config.root);
|
|
900
950
|
}
|
|
@@ -913,14 +963,17 @@ class Typechecker {
|
|
|
913
963
|
}
|
|
914
964
|
async start() {
|
|
915
965
|
var _a, _b, _c;
|
|
916
|
-
if (!this.tempConfigPath)
|
|
966
|
+
if (!this.tempConfigPath) {
|
|
917
967
|
throw new Error("tsconfig was not initialized");
|
|
968
|
+
}
|
|
918
969
|
const { root, watch, typecheck } = this.ctx.config;
|
|
919
970
|
const args = ["--noEmit", "--pretty", "false", "-p", this.tempConfigPath];
|
|
920
|
-
if (watch)
|
|
971
|
+
if (watch) {
|
|
921
972
|
args.push("--watch");
|
|
922
|
-
|
|
973
|
+
}
|
|
974
|
+
if (typecheck.allowJs) {
|
|
923
975
|
args.push("--allowJs", "--checkJs");
|
|
976
|
+
}
|
|
924
977
|
this._output = "";
|
|
925
978
|
this._startTime = performance.now();
|
|
926
979
|
const child = execa(typecheck.checker, args, {
|
|
@@ -934,8 +987,9 @@ class Typechecker {
|
|
|
934
987
|
(_b = child.stdout) == null ? void 0 : _b.on("data", (chunk) => {
|
|
935
988
|
var _a2;
|
|
936
989
|
this._output += chunk;
|
|
937
|
-
if (!watch)
|
|
990
|
+
if (!watch) {
|
|
938
991
|
return;
|
|
992
|
+
}
|
|
939
993
|
if (this._output.includes("File change detected") && !rerunTriggered) {
|
|
940
994
|
(_a2 = this._onWatcherRerun) == null ? void 0 : _a2.call(this);
|
|
941
995
|
this._startTime = performance.now();
|
|
@@ -976,11 +1030,17 @@ const HELP_HINT = `${c.dim("press ")}${c.bold("h")}${c.dim(" to show help")}`;
|
|
|
976
1030
|
const HELP_UPDATE_SNAP = c.dim("press ") + c.bold(c.yellow("u")) + c.dim(" to update snapshot");
|
|
977
1031
|
const HELP_QUITE = `${c.dim("press ")}${c.bold("q")}${c.dim(" to quit")}`;
|
|
978
1032
|
const WAIT_FOR_CHANGE_PASS = `
|
|
979
|
-
${c.bold(
|
|
1033
|
+
${c.bold(
|
|
1034
|
+
c.inverse(c.green(" PASS "))
|
|
1035
|
+
)}${c.green(" Waiting for file changes...")}`;
|
|
980
1036
|
const WAIT_FOR_CHANGE_FAIL = `
|
|
981
|
-
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(
|
|
1037
|
+
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(
|
|
1038
|
+
" Tests failed. Watching for file changes..."
|
|
1039
|
+
)}`;
|
|
982
1040
|
const WAIT_FOR_CHANGE_CANCELLED = `
|
|
983
|
-
${c.bold(
|
|
1041
|
+
${c.bold(
|
|
1042
|
+
c.inverse(c.red(" CANCELLED "))
|
|
1043
|
+
)}${c.red(" Test run cancelled. Watching for file changes...")}`;
|
|
984
1044
|
const LAST_RUN_LOG_TIMEOUT = 1500;
|
|
985
1045
|
class BaseReporter {
|
|
986
1046
|
start = 0;
|
|
@@ -988,6 +1048,7 @@ class BaseReporter {
|
|
|
988
1048
|
watchFilters;
|
|
989
1049
|
isTTY;
|
|
990
1050
|
ctx = void 0;
|
|
1051
|
+
verbose = false;
|
|
991
1052
|
_filesInWatchMode = /* @__PURE__ */ new Map();
|
|
992
1053
|
_lastRunTimeout = 0;
|
|
993
1054
|
_lastRunTimer;
|
|
@@ -1018,14 +1079,16 @@ class BaseReporter {
|
|
|
1018
1079
|
this.end = performance.now();
|
|
1019
1080
|
this.reportSummary(files, errors);
|
|
1020
1081
|
if (errors.length) {
|
|
1021
|
-
if (!this.ctx.config.dangerouslyIgnoreUnhandledErrors)
|
|
1082
|
+
if (!this.ctx.config.dangerouslyIgnoreUnhandledErrors) {
|
|
1022
1083
|
process.exitCode = 1;
|
|
1084
|
+
}
|
|
1023
1085
|
}
|
|
1024
1086
|
}
|
|
1025
1087
|
onTaskUpdate(packs) {
|
|
1026
1088
|
var _a, _b, _c, _d;
|
|
1027
|
-
if (this.isTTY)
|
|
1089
|
+
if (this.isTTY) {
|
|
1028
1090
|
return;
|
|
1091
|
+
}
|
|
1029
1092
|
const logger = this.ctx.logger;
|
|
1030
1093
|
for (const pack of packs) {
|
|
1031
1094
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
@@ -1035,22 +1098,30 @@ class BaseReporter {
|
|
|
1035
1098
|
var _a2;
|
|
1036
1099
|
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
|
|
1037
1100
|
});
|
|
1038
|
-
const skipped = tests.filter(
|
|
1101
|
+
const skipped = tests.filter(
|
|
1102
|
+
(t) => t.mode === "skip" || t.mode === "todo"
|
|
1103
|
+
);
|
|
1039
1104
|
let state = c.dim(`${tests.length} test${tests.length > 1 ? "s" : ""}`);
|
|
1040
|
-
if (failed.length)
|
|
1105
|
+
if (failed.length) {
|
|
1041
1106
|
state += ` ${c.dim("|")} ${c.red(`${failed.length} failed`)}`;
|
|
1042
|
-
|
|
1107
|
+
}
|
|
1108
|
+
if (skipped.length) {
|
|
1043
1109
|
state += ` ${c.dim("|")} ${c.yellow(`${skipped.length} skipped`)}`;
|
|
1110
|
+
}
|
|
1044
1111
|
let suffix = c.dim(" (") + state + c.dim(")");
|
|
1045
1112
|
if (task.result.duration) {
|
|
1046
1113
|
const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.gray;
|
|
1047
1114
|
suffix += color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
|
|
1048
1115
|
}
|
|
1049
|
-
if (this.ctx.config.logHeapUsage && task.result.heap != null)
|
|
1050
|
-
suffix += c.magenta(
|
|
1116
|
+
if (this.ctx.config.logHeapUsage && task.result.heap != null) {
|
|
1117
|
+
suffix += c.magenta(
|
|
1118
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1051
1121
|
let title = ` ${getStateSymbol(task)} `;
|
|
1052
|
-
if (task.projectName)
|
|
1122
|
+
if (task.projectName) {
|
|
1053
1123
|
title += formatProjectName(task.projectName);
|
|
1124
|
+
}
|
|
1054
1125
|
title += `${task.name} ${suffix}`;
|
|
1055
1126
|
logger.log(title);
|
|
1056
1127
|
for (const test of failed) {
|
|
@@ -1067,18 +1138,20 @@ class BaseReporter {
|
|
|
1067
1138
|
const failed = errors.length > 0 || hasFailed(files);
|
|
1068
1139
|
const failedSnap = hasFailedSnapshot(files);
|
|
1069
1140
|
const cancelled = this.ctx.isCancelling;
|
|
1070
|
-
if (failed)
|
|
1141
|
+
if (failed) {
|
|
1071
1142
|
this.ctx.logger.log(WAIT_FOR_CHANGE_FAIL);
|
|
1072
|
-
else if (cancelled)
|
|
1143
|
+
} else if (cancelled) {
|
|
1073
1144
|
this.ctx.logger.log(WAIT_FOR_CHANGE_CANCELLED);
|
|
1074
|
-
else
|
|
1145
|
+
} else {
|
|
1075
1146
|
this.ctx.logger.log(WAIT_FOR_CHANGE_PASS);
|
|
1147
|
+
}
|
|
1076
1148
|
const hints = [];
|
|
1077
1149
|
hints.push(HELP_HINT);
|
|
1078
|
-
if (failedSnap)
|
|
1150
|
+
if (failedSnap) {
|
|
1079
1151
|
hints.unshift(HELP_UPDATE_SNAP);
|
|
1080
|
-
else
|
|
1152
|
+
} else {
|
|
1081
1153
|
hints.push(HELP_QUITE);
|
|
1154
|
+
}
|
|
1082
1155
|
this.ctx.logger.log(BADGE_PADDING + hints.join(c.dim(", ")));
|
|
1083
1156
|
if (this._lastRunCount) {
|
|
1084
1157
|
const LAST_RUN_TEXT = `rerun x${this._lastRunCount}`;
|
|
@@ -1090,16 +1163,16 @@ class BaseReporter {
|
|
|
1090
1163
|
this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]);
|
|
1091
1164
|
this._lastRunTimeout = 0;
|
|
1092
1165
|
const { setInterval } = getSafeTimers();
|
|
1093
|
-
this._lastRunTimer = setInterval(
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
);
|
|
1166
|
+
this._lastRunTimer = setInterval(() => {
|
|
1167
|
+
this._lastRunTimeout += 1;
|
|
1168
|
+
if (this._lastRunTimeout >= LAST_RUN_TEXTS.length) {
|
|
1169
|
+
this.resetLastRunLog();
|
|
1170
|
+
} else {
|
|
1171
|
+
this.ctx.logger.logUpdate(
|
|
1172
|
+
BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
}, LAST_RUN_LOG_TIMEOUT / LAST_RUN_TEXTS.length);
|
|
1103
1176
|
}
|
|
1104
1177
|
}
|
|
1105
1178
|
resetLastRunLog() {
|
|
@@ -1117,39 +1190,57 @@ class BaseReporter {
|
|
|
1117
1190
|
});
|
|
1118
1191
|
const BADGE = c.inverse(c.bold(c.blue(" RERUN ")));
|
|
1119
1192
|
const TRIGGER = trigger ? c.dim(` ${this.relative(trigger)}`) : "";
|
|
1120
|
-
const FILENAME_PATTERN = this.ctx.filenamePattern ? `${BADGE_PADDING} ${c.dim("Filename pattern: ")}${c.blue(
|
|
1193
|
+
const FILENAME_PATTERN = this.ctx.filenamePattern ? `${BADGE_PADDING} ${c.dim("Filename pattern: ")}${c.blue(
|
|
1194
|
+
this.ctx.filenamePattern
|
|
1195
|
+
)}
|
|
1121
1196
|
` : "";
|
|
1122
|
-
const TESTNAME_PATTERN = this.ctx.configOverride.testNamePattern ? `${BADGE_PADDING} ${c.dim("Test name pattern: ")}${c.blue(
|
|
1197
|
+
const TESTNAME_PATTERN = this.ctx.configOverride.testNamePattern ? `${BADGE_PADDING} ${c.dim("Test name pattern: ")}${c.blue(
|
|
1198
|
+
String(this.ctx.configOverride.testNamePattern)
|
|
1199
|
+
)}
|
|
1123
1200
|
` : "";
|
|
1124
|
-
const PROJECT_FILTER = this.ctx.configOverride.project ? `${BADGE_PADDING} ${c.dim("Project name: ")}${c.blue(
|
|
1201
|
+
const PROJECT_FILTER = this.ctx.configOverride.project ? `${BADGE_PADDING} ${c.dim("Project name: ")}${c.blue(
|
|
1202
|
+
toArray(this.ctx.configOverride.project).join(", ")
|
|
1203
|
+
)}
|
|
1125
1204
|
` : "";
|
|
1126
1205
|
if (files.length > 1 || !files.length) {
|
|
1127
|
-
this.ctx.logger.clearFullScreen(
|
|
1206
|
+
this.ctx.logger.clearFullScreen(
|
|
1207
|
+
`
|
|
1128
1208
|
${BADGE}${TRIGGER}
|
|
1129
|
-
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1209
|
+
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1210
|
+
);
|
|
1130
1211
|
this._lastRunCount = 0;
|
|
1131
1212
|
} else if (files.length === 1) {
|
|
1132
1213
|
const rerun = this._filesInWatchMode.get(files[0]) ?? 1;
|
|
1133
1214
|
this._lastRunCount = rerun;
|
|
1134
|
-
this.ctx.logger.clearFullScreen(
|
|
1135
|
-
|
|
1136
|
-
${
|
|
1215
|
+
this.ctx.logger.clearFullScreen(
|
|
1216
|
+
`
|
|
1217
|
+
${BADGE}${TRIGGER} ${c.blue(
|
|
1218
|
+
`x${rerun}`
|
|
1219
|
+
)}
|
|
1220
|
+
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1221
|
+
);
|
|
1137
1222
|
}
|
|
1138
1223
|
this._timeStart = /* @__PURE__ */ new Date();
|
|
1139
1224
|
this.start = performance.now();
|
|
1140
1225
|
}
|
|
1141
1226
|
onUserConsoleLog(log) {
|
|
1142
|
-
if (!this.shouldLog(log))
|
|
1227
|
+
if (!this.shouldLog(log)) {
|
|
1143
1228
|
return;
|
|
1229
|
+
}
|
|
1144
1230
|
const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0;
|
|
1145
|
-
const header = c.gray(
|
|
1231
|
+
const header = c.gray(
|
|
1232
|
+
log.type + c.dim(
|
|
1233
|
+
` | ${task ? getFullName(task, c.dim(" > ")) : log.taskId !== UNKNOWN_TEST_ID ? log.taskId : "unknown test"}`
|
|
1234
|
+
)
|
|
1235
|
+
);
|
|
1146
1236
|
const output = log.type === "stdout" ? this.ctx.logger.outputStream : this.ctx.logger.errorStream;
|
|
1147
1237
|
const write = (msg) => output.write(msg);
|
|
1148
1238
|
write(`${header}
|
|
1149
1239
|
${log.content}`);
|
|
1150
1240
|
if (log.origin) {
|
|
1151
|
-
if (log.browser)
|
|
1241
|
+
if (log.browser) {
|
|
1152
1242
|
write("\n");
|
|
1243
|
+
}
|
|
1153
1244
|
const project = log.taskId ? this.ctx.getProjectByTaskId(log.taskId) : this.ctx.getCoreWorkspaceProject();
|
|
1154
1245
|
const stack = parseStacktrace(log.origin, {
|
|
1155
1246
|
getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
|
|
@@ -1159,84 +1250,140 @@ ${log.content}`);
|
|
|
1159
1250
|
for (const frame of stack) {
|
|
1160
1251
|
const color = frame === highlight ? c.cyan : c.gray;
|
|
1161
1252
|
const path = relative(project.config.root, frame.file);
|
|
1162
|
-
write(
|
|
1163
|
-
|
|
1253
|
+
write(
|
|
1254
|
+
color(
|
|
1255
|
+
` ${c.dim(F_POINTER)} ${[
|
|
1256
|
+
frame.method,
|
|
1257
|
+
`${path}:${c.dim(`${frame.line}:${frame.column}`)}`
|
|
1258
|
+
].filter(Boolean).join(" ")}
|
|
1259
|
+
`
|
|
1260
|
+
)
|
|
1261
|
+
);
|
|
1164
1262
|
}
|
|
1165
1263
|
}
|
|
1166
1264
|
write("\n");
|
|
1167
1265
|
}
|
|
1168
1266
|
shouldLog(log) {
|
|
1169
1267
|
var _a, _b;
|
|
1170
|
-
if (this.ctx.config.silent)
|
|
1268
|
+
if (this.ctx.config.silent) {
|
|
1171
1269
|
return false;
|
|
1270
|
+
}
|
|
1172
1271
|
const shouldLog = (_b = (_a = this.ctx.config).onConsoleLog) == null ? void 0 : _b.call(_a, log.content, log.type);
|
|
1173
|
-
if (shouldLog === false)
|
|
1272
|
+
if (shouldLog === false) {
|
|
1174
1273
|
return shouldLog;
|
|
1274
|
+
}
|
|
1175
1275
|
return true;
|
|
1176
1276
|
}
|
|
1177
1277
|
onServerRestart(reason) {
|
|
1178
|
-
this.ctx.logger.log(
|
|
1179
|
-
|
|
1180
|
-
|
|
1278
|
+
this.ctx.logger.log(
|
|
1279
|
+
c.bold(
|
|
1280
|
+
c.magenta(
|
|
1281
|
+
reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest..."
|
|
1282
|
+
)
|
|
1283
|
+
)
|
|
1284
|
+
);
|
|
1181
1285
|
}
|
|
1182
1286
|
reportSummary(files, errors) {
|
|
1183
1287
|
this.printErrorsSummary(files, errors);
|
|
1184
|
-
if (this.mode === "benchmark")
|
|
1288
|
+
if (this.mode === "benchmark") {
|
|
1185
1289
|
this.reportBenchmarkSummary(files);
|
|
1186
|
-
else
|
|
1290
|
+
} else {
|
|
1187
1291
|
this.reportTestSummary(files, errors);
|
|
1292
|
+
}
|
|
1188
1293
|
}
|
|
1189
1294
|
reportTestSummary(files, errors) {
|
|
1190
1295
|
const tests = getTests(files);
|
|
1191
1296
|
const logger = this.ctx.logger;
|
|
1192
1297
|
const executionTime = this.end - this.start;
|
|
1193
|
-
const collectTime = files.reduce(
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1298
|
+
const collectTime = files.reduce(
|
|
1299
|
+
(acc, test) => acc + Math.max(0, test.collectDuration || 0),
|
|
1300
|
+
0
|
|
1301
|
+
);
|
|
1302
|
+
const setupTime = files.reduce(
|
|
1303
|
+
(acc, test) => acc + Math.max(0, test.setupDuration || 0),
|
|
1304
|
+
0
|
|
1305
|
+
);
|
|
1306
|
+
const testsTime = files.reduce(
|
|
1307
|
+
(acc, test) => {
|
|
1308
|
+
var _a;
|
|
1309
|
+
return acc + Math.max(0, ((_a = test.result) == null ? void 0 : _a.duration) || 0);
|
|
1310
|
+
},
|
|
1311
|
+
0
|
|
1312
|
+
);
|
|
1199
1313
|
const transformTime = this.ctx.projects.flatMap((w) => w.vitenode.getTotalDuration()).reduce((a, b) => a + b, 0);
|
|
1200
|
-
const environmentTime = files.reduce(
|
|
1201
|
-
|
|
1314
|
+
const environmentTime = files.reduce(
|
|
1315
|
+
(acc, file) => acc + Math.max(0, file.environmentLoad || 0),
|
|
1316
|
+
0
|
|
1317
|
+
);
|
|
1318
|
+
const prepareTime = files.reduce(
|
|
1319
|
+
(acc, file) => acc + Math.max(0, file.prepareDuration || 0),
|
|
1320
|
+
0
|
|
1321
|
+
);
|
|
1202
1322
|
const threadTime = collectTime + testsTime + setupTime;
|
|
1203
1323
|
const padTitle = (str) => c.dim(`${str.padStart(11)} `);
|
|
1204
1324
|
const time = (time2) => {
|
|
1205
|
-
if (time2 > 1e3)
|
|
1325
|
+
if (time2 > 1e3) {
|
|
1206
1326
|
return `${(time2 / 1e3).toFixed(2)}s`;
|
|
1327
|
+
}
|
|
1207
1328
|
return `${Math.round(time2)}ms`;
|
|
1208
1329
|
};
|
|
1209
|
-
const snapshotOutput = renderSnapshotSummary(
|
|
1330
|
+
const snapshotOutput = renderSnapshotSummary(
|
|
1331
|
+
this.ctx.config.root,
|
|
1332
|
+
this.ctx.snapshot.summary
|
|
1333
|
+
);
|
|
1210
1334
|
if (snapshotOutput.length) {
|
|
1211
|
-
logger.log(
|
|
1212
|
-
(
|
|
1213
|
-
|
|
1214
|
-
|
|
1335
|
+
logger.log(
|
|
1336
|
+
snapshotOutput.map(
|
|
1337
|
+
(t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`
|
|
1338
|
+
).join("\n")
|
|
1339
|
+
);
|
|
1340
|
+
if (snapshotOutput.length > 1) {
|
|
1215
1341
|
logger.log();
|
|
1342
|
+
}
|
|
1216
1343
|
}
|
|
1217
1344
|
logger.log(padTitle("Test Files"), getStateString(files));
|
|
1218
1345
|
logger.log(padTitle("Tests"), getStateString(tests));
|
|
1219
1346
|
if (this.ctx.projects.some((c2) => c2.config.typecheck.enabled)) {
|
|
1220
|
-
const failed = tests.filter(
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1347
|
+
const failed = tests.filter(
|
|
1348
|
+
(t) => {
|
|
1349
|
+
var _a, _b, _c;
|
|
1350
|
+
return ((_a = t.meta) == null ? void 0 : _a.typecheck) && ((_c = (_b = t.result) == null ? void 0 : _b.errors) == null ? void 0 : _c.length);
|
|
1351
|
+
}
|
|
1352
|
+
);
|
|
1353
|
+
logger.log(
|
|
1354
|
+
padTitle("Type Errors"),
|
|
1355
|
+
failed.length ? c.bold(c.red(`${failed.length} failed`)) : c.dim("no errors")
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
if (errors.length) {
|
|
1359
|
+
logger.log(
|
|
1360
|
+
padTitle("Errors"),
|
|
1361
|
+
c.bold(c.red(`${errors.length} error${errors.length > 1 ? "s" : ""}`))
|
|
1362
|
+
);
|
|
1225
1363
|
}
|
|
1226
|
-
if (errors.length)
|
|
1227
|
-
logger.log(padTitle("Errors"), c.bold(c.red(`${errors.length} error${errors.length > 1 ? "s" : ""}`)));
|
|
1228
1364
|
logger.log(padTitle("Start at"), formatTimeString(this._timeStart));
|
|
1229
1365
|
if (this.watchFilters) {
|
|
1230
1366
|
logger.log(padTitle("Duration"), time(threadTime));
|
|
1231
1367
|
} else {
|
|
1232
|
-
let timers = `transform ${time(transformTime)}, setup ${time(
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
},
|
|
1237
|
-
|
|
1368
|
+
let timers = `transform ${time(transformTime)}, setup ${time(
|
|
1369
|
+
setupTime
|
|
1370
|
+
)}, collect ${time(collectTime)}, tests ${time(
|
|
1371
|
+
testsTime
|
|
1372
|
+
)}, environment ${time(environmentTime)}, prepare ${time(prepareTime)}`;
|
|
1373
|
+
const typecheck = this.ctx.projects.reduce(
|
|
1374
|
+
(acc, c2) => {
|
|
1375
|
+
var _a;
|
|
1376
|
+
return acc + (((_a = c2.typechecker) == null ? void 0 : _a.getResult().time) || 0);
|
|
1377
|
+
},
|
|
1378
|
+
0
|
|
1379
|
+
);
|
|
1380
|
+
if (typecheck) {
|
|
1238
1381
|
timers += `, typecheck ${time(typecheck)}`;
|
|
1239
|
-
|
|
1382
|
+
}
|
|
1383
|
+
logger.log(
|
|
1384
|
+
padTitle("Duration"),
|
|
1385
|
+
time(executionTime) + c.dim(` (${timers})`)
|
|
1386
|
+
);
|
|
1240
1387
|
}
|
|
1241
1388
|
logger.log();
|
|
1242
1389
|
}
|
|
@@ -1254,15 +1401,27 @@ ${log.content}`);
|
|
|
1254
1401
|
});
|
|
1255
1402
|
const failedTotal = countTestErrors(failedSuites) + countTestErrors(failedTests);
|
|
1256
1403
|
let current = 1;
|
|
1257
|
-
const errorDivider = () => logger.error(
|
|
1258
|
-
|
|
1404
|
+
const errorDivider = () => logger.error(
|
|
1405
|
+
`${c.red(
|
|
1406
|
+
c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1))
|
|
1407
|
+
)}
|
|
1408
|
+
`
|
|
1409
|
+
);
|
|
1259
1410
|
if (failedSuites.length) {
|
|
1260
|
-
logger.error(
|
|
1411
|
+
logger.error(
|
|
1412
|
+
c.red(
|
|
1413
|
+
divider(c.bold(c.inverse(` Failed Suites ${failedSuites.length} `)))
|
|
1414
|
+
)
|
|
1415
|
+
);
|
|
1261
1416
|
logger.error();
|
|
1262
1417
|
this.printTaskErrors(failedSuites, errorDivider);
|
|
1263
1418
|
}
|
|
1264
1419
|
if (failedTests.length) {
|
|
1265
|
-
logger.error(
|
|
1420
|
+
logger.error(
|
|
1421
|
+
c.red(
|
|
1422
|
+
divider(c.bold(c.inverse(` Failed Tests ${failedTests.length} `)))
|
|
1423
|
+
)
|
|
1424
|
+
);
|
|
1266
1425
|
logger.error();
|
|
1267
1426
|
this.printTaskErrors(failedTests, errorDivider);
|
|
1268
1427
|
}
|
|
@@ -1279,13 +1438,16 @@ ${log.content}`);
|
|
|
1279
1438
|
var _a, _b;
|
|
1280
1439
|
return ((_b = (_a = i.result) == null ? void 0 : _a.benchmark) == null ? void 0 : _b.rank) === 1;
|
|
1281
1440
|
});
|
|
1282
|
-
logger.log(
|
|
1441
|
+
logger.log(
|
|
1442
|
+
`
|
|
1283
1443
|
${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
1284
|
-
`
|
|
1444
|
+
`
|
|
1445
|
+
);
|
|
1285
1446
|
for (const bench of topBenches) {
|
|
1286
1447
|
const group = bench.suite || bench.file;
|
|
1287
|
-
if (!group)
|
|
1448
|
+
if (!group) {
|
|
1288
1449
|
continue;
|
|
1450
|
+
}
|
|
1289
1451
|
const groupName = getFullName(group, c.dim(" > "));
|
|
1290
1452
|
logger.log(` ${bench.name}${c.dim(` - ${groupName}`)}`);
|
|
1291
1453
|
const siblings = group.tasks.filter((i) => {
|
|
@@ -1298,7 +1460,9 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1298
1460
|
}
|
|
1299
1461
|
for (const sibling of siblings) {
|
|
1300
1462
|
const number = `${(sibling.result.benchmark.mean / bench.result.benchmark.mean).toFixed(2)}x`;
|
|
1301
|
-
logger.log(
|
|
1463
|
+
logger.log(
|
|
1464
|
+
` ${c.green(number)} ${c.gray("faster than")} ${sibling.name}`
|
|
1465
|
+
);
|
|
1302
1466
|
}
|
|
1303
1467
|
logger.log("");
|
|
1304
1468
|
}
|
|
@@ -1311,16 +1475,18 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1311
1475
|
const errorItem = (error == null ? void 0 : error.stackStr) && errorsQueue.find((i) => {
|
|
1312
1476
|
var _a2, _b2, _c2, _d;
|
|
1313
1477
|
const hasStr = ((_a2 = i[0]) == null ? void 0 : _a2.stackStr) === error.stackStr;
|
|
1314
|
-
if (!hasStr)
|
|
1478
|
+
if (!hasStr) {
|
|
1315
1479
|
return false;
|
|
1480
|
+
}
|
|
1316
1481
|
const currentProjectName = (task == null ? void 0 : task.projectName) || ((_b2 = task.file) == null ? void 0 : _b2.projectName) || "";
|
|
1317
1482
|
const projectName = ((_c2 = i[1][0]) == null ? void 0 : _c2.projectName) || ((_d = i[1][0].file) == null ? void 0 : _d.projectName) || "";
|
|
1318
1483
|
return projectName === currentProjectName;
|
|
1319
1484
|
});
|
|
1320
|
-
if (errorItem)
|
|
1485
|
+
if (errorItem) {
|
|
1321
1486
|
errorItem[1].push(task);
|
|
1322
|
-
else
|
|
1487
|
+
} else {
|
|
1323
1488
|
errorsQueue.push([error, [task]]);
|
|
1489
|
+
}
|
|
1324
1490
|
});
|
|
1325
1491
|
}
|
|
1326
1492
|
for (const [error, tasks2] of errorsQueue) {
|
|
@@ -1328,19 +1494,27 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1328
1494
|
const filepath = (task == null ? void 0 : task.filepath) || "";
|
|
1329
1495
|
const projectName = (task == null ? void 0 : task.projectName) || ((_c = task.file) == null ? void 0 : _c.projectName) || "";
|
|
1330
1496
|
let name = getFullName(task, c.dim(" > "));
|
|
1331
|
-
if (filepath)
|
|
1497
|
+
if (filepath) {
|
|
1332
1498
|
name = `${name} ${c.dim(`[ ${this.relative(filepath)} ]`)}`;
|
|
1333
|
-
|
|
1499
|
+
}
|
|
1500
|
+
this.ctx.logger.error(
|
|
1501
|
+
`${c.red(c.bold(c.inverse(" FAIL ")))} ${formatProjectName(
|
|
1502
|
+
projectName
|
|
1503
|
+
)}${name}`
|
|
1504
|
+
);
|
|
1334
1505
|
}
|
|
1335
1506
|
const project = this.ctx.getProjectByTaskId(tasks2[0].id);
|
|
1336
|
-
this.ctx.logger.printError(error, { project });
|
|
1507
|
+
this.ctx.logger.printError(error, { project, verbose: this.verbose });
|
|
1337
1508
|
errorDivider();
|
|
1338
1509
|
}
|
|
1339
1510
|
}
|
|
1340
1511
|
registerUnhandledRejection() {
|
|
1341
1512
|
const onUnhandledRejection = async (err) => {
|
|
1342
1513
|
process.exitCode = 1;
|
|
1343
|
-
this.ctx.logger.printError(err, {
|
|
1514
|
+
this.ctx.logger.printError(err, {
|
|
1515
|
+
fullStack: true,
|
|
1516
|
+
type: "Unhandled Rejection"
|
|
1517
|
+
});
|
|
1344
1518
|
this.ctx.logger.error("\n\n");
|
|
1345
1519
|
process.exit(1);
|
|
1346
1520
|
};
|
|
@@ -2259,8 +2433,9 @@ function formatFilepath$1(path) {
|
|
|
2259
2433
|
const lastSlash = Math.max(path.lastIndexOf("/") + 1, 0);
|
|
2260
2434
|
const basename = path.slice(lastSlash);
|
|
2261
2435
|
let firstDot = basename.indexOf(".");
|
|
2262
|
-
if (firstDot < 0)
|
|
2436
|
+
if (firstDot < 0) {
|
|
2263
2437
|
firstDot = basename.length;
|
|
2438
|
+
}
|
|
2264
2439
|
firstDot += lastSlash;
|
|
2265
2440
|
return c.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + c.dim(path.slice(firstDot));
|
|
2266
2441
|
}
|
|
@@ -2271,8 +2446,11 @@ function formatNumber$1(number) {
|
|
|
2271
2446
|
function renderHookState(task, hookName, level = 0) {
|
|
2272
2447
|
var _a, _b;
|
|
2273
2448
|
const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
|
|
2274
|
-
if (state && state === "run")
|
|
2275
|
-
return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${c.dim(
|
|
2449
|
+
if (state && state === "run") {
|
|
2450
|
+
return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${c.dim(
|
|
2451
|
+
`[ ${hookName} ]`
|
|
2452
|
+
)}`;
|
|
2453
|
+
}
|
|
2276
2454
|
return "";
|
|
2277
2455
|
}
|
|
2278
2456
|
function renderBenchmarkItems$1(result) {
|
|
@@ -2287,8 +2465,9 @@ function renderBenchmarkItems$1(result) {
|
|
|
2287
2465
|
function renderBenchmark$1(task, tasks) {
|
|
2288
2466
|
var _a;
|
|
2289
2467
|
const result = (_a = task.result) == null ? void 0 : _a.benchmark;
|
|
2290
|
-
if (!result)
|
|
2468
|
+
if (!result) {
|
|
2291
2469
|
return task.name;
|
|
2470
|
+
}
|
|
2292
2471
|
const benches = tasks.map((i) => {
|
|
2293
2472
|
var _a2, _b;
|
|
2294
2473
|
return ((_a2 = i.meta) == null ? void 0 : _a2.benchmark) ? (_b = i.result) == null ? void 0 : _b.benchmark : void 0;
|
|
@@ -2318,27 +2497,38 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2318
2497
|
const taskOutput = [];
|
|
2319
2498
|
let suffix = "";
|
|
2320
2499
|
let prefix = ` ${getStateSymbol(task)} `;
|
|
2321
|
-
if (level === 0 && task.type === "suite" && "projectName" in task)
|
|
2500
|
+
if (level === 0 && task.type === "suite" && "projectName" in task) {
|
|
2322
2501
|
prefix += formatProjectName(task.projectName);
|
|
2323
|
-
|
|
2502
|
+
}
|
|
2503
|
+
if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.retryCount) && task.result.retryCount > 0) {
|
|
2324
2504
|
suffix += c.yellow(` (retry x${task.result.retryCount})`);
|
|
2505
|
+
}
|
|
2325
2506
|
if (task.type === "suite") {
|
|
2326
2507
|
const tests = getTests(task);
|
|
2327
2508
|
suffix += c.dim(` (${tests.length})`);
|
|
2328
2509
|
}
|
|
2329
|
-
if (task.mode === "skip" || task.mode === "todo")
|
|
2510
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
2330
2511
|
suffix += ` ${c.dim(c.gray("[skipped]"))}`;
|
|
2331
|
-
|
|
2512
|
+
}
|
|
2513
|
+
if (task.type === "test" && ((_b = task.result) == null ? void 0 : _b.repeatCount) && task.result.repeatCount > 0) {
|
|
2332
2514
|
suffix += c.yellow(` (repeat x${task.result.repeatCount})`);
|
|
2515
|
+
}
|
|
2333
2516
|
if (((_c = task.result) == null ? void 0 : _c.duration) != null) {
|
|
2334
|
-
if (task.result.duration > options.slowTestThreshold)
|
|
2335
|
-
suffix += c.yellow(
|
|
2517
|
+
if (task.result.duration > options.slowTestThreshold) {
|
|
2518
|
+
suffix += c.yellow(
|
|
2519
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
if (options.showHeap && ((_d = task.result) == null ? void 0 : _d.heap) != null) {
|
|
2524
|
+
suffix += c.magenta(
|
|
2525
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
2526
|
+
);
|
|
2336
2527
|
}
|
|
2337
|
-
if (options.showHeap && ((_d = task.result) == null ? void 0 : _d.heap) != null)
|
|
2338
|
-
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
2339
2528
|
let name = task.name;
|
|
2340
|
-
if (level === 0)
|
|
2529
|
+
if (level === 0) {
|
|
2341
2530
|
name = formatFilepath$1(name);
|
|
2531
|
+
}
|
|
2342
2532
|
const padding = " ".repeat(level);
|
|
2343
2533
|
const body = ((_e = task.meta) == null ? void 0 : _e.benchmark) ? renderBenchmark$1(task, tasks) : name;
|
|
2344
2534
|
taskOutput.push(padding + prefix + body + suffix);
|
|
@@ -2346,8 +2536,9 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2346
2536
|
let data = outputMap$1.get(task);
|
|
2347
2537
|
if (typeof data === "string") {
|
|
2348
2538
|
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
2349
|
-
if (data === "")
|
|
2539
|
+
if (data === "") {
|
|
2350
2540
|
data = void 0;
|
|
2541
|
+
}
|
|
2351
2542
|
}
|
|
2352
2543
|
if (data != null) {
|
|
2353
2544
|
const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
|
|
@@ -2359,8 +2550,12 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2359
2550
|
if (task.type === "suite" && task.tasks.length > 0) {
|
|
2360
2551
|
if (((_g = task.result) == null ? void 0 : _g.state) === "fail" || ((_h = task.result) == null ? void 0 : _h.state) === "run" || options.renderSucceed) {
|
|
2361
2552
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2362
|
-
const filteredTasks = task.tasks.filter(
|
|
2363
|
-
|
|
2553
|
+
const filteredTasks = task.tasks.filter(
|
|
2554
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2555
|
+
);
|
|
2556
|
+
taskOutput.push(
|
|
2557
|
+
renderTree$1(filteredTasks, options, level + 1, maxRows)
|
|
2558
|
+
);
|
|
2364
2559
|
} else {
|
|
2365
2560
|
taskOutput.push(renderTree$1(task.tasks, options, level + 1, maxRows));
|
|
2366
2561
|
}
|
|
@@ -2371,8 +2566,9 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2371
2566
|
const rows = taskOutput.filter(Boolean);
|
|
2372
2567
|
output.push(rows.join("\n"));
|
|
2373
2568
|
currentRowCount += rows.length;
|
|
2374
|
-
if (maxRows && currentRowCount >= maxRows)
|
|
2569
|
+
if (maxRows && currentRowCount >= maxRows) {
|
|
2375
2570
|
break;
|
|
2571
|
+
}
|
|
2376
2572
|
}
|
|
2377
2573
|
return output.reverse().join("\n");
|
|
2378
2574
|
}
|
|
@@ -2382,30 +2578,37 @@ function createListRenderer(_tasks, options) {
|
|
|
2382
2578
|
const log = options.logger.logUpdate;
|
|
2383
2579
|
function update() {
|
|
2384
2580
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2385
|
-
const filteredTasks = tasks.filter(
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2581
|
+
const filteredTasks = tasks.filter(
|
|
2582
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2583
|
+
);
|
|
2584
|
+
log(
|
|
2585
|
+
renderTree$1(
|
|
2586
|
+
filteredTasks,
|
|
2587
|
+
options,
|
|
2588
|
+
0,
|
|
2589
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
2590
|
+
// but we can optimize performance by doing it ourselves
|
|
2591
|
+
process.stdout.rows
|
|
2592
|
+
)
|
|
2593
|
+
);
|
|
2394
2594
|
} else {
|
|
2395
|
-
log(
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2595
|
+
log(
|
|
2596
|
+
renderTree$1(
|
|
2597
|
+
tasks,
|
|
2598
|
+
options,
|
|
2599
|
+
0,
|
|
2600
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
2601
|
+
// but we can optimize performance by doing it ourselves
|
|
2602
|
+
process.stdout.rows
|
|
2603
|
+
)
|
|
2604
|
+
);
|
|
2403
2605
|
}
|
|
2404
2606
|
}
|
|
2405
2607
|
return {
|
|
2406
2608
|
start() {
|
|
2407
|
-
if (timer)
|
|
2609
|
+
if (timer) {
|
|
2408
2610
|
return this;
|
|
2611
|
+
}
|
|
2409
2612
|
timer = setInterval(update, 16);
|
|
2410
2613
|
return this;
|
|
2411
2614
|
},
|
|
@@ -2420,7 +2623,9 @@ function createListRenderer(_tasks, options) {
|
|
|
2420
2623
|
}
|
|
2421
2624
|
log.clear();
|
|
2422
2625
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2423
|
-
const filteredTasks = tasks.filter(
|
|
2626
|
+
const filteredTasks = tasks.filter(
|
|
2627
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2628
|
+
);
|
|
2424
2629
|
options.logger.log(renderTree$1(filteredTasks, options));
|
|
2425
2630
|
} else {
|
|
2426
2631
|
options.logger.log(renderTree$1(tasks, options));
|
|
@@ -2439,16 +2644,21 @@ class DefaultReporter extends BaseReporter {
|
|
|
2439
2644
|
renderSucceedDefault;
|
|
2440
2645
|
onPathsCollected(paths = []) {
|
|
2441
2646
|
if (this.isTTY) {
|
|
2442
|
-
if (this.renderSucceedDefault === void 0)
|
|
2647
|
+
if (this.renderSucceedDefault === void 0) {
|
|
2443
2648
|
this.renderSucceedDefault = !!this.rendererOptions.renderSucceed;
|
|
2444
|
-
|
|
2649
|
+
}
|
|
2650
|
+
if (this.renderSucceedDefault !== true) {
|
|
2445
2651
|
this.rendererOptions.renderSucceed = paths.length <= 1;
|
|
2652
|
+
}
|
|
2446
2653
|
}
|
|
2447
2654
|
}
|
|
2448
2655
|
async onTestRemoved(trigger) {
|
|
2449
2656
|
this.stopListRender();
|
|
2450
|
-
this.ctx.logger.clearScreen(
|
|
2451
|
-
|
|
2657
|
+
this.ctx.logger.clearScreen(
|
|
2658
|
+
c.yellow("Test removed...") + (trigger ? c.dim(` [ ${this.relative(trigger)} ]
|
|
2659
|
+
`) : ""),
|
|
2660
|
+
true
|
|
2661
|
+
);
|
|
2452
2662
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2453
2663
|
createListRenderer(files, this.rendererOptions).stop();
|
|
2454
2664
|
this.ctx.logger.log();
|
|
@@ -2462,10 +2672,11 @@ class DefaultReporter extends BaseReporter {
|
|
|
2462
2672
|
this.rendererOptions.slowTestThreshold = this.ctx.config.slowTestThreshold;
|
|
2463
2673
|
this.rendererOptions.mode = this.mode;
|
|
2464
2674
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2465
|
-
if (!this.renderer)
|
|
2675
|
+
if (!this.renderer) {
|
|
2466
2676
|
this.renderer = createListRenderer(files, this.rendererOptions).start();
|
|
2467
|
-
else
|
|
2677
|
+
} else {
|
|
2468
2678
|
this.renderer.update(files);
|
|
2679
|
+
}
|
|
2469
2680
|
}
|
|
2470
2681
|
}
|
|
2471
2682
|
onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
@@ -2488,8 +2699,9 @@ class DefaultReporter extends BaseReporter {
|
|
|
2488
2699
|
}
|
|
2489
2700
|
onUserConsoleLog(log) {
|
|
2490
2701
|
var _a;
|
|
2491
|
-
if (!this.shouldLog(log))
|
|
2702
|
+
if (!this.shouldLog(log)) {
|
|
2492
2703
|
return;
|
|
2704
|
+
}
|
|
2493
2705
|
(_a = this.renderer) == null ? void 0 : _a.clear();
|
|
2494
2706
|
super.onUserConsoleLog(log);
|
|
2495
2707
|
}
|
|
@@ -2501,8 +2713,9 @@ const pending = { char: "*", color: c.yellow };
|
|
|
2501
2713
|
const skip = { char: "-", color: (char) => c.dim(c.gray(char)) };
|
|
2502
2714
|
function getIcon(task) {
|
|
2503
2715
|
var _a;
|
|
2504
|
-
if (task.mode === "skip" || task.mode === "todo")
|
|
2716
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
2505
2717
|
return skip;
|
|
2718
|
+
}
|
|
2506
2719
|
switch ((_a = task.result) == null ? void 0 : _a.state) {
|
|
2507
2720
|
case "pass":
|
|
2508
2721
|
return check;
|
|
@@ -2564,8 +2777,9 @@ function createDotRenderer(_tasks, options) {
|
|
|
2564
2777
|
}
|
|
2565
2778
|
return {
|
|
2566
2779
|
start() {
|
|
2567
|
-
if (timer)
|
|
2780
|
+
if (timer) {
|
|
2568
2781
|
return this;
|
|
2782
|
+
}
|
|
2569
2783
|
timer = setInterval(update, 16);
|
|
2570
2784
|
return this;
|
|
2571
2785
|
},
|
|
@@ -2593,10 +2807,13 @@ class DotReporter extends BaseReporter {
|
|
|
2593
2807
|
onCollected() {
|
|
2594
2808
|
if (this.isTTY) {
|
|
2595
2809
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2596
|
-
if (!this.renderer)
|
|
2597
|
-
this.renderer = createDotRenderer(files, {
|
|
2598
|
-
|
|
2810
|
+
if (!this.renderer) {
|
|
2811
|
+
this.renderer = createDotRenderer(files, {
|
|
2812
|
+
logger: this.ctx.logger
|
|
2813
|
+
}).start();
|
|
2814
|
+
} else {
|
|
2599
2815
|
this.renderer.update(files);
|
|
2816
|
+
}
|
|
2600
2817
|
}
|
|
2601
2818
|
}
|
|
2602
2819
|
async onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
@@ -2655,34 +2872,50 @@ class JsonReporter {
|
|
|
2655
2872
|
return (_a2 = s.result) == null ? void 0 : _a2.errors;
|
|
2656
2873
|
}).length;
|
|
2657
2874
|
const numPassedTestSuites = numTotalTestSuites - numFailedTestSuites;
|
|
2658
|
-
const numPendingTestSuites = suites.filter(
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2875
|
+
const numPendingTestSuites = suites.filter(
|
|
2876
|
+
(s) => {
|
|
2877
|
+
var _a2;
|
|
2878
|
+
return ((_a2 = s.result) == null ? void 0 : _a2.state) === "run";
|
|
2879
|
+
}
|
|
2880
|
+
).length;
|
|
2881
|
+
const numFailedTests = tests.filter(
|
|
2882
|
+
(t) => {
|
|
2883
|
+
var _a2;
|
|
2884
|
+
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
|
|
2885
|
+
}
|
|
2886
|
+
).length;
|
|
2666
2887
|
const numPassedTests = numTotalTests - numFailedTests;
|
|
2667
|
-
const numPendingTests = tests.filter(
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2888
|
+
const numPendingTests = tests.filter(
|
|
2889
|
+
(t) => {
|
|
2890
|
+
var _a2;
|
|
2891
|
+
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
|
|
2892
|
+
}
|
|
2893
|
+
).length;
|
|
2671
2894
|
const numTodoTests = tests.filter((t) => t.mode === "todo").length;
|
|
2672
2895
|
const testResults = [];
|
|
2673
2896
|
const success = numFailedTestSuites === 0 && numFailedTests === 0;
|
|
2674
2897
|
for (const file of files) {
|
|
2675
2898
|
const tests2 = getTests([file]);
|
|
2676
|
-
let startTime = tests2.reduce(
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2899
|
+
let startTime = tests2.reduce(
|
|
2900
|
+
(prev, next) => {
|
|
2901
|
+
var _a2;
|
|
2902
|
+
return Math.min(prev, ((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? Number.POSITIVE_INFINITY);
|
|
2903
|
+
},
|
|
2904
|
+
Number.POSITIVE_INFINITY
|
|
2905
|
+
);
|
|
2906
|
+
if (startTime === Number.POSITIVE_INFINITY) {
|
|
2681
2907
|
startTime = this.start;
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2908
|
+
}
|
|
2909
|
+
const endTime = tests2.reduce(
|
|
2910
|
+
(prev, next) => {
|
|
2911
|
+
var _a2, _b2;
|
|
2912
|
+
return Math.max(
|
|
2913
|
+
prev,
|
|
2914
|
+
(((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? 0) + (((_b2 = next.result) == null ? void 0 : _b2.duration) ?? 0)
|
|
2915
|
+
);
|
|
2916
|
+
},
|
|
2917
|
+
startTime
|
|
2918
|
+
);
|
|
2686
2919
|
const assertionResults = tests2.map((t) => {
|
|
2687
2920
|
var _a2, _b2, _c2, _d2;
|
|
2688
2921
|
const ancestorTitles = [];
|
|
@@ -2707,7 +2940,9 @@ class JsonReporter {
|
|
|
2707
2940
|
var _a2;
|
|
2708
2941
|
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
|
|
2709
2942
|
})) {
|
|
2710
|
-
this.ctx.logger.warn(
|
|
2943
|
+
this.ctx.logger.warn(
|
|
2944
|
+
"WARNING: Some tests are still running when generating the JSON report.This is likely an internal bug in Vitest.Please report it to https://github.com/vitest-dev/vitest/issues"
|
|
2945
|
+
);
|
|
2711
2946
|
}
|
|
2712
2947
|
const hasFailedTests = tests2.some((t) => {
|
|
2713
2948
|
var _a2;
|
|
@@ -2752,8 +2987,9 @@ class JsonReporter {
|
|
|
2752
2987
|
if (outputFile) {
|
|
2753
2988
|
const reportFile = resolve(this.ctx.config.root, outputFile);
|
|
2754
2989
|
const outputDirectory = dirname(reportFile);
|
|
2755
|
-
if (!existsSync(outputDirectory))
|
|
2990
|
+
if (!existsSync(outputDirectory)) {
|
|
2756
2991
|
await promises.mkdir(outputDirectory, { recursive: true });
|
|
2992
|
+
}
|
|
2757
2993
|
await promises.writeFile(reportFile, report, "utf-8");
|
|
2758
2994
|
this.ctx.logger.log(`JSON report written to ${reportFile}`);
|
|
2759
2995
|
} else {
|
|
@@ -2763,25 +2999,34 @@ class JsonReporter {
|
|
|
2763
2999
|
}
|
|
2764
3000
|
|
|
2765
3001
|
class VerboseReporter extends DefaultReporter {
|
|
3002
|
+
verbose = true;
|
|
2766
3003
|
constructor() {
|
|
2767
3004
|
super();
|
|
2768
3005
|
this.rendererOptions.renderSucceed = true;
|
|
2769
3006
|
}
|
|
2770
3007
|
onTaskUpdate(packs) {
|
|
2771
3008
|
var _a, _b, _c;
|
|
2772
|
-
if (this.isTTY)
|
|
3009
|
+
if (this.isTTY) {
|
|
2773
3010
|
return;
|
|
3011
|
+
}
|
|
2774
3012
|
for (const pack of packs) {
|
|
2775
3013
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
2776
3014
|
if (task && task.type === "test" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
|
|
2777
3015
|
let title = ` ${getStateSymbol(task)} `;
|
|
2778
|
-
if (task.file.projectName)
|
|
3016
|
+
if (task.file.projectName) {
|
|
2779
3017
|
title += formatProjectName(task.file.projectName);
|
|
3018
|
+
}
|
|
2780
3019
|
title += getFullName(task, c.dim(" > "));
|
|
2781
|
-
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold)
|
|
2782
|
-
title += c.yellow(
|
|
2783
|
-
|
|
2784
|
-
|
|
3020
|
+
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold) {
|
|
3021
|
+
title += c.yellow(
|
|
3022
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
3023
|
+
);
|
|
3024
|
+
}
|
|
3025
|
+
if (this.ctx.config.logHeapUsage && task.result.heap != null) {
|
|
3026
|
+
title += c.magenta(
|
|
3027
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
3028
|
+
);
|
|
3029
|
+
}
|
|
2785
3030
|
this.ctx.logger.log(title);
|
|
2786
3031
|
if (task.result.state === "fail") {
|
|
2787
3032
|
(_c = task.result.errors) == null ? void 0 : _c.forEach((error) => {
|
|
@@ -2802,7 +3047,10 @@ class IndentedLogger {
|
|
|
2802
3047
|
this.currentIndent += " ";
|
|
2803
3048
|
}
|
|
2804
3049
|
unindent() {
|
|
2805
|
-
this.currentIndent = this.currentIndent.substring(
|
|
3050
|
+
this.currentIndent = this.currentIndent.substring(
|
|
3051
|
+
0,
|
|
3052
|
+
this.currentIndent.length - 4
|
|
3053
|
+
);
|
|
2806
3054
|
}
|
|
2807
3055
|
log(text) {
|
|
2808
3056
|
return this.baseLog(this.currentIndent + text);
|
|
@@ -2824,21 +3072,24 @@ class TapReporter {
|
|
|
2824
3072
|
}
|
|
2825
3073
|
static getComment(task) {
|
|
2826
3074
|
var _a;
|
|
2827
|
-
if (task.mode === "skip")
|
|
3075
|
+
if (task.mode === "skip") {
|
|
2828
3076
|
return " # SKIP";
|
|
2829
|
-
else if (task.mode === "todo")
|
|
3077
|
+
} else if (task.mode === "todo") {
|
|
2830
3078
|
return " # TODO";
|
|
2831
|
-
else if (((_a = task.result) == null ? void 0 : _a.duration) != null)
|
|
3079
|
+
} else if (((_a = task.result) == null ? void 0 : _a.duration) != null) {
|
|
2832
3080
|
return ` # time=${task.result.duration.toFixed(2)}ms`;
|
|
2833
|
-
else
|
|
3081
|
+
} else {
|
|
2834
3082
|
return "";
|
|
3083
|
+
}
|
|
2835
3084
|
}
|
|
2836
3085
|
logErrorDetails(error, stack) {
|
|
2837
3086
|
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
2838
3087
|
this.logger.log(`name: ${yamlString(String(errorName))}`);
|
|
2839
3088
|
this.logger.log(`message: ${yamlString(String(error.message))}`);
|
|
2840
3089
|
if (stack) {
|
|
2841
|
-
this.logger.log(
|
|
3090
|
+
this.logger.log(
|
|
3091
|
+
`stack: ${yamlString(`${stack.file}:${stack.line}:${stack.column}`)}`
|
|
3092
|
+
);
|
|
2842
3093
|
}
|
|
2843
3094
|
}
|
|
2844
3095
|
logTasks(tasks) {
|
|
@@ -2870,8 +3121,13 @@ class TapReporter {
|
|
|
2870
3121
|
this.logger.indent();
|
|
2871
3122
|
this.logErrorDetails(error);
|
|
2872
3123
|
this.logger.unindent();
|
|
2873
|
-
if (stack)
|
|
2874
|
-
this.logger.log(
|
|
3124
|
+
if (stack) {
|
|
3125
|
+
this.logger.log(
|
|
3126
|
+
`at: ${yamlString(
|
|
3127
|
+
`${stack.file}:${stack.line}:${stack.column}`
|
|
3128
|
+
)}`
|
|
3129
|
+
);
|
|
3130
|
+
}
|
|
2875
3131
|
if (error.showDiff) {
|
|
2876
3132
|
this.logger.log(`actual: ${yamlString(error.actual)}`);
|
|
2877
3133
|
this.logger.log(`expected: ${yamlString(error.expected)}`);
|
|
@@ -4088,18 +4344,21 @@ createLogUpdate(process$2.stdout);
|
|
|
4088
4344
|
|
|
4089
4345
|
createLogUpdate(process$2.stderr);
|
|
4090
4346
|
|
|
4091
|
-
const HIGHLIGHT_SUPPORTED_EXTS = new Set(
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4347
|
+
const HIGHLIGHT_SUPPORTED_EXTS = new Set(
|
|
4348
|
+
["js", "ts"].flatMap((lang) => [
|
|
4349
|
+
`.${lang}`,
|
|
4350
|
+
`.m${lang}`,
|
|
4351
|
+
`.c${lang}`,
|
|
4352
|
+
`.${lang}x`,
|
|
4353
|
+
`.m${lang}x`,
|
|
4354
|
+
`.c${lang}x`
|
|
4355
|
+
])
|
|
4356
|
+
);
|
|
4099
4357
|
function highlightCode(id, source, colors) {
|
|
4100
4358
|
const ext = extname(id);
|
|
4101
|
-
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
|
|
4359
|
+
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext)) {
|
|
4102
4360
|
return source;
|
|
4361
|
+
}
|
|
4103
4362
|
const isJsx = ext.endsWith("x");
|
|
4104
4363
|
return highlight(source, { jsx: isJsx, colors: c });
|
|
4105
4364
|
}
|
|
@@ -4136,14 +4395,17 @@ class BaseSequencer {
|
|
|
4136
4395
|
if (!aState || !bState) {
|
|
4137
4396
|
const statsA = cache.getFileStats(keyA);
|
|
4138
4397
|
const statsB = cache.getFileStats(keyB);
|
|
4139
|
-
if (!statsA || !statsB)
|
|
4398
|
+
if (!statsA || !statsB) {
|
|
4140
4399
|
return !statsA && statsB ? -1 : !statsB && statsA ? 1 : 0;
|
|
4400
|
+
}
|
|
4141
4401
|
return statsB.size - statsA.size;
|
|
4142
4402
|
}
|
|
4143
|
-
if (aState.failed && !bState.failed)
|
|
4403
|
+
if (aState.failed && !bState.failed) {
|
|
4144
4404
|
return -1;
|
|
4145
|
-
|
|
4405
|
+
}
|
|
4406
|
+
if (!aState.failed && bState.failed) {
|
|
4146
4407
|
return 1;
|
|
4408
|
+
}
|
|
4147
4409
|
return bState.duration - aState.duration;
|
|
4148
4410
|
});
|
|
4149
4411
|
}
|
|
@@ -4199,12 +4461,14 @@ class Logger {
|
|
|
4199
4461
|
return;
|
|
4200
4462
|
}
|
|
4201
4463
|
this._clearScreenPending = message;
|
|
4202
|
-
if (force)
|
|
4464
|
+
if (force) {
|
|
4203
4465
|
this._clearScreen();
|
|
4466
|
+
}
|
|
4204
4467
|
}
|
|
4205
4468
|
_clearScreen() {
|
|
4206
|
-
if (this._clearScreenPending == null)
|
|
4469
|
+
if (this._clearScreenPending == null) {
|
|
4207
4470
|
return;
|
|
4471
|
+
}
|
|
4208
4472
|
const log = this._clearScreenPending;
|
|
4209
4473
|
this._clearScreenPending = void 0;
|
|
4210
4474
|
this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
|
|
@@ -4216,18 +4480,21 @@ class Logger {
|
|
|
4216
4480
|
fullStack,
|
|
4217
4481
|
type,
|
|
4218
4482
|
showCodeFrame: true,
|
|
4219
|
-
logger: this
|
|
4483
|
+
logger: this,
|
|
4484
|
+
printProperties: options.verbose
|
|
4220
4485
|
});
|
|
4221
4486
|
}
|
|
4222
4487
|
clearHighlightCache(filename) {
|
|
4223
|
-
if (filename)
|
|
4488
|
+
if (filename) {
|
|
4224
4489
|
this._highlights.delete(filename);
|
|
4225
|
-
else
|
|
4490
|
+
} else {
|
|
4226
4491
|
this._highlights.clear();
|
|
4492
|
+
}
|
|
4227
4493
|
}
|
|
4228
4494
|
highlight(filename, source) {
|
|
4229
|
-
if (this._highlights.has(filename))
|
|
4495
|
+
if (this._highlights.has(filename)) {
|
|
4230
4496
|
return this._highlights.get(filename);
|
|
4497
|
+
}
|
|
4231
4498
|
const code = highlightCode(filename, source);
|
|
4232
4499
|
this._highlights.set(filename, code);
|
|
4233
4500
|
return code;
|
|
@@ -4236,36 +4503,54 @@ class Logger {
|
|
|
4236
4503
|
var _a;
|
|
4237
4504
|
const config = this.ctx.config;
|
|
4238
4505
|
const comma = c.dim(", ");
|
|
4239
|
-
if (filters == null ? void 0 : filters.length)
|
|
4506
|
+
if (filters == null ? void 0 : filters.length) {
|
|
4240
4507
|
this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
4508
|
+
}
|
|
4241
4509
|
const projectsFilter = toArray(config.project);
|
|
4242
|
-
if (projectsFilter.length)
|
|
4243
|
-
this.console.error(
|
|
4510
|
+
if (projectsFilter.length) {
|
|
4511
|
+
this.console.error(
|
|
4512
|
+
c.dim("projects: ") + c.yellow(projectsFilter.join(comma))
|
|
4513
|
+
);
|
|
4514
|
+
}
|
|
4244
4515
|
this.ctx.projects.forEach((project) => {
|
|
4245
4516
|
const config2 = project.config;
|
|
4246
4517
|
const name = project.getName();
|
|
4247
4518
|
const output = project.isCore() || !name ? "" : `[${name}]`;
|
|
4248
|
-
if (output)
|
|
4519
|
+
if (output) {
|
|
4249
4520
|
this.console.error(c.bgCyan(`${output} Config`));
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4521
|
+
}
|
|
4522
|
+
if (config2.include) {
|
|
4523
|
+
this.console.error(
|
|
4524
|
+
c.dim("include: ") + c.yellow(config2.include.join(comma))
|
|
4525
|
+
);
|
|
4526
|
+
}
|
|
4527
|
+
if (config2.exclude) {
|
|
4528
|
+
this.console.error(
|
|
4529
|
+
c.dim("exclude: ") + c.yellow(config2.exclude.join(comma))
|
|
4530
|
+
);
|
|
4531
|
+
}
|
|
4254
4532
|
if (config2.typecheck.enabled) {
|
|
4255
|
-
this.console.error(
|
|
4256
|
-
|
|
4533
|
+
this.console.error(
|
|
4534
|
+
c.dim("typecheck include: ") + c.yellow(config2.typecheck.include.join(comma))
|
|
4535
|
+
);
|
|
4536
|
+
this.console.error(
|
|
4537
|
+
c.dim("typecheck exclude: ") + c.yellow(config2.typecheck.exclude.join(comma))
|
|
4538
|
+
);
|
|
4257
4539
|
}
|
|
4258
4540
|
});
|
|
4259
4541
|
if (config.watch && (config.changed || ((_a = config.related) == null ? void 0 : _a.length))) {
|
|
4260
4542
|
this.log(`No affected ${config.mode} files found
|
|
4261
4543
|
`);
|
|
4262
4544
|
} else {
|
|
4263
|
-
if (config.passWithNoTests)
|
|
4545
|
+
if (config.passWithNoTests) {
|
|
4264
4546
|
this.log(`No ${config.mode} files found, exiting with code 0
|
|
4265
4547
|
`);
|
|
4266
|
-
else
|
|
4267
|
-
this.error(
|
|
4268
|
-
|
|
4548
|
+
} else {
|
|
4549
|
+
this.error(
|
|
4550
|
+
c.red(`
|
|
4551
|
+
No ${config.mode} files found, exiting with code 1`)
|
|
4552
|
+
);
|
|
4553
|
+
}
|
|
4269
4554
|
}
|
|
4270
4555
|
}
|
|
4271
4556
|
printBanner() {
|
|
@@ -4273,52 +4558,89 @@ No ${config.mode} files found, exiting with code 1`));
|
|
|
4273
4558
|
this.log();
|
|
4274
4559
|
const versionTest = this.ctx.config.watch ? c.blue(`v${this.ctx.version}`) : c.cyan(`v${this.ctx.version}`);
|
|
4275
4560
|
const mode = this.ctx.config.watch ? c.blue(" DEV ") : c.cyan(" RUN ");
|
|
4276
|
-
this.log(
|
|
4277
|
-
|
|
4278
|
-
|
|
4561
|
+
this.log(
|
|
4562
|
+
`${c.inverse(c.bold(mode))} ${versionTest} ${c.gray(
|
|
4563
|
+
this.ctx.config.root
|
|
4564
|
+
)}`
|
|
4565
|
+
);
|
|
4566
|
+
if (this.ctx.config.sequence.sequencer === RandomSequencer) {
|
|
4567
|
+
this.log(
|
|
4568
|
+
c.gray(
|
|
4569
|
+
` Running tests with seed "${this.ctx.config.sequence.seed}"`
|
|
4570
|
+
)
|
|
4571
|
+
);
|
|
4572
|
+
}
|
|
4279
4573
|
this.ctx.projects.forEach((project) => {
|
|
4280
|
-
if (!project.browser)
|
|
4574
|
+
if (!project.browser) {
|
|
4281
4575
|
return;
|
|
4576
|
+
}
|
|
4282
4577
|
const name = project.getName();
|
|
4283
4578
|
const output = project.isCore() ? "" : ` [${name}]`;
|
|
4284
|
-
const resolvedUrls = project.browser.resolvedUrls;
|
|
4579
|
+
const resolvedUrls = project.browser.vite.resolvedUrls;
|
|
4285
4580
|
const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
|
|
4286
|
-
this.log(
|
|
4581
|
+
this.log(
|
|
4582
|
+
c.dim(
|
|
4583
|
+
c.green(
|
|
4584
|
+
` ${output} Browser runner started at ${new URL("/", origin)}`
|
|
4585
|
+
)
|
|
4586
|
+
)
|
|
4587
|
+
);
|
|
4287
4588
|
});
|
|
4288
4589
|
if (this.ctx.config.ui) {
|
|
4289
|
-
this.log(
|
|
4590
|
+
this.log(
|
|
4591
|
+
c.dim(
|
|
4592
|
+
c.green(
|
|
4593
|
+
` UI started at http://${((_a = this.ctx.config.api) == null ? void 0 : _a.host) || "localhost"}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`
|
|
4594
|
+
)
|
|
4595
|
+
)
|
|
4596
|
+
);
|
|
4290
4597
|
} else if ((_b = this.ctx.config.api) == null ? void 0 : _b.port) {
|
|
4291
4598
|
const resolvedUrls = this.ctx.server.resolvedUrls;
|
|
4292
4599
|
const fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`;
|
|
4293
4600
|
const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]) ?? fallbackUrl;
|
|
4294
4601
|
this.log(c.dim(c.green(` API started at ${new URL("/", origin)}`)));
|
|
4295
4602
|
}
|
|
4296
|
-
if (this.ctx.coverageProvider)
|
|
4297
|
-
this.log(
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4603
|
+
if (this.ctx.coverageProvider) {
|
|
4604
|
+
this.log(
|
|
4605
|
+
c.dim(" Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name)
|
|
4606
|
+
);
|
|
4607
|
+
}
|
|
4608
|
+
if (this.ctx.config.standalone) {
|
|
4609
|
+
this.log(
|
|
4610
|
+
c.yellow(
|
|
4611
|
+
`
|
|
4612
|
+
Vitest is running in standalone mode. Edit a test file to rerun tests.`
|
|
4613
|
+
)
|
|
4614
|
+
);
|
|
4615
|
+
} else {
|
|
4302
4616
|
this.log();
|
|
4617
|
+
}
|
|
4303
4618
|
}
|
|
4304
4619
|
printUnhandledErrors(errors) {
|
|
4305
|
-
const errorMessage = c.red(
|
|
4306
|
-
|
|
4620
|
+
const errorMessage = c.red(
|
|
4621
|
+
c.bold(
|
|
4622
|
+
`
|
|
4307
4623
|
Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
4308
4624
|
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
|
|
4309
|
-
|
|
4625
|
+
)
|
|
4626
|
+
);
|
|
4310
4627
|
this.log(c.red(divider(c.bold(c.inverse(" Unhandled Errors ")))));
|
|
4311
4628
|
this.log(errorMessage);
|
|
4312
4629
|
errors.forEach((err) => {
|
|
4313
|
-
this.printError(err, {
|
|
4630
|
+
this.printError(err, {
|
|
4631
|
+
fullStack: true,
|
|
4632
|
+
type: err.type || "Unhandled Error"
|
|
4633
|
+
});
|
|
4314
4634
|
});
|
|
4315
4635
|
this.log(c.red(divider()));
|
|
4316
4636
|
}
|
|
4317
4637
|
printSourceTypeErrors(errors) {
|
|
4318
|
-
const errorMessage = c.red(
|
|
4319
|
-
|
|
4638
|
+
const errorMessage = c.red(
|
|
4639
|
+
c.bold(
|
|
4640
|
+
`
|
|
4320
4641
|
Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`
|
|
4321
|
-
|
|
4642
|
+
)
|
|
4643
|
+
);
|
|
4322
4644
|
this.log(c.red(divider(c.bold(c.inverse(" Source Errors ")))));
|
|
4323
4645
|
this.log(errorMessage);
|
|
4324
4646
|
errors.forEach((err) => {
|
|
@@ -4343,7 +4665,7 @@ function capturePrintError(error, ctx, project) {
|
|
|
4343
4665
|
return { nearest: result == null ? void 0 : result.nearest, output };
|
|
4344
4666
|
}
|
|
4345
4667
|
function printError(error, project, options) {
|
|
4346
|
-
const { showCodeFrame = true, fullStack = false, type } = options;
|
|
4668
|
+
const { showCodeFrame = true, fullStack = false, type, printProperties = true } = options;
|
|
4347
4669
|
const logger = options.logger;
|
|
4348
4670
|
let e = error;
|
|
4349
4671
|
if (isPrimitive(e)) {
|
|
@@ -4368,53 +4690,82 @@ function printError(error, project, options) {
|
|
|
4368
4690
|
getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
|
|
4369
4691
|
frameFilter: project.config.onStackTrace
|
|
4370
4692
|
};
|
|
4371
|
-
if (fullStack)
|
|
4693
|
+
if (fullStack) {
|
|
4372
4694
|
parserOptions.ignoreStackEntries = [];
|
|
4695
|
+
}
|
|
4373
4696
|
const stacks = parseErrorStacktrace(e, parserOptions);
|
|
4374
|
-
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
return false;
|
|
4380
|
-
}
|
|
4697
|
+
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => {
|
|
4698
|
+
try {
|
|
4699
|
+
return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
|
|
4700
|
+
} catch {
|
|
4701
|
+
return false;
|
|
4381
4702
|
}
|
|
4382
|
-
);
|
|
4383
|
-
const errorProperties = getErrorProperties(e);
|
|
4384
|
-
if (type)
|
|
4703
|
+
});
|
|
4704
|
+
const errorProperties = printProperties ? getErrorProperties(e) : {};
|
|
4705
|
+
if (type) {
|
|
4385
4706
|
printErrorType(type, project.ctx);
|
|
4707
|
+
}
|
|
4386
4708
|
printErrorMessage(e, logger);
|
|
4387
|
-
if (e.codeFrame)
|
|
4709
|
+
if (e.codeFrame) {
|
|
4388
4710
|
logger.error(`${e.codeFrame}
|
|
4389
4711
|
`);
|
|
4390
|
-
|
|
4712
|
+
}
|
|
4713
|
+
if (e.diff) {
|
|
4391
4714
|
displayDiff(e.diff, logger.console);
|
|
4715
|
+
}
|
|
4392
4716
|
if (e.frame) {
|
|
4393
4717
|
logger.error(c.yellow(e.frame));
|
|
4394
4718
|
} else {
|
|
4395
4719
|
printStack(logger, project, stacks, nearest, errorProperties, (s) => {
|
|
4396
4720
|
if (showCodeFrame && s === nearest && nearest) {
|
|
4397
4721
|
const sourceCode = readFileSync(nearest.file, "utf-8");
|
|
4398
|
-
logger.error(
|
|
4722
|
+
logger.error(
|
|
4723
|
+
generateCodeFrame(
|
|
4724
|
+
sourceCode.length > 1e5 ? sourceCode : logger.highlight(nearest.file, sourceCode),
|
|
4725
|
+
4,
|
|
4726
|
+
s
|
|
4727
|
+
)
|
|
4728
|
+
);
|
|
4399
4729
|
}
|
|
4400
4730
|
});
|
|
4401
4731
|
}
|
|
4402
4732
|
const testPath = e.VITEST_TEST_PATH;
|
|
4403
4733
|
const testName = e.VITEST_TEST_NAME;
|
|
4404
4734
|
const afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN;
|
|
4405
|
-
if (testPath)
|
|
4406
|
-
logger.error(
|
|
4735
|
+
if (testPath) {
|
|
4736
|
+
logger.error(
|
|
4737
|
+
c.red(
|
|
4738
|
+
`This error originated in "${c.bold(
|
|
4739
|
+
testPath
|
|
4740
|
+
)}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`
|
|
4741
|
+
)
|
|
4742
|
+
);
|
|
4743
|
+
}
|
|
4407
4744
|
if (testName) {
|
|
4408
|
-
logger.error(
|
|
4745
|
+
logger.error(
|
|
4746
|
+
c.red(
|
|
4747
|
+
`The latest test that might've caused the error is "${c.bold(
|
|
4748
|
+
testName
|
|
4749
|
+
)}". It might mean one of the following:
|
|
4409
4750
|
- The error was thrown, while Vitest was running this test.
|
|
4410
|
-
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.`
|
|
4751
|
+
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.`
|
|
4752
|
+
)
|
|
4753
|
+
);
|
|
4411
4754
|
}
|
|
4412
4755
|
if (afterEnvTeardown) {
|
|
4413
|
-
logger.error(
|
|
4756
|
+
logger.error(
|
|
4757
|
+
c.red(
|
|
4758
|
+
"This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:\n- cancel timeouts using clearTimeout and clearInterval\n- wait for promises to resolve using the await keyword"
|
|
4759
|
+
)
|
|
4760
|
+
);
|
|
4414
4761
|
}
|
|
4415
4762
|
if (typeof e.cause === "object" && e.cause && "name" in e.cause) {
|
|
4416
4763
|
e.cause.name = `Caused by: ${e.cause.name}`;
|
|
4417
|
-
printError(e.cause, project, {
|
|
4764
|
+
printError(e.cause, project, {
|
|
4765
|
+
fullStack,
|
|
4766
|
+
showCodeFrame: false,
|
|
4767
|
+
logger: options.logger
|
|
4768
|
+
});
|
|
4418
4769
|
}
|
|
4419
4770
|
handleImportOutsideModuleError(e.stack || e.stackStr || "", logger);
|
|
4420
4771
|
return { nearest };
|
|
@@ -4446,11 +4797,13 @@ const skipErrorProperties = /* @__PURE__ */ new Set([
|
|
|
4446
4797
|
]);
|
|
4447
4798
|
function getErrorProperties(e) {
|
|
4448
4799
|
const errorObject = /* @__PURE__ */ Object.create(null);
|
|
4449
|
-
if (e.name === "AssertionError")
|
|
4800
|
+
if (e.name === "AssertionError") {
|
|
4450
4801
|
return errorObject;
|
|
4802
|
+
}
|
|
4451
4803
|
for (const key of Object.getOwnPropertyNames(e)) {
|
|
4452
|
-
if (!skipErrorProperties.has(key))
|
|
4804
|
+
if (!skipErrorProperties.has(key)) {
|
|
4453
4805
|
errorObject[key] = e[key];
|
|
4806
|
+
}
|
|
4454
4807
|
}
|
|
4455
4808
|
return errorObject;
|
|
4456
4809
|
}
|
|
@@ -4459,22 +4812,28 @@ const esmErrors = [
|
|
|
4459
4812
|
"Unexpected token 'export'"
|
|
4460
4813
|
];
|
|
4461
4814
|
function handleImportOutsideModuleError(stack, logger) {
|
|
4462
|
-
if (!esmErrors.some((e) => stack.includes(e)))
|
|
4815
|
+
if (!esmErrors.some((e) => stack.includes(e))) {
|
|
4463
4816
|
return;
|
|
4817
|
+
}
|
|
4464
4818
|
const path = normalize(stack.split("\n")[0].trim());
|
|
4465
4819
|
let name = path.split("/node_modules/").pop() || "";
|
|
4466
|
-
if (name == null ? void 0 : name.startsWith("@"))
|
|
4820
|
+
if (name == null ? void 0 : name.startsWith("@")) {
|
|
4467
4821
|
name = name.split("/").slice(0, 2).join("/");
|
|
4468
|
-
else
|
|
4822
|
+
} else {
|
|
4469
4823
|
name = name.split("/")[0];
|
|
4470
|
-
|
|
4824
|
+
}
|
|
4825
|
+
if (name) {
|
|
4471
4826
|
printModuleWarningForPackage(logger, path, name);
|
|
4472
|
-
else
|
|
4827
|
+
} else {
|
|
4473
4828
|
printModuleWarningForSourceCode(logger, path);
|
|
4829
|
+
}
|
|
4474
4830
|
}
|
|
4475
4831
|
function printModuleWarningForPackage(logger, path, name) {
|
|
4476
|
-
logger.error(
|
|
4477
|
-
|
|
4832
|
+
logger.error(
|
|
4833
|
+
c.yellow(
|
|
4834
|
+
`Module ${path} seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package ${c.bold(
|
|
4835
|
+
`"${name}"`
|
|
4836
|
+
)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
|
|
4478
4837
|
|
|
4479
4838
|
As a temporary workaround you can try to inline the package by updating your config:
|
|
4480
4839
|
|
|
@@ -4490,18 +4849,22 @@ As a temporary workaround you can try to inline the package by updating your con
|
|
|
4490
4849
|
}
|
|
4491
4850
|
}
|
|
4492
4851
|
`)
|
|
4493
|
-
|
|
4852
|
+
)
|
|
4853
|
+
);
|
|
4494
4854
|
}
|
|
4495
4855
|
function printModuleWarningForSourceCode(logger, path) {
|
|
4496
|
-
logger.error(
|
|
4497
|
-
|
|
4498
|
-
|
|
4856
|
+
logger.error(
|
|
4857
|
+
c.yellow(
|
|
4858
|
+
`Module ${path} seems to be an ES Module but shipped in a CommonJS package. To fix this issue, change the file extension to .mjs or add "type": "module" in your package.json.`
|
|
4859
|
+
)
|
|
4860
|
+
);
|
|
4499
4861
|
}
|
|
4500
4862
|
function displayDiff(diff, console) {
|
|
4501
|
-
if (diff)
|
|
4863
|
+
if (diff) {
|
|
4502
4864
|
console.error(`
|
|
4503
4865
|
${diff}
|
|
4504
4866
|
`);
|
|
4867
|
+
}
|
|
4505
4868
|
}
|
|
4506
4869
|
function printErrorMessage(error, logger) {
|
|
4507
4870
|
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
@@ -4519,18 +4882,31 @@ function printStack(logger, project, stack, highlight, errorProperties, onStack)
|
|
|
4519
4882
|
for (const frame of stack) {
|
|
4520
4883
|
const color = frame === highlight ? c.cyan : c.gray;
|
|
4521
4884
|
const path = relative(project.config.root, frame.file);
|
|
4522
|
-
logger.error(
|
|
4885
|
+
logger.error(
|
|
4886
|
+
color(
|
|
4887
|
+
` ${c.dim(F_POINTER)} ${[
|
|
4888
|
+
frame.method,
|
|
4889
|
+
`${path}:${c.dim(`${frame.line}:${frame.column}`)}`
|
|
4890
|
+
].filter(Boolean).join(" ")}`
|
|
4891
|
+
)
|
|
4892
|
+
);
|
|
4523
4893
|
onStack == null ? void 0 : onStack(frame);
|
|
4524
4894
|
}
|
|
4525
|
-
if (stack.length)
|
|
4895
|
+
if (stack.length) {
|
|
4526
4896
|
logger.error();
|
|
4527
|
-
|
|
4528
|
-
if (hasProperties) {
|
|
4897
|
+
}
|
|
4898
|
+
if (hasProperties(errorProperties)) {
|
|
4529
4899
|
logger.error(c.red(c.dim(divider())));
|
|
4530
4900
|
const propertiesString = inspect(errorProperties);
|
|
4531
4901
|
logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
|
|
4532
4902
|
}
|
|
4533
4903
|
}
|
|
4904
|
+
function hasProperties(obj) {
|
|
4905
|
+
for (const _key in obj) {
|
|
4906
|
+
return true;
|
|
4907
|
+
}
|
|
4908
|
+
return false;
|
|
4909
|
+
}
|
|
4534
4910
|
function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
4535
4911
|
var _a;
|
|
4536
4912
|
const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc;
|
|
@@ -4547,15 +4923,22 @@ function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
|
4547
4923
|
count += lines[i].length + nl;
|
|
4548
4924
|
if (count >= start) {
|
|
4549
4925
|
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
4550
|
-
if (j < 0 || j >= lines.length)
|
|
4926
|
+
if (j < 0 || j >= lines.length) {
|
|
4551
4927
|
continue;
|
|
4928
|
+
}
|
|
4552
4929
|
const lineLength = lines[j].length;
|
|
4553
|
-
if (stripAnsi(lines[j]).length > 200)
|
|
4930
|
+
if (stripAnsi(lines[j]).length > 200) {
|
|
4554
4931
|
return "";
|
|
4555
|
-
|
|
4932
|
+
}
|
|
4933
|
+
res.push(
|
|
4934
|
+
lineNo(j + 1) + cliTruncate(lines[j].replace(/\t/g, " "), columns - 5 - indent)
|
|
4935
|
+
);
|
|
4556
4936
|
if (j === i) {
|
|
4557
4937
|
const pad = start - (count - lineLength) + (nl - 1);
|
|
4558
|
-
const length = Math.max(
|
|
4938
|
+
const length = Math.max(
|
|
4939
|
+
1,
|
|
4940
|
+
end > count ? lineLength - pad : end - start
|
|
4941
|
+
);
|
|
4559
4942
|
res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
|
|
4560
4943
|
} else if (j > i) {
|
|
4561
4944
|
if (end > count) {
|
|
@@ -4568,20 +4951,25 @@ function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
|
4568
4951
|
break;
|
|
4569
4952
|
}
|
|
4570
4953
|
}
|
|
4571
|
-
if (indent)
|
|
4954
|
+
if (indent) {
|
|
4572
4955
|
res = res.map((line) => " ".repeat(indent) + line);
|
|
4956
|
+
}
|
|
4573
4957
|
return res.join("\n");
|
|
4574
4958
|
}
|
|
4575
4959
|
|
|
4576
4960
|
function flattenTasks$1(task, baseName = "") {
|
|
4577
4961
|
const base = baseName ? `${baseName} > ` : "";
|
|
4578
4962
|
if (task.type === "suite") {
|
|
4579
|
-
return task.tasks.flatMap(
|
|
4963
|
+
return task.tasks.flatMap(
|
|
4964
|
+
(child) => flattenTasks$1(child, `${base}${task.name}`)
|
|
4965
|
+
);
|
|
4580
4966
|
} else {
|
|
4581
|
-
return [
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4967
|
+
return [
|
|
4968
|
+
{
|
|
4969
|
+
...task,
|
|
4970
|
+
name: `${base}${task.name}`
|
|
4971
|
+
}
|
|
4972
|
+
];
|
|
4585
4973
|
}
|
|
4586
4974
|
}
|
|
4587
4975
|
function removeInvalidXMLCharacters(value, removeDiscouragedChars) {
|
|
@@ -4603,7 +4991,10 @@ function escapeXML(value) {
|
|
|
4603
4991
|
String(value).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">"));
|
|
4604
4992
|
}
|
|
4605
4993
|
function executionTime(durationMS) {
|
|
4606
|
-
return (durationMS / 1e3).toLocaleString("en-US", {
|
|
4994
|
+
return (durationMS / 1e3).toLocaleString("en-US", {
|
|
4995
|
+
useGrouping: false,
|
|
4996
|
+
maximumFractionDigits: 10
|
|
4997
|
+
});
|
|
4607
4998
|
}
|
|
4608
4999
|
function getDuration(task) {
|
|
4609
5000
|
var _a;
|
|
@@ -4629,13 +5020,15 @@ class JUnitReporter {
|
|
|
4629
5020
|
if (outputFile) {
|
|
4630
5021
|
this.reportFile = resolve(this.ctx.config.root, outputFile);
|
|
4631
5022
|
const outputDirectory = dirname(this.reportFile);
|
|
4632
|
-
if (!existsSync(outputDirectory))
|
|
5023
|
+
if (!existsSync(outputDirectory)) {
|
|
4633
5024
|
await promises.mkdir(outputDirectory, { recursive: true });
|
|
5025
|
+
}
|
|
4634
5026
|
const fileFd = await promises.open(this.reportFile, "w+");
|
|
4635
5027
|
this.fileFd = fileFd;
|
|
4636
5028
|
this.baseLog = async (text) => {
|
|
4637
|
-
if (!this.fileFd)
|
|
5029
|
+
if (!this.fileFd) {
|
|
4638
5030
|
this.fileFd = await promises.open(this.reportFile, "w+");
|
|
5031
|
+
}
|
|
4639
5032
|
await promises.writeFile(this.fileFd, `${text}
|
|
4640
5033
|
`);
|
|
4641
5034
|
};
|
|
@@ -4649,62 +5042,80 @@ class JUnitReporter {
|
|
|
4649
5042
|
const pairs = [];
|
|
4650
5043
|
for (const key in attrs) {
|
|
4651
5044
|
const attr = attrs[key];
|
|
4652
|
-
if (attr === void 0)
|
|
5045
|
+
if (attr === void 0) {
|
|
4653
5046
|
continue;
|
|
5047
|
+
}
|
|
4654
5048
|
pairs.push(`${key}="${escapeXML(attr)}"`);
|
|
4655
5049
|
}
|
|
4656
|
-
await this.logger.log(
|
|
5050
|
+
await this.logger.log(
|
|
5051
|
+
`<${name}${pairs.length ? ` ${pairs.join(" ")}` : ""}>`
|
|
5052
|
+
);
|
|
4657
5053
|
this.logger.indent();
|
|
4658
5054
|
await children.call(this);
|
|
4659
5055
|
this.logger.unindent();
|
|
4660
5056
|
await this.logger.log(`</${name}>`);
|
|
4661
5057
|
}
|
|
4662
5058
|
async writeLogs(task, type) {
|
|
4663
|
-
if (task.logs == null || task.logs.length === 0)
|
|
5059
|
+
if (task.logs == null || task.logs.length === 0) {
|
|
4664
5060
|
return;
|
|
5061
|
+
}
|
|
4665
5062
|
const logType = type === "err" ? "stderr" : "stdout";
|
|
4666
5063
|
const logs = task.logs.filter((log) => log.type === logType);
|
|
4667
|
-
if (logs.length === 0)
|
|
5064
|
+
if (logs.length === 0) {
|
|
4668
5065
|
return;
|
|
5066
|
+
}
|
|
4669
5067
|
await this.writeElement(`system-${type}`, {}, async () => {
|
|
4670
|
-
for (const log of logs)
|
|
5068
|
+
for (const log of logs) {
|
|
4671
5069
|
await this.baseLog(escapeXML(log.content));
|
|
5070
|
+
}
|
|
4672
5071
|
});
|
|
4673
5072
|
}
|
|
4674
5073
|
async writeTasks(tasks, filename) {
|
|
4675
5074
|
for (const task of tasks) {
|
|
4676
|
-
await this.writeElement(
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
5075
|
+
await this.writeElement(
|
|
5076
|
+
"testcase",
|
|
5077
|
+
{
|
|
5078
|
+
classname: this.options.classname ?? filename,
|
|
5079
|
+
file: this.options.addFileAttribute ? filename : void 0,
|
|
5080
|
+
name: task.name,
|
|
5081
|
+
time: getDuration(task)
|
|
5082
|
+
},
|
|
5083
|
+
async () => {
|
|
5084
|
+
var _a;
|
|
5085
|
+
if (this.options.includeConsoleOutput) {
|
|
5086
|
+
await this.writeLogs(task, "out");
|
|
5087
|
+
await this.writeLogs(task, "err");
|
|
5088
|
+
}
|
|
5089
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
5090
|
+
await this.logger.log("<skipped/>");
|
|
5091
|
+
}
|
|
5092
|
+
if (((_a = task.result) == null ? void 0 : _a.state) === "fail") {
|
|
5093
|
+
const errors = task.result.errors || [];
|
|
5094
|
+
for (const error of errors) {
|
|
5095
|
+
await this.writeElement(
|
|
5096
|
+
"failure",
|
|
5097
|
+
{
|
|
5098
|
+
message: error == null ? void 0 : error.message,
|
|
5099
|
+
type: (error == null ? void 0 : error.name) ?? (error == null ? void 0 : error.nameStr)
|
|
5100
|
+
},
|
|
5101
|
+
async () => {
|
|
5102
|
+
if (!error) {
|
|
5103
|
+
return;
|
|
5104
|
+
}
|
|
5105
|
+
const result = capturePrintError(
|
|
5106
|
+
error,
|
|
5107
|
+
this.ctx,
|
|
5108
|
+
this.ctx.getProjectByTaskId(task.id)
|
|
5109
|
+
);
|
|
5110
|
+
await this.baseLog(
|
|
5111
|
+
escapeXML(stripAnsi(result.output.trim()))
|
|
5112
|
+
);
|
|
5113
|
+
}
|
|
4702
5114
|
);
|
|
4703
|
-
|
|
4704
|
-
});
|
|
5115
|
+
}
|
|
4705
5116
|
}
|
|
4706
5117
|
}
|
|
4707
|
-
|
|
5118
|
+
);
|
|
4708
5119
|
}
|
|
4709
5120
|
}
|
|
4710
5121
|
async onFinished(files = this.ctx.state.getFiles()) {
|
|
@@ -4713,18 +5124,21 @@ class JUnitReporter {
|
|
|
4713
5124
|
const transformed = files.map((file) => {
|
|
4714
5125
|
var _a2, _b;
|
|
4715
5126
|
const tasks = file.tasks.flatMap((task) => flattenTasks$1(task));
|
|
4716
|
-
const stats2 = tasks.reduce(
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
5127
|
+
const stats2 = tasks.reduce(
|
|
5128
|
+
(stats3, task) => {
|
|
5129
|
+
var _a3, _b2;
|
|
5130
|
+
return {
|
|
5131
|
+
passed: stats3.passed + Number(((_a3 = task.result) == null ? void 0 : _a3.state) === "pass"),
|
|
5132
|
+
failures: stats3.failures + Number(((_b2 = task.result) == null ? void 0 : _b2.state) === "fail"),
|
|
5133
|
+
skipped: stats3.skipped + Number(task.mode === "skip" || task.mode === "todo")
|
|
5134
|
+
};
|
|
5135
|
+
},
|
|
5136
|
+
{
|
|
5137
|
+
passed: 0,
|
|
5138
|
+
failures: 0,
|
|
5139
|
+
skipped: 0
|
|
5140
|
+
}
|
|
5141
|
+
);
|
|
4728
5142
|
const suites = getSuites(file);
|
|
4729
5143
|
for (const suite of suites) {
|
|
4730
5144
|
if ((_a2 = suite.result) == null ? void 0 : _a2.errors) {
|
|
@@ -4753,38 +5167,46 @@ class JUnitReporter {
|
|
|
4753
5167
|
stats: stats2
|
|
4754
5168
|
};
|
|
4755
5169
|
});
|
|
4756
|
-
const stats = transformed.reduce(
|
|
4757
|
-
stats2
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
5170
|
+
const stats = transformed.reduce(
|
|
5171
|
+
(stats2, file) => {
|
|
5172
|
+
stats2.tests += file.tasks.length;
|
|
5173
|
+
stats2.failures += file.stats.failures;
|
|
5174
|
+
return stats2;
|
|
5175
|
+
},
|
|
5176
|
+
{
|
|
5177
|
+
name: this.options.suiteName || "vitest tests",
|
|
5178
|
+
tests: 0,
|
|
5179
|
+
failures: 0,
|
|
5180
|
+
errors: 0,
|
|
5181
|
+
// we cannot detect those
|
|
5182
|
+
time: executionTime((/* @__PURE__ */ new Date()).getTime() - this._timeStart.getTime())
|
|
5183
|
+
}
|
|
5184
|
+
);
|
|
4768
5185
|
await this.writeElement("testsuites", stats, async () => {
|
|
4769
5186
|
for (const file of transformed) {
|
|
4770
5187
|
const filename = relative(this.ctx.config.root, file.filepath);
|
|
4771
|
-
await this.writeElement(
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
5188
|
+
await this.writeElement(
|
|
5189
|
+
"testsuite",
|
|
5190
|
+
{
|
|
5191
|
+
name: filename,
|
|
5192
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5193
|
+
hostname: hostname(),
|
|
5194
|
+
tests: file.tasks.length,
|
|
5195
|
+
failures: file.stats.failures,
|
|
5196
|
+
errors: 0,
|
|
5197
|
+
// An errored test is one that had an unanticipated problem. We cannot detect those.
|
|
5198
|
+
skipped: file.stats.skipped,
|
|
5199
|
+
time: getDuration(file)
|
|
5200
|
+
},
|
|
5201
|
+
async () => {
|
|
5202
|
+
await this.writeTasks(file.tasks, filename);
|
|
5203
|
+
}
|
|
5204
|
+
);
|
|
4784
5205
|
}
|
|
4785
5206
|
});
|
|
4786
|
-
if (this.reportFile)
|
|
5207
|
+
if (this.reportFile) {
|
|
4787
5208
|
this.ctx.logger.log(`JUNIT report written to ${this.reportFile}`);
|
|
5209
|
+
}
|
|
4788
5210
|
await ((_a = this.fileFd) == null ? void 0 : _a.close());
|
|
4789
5211
|
this.fileFd = void 0;
|
|
4790
5212
|
}
|
|
@@ -4793,12 +5215,16 @@ class JUnitReporter {
|
|
|
4793
5215
|
function flattenTasks(task, baseName = "") {
|
|
4794
5216
|
const base = baseName ? `${baseName} > ` : "";
|
|
4795
5217
|
if (task.type === "suite" && task.tasks.length > 0) {
|
|
4796
|
-
return task.tasks.flatMap(
|
|
5218
|
+
return task.tasks.flatMap(
|
|
5219
|
+
(child) => flattenTasks(child, `${base}${task.name}`)
|
|
5220
|
+
);
|
|
4797
5221
|
} else {
|
|
4798
|
-
return [
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
5222
|
+
return [
|
|
5223
|
+
{
|
|
5224
|
+
...task,
|
|
5225
|
+
name: `${base}${task.name}`
|
|
5226
|
+
}
|
|
5227
|
+
];
|
|
4802
5228
|
}
|
|
4803
5229
|
}
|
|
4804
5230
|
class TapFlatReporter extends TapReporter {
|
|
@@ -4843,8 +5269,9 @@ class GithubActionsReporter {
|
|
|
4843
5269
|
const tasks = getTasks(file);
|
|
4844
5270
|
const project = this.ctx.getProjectByTaskId(file.id);
|
|
4845
5271
|
for (const task of tasks) {
|
|
4846
|
-
if (((_a = task.result) == null ? void 0 : _a.state) !== "fail")
|
|
5272
|
+
if (((_a = task.result) == null ? void 0 : _a.state) !== "fail") {
|
|
4847
5273
|
continue;
|
|
5274
|
+
}
|
|
4848
5275
|
const title = getFullName(task, " > ");
|
|
4849
5276
|
for (const error of ((_b = task.result) == null ? void 0 : _b.errors) ?? []) {
|
|
4850
5277
|
projectErrors.push({
|
|
@@ -4858,8 +5285,9 @@ class GithubActionsReporter {
|
|
|
4858
5285
|
for (const { project, title, error } of projectErrors) {
|
|
4859
5286
|
const result = capturePrintError(error, this.ctx, project);
|
|
4860
5287
|
const stack = result == null ? void 0 : result.nearest;
|
|
4861
|
-
if (!stack)
|
|
5288
|
+
if (!stack) {
|
|
4862
5289
|
continue;
|
|
5290
|
+
}
|
|
4863
5291
|
const formatted = formatMessage({
|
|
4864
5292
|
command: "error",
|
|
4865
5293
|
properties: {
|
|
@@ -4902,8 +5330,9 @@ class BlobReporter {
|
|
|
4902
5330
|
this.options = options;
|
|
4903
5331
|
}
|
|
4904
5332
|
onInit(ctx) {
|
|
4905
|
-
if (ctx.config.watch)
|
|
5333
|
+
if (ctx.config.watch) {
|
|
4906
5334
|
throw new Error("Blob reporter is not supported in watch mode");
|
|
5335
|
+
}
|
|
4907
5336
|
this.ctx = ctx;
|
|
4908
5337
|
}
|
|
4909
5338
|
async onFinished(files = [], errors = [], coverage) {
|
|
@@ -4912,19 +5341,27 @@ class BlobReporter {
|
|
|
4912
5341
|
const shard = this.ctx.config.shard;
|
|
4913
5342
|
outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json";
|
|
4914
5343
|
}
|
|
4915
|
-
const moduleKeys = this.ctx.projects.map(
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
5344
|
+
const moduleKeys = this.ctx.projects.map(
|
|
5345
|
+
(project) => {
|
|
5346
|
+
return [
|
|
5347
|
+
project.getName(),
|
|
5348
|
+
[...project.server.moduleGraph.idToModuleMap.keys()]
|
|
5349
|
+
];
|
|
5350
|
+
}
|
|
5351
|
+
);
|
|
5352
|
+
const report = stringify([
|
|
5353
|
+
this.ctx.version,
|
|
5354
|
+
files,
|
|
5355
|
+
errors,
|
|
5356
|
+
moduleKeys,
|
|
5357
|
+
coverage
|
|
5358
|
+
]);
|
|
4919
5359
|
const reportFile = resolve(this.ctx.config.root, outputFile);
|
|
4920
5360
|
const dir = dirname(reportFile);
|
|
4921
|
-
if (!existsSync(dir))
|
|
5361
|
+
if (!existsSync(dir)) {
|
|
4922
5362
|
await mkdir(dir, { recursive: true });
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
report,
|
|
4926
|
-
"utf-8"
|
|
4927
|
-
);
|
|
5363
|
+
}
|
|
5364
|
+
await writeFile(reportFile, report, "utf-8");
|
|
4928
5365
|
this.ctx.logger.log("blob report written to", reportFile);
|
|
4929
5366
|
}
|
|
4930
5367
|
}
|
|
@@ -4933,18 +5370,26 @@ async function readBlobs(blobsDirectory, projectsArray) {
|
|
|
4933
5370
|
const blobsFiles = await readdir(resolvedDir);
|
|
4934
5371
|
const promises = blobsFiles.map(async (file) => {
|
|
4935
5372
|
const content = await readFile(resolve(resolvedDir, file), "utf-8");
|
|
4936
|
-
const [version, files2, errors2, moduleKeys, coverage] = parse(
|
|
5373
|
+
const [version, files2, errors2, moduleKeys, coverage] = parse(
|
|
5374
|
+
content
|
|
5375
|
+
);
|
|
4937
5376
|
return { version, files: files2, errors: errors2, moduleKeys, coverage };
|
|
4938
5377
|
});
|
|
4939
5378
|
const blobs = await Promise.all(promises);
|
|
4940
|
-
if (!blobs.length)
|
|
4941
|
-
throw new Error(
|
|
4942
|
-
|
|
5379
|
+
if (!blobs.length) {
|
|
5380
|
+
throw new Error(
|
|
5381
|
+
`vitest.mergeReports() requires at least one blob file paths in the config`
|
|
5382
|
+
);
|
|
5383
|
+
}
|
|
5384
|
+
const projects = Object.fromEntries(
|
|
5385
|
+
projectsArray.map((p) => [p.getName(), p])
|
|
5386
|
+
);
|
|
4943
5387
|
blobs.forEach((blob) => {
|
|
4944
5388
|
blob.moduleKeys.forEach(([projectName, moduleIds]) => {
|
|
4945
5389
|
const project = projects[projectName];
|
|
4946
|
-
if (!project)
|
|
5390
|
+
if (!project) {
|
|
4947
5391
|
return;
|
|
5392
|
+
}
|
|
4948
5393
|
moduleIds.forEach((moduleId) => {
|
|
4949
5394
|
project.server.moduleGraph.idToModuleMap.set(moduleId, {
|
|
4950
5395
|
id: moduleId,
|
|
@@ -4988,8 +5433,9 @@ function formatFilepath(path) {
|
|
|
4988
5433
|
const lastSlash = Math.max(path.lastIndexOf("/") + 1, 0);
|
|
4989
5434
|
const basename = path.slice(lastSlash);
|
|
4990
5435
|
let firstDot = basename.indexOf(".");
|
|
4991
|
-
if (firstDot < 0)
|
|
5436
|
+
if (firstDot < 0) {
|
|
4992
5437
|
firstDot = basename.length;
|
|
5438
|
+
}
|
|
4993
5439
|
firstDot += lastSlash;
|
|
4994
5440
|
return c.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + c.dim(path.slice(firstDot));
|
|
4995
5441
|
}
|
|
@@ -4997,7 +5443,19 @@ function formatNumber(number) {
|
|
|
4997
5443
|
const res = String(number.toFixed(number < 100 ? 4 : 2)).split(".");
|
|
4998
5444
|
return res[0].replace(/(?=(?:\d{3})+$)\B/g, ",") + (res[1] ? `.${res[1]}` : "");
|
|
4999
5445
|
}
|
|
5000
|
-
const tableHead = [
|
|
5446
|
+
const tableHead = [
|
|
5447
|
+
"name",
|
|
5448
|
+
"hz",
|
|
5449
|
+
"min",
|
|
5450
|
+
"max",
|
|
5451
|
+
"mean",
|
|
5452
|
+
"p75",
|
|
5453
|
+
"p99",
|
|
5454
|
+
"p995",
|
|
5455
|
+
"p999",
|
|
5456
|
+
"rme",
|
|
5457
|
+
"samples"
|
|
5458
|
+
];
|
|
5001
5459
|
function renderBenchmarkItems(result) {
|
|
5002
5460
|
return [
|
|
5003
5461
|
result.name,
|
|
@@ -5014,14 +5472,8 @@ function renderBenchmarkItems(result) {
|
|
|
5014
5472
|
];
|
|
5015
5473
|
}
|
|
5016
5474
|
function computeColumnWidths(results) {
|
|
5017
|
-
const rows = [
|
|
5018
|
-
|
|
5019
|
-
...results.map((v) => renderBenchmarkItems(v))
|
|
5020
|
-
];
|
|
5021
|
-
return Array.from(
|
|
5022
|
-
tableHead,
|
|
5023
|
-
(_, i) => Math.max(...rows.map((row) => stripAnsi(row[i]).length))
|
|
5024
|
-
);
|
|
5475
|
+
const rows = [tableHead, ...results.map((v) => renderBenchmarkItems(v))];
|
|
5476
|
+
return Array.from(tableHead, (_, i) => Math.max(...rows.map((row) => stripAnsi(row[i]).length)));
|
|
5025
5477
|
}
|
|
5026
5478
|
function padRow(row, widths) {
|
|
5027
5479
|
return row.map(
|
|
@@ -5085,24 +5537,34 @@ function renderTree(tasks, options, level = 0, shallow = false) {
|
|
|
5085
5537
|
for (const task of tasks) {
|
|
5086
5538
|
const padding = " ".repeat(level ? 1 : 0);
|
|
5087
5539
|
let prefix = "";
|
|
5088
|
-
if (idx === 0 && ((_c = task.meta) == null ? void 0 : _c.benchmark))
|
|
5540
|
+
if (idx === 0 && ((_c = task.meta) == null ? void 0 : _c.benchmark)) {
|
|
5089
5541
|
prefix += `${renderTableHead(columnWidths)}
|
|
5090
5542
|
${padding}`;
|
|
5543
|
+
}
|
|
5091
5544
|
prefix += ` ${getStateSymbol(task)} `;
|
|
5092
5545
|
let suffix = "";
|
|
5093
|
-
if (task.type === "suite")
|
|
5546
|
+
if (task.type === "suite") {
|
|
5094
5547
|
suffix += c.dim(` (${getTests(task).length})`);
|
|
5095
|
-
|
|
5548
|
+
}
|
|
5549
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
5096
5550
|
suffix += ` ${c.dim(c.gray("[skipped]"))}`;
|
|
5551
|
+
}
|
|
5097
5552
|
if (((_d = task.result) == null ? void 0 : _d.duration) != null) {
|
|
5098
|
-
if (task.result.duration > options.slowTestThreshold)
|
|
5099
|
-
suffix += c.yellow(
|
|
5553
|
+
if (task.result.duration > options.slowTestThreshold) {
|
|
5554
|
+
suffix += c.yellow(
|
|
5555
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
5556
|
+
);
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
if (options.showHeap && ((_e = task.result) == null ? void 0 : _e.heap) != null) {
|
|
5560
|
+
suffix += c.magenta(
|
|
5561
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
5562
|
+
);
|
|
5100
5563
|
}
|
|
5101
|
-
if (options.showHeap && ((_e = task.result) == null ? void 0 : _e.heap) != null)
|
|
5102
|
-
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
5103
5564
|
let name = task.name;
|
|
5104
|
-
if (level === 0)
|
|
5565
|
+
if (level === 0) {
|
|
5105
5566
|
name = formatFilepath(name);
|
|
5567
|
+
}
|
|
5106
5568
|
const bench = benchMap[task.id];
|
|
5107
5569
|
if (bench) {
|
|
5108
5570
|
let body = renderBenchmark(bench.current, columnWidths);
|
|
@@ -5110,21 +5572,25 @@ ${padding}`;
|
|
|
5110
5572
|
if (bench.current.hz) {
|
|
5111
5573
|
const diff = bench.current.hz / bench.baseline.hz;
|
|
5112
5574
|
const diffFixed = diff.toFixed(2);
|
|
5113
|
-
if (diffFixed === "1.0.0")
|
|
5575
|
+
if (diffFixed === "1.0.0") {
|
|
5114
5576
|
body += ` ${c.gray(`[${diffFixed}x]`)}`;
|
|
5115
|
-
|
|
5577
|
+
}
|
|
5578
|
+
if (diff > 1) {
|
|
5116
5579
|
body += ` ${c.blue(`[${diffFixed}x] \u21D1`)}`;
|
|
5117
|
-
else
|
|
5580
|
+
} else {
|
|
5118
5581
|
body += ` ${c.red(`[${diffFixed}x] \u21D3`)}`;
|
|
5582
|
+
}
|
|
5119
5583
|
}
|
|
5120
5584
|
output.push(padding + prefix + body + suffix);
|
|
5121
5585
|
const bodyBaseline = renderBenchmark(bench.baseline, columnWidths);
|
|
5122
5586
|
output.push(`${padding} ${bodyBaseline} ${c.dim("(baseline)")}`);
|
|
5123
5587
|
} else {
|
|
5124
|
-
if (bench.current.rank === 1 && benchCount > 1)
|
|
5588
|
+
if (bench.current.rank === 1 && benchCount > 1) {
|
|
5125
5589
|
body += ` ${c.bold(c.green(" fastest"))}`;
|
|
5126
|
-
|
|
5590
|
+
}
|
|
5591
|
+
if (bench.current.rank === benchCount && benchCount > 2) {
|
|
5127
5592
|
body += ` ${c.bold(c.gray(" slowest"))}`;
|
|
5593
|
+
}
|
|
5128
5594
|
output.push(padding + prefix + body + suffix);
|
|
5129
5595
|
}
|
|
5130
5596
|
} else {
|
|
@@ -5134,8 +5600,9 @@ ${padding}`;
|
|
|
5134
5600
|
let data = outputMap.get(task);
|
|
5135
5601
|
if (typeof data === "string") {
|
|
5136
5602
|
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
5137
|
-
if (data === "")
|
|
5603
|
+
if (data === "") {
|
|
5138
5604
|
data = void 0;
|
|
5605
|
+
}
|
|
5139
5606
|
}
|
|
5140
5607
|
if (data != null) {
|
|
5141
5608
|
const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
|
|
@@ -5143,8 +5610,9 @@ ${padding}`;
|
|
|
5143
5610
|
}
|
|
5144
5611
|
}
|
|
5145
5612
|
if (!shallow && task.type === "suite" && task.tasks.length > 0) {
|
|
5146
|
-
if ((_g = task.result) == null ? void 0 : _g.state)
|
|
5613
|
+
if ((_g = task.result) == null ? void 0 : _g.state) {
|
|
5147
5614
|
output.push(renderTree(task.tasks, options, level + 1));
|
|
5615
|
+
}
|
|
5148
5616
|
}
|
|
5149
5617
|
idx++;
|
|
5150
5618
|
}
|
|
@@ -5159,8 +5627,9 @@ function createTableRenderer(_tasks, options) {
|
|
|
5159
5627
|
}
|
|
5160
5628
|
return {
|
|
5161
5629
|
start() {
|
|
5162
|
-
if (timer)
|
|
5630
|
+
if (timer) {
|
|
5163
5631
|
return this;
|
|
5632
|
+
}
|
|
5164
5633
|
timer = setInterval(update, 200);
|
|
5165
5634
|
return this;
|
|
5166
5635
|
},
|
|
@@ -5189,8 +5658,11 @@ class TableReporter extends BaseReporter {
|
|
|
5189
5658
|
rendererOptions = {};
|
|
5190
5659
|
onTestRemoved(trigger) {
|
|
5191
5660
|
this.stopListRender();
|
|
5192
|
-
this.ctx.logger.clearScreen(
|
|
5193
|
-
|
|
5661
|
+
this.ctx.logger.clearScreen(
|
|
5662
|
+
c.yellow("Test removed...") + (trigger ? c.dim(` [ ${this.relative(trigger)} ]
|
|
5663
|
+
`) : ""),
|
|
5664
|
+
true
|
|
5665
|
+
);
|
|
5194
5666
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
5195
5667
|
createTableRenderer(files, this.rendererOptions).stop();
|
|
5196
5668
|
this.ctx.logger.log();
|
|
@@ -5203,9 +5675,12 @@ class TableReporter extends BaseReporter {
|
|
|
5203
5675
|
this.rendererOptions.showHeap = this.ctx.config.logHeapUsage;
|
|
5204
5676
|
this.rendererOptions.slowTestThreshold = this.ctx.config.slowTestThreshold;
|
|
5205
5677
|
if ((_a = this.ctx.config.benchmark) == null ? void 0 : _a.compare) {
|
|
5206
|
-
const compareFile = pathe.resolve(
|
|
5678
|
+
const compareFile = pathe.resolve(
|
|
5679
|
+
this.ctx.config.root,
|
|
5680
|
+
(_b = this.ctx.config.benchmark) == null ? void 0 : _b.compare
|
|
5681
|
+
);
|
|
5207
5682
|
try {
|
|
5208
|
-
this.rendererOptions.compare =
|
|
5683
|
+
this.rendererOptions.compare = flattenFormattedBenchmarkReport(
|
|
5209
5684
|
JSON.parse(
|
|
5210
5685
|
await fs.promises.readFile(compareFile, "utf-8")
|
|
5211
5686
|
)
|
|
@@ -5216,16 +5691,21 @@ class TableReporter extends BaseReporter {
|
|
|
5216
5691
|
}
|
|
5217
5692
|
if (this.isTTY) {
|
|
5218
5693
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
5219
|
-
if (!this.renderer)
|
|
5220
|
-
this.renderer = createTableRenderer(
|
|
5221
|
-
|
|
5694
|
+
if (!this.renderer) {
|
|
5695
|
+
this.renderer = createTableRenderer(
|
|
5696
|
+
files,
|
|
5697
|
+
this.rendererOptions
|
|
5698
|
+
).start();
|
|
5699
|
+
} else {
|
|
5222
5700
|
this.renderer.update(files);
|
|
5701
|
+
}
|
|
5223
5702
|
}
|
|
5224
5703
|
}
|
|
5225
5704
|
onTaskUpdate(packs) {
|
|
5226
5705
|
var _a, _b;
|
|
5227
|
-
if (this.isTTY)
|
|
5706
|
+
if (this.isTTY) {
|
|
5228
5707
|
return;
|
|
5708
|
+
}
|
|
5229
5709
|
for (const pack of packs) {
|
|
5230
5710
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
5231
5711
|
if (task && task.type === "suite" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
|
|
@@ -5234,11 +5714,19 @@ class TableReporter extends BaseReporter {
|
|
|
5234
5714
|
var _a2;
|
|
5235
5715
|
return ((_a2 = t.result) == null ? void 0 : _a2.state) !== "run";
|
|
5236
5716
|
})) {
|
|
5237
|
-
let title = ` ${getStateSymbol(task)} ${getFullName(
|
|
5238
|
-
|
|
5239
|
-
|
|
5717
|
+
let title = ` ${getStateSymbol(task)} ${getFullName(
|
|
5718
|
+
task,
|
|
5719
|
+
c.dim(" > ")
|
|
5720
|
+
)}`;
|
|
5721
|
+
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold) {
|
|
5722
|
+
title += c.yellow(
|
|
5723
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
5724
|
+
);
|
|
5725
|
+
}
|
|
5240
5726
|
this.ctx.logger.log(title);
|
|
5241
|
-
this.ctx.logger.log(
|
|
5727
|
+
this.ctx.logger.log(
|
|
5728
|
+
renderTree(benches, this.rendererOptions, 1, true)
|
|
5729
|
+
);
|
|
5242
5730
|
}
|
|
5243
5731
|
}
|
|
5244
5732
|
}
|
|
@@ -5252,9 +5740,10 @@ class TableReporter extends BaseReporter {
|
|
|
5252
5740
|
if (outputFile) {
|
|
5253
5741
|
outputFile = pathe.resolve(this.ctx.config.root, outputFile);
|
|
5254
5742
|
const outputDirectory = pathe.dirname(outputFile);
|
|
5255
|
-
if (!fs.existsSync(outputDirectory))
|
|
5743
|
+
if (!fs.existsSync(outputDirectory)) {
|
|
5256
5744
|
await fs.promises.mkdir(outputDirectory, { recursive: true });
|
|
5257
|
-
|
|
5745
|
+
}
|
|
5746
|
+
const output = createFormattedBenchmarkReport(files);
|
|
5258
5747
|
await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
|
|
5259
5748
|
this.ctx.logger.log(`Benchmark report written to ${outputFile}`);
|
|
5260
5749
|
}
|
|
@@ -5274,13 +5763,14 @@ class TableReporter extends BaseReporter {
|
|
|
5274
5763
|
}
|
|
5275
5764
|
onUserConsoleLog(log) {
|
|
5276
5765
|
var _a;
|
|
5277
|
-
if (!this.shouldLog(log))
|
|
5766
|
+
if (!this.shouldLog(log)) {
|
|
5278
5767
|
return;
|
|
5768
|
+
}
|
|
5279
5769
|
(_a = this.renderer) == null ? void 0 : _a.clear();
|
|
5280
5770
|
super.onUserConsoleLog(log);
|
|
5281
5771
|
}
|
|
5282
5772
|
}
|
|
5283
|
-
function
|
|
5773
|
+
function createFormattedBenchmarkReport(files) {
|
|
5284
5774
|
var _a;
|
|
5285
5775
|
const report = { files: [] };
|
|
5286
5776
|
for (const file of files) {
|
|
@@ -5315,12 +5805,13 @@ function createFormattedBenchamrkReport(files) {
|
|
|
5315
5805
|
}
|
|
5316
5806
|
return report;
|
|
5317
5807
|
}
|
|
5318
|
-
function
|
|
5808
|
+
function flattenFormattedBenchmarkReport(report) {
|
|
5319
5809
|
const flat = {};
|
|
5320
5810
|
for (const file of report.files) {
|
|
5321
5811
|
for (const group of file.groups) {
|
|
5322
|
-
for (const t of group.benchmarks)
|
|
5812
|
+
for (const t of group.benchmarks) {
|
|
5323
5813
|
flat[t.id] = t;
|
|
5814
|
+
}
|
|
5324
5815
|
}
|
|
5325
5816
|
}
|
|
5326
5817
|
return flat;
|
|
@@ -5345,4 +5836,4 @@ const ReportersMap = {
|
|
|
5345
5836
|
"github-actions": GithubActionsReporter
|
|
5346
5837
|
};
|
|
5347
5838
|
|
|
5348
|
-
export {
|
|
5839
|
+
export { BasicReporter as B, DefaultReporter as D, GithubActionsReporter as G, HangingProcessReporter as H, JsonReporter as J, Logger as L, ReportersMap as R, TapReporter as T, VerboseReporter as V, DotReporter as a, JUnitReporter as b, TapFlatReporter as c, BenchmarkReportsMap as d, BaseSequencer as e, Typechecker as f, RandomSequencer as g, findNodeAround as h, generateCodeFrame as i, highlightCode as j, BlobReporter as k, parse as p, readBlobs as r, stringify as s, wrapSerializableConfig as w };
|