vitest 2.0.0-beta.9 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -22
- package/dist/browser.d.ts +24 -7
- package/dist/browser.js +5 -19
- package/dist/chunks/browser-creator.DSqYDthP.js +673 -0
- package/dist/chunks/{environments-node.39w4gmlF.js → environments-node.XE5FbRPQ.js} +1 -1
- package/dist/chunks/{integrations-globals.BK0Cn4q1.js → integrations-globals.CzYWb38r.js} +10 -9
- package/dist/chunks/{node-git.CCI8evVZ.js → node-git.ZtkbKc8u.js} +14 -15
- package/dist/chunks/{runtime-console.DiVMr5d4.js → runtime-console.O41g23Zj.js} +26 -11
- package/dist/chunks/{runtime-runBaseTests.C-Bkopka.js → runtime-runBaseTests.DX3h28Mp.js} +47 -34
- package/dist/cli.js +3 -3
- package/dist/config.cjs +48 -23
- package/dist/config.d.ts +2 -1
- package/dist/config.js +48 -24
- package/dist/coverage.d.ts +6 -4
- package/dist/coverage.js +102 -38
- package/dist/environments.d.ts +2 -1
- package/dist/environments.js +1 -1
- package/dist/execute.d.ts +4 -3
- package/dist/execute.js +2 -2
- package/dist/index.d.ts +1437 -7
- package/dist/index.js +10 -9
- package/dist/node.d.ts +34 -7
- package/dist/node.js +31 -20
- package/dist/path.js +4 -1
- package/dist/{reporters-DaDey3o0.d.ts → reporters-BU_vXAUX.d.ts} +216 -206
- package/dist/reporters.d.ts +2 -1
- package/dist/reporters.js +8 -8
- package/dist/runners.d.ts +3 -1
- package/dist/runners.js +100 -61
- package/dist/snapshot.js +2 -2
- package/dist/{suite-BHSUxUib.d.ts → suite-BRl_IYuM.d.ts} +1 -1
- package/dist/suite.d.ts +3 -2
- package/dist/suite.js +3 -3
- package/dist/utils.d.ts +1 -5
- package/dist/utils.js +1 -6
- package/dist/vendor/{base._gnK9Slw.js → base.CTYV4Gnz.js} +24 -17
- package/dist/vendor/{base.D4XK-wRp.js → base.CdA1i5tB.js} +6 -4
- package/dist/vendor/{benchmark.BNLebNi5.js → benchmark.B6pblCp2.js} +13 -14
- package/dist/vendor/{cac.DCg3FnEs.js → cac.BQc6bsef.js} +142 -47
- package/dist/vendor/{cli-api.LMvYagQ5.js → cli-api.BGRtK_Kj.js} +4189 -9537
- package/dist/vendor/{constants.TCjCaw2D.js → constants.CsnA4eRy.js} +5 -23
- 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/env.2ltrQNq0.js +8 -0
- package/dist/vendor/{execute.BHj6OMh4.js → execute.Dx503nGn.js} +186 -64
- package/dist/vendor/{index.TBU3GqRP.js → index.3x3MdmUV.js} +1075 -526
- package/dist/vendor/{index._7XLd8Kd.js → index.BJmtb_7W.js} +3 -2
- package/dist/vendor/{index.DP-km6lF.js → index.BMmMjLIQ.js} +64 -51
- package/dist/vendor/{index.DHRpy7zp.js → index.CROIsoiT.js} +18 -10
- package/dist/vendor/{index.DeR1hhfY.js → index.D4nqnQWz.js} +71 -74
- package/dist/vendor/index.D6GZqexG.js +6575 -0
- package/dist/vendor/{index.DwR86H5i.js → index.Hqvcg1pf.js} +4 -27
- package/dist/vendor/{rpc.DRDE9Pu1.js → rpc.BGx7q_k2.js} +30 -19
- package/dist/vendor/run-once.Db8Hgq9X.js +28 -0
- package/dist/vendor/{setup-common.BhJvzjns.js → setup-common.yHaxjRhz.js} +30 -15
- package/dist/vendor/spy.Cf_4R5Oe.js +22 -0
- package/dist/vendor/{tasks.WC7M-K-v.js → tasks.DhVtQBtW.js} +3 -1
- package/dist/vendor/{utils.YuQ3LT2a.js → utils.BVMrsl6E.js} +55 -30
- package/dist/vendor/{utils.CUjzkRH7.js → utils.DkxLWvS1.js} +12 -5
- package/dist/vendor/{vi.C6AfDXK6.js → vi.DXACdGTu.js} +269 -136
- package/dist/vendor/{vm.Ow-X2mkS.js → vm.BrDS6p7h.js} +157 -90
- package/dist/worker.js +41 -18
- package/dist/workers/forks.js +12 -6
- package/dist/workers/runVmTests.js +22 -16
- package/dist/workers/threads.js +8 -5
- package/dist/workers/vmForks.js +15 -9
- package/dist/workers/vmThreads.js +11 -8
- package/dist/workers.d.ts +8 -5
- package/dist/workers.js +11 -11
- package/package.json +22 -21
- package/suppress-warnings.cjs +2 -4
- package/dist/index-B0dCycbN.d.ts +0 -1571
- package/dist/vendor/env.bmJgw1qP.js +0 -7
|
@@ -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 {
|
|
5
|
+
import { g as getTestName, h as hasFailedSnapshot, a as getFullName } from './tasks.DhVtQBtW.js';
|
|
6
6
|
import { getSafeTimers, notNullish, highlight, shuffle, inspect, positionToOffset, lineSplitRE } from '@vitest/utils';
|
|
7
|
-
import { i as isNode } from './env.
|
|
8
|
-
import { g as getStateSymbol, f as formatProjectName,
|
|
7
|
+
import { i as isNode, a as isDeno } from './env.2ltrQNq0.js';
|
|
8
|
+
import { g as getStateSymbol, f as formatProjectName, t as taskFail, 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.BVMrsl6E.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.BJmtb_7W.js';
|
|
13
|
+
import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.O41g23Zj.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,
|
|
@@ -168,7 +172,7 @@ function B(e){return e.startsWith("\\\\?\\")?e:e.replace(/\\/g,"/")}const W=e=>{
|
|
|
168
172
|
`+" ".repeat(t)),new Array(F).fill(0).map((e,t)=>"\r"+" ".repeat(t)),new Array(F).fill(0).map((e,t)=>`\r
|
|
169
173
|
`+" ".repeat(t)),new Array(F).fill(0).map((e,t)=>`
|
|
170
174
|
`+" ".repeat(t)),new Array(F).fill(0).map((e,t)=>"\r"+" ".repeat(t)),new Array(F).fill(0).map((e,t)=>`\r
|
|
171
|
-
`+" ".repeat(t));var P;(function(e){e.DEFAULT={allowTrailingComma:!1};})(P||(P={}));function we(e,t=[],i=P.DEFAULT){let n=null,l=[];const s=[];function o(u){Array.isArray(l)?l.push(u):n!==null&&(l[n]=u);}return Te(e,{onObjectBegin:()=>{const u={};o(u),s.push(l),l=u,n=null;},onObjectProperty:u=>{n=u;},onObjectEnd:()=>{l=s.pop();},onArrayBegin:()=>{const u=[];o(u),s.push(l),l=u,n=null;},onArrayEnd:()=>{l=s.pop();},onLiteralValue:o,onError:(u,w,v)=>{t.push({error:u,offset:w,length:v});}},i),l[0]}function Te(e,t,i=P.DEFAULT){const n=be(e,!1),l=[];function s(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function o(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>l.slice()):()=>!0}function m(a){return a?O=>a(O,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function u(a){return a?O=>a(O,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>l.slice()):()=>!0}const w=o(t.onObjectBegin),v=u(t.onObjectProperty),f=s(t.onObjectEnd),E=o(t.onArrayBegin),b=s(t.onArrayEnd),T=u(t.onLiteralValue),k=m(t.onSeparator),j=s(t.onComment),L=m(t.onError),U=i&&i.disallowComments,r=i&&i.allowTrailingComma;function g(){for(;;){const a=n.scan();switch(n.getTokenError()){case 4:c(14);break;case 5:c(15);break;case 3:c(13);break;case 1:U||c(11);break;case 2:c(12);break;case 6:c(16);break}switch(a){case 12:case 13:U?c(10):j();break;case 16:c(1);break;case 15:case 14:break;default:return a}}}function c(a,O=[],Z=[]){if(L(a),O.length+Z.length>0){let x=n.getToken();for(;x!==17;){if(O.indexOf(x)!==-1){g();break}else if(Z.indexOf(x)!==-1)break;x=g();}}}function $(a){const O=n.getTokenValue();return a?T(O):(v(O),l.push(O)),g(),!0}function A(){switch(n.getToken()){case 11:const a=n.getTokenValue();let O=Number(a);isNaN(O)&&(c(2),O=0),T(O);break;case 7:T(null);break;case 8:T(!0);break;case 9:T(!1);break;default:return !1}return g(),!0}function ce(){return n.getToken()!==10?(c(3,[],[2,5]),!1):($(!1),n.getToken()===6?(k(":"),g(),S()||c(4,[],[2,5])):c(5,[],[2,5]),l.pop(),!0)}function pe(){w(),g();let a=!1;for(;n.getToken()!==2&&n.getToken()!==17;){if(n.getToken()===5){if(a||c(4,[],[]),k(","),g(),n.getToken()===2&&r)break}else a&&c(6,[],[]);ce()||c(4,[],[2,5]),a=!0;}return f(),n.getToken()!==2?c(7,[2],[]):g(),!0}function me(){E(),g();let a=!0,O=!1;for(;n.getToken()!==4&&n.getToken()!==17;){if(n.getToken()===5){if(O||c(4,[],[]),k(","),g(),n.getToken()===4&&r)break}else O&&c(6,[],[]);a?(l.push(0),a=!1):l[l.length-1]++,S()||c(4,[],[4,5]),O=!0;}return b(),a||l.pop(),n.getToken()!==4?c(8,[4],[]):g(),!0}function S(){switch(n.getToken()){case 3:return me();case 1:return pe();case 10:return $(!0);default:return A()}}return g(),n.getToken()===17?i.allowEmptyContent?!0:(c(4,[],[]),!1):S()?(n.getToken()!==17&&c(9,[],[]),!0):(c(4,[],[]),!1)}var C;(function(e){e[e.None=0]="None",e[e.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=2]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",e[e.InvalidUnicode=4]="InvalidUnicode",e[e.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",e[e.InvalidCharacter=6]="InvalidCharacter";})(C||(C={}));var ee;(function(e){e[e.OpenBraceToken=1]="OpenBraceToken",e[e.CloseBraceToken=2]="CloseBraceToken",e[e.OpenBracketToken=3]="OpenBracketToken",e[e.CloseBracketToken=4]="CloseBracketToken",e[e.CommaToken=5]="CommaToken",e[e.ColonToken=6]="ColonToken",e[e.NullKeyword=7]="NullKeyword",e[e.TrueKeyword=8]="TrueKeyword",e[e.FalseKeyword=9]="FalseKeyword",e[e.StringLiteral=10]="StringLiteral",e[e.NumericLiteral=11]="NumericLiteral",e[e.LineCommentTrivia=12]="LineCommentTrivia",e[e.BlockCommentTrivia=13]="BlockCommentTrivia",e[e.LineBreakTrivia=14]="LineBreakTrivia",e[e.Trivia=15]="Trivia",e[e.Unknown=16]="Unknown",e[e.EOF=17]="EOF";})(ee||(ee={}));const ve=we;var ne;(function(e){e[e.InvalidSymbol=1]="InvalidSymbol",e[e.InvalidNumberFormat=2]="InvalidNumberFormat",e[e.PropertyNameExpected=3]="PropertyNameExpected",e[e.ValueExpected=4]="ValueExpected",e[e.ColonExpected=5]="ColonExpected",e[e.CommaExpected=6]="CommaExpected",e[e.CloseBraceExpected=7]="CloseBraceExpected",e[e.CloseBracketExpected=8]="CloseBracketExpected",e[e.EndOfFileExpected=9]="EndOfFileExpected",e[e.InvalidCommentToken=10]="InvalidCommentToken",e[e.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=12]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",e[e.InvalidUnicode=14]="InvalidUnicode",e[e.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",e[e.InvalidCharacter=16]="InvalidCharacter";})(ne||(ne={}));const te=(e,t)=>ve(ke(t,e,"utf8")),R=Symbol("implicitBaseUrl"),Ae=()=>{const{findPnpApi:e}=ge;return e&&e(process.cwd())},G=(e,t,i,n)=>{const l=`resolveFromPackageJsonPath:${e}:${t}:${i}`;if(n!=null&&n.has(l))return n.get(l);const s=te(e,n);if(!s)return;let o=t||"tsconfig.json";if(!i&&s.exports)try{const[m]=v(s.exports,t,["require","types"]);o=m;}catch{return !1}else !t&&s.tsconfig&&(o=s.tsconfig);return o=p$1.join(e,"..",o),n==null||n.set(l,o),o},z="package.json",Q="tsconfig.json",Oe=(e,t,i)=>{let n=e;if(e===".."&&(n=p$1.join(n,Q)),e[0]==="."&&(n=p$1.resolve(t,n)),p$1.isAbsolute(n)){if(_(i,n)){if(I(i,n).isFile())return n}else if(!n.endsWith(".json")){const b=`${n}.json`;if(_(i,b))return b}return}const[l,...s]=e.split("/"),o=l[0]==="@"?`${l}/${s.shift()}`:l,m=s.join("/"),u=Ae();if(u){const{resolveRequest:b}=u;try{if(o===e){const T=b(p$1.join(o,z),t);if(T){const k=G(T,m,!1,i);if(k&&_(i,k))return k}}else {let T;try{T=b(e,t,{extensions:[".json"]});}catch{T=b(p$1.join(e,Q),t);}if(T)return T}}catch{}}const w=q(t,p$1.join("node_modules",o),i);if(!w||!I(i,w).isDirectory())return;const v=p$1.join(w,z);if(_(i,v)){const b=G(v,m,!1,i);if(b===!1)return;if(b&&_(i,b)&&I(i,b).isFile())return b}const f=p$1.join(w,m),E=f.endsWith(".json");if(!E){const b=`${f}.json`;if(_(i,b))return b}if(_(i,f)){if(I(i,f).isDirectory()){const b=p$1.join(f,z);if(_(i,b)){const k=G(b,"",!0,i);if(k&&_(i,k))return k}const T=p$1.join(f,Q);if(_(i,T))return T}else if(E)return f}},je=(e,t,i,n)=>{const l=Oe(e,t,n);if(!l)throw new Error(`File '${e}' not found.`);if(i.has(l))throw new Error(`Circularity detected while resolving configuration: ${l}`);i.add(l);const s=p$1.dirname(l),o=ie(l,n,i);delete o.references;const{compilerOptions:m}=o;if(m){const u=["baseUrl","outDir"];for(const w of u){const v=m[w];v&&(m[w]=B(p$1.relative(t,p$1.join(s,v)))||"./");}}return o.files&&(o.files=o.files.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o.include&&(o.include=o.include.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o.exclude&&(o.exclude=o.exclude.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o},ie=(e,t,i=new Set)=>{let n;try{n=te(e,t)||{};}catch{throw new Error(`Cannot resolve tsconfig at path: ${e}`)}if(typeof n!="object")throw new SyntaxError(`Failed to parse tsconfig at: ${e}`);const l=p$1.dirname(e);if(n.compilerOptions){const{compilerOptions:s}=n;s.paths&&!s.baseUrl&&(s[R]=l);}if(n.extends){const s=Array.isArray(n.extends)?n.extends:[n.extends];delete n.extends;for(const o of s.reverse()){const m=je(o,l,new Set(i),t),u={...m,...n,compilerOptions:{...m.compilerOptions,...n.compilerOptions}};m.watchOptions&&(u.watchOptions={...m.watchOptions,...n.watchOptions}),n=u;}}if(n.compilerOptions){const{compilerOptions:s}=n,o=["baseUrl","rootDir"];for(const u of o){const w=s[u];if(w){const v=p$1.resolve(l,w),f=J(p$1.relative(l,v));s[u]=f;}}const{outDir:m}=s;m&&(Array.isArray(n.exclude)||(n.exclude=[]),n.exclude.includes(m)||n.exclude.push(m),s.outDir=J(m));}else n.compilerOptions={};if(n.files&&(n.files=n.files.map(J)),n.include&&(n.include=n.include.map(B)),n.watchOptions){const{watchOptions:s}=n;s.excludeDirectories&&(s.excludeDirectories=s.excludeDirectories.map(o=>B(p$1.resolve(l,o))));}return n},le=(e,t=new Map)=>ie(e,t),$e=(e=process.cwd(),t="tsconfig.json",i=new Map)=>{const n=q(B(e),t,i);if(!n)return null;const l=le(n,i);return {path:n,config:l}};p$1.posix;process.platform==="win32";
|
|
175
|
+
`+" ".repeat(t));var P;(function(e){e.DEFAULT={allowTrailingComma:!1};})(P||(P={}));function we(e,t=[],i=P.DEFAULT){let n=null,l=[];const s=[];function o(u){Array.isArray(l)?l.push(u):n!==null&&(l[n]=u);}return Te(e,{onObjectBegin:()=>{const u={};o(u),s.push(l),l=u,n=null;},onObjectProperty:u=>{n=u;},onObjectEnd:()=>{l=s.pop();},onArrayBegin:()=>{const u=[];o(u),s.push(l),l=u,n=null;},onArrayEnd:()=>{l=s.pop();},onLiteralValue:o,onError:(u,w,v)=>{t.push({error:u,offset:w,length:v});}},i),l[0]}function Te(e,t,i=P.DEFAULT){const n=be(e,!1),l=[];function s(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function o(a){return a?()=>a(n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>l.slice()):()=>!0}function m(a){return a?O=>a(O,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter()):()=>!0}function u(a){return a?O=>a(O,n.getTokenOffset(),n.getTokenLength(),n.getTokenStartLine(),n.getTokenStartCharacter(),()=>l.slice()):()=>!0}const w=o(t.onObjectBegin),v=u(t.onObjectProperty),f=s(t.onObjectEnd),E=o(t.onArrayBegin),b=s(t.onArrayEnd),T=u(t.onLiteralValue),k=m(t.onSeparator),j=s(t.onComment),L=m(t.onError),U=i&&i.disallowComments,r=i&&i.allowTrailingComma;function g(){for(;;){const a=n.scan();switch(n.getTokenError()){case 4:c(14);break;case 5:c(15);break;case 3:c(13);break;case 1:U||c(11);break;case 2:c(12);break;case 6:c(16);break}switch(a){case 12:case 13:U?c(10):j();break;case 16:c(1);break;case 15:case 14:break;default:return a}}}function c(a,O=[],Z=[]){if(L(a),O.length+Z.length>0){let x=n.getToken();for(;x!==17;){if(O.indexOf(x)!==-1){g();break}else if(Z.indexOf(x)!==-1)break;x=g();}}}function $(a){const O=n.getTokenValue();return a?T(O):(v(O),l.push(O)),g(),!0}function A(){switch(n.getToken()){case 11:const a=n.getTokenValue();let O=Number(a);isNaN(O)&&(c(2),O=0),T(O);break;case 7:T(null);break;case 8:T(!0);break;case 9:T(!1);break;default:return !1}return g(),!0}function ce(){return n.getToken()!==10?(c(3,[],[2,5]),!1):($(!1),n.getToken()===6?(k(":"),g(),S()||c(4,[],[2,5])):c(5,[],[2,5]),l.pop(),!0)}function pe(){w(),g();let a=!1;for(;n.getToken()!==2&&n.getToken()!==17;){if(n.getToken()===5){if(a||c(4,[],[]),k(","),g(),n.getToken()===2&&r)break}else a&&c(6,[],[]);ce()||c(4,[],[2,5]),a=!0;}return f(),n.getToken()!==2?c(7,[2],[]):g(),!0}function me(){E(),g();let a=!0,O=!1;for(;n.getToken()!==4&&n.getToken()!==17;){if(n.getToken()===5){if(O||c(4,[],[]),k(","),g(),n.getToken()===4&&r)break}else O&&c(6,[],[]);a?(l.push(0),a=!1):l[l.length-1]++,S()||c(4,[],[4,5]),O=!0;}return b(),a||l.pop(),n.getToken()!==4?c(8,[4],[]):g(),!0}function S(){switch(n.getToken()){case 3:return me();case 1:return pe();case 10:return $(!0);default:return A()}}return g(),n.getToken()===17?i.allowEmptyContent?!0:(c(4,[],[]),!1):S()?(n.getToken()!==17&&c(9,[],[]),!0):(c(4,[],[]),!1)}var C;(function(e){e[e.None=0]="None",e[e.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=2]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",e[e.InvalidUnicode=4]="InvalidUnicode",e[e.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",e[e.InvalidCharacter=6]="InvalidCharacter";})(C||(C={}));var ee;(function(e){e[e.OpenBraceToken=1]="OpenBraceToken",e[e.CloseBraceToken=2]="CloseBraceToken",e[e.OpenBracketToken=3]="OpenBracketToken",e[e.CloseBracketToken=4]="CloseBracketToken",e[e.CommaToken=5]="CommaToken",e[e.ColonToken=6]="ColonToken",e[e.NullKeyword=7]="NullKeyword",e[e.TrueKeyword=8]="TrueKeyword",e[e.FalseKeyword=9]="FalseKeyword",e[e.StringLiteral=10]="StringLiteral",e[e.NumericLiteral=11]="NumericLiteral",e[e.LineCommentTrivia=12]="LineCommentTrivia",e[e.BlockCommentTrivia=13]="BlockCommentTrivia",e[e.LineBreakTrivia=14]="LineBreakTrivia",e[e.Trivia=15]="Trivia",e[e.Unknown=16]="Unknown",e[e.EOF=17]="EOF";})(ee||(ee={}));const ve=we;var ne;(function(e){e[e.InvalidSymbol=1]="InvalidSymbol",e[e.InvalidNumberFormat=2]="InvalidNumberFormat",e[e.PropertyNameExpected=3]="PropertyNameExpected",e[e.ValueExpected=4]="ValueExpected",e[e.ColonExpected=5]="ColonExpected",e[e.CommaExpected=6]="CommaExpected",e[e.CloseBraceExpected=7]="CloseBraceExpected",e[e.CloseBracketExpected=8]="CloseBracketExpected",e[e.EndOfFileExpected=9]="EndOfFileExpected",e[e.InvalidCommentToken=10]="InvalidCommentToken",e[e.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",e[e.UnexpectedEndOfString=12]="UnexpectedEndOfString",e[e.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",e[e.InvalidUnicode=14]="InvalidUnicode",e[e.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",e[e.InvalidCharacter=16]="InvalidCharacter";})(ne||(ne={}));const te=(e,t)=>ve(ke(t,e,"utf8")),R=Symbol("implicitBaseUrl"),Ae=()=>{const{findPnpApi:e}=ge;return e&&e(process.cwd())},G=(e,t,i,n)=>{const l=`resolveFromPackageJsonPath:${e}:${t}:${i}`;if(n!=null&&n.has(l))return n.get(l);const s=te(e,n);if(!s)return;let o=t||"tsconfig.json";if(!i&&s.exports)try{const[m]=v(s.exports,t,["require","types"]);o=m;}catch{return !1}else !t&&s.tsconfig&&(o=s.tsconfig);return o=p$1.join(e,"..",o),n==null||n.set(l,o),o},z="package.json",Q="tsconfig.json",Oe=(e,t,i)=>{let n=e;if(e===".."&&(n=p$1.join(n,Q)),e[0]==="."&&(n=p$1.resolve(t,n)),p$1.isAbsolute(n)){if(_(i,n)){if(I(i,n).isFile())return n}else if(!n.endsWith(".json")){const b=`${n}.json`;if(_(i,b))return b}return}const[l,...s]=e.split("/"),o=l[0]==="@"?`${l}/${s.shift()}`:l,m=s.join("/"),u=Ae();if(u){const{resolveRequest:b}=u;try{if(o===e){const T=b(p$1.join(o,z),t);if(T){const k=G(T,m,!1,i);if(k&&_(i,k))return k}}else {let T;try{T=b(e,t,{extensions:[".json"]});}catch{T=b(p$1.join(e,Q),t);}if(T)return T}}catch{}}const w=q(p$1.resolve(t),p$1.join("node_modules",o),i);if(!w||!I(i,w).isDirectory())return;const v=p$1.join(w,z);if(_(i,v)){const b=G(v,m,!1,i);if(b===!1)return;if(b&&_(i,b)&&I(i,b).isFile())return b}const f=p$1.join(w,m),E=f.endsWith(".json");if(!E){const b=`${f}.json`;if(_(i,b))return b}if(_(i,f)){if(I(i,f).isDirectory()){const b=p$1.join(f,z);if(_(i,b)){const k=G(b,"",!0,i);if(k&&_(i,k))return k}const T=p$1.join(f,Q);if(_(i,T))return T}else if(E)return f}},je=(e,t,i,n)=>{const l=Oe(e,t,n);if(!l)throw new Error(`File '${e}' not found.`);if(i.has(l))throw new Error(`Circularity detected while resolving configuration: ${l}`);i.add(l);const s=p$1.dirname(l),o=ie(l,n,i);delete o.references;const{compilerOptions:m}=o;if(m){const u=["baseUrl","outDir"];for(const w of u){const v=m[w];v&&(m[w]=B(p$1.relative(t,p$1.join(s,v)))||"./");}}return o.files&&(o.files=o.files.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o.include&&(o.include=o.include.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o.exclude&&(o.exclude=o.exclude.map(u=>B(p$1.relative(t,p$1.join(s,u))))),o},ie=(e,t,i=new Set)=>{let n;try{n=te(e,t)||{};}catch{throw new Error(`Cannot resolve tsconfig at path: ${e}`)}if(typeof n!="object")throw new SyntaxError(`Failed to parse tsconfig at: ${e}`);const l=p$1.dirname(e);if(n.compilerOptions){const{compilerOptions:s}=n;s.paths&&!s.baseUrl&&(s[R]=l);}if(n.extends){const s=Array.isArray(n.extends)?n.extends:[n.extends];delete n.extends;for(const o of s.reverse()){const m=je(o,l,new Set(i),t),u={...m,...n,compilerOptions:{...m.compilerOptions,...n.compilerOptions}};m.watchOptions&&(u.watchOptions={...m.watchOptions,...n.watchOptions}),n=u;}}if(n.compilerOptions){const{compilerOptions:s}=n,o=["baseUrl","rootDir"];for(const u of o){const w=s[u];if(w){const v=p$1.resolve(l,w),f=J(p$1.relative(l,v));s[u]=f;}}const{outDir:m}=s;m&&(Array.isArray(n.exclude)||(n.exclude=[]),n.exclude.includes(m)||n.exclude.push(m),s.outDir=J(m));}else n.compilerOptions={};if(n.files&&(n.files=n.files.map(J)),n.include&&(n.include=n.include.map(B)),n.watchOptions){const{watchOptions:s}=n;s.excludeDirectories&&(s.excludeDirectories=s.excludeDirectories.map(o=>B(p$1.resolve(l,o))));}return n},le=(e,t=new Map)=>ie(e,t),$e=(e=process.cwd(),t="tsconfig.json",i=new Map)=>{const n=q(B(e),t,i);if(!n)return null;const l=le(n,i);return {path:n,config:l}};p$1.posix;process.platform==="win32";
|
|
172
176
|
|
|
173
177
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
174
178
|
const newLineRegExp = /\r?\n/;
|
|
@@ -176,21 +180,26 @@ const errCodeRegExp = /error TS(?<errCode>\d+)/;
|
|
|
176
180
|
async function makeTscErrorInfo(errInfo) {
|
|
177
181
|
var _a;
|
|
178
182
|
const [errFilePathPos = "", ...errMsgRawArr] = errInfo.split(":");
|
|
179
|
-
if (!errFilePathPos || errMsgRawArr.length === 0 || errMsgRawArr.join("").length === 0)
|
|
183
|
+
if (!errFilePathPos || errMsgRawArr.length === 0 || errMsgRawArr.join("").length === 0) {
|
|
180
184
|
return ["unknown filepath", null];
|
|
185
|
+
}
|
|
181
186
|
const errMsgRaw = errMsgRawArr.join("").trim();
|
|
182
187
|
const [errFilePath, errPos] = errFilePathPos.slice(0, -1).split("(");
|
|
183
|
-
if (!errFilePath || !errPos)
|
|
188
|
+
if (!errFilePath || !errPos) {
|
|
184
189
|
return ["unknown filepath", null];
|
|
190
|
+
}
|
|
185
191
|
const [errLine, errCol] = errPos.split(",");
|
|
186
|
-
if (!errLine || !errCol)
|
|
192
|
+
if (!errLine || !errCol) {
|
|
187
193
|
return [errFilePath, null];
|
|
194
|
+
}
|
|
188
195
|
const execArr = errCodeRegExp.exec(errMsgRaw);
|
|
189
|
-
if (!execArr)
|
|
196
|
+
if (!execArr) {
|
|
190
197
|
return [errFilePath, null];
|
|
198
|
+
}
|
|
191
199
|
const errCodeStr = ((_a = execArr.groups) == null ? void 0 : _a.errCode) ?? "";
|
|
192
|
-
if (!errCodeStr)
|
|
200
|
+
if (!errCodeStr) {
|
|
193
201
|
return [errFilePath, null];
|
|
202
|
+
}
|
|
194
203
|
const line = Number(errLine);
|
|
195
204
|
const col = Number(errCol);
|
|
196
205
|
const errCode = Number(errCodeStr);
|
|
@@ -209,9 +218,13 @@ async function getTsconfig(root, config) {
|
|
|
209
218
|
const configName = config.tsconfig ? basename(config.tsconfig) : void 0;
|
|
210
219
|
const configSearchPath = config.tsconfig ? dirname(resolve(root, config.tsconfig)) : root;
|
|
211
220
|
const tsconfig = $e(configSearchPath, configName);
|
|
212
|
-
if (!tsconfig)
|
|
221
|
+
if (!tsconfig) {
|
|
213
222
|
throw new Error("no tsconfig.json found");
|
|
214
|
-
|
|
223
|
+
}
|
|
224
|
+
const tempConfigPath = join(
|
|
225
|
+
dirname(tsconfig.path),
|
|
226
|
+
"tsconfig.vitest-temp.json"
|
|
227
|
+
);
|
|
215
228
|
try {
|
|
216
229
|
const tmpTsConfig = { ...tsconfig.config };
|
|
217
230
|
tmpTsConfig.compilerOptions = tmpTsConfig.compilerOptions || {};
|
|
@@ -232,24 +245,27 @@ async function getRawErrsMapFromTsCompile(tscErrorStdout) {
|
|
|
232
245
|
const rawErrsMap = /* @__PURE__ */ new Map();
|
|
233
246
|
const infos = await Promise.all(
|
|
234
247
|
tscErrorStdout.split(newLineRegExp).reduce((prev, next) => {
|
|
235
|
-
if (!next)
|
|
248
|
+
if (!next) {
|
|
236
249
|
return prev;
|
|
237
|
-
else if (!next.startsWith(" "))
|
|
250
|
+
} else if (!next.startsWith(" ")) {
|
|
238
251
|
prev.push(next);
|
|
239
|
-
else
|
|
252
|
+
} else {
|
|
240
253
|
prev[prev.length - 1] += `
|
|
241
254
|
${next}`;
|
|
255
|
+
}
|
|
242
256
|
return prev;
|
|
243
257
|
}, []).map((errInfoLine) => makeTscErrorInfo(errInfoLine))
|
|
244
258
|
);
|
|
245
259
|
infos.forEach(([errFilePath, errInfo]) => {
|
|
246
260
|
var _a;
|
|
247
|
-
if (!errInfo)
|
|
261
|
+
if (!errInfo) {
|
|
248
262
|
return;
|
|
249
|
-
|
|
263
|
+
}
|
|
264
|
+
if (!rawErrsMap.has(errFilePath)) {
|
|
250
265
|
rawErrsMap.set(errFilePath, [errInfo]);
|
|
251
|
-
else
|
|
266
|
+
} else {
|
|
252
267
|
(_a = rawErrsMap.get(errFilePath)) == null ? void 0 : _a.push(errInfo);
|
|
268
|
+
}
|
|
253
269
|
});
|
|
254
270
|
return rawErrsMap;
|
|
255
271
|
}
|
|
@@ -584,8 +600,9 @@ base.MethodDefinition = base.PropertyDefinition = base.Property = function (node
|
|
|
584
600
|
|
|
585
601
|
async function collectTests(ctx, filepath) {
|
|
586
602
|
const request = await ctx.vitenode.transformRequest(filepath, filepath);
|
|
587
|
-
if (!request)
|
|
603
|
+
if (!request) {
|
|
588
604
|
return null;
|
|
605
|
+
}
|
|
589
606
|
const ast = await parseAstAsync(request.code);
|
|
590
607
|
const testFilepath = relative(ctx.config.root, filepath);
|
|
591
608
|
const file = {
|
|
@@ -605,13 +622,16 @@ async function collectTests(ctx, filepath) {
|
|
|
605
622
|
const definitions = [];
|
|
606
623
|
const getName = (callee) => {
|
|
607
624
|
var _a, _b, _c;
|
|
608
|
-
if (!callee)
|
|
625
|
+
if (!callee) {
|
|
609
626
|
return null;
|
|
610
|
-
|
|
627
|
+
}
|
|
628
|
+
if (callee.type === "Identifier") {
|
|
611
629
|
return callee.name;
|
|
630
|
+
}
|
|
612
631
|
if (callee.type === "MemberExpression") {
|
|
613
|
-
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_")) {
|
|
614
633
|
return getName(callee.property);
|
|
634
|
+
}
|
|
615
635
|
return getName((_c = callee.object) == null ? void 0 : _c.property);
|
|
616
636
|
}
|
|
617
637
|
return null;
|
|
@@ -621,17 +641,25 @@ async function collectTests(ctx, filepath) {
|
|
|
621
641
|
var _a;
|
|
622
642
|
const { callee } = node;
|
|
623
643
|
const name = getName(callee);
|
|
624
|
-
if (!name)
|
|
644
|
+
if (!name) {
|
|
625
645
|
return;
|
|
626
|
-
|
|
646
|
+
}
|
|
647
|
+
if (!["it", "test", "describe", "suite"].includes(name)) {
|
|
627
648
|
return;
|
|
628
|
-
|
|
649
|
+
}
|
|
650
|
+
const {
|
|
651
|
+
arguments: [{ value: message }]
|
|
652
|
+
} = node;
|
|
629
653
|
const property = (_a = callee == null ? void 0 : callee.property) == null ? void 0 : _a.name;
|
|
630
654
|
let mode = !property || property === name ? "run" : property;
|
|
631
|
-
if (!["run", "skip", "todo", "only", "skipIf", "runIf"].includes(mode))
|
|
632
|
-
throw new Error(
|
|
633
|
-
|
|
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") {
|
|
634
661
|
mode = "skip";
|
|
662
|
+
}
|
|
635
663
|
definitions.push({
|
|
636
664
|
start: node.start,
|
|
637
665
|
end: node.end,
|
|
@@ -643,15 +671,17 @@ async function collectTests(ctx, filepath) {
|
|
|
643
671
|
});
|
|
644
672
|
let lastSuite = file;
|
|
645
673
|
const updateLatestSuite = (index) => {
|
|
646
|
-
while (lastSuite.suite && lastSuite.end < index)
|
|
674
|
+
while (lastSuite.suite && lastSuite.end < index) {
|
|
647
675
|
lastSuite = lastSuite.suite;
|
|
676
|
+
}
|
|
648
677
|
return lastSuite;
|
|
649
678
|
};
|
|
650
679
|
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
|
|
651
680
|
const latestSuite = updateLatestSuite(definition.start);
|
|
652
681
|
let mode = definition.mode;
|
|
653
|
-
if (latestSuite.mode !== "run")
|
|
682
|
+
if (latestSuite.mode !== "run") {
|
|
654
683
|
mode = latestSuite.mode;
|
|
684
|
+
}
|
|
655
685
|
if (definition.type === "suite") {
|
|
656
686
|
const task2 = {
|
|
657
687
|
type: definition.type,
|
|
@@ -692,7 +722,13 @@ async function collectTests(ctx, filepath) {
|
|
|
692
722
|
});
|
|
693
723
|
calculateSuiteHash(file);
|
|
694
724
|
const hasOnly = someTasksAreOnly(file);
|
|
695
|
-
interpretTaskModes(
|
|
725
|
+
interpretTaskModes(
|
|
726
|
+
file,
|
|
727
|
+
ctx.config.testNamePattern,
|
|
728
|
+
hasOnly,
|
|
729
|
+
false,
|
|
730
|
+
ctx.config.allowOnly
|
|
731
|
+
);
|
|
696
732
|
return {
|
|
697
733
|
file,
|
|
698
734
|
parsed: request.code,
|
|
@@ -754,8 +790,9 @@ class Typechecker {
|
|
|
754
790
|
const tests = (await Promise.all(
|
|
755
791
|
this.getFiles().map((filepath) => this.collectFileTests(filepath))
|
|
756
792
|
)).reduce((acc, data) => {
|
|
757
|
-
if (!data)
|
|
793
|
+
if (!data) {
|
|
758
794
|
return acc;
|
|
795
|
+
}
|
|
759
796
|
acc[data.filepath] = data;
|
|
760
797
|
return acc;
|
|
761
798
|
}, {});
|
|
@@ -772,8 +809,9 @@ class Typechecker {
|
|
|
772
809
|
const markTasks = (tasks) => {
|
|
773
810
|
var _a2;
|
|
774
811
|
for (const task of tasks) {
|
|
775
|
-
if ("tasks" in task)
|
|
812
|
+
if ("tasks" in task) {
|
|
776
813
|
markTasks(task.tasks);
|
|
814
|
+
}
|
|
777
815
|
if (!((_a2 = task.result) == null ? void 0 : _a2.state) && task.mode === "run") {
|
|
778
816
|
task.result = {
|
|
779
817
|
state: "pass"
|
|
@@ -786,8 +824,9 @@ class Typechecker {
|
|
|
786
824
|
async prepareResults(output) {
|
|
787
825
|
const typeErrors = await this.parseTscLikeOutput(output);
|
|
788
826
|
const testFiles = new Set(this.getFiles());
|
|
789
|
-
if (!this._tests)
|
|
827
|
+
if (!this._tests) {
|
|
790
828
|
this._tests = await this.collectTests();
|
|
829
|
+
}
|
|
791
830
|
const sourceErrors = [];
|
|
792
831
|
const files = [];
|
|
793
832
|
testFiles.forEach((path) => {
|
|
@@ -798,17 +837,20 @@ class Typechecker {
|
|
|
798
837
|
this.markPassed(file);
|
|
799
838
|
return;
|
|
800
839
|
}
|
|
801
|
-
const sortedDefinitions = [
|
|
840
|
+
const sortedDefinitions = [
|
|
841
|
+
...definitions.sort((a, b) => b.start - a.start)
|
|
842
|
+
];
|
|
802
843
|
const traceMap = map && new TraceMap(map);
|
|
803
844
|
const indexMap = createIndexMap(parsed);
|
|
804
845
|
const markState = (task, state) => {
|
|
805
846
|
task.result = {
|
|
806
847
|
state: task.mode === "run" || task.mode === "only" ? state : task.mode
|
|
807
848
|
};
|
|
808
|
-
if (task.suite)
|
|
849
|
+
if (task.suite) {
|
|
809
850
|
markState(task.suite, state);
|
|
810
|
-
else if (task.file && task !== task.file)
|
|
851
|
+
} else if (task.file && task !== task.file) {
|
|
811
852
|
markState(task.file, state);
|
|
853
|
+
}
|
|
812
854
|
};
|
|
813
855
|
errors.forEach(({ error, originalError }) => {
|
|
814
856
|
var _a;
|
|
@@ -820,7 +862,9 @@ class Typechecker {
|
|
|
820
862
|
const line = processedPos.line ?? originalError.line;
|
|
821
863
|
const column = processedPos.column ?? originalError.column;
|
|
822
864
|
const index = indexMap.get(`${line}:${column}`);
|
|
823
|
-
const definition = index != null && sortedDefinitions.find(
|
|
865
|
+
const definition = index != null && sortedDefinitions.find(
|
|
866
|
+
(def) => def.start <= index && def.end >= index
|
|
867
|
+
);
|
|
824
868
|
const suite = definition ? definition.task : file;
|
|
825
869
|
const state = suite.mode === "run" || suite.mode === "only" ? "fail" : suite.mode;
|
|
826
870
|
const errors2 = ((_a = suite.result) == null ? void 0 : _a.errors) || [];
|
|
@@ -830,17 +874,19 @@ class Typechecker {
|
|
|
830
874
|
};
|
|
831
875
|
errors2.push(error);
|
|
832
876
|
if (state === "fail") {
|
|
833
|
-
if (suite.suite)
|
|
877
|
+
if (suite.suite) {
|
|
834
878
|
markState(suite.suite, "fail");
|
|
835
|
-
else if (suite.file && suite !== suite.file)
|
|
879
|
+
} else if (suite.file && suite !== suite.file) {
|
|
836
880
|
markState(suite.file, "fail");
|
|
881
|
+
}
|
|
837
882
|
}
|
|
838
883
|
});
|
|
839
884
|
this.markPassed(file);
|
|
840
885
|
});
|
|
841
886
|
typeErrors.forEach((errors, path) => {
|
|
842
|
-
if (!testFiles.has(path))
|
|
887
|
+
if (!testFiles.has(path)) {
|
|
843
888
|
sourceErrors.push(...errors.map(({ error }) => error));
|
|
889
|
+
}
|
|
844
890
|
});
|
|
845
891
|
return {
|
|
846
892
|
files,
|
|
@@ -856,7 +902,10 @@ class Typechecker {
|
|
|
856
902
|
const suiteErrors = errors.map((info) => {
|
|
857
903
|
const limit = Error.stackTraceLimit;
|
|
858
904
|
Error.stackTraceLimit = 0;
|
|
859
|
-
const errMsg = info.errMsg.replace(
|
|
905
|
+
const errMsg = info.errMsg.replace(
|
|
906
|
+
/\r?\n\s*(Type .* has no call signatures)/g,
|
|
907
|
+
" $1"
|
|
908
|
+
);
|
|
860
909
|
const error = new TypeCheckError(errMsg, [
|
|
861
910
|
{
|
|
862
911
|
file: filepath,
|
|
@@ -883,17 +932,20 @@ class Typechecker {
|
|
|
883
932
|
return typesErrors;
|
|
884
933
|
}
|
|
885
934
|
async clear() {
|
|
886
|
-
if (this.tempConfigPath)
|
|
935
|
+
if (this.tempConfigPath) {
|
|
887
936
|
await rm(this.tempConfigPath, { force: true });
|
|
937
|
+
}
|
|
888
938
|
}
|
|
889
939
|
async stop() {
|
|
890
940
|
var _a;
|
|
891
941
|
await this.clear();
|
|
892
942
|
(_a = this.process) == null ? void 0 : _a.kill();
|
|
943
|
+
this.process = void 0;
|
|
893
944
|
}
|
|
894
945
|
async ensurePackageInstalled(ctx, checker) {
|
|
895
|
-
if (checker !== "tsc" && checker !== "vue-tsc")
|
|
946
|
+
if (checker !== "tsc" && checker !== "vue-tsc") {
|
|
896
947
|
return;
|
|
948
|
+
}
|
|
897
949
|
const packageName = checker === "tsc" ? "typescript" : "vue-tsc";
|
|
898
950
|
await ctx.packageInstaller.ensureInstalled(packageName, ctx.config.root);
|
|
899
951
|
}
|
|
@@ -912,14 +964,20 @@ class Typechecker {
|
|
|
912
964
|
}
|
|
913
965
|
async start() {
|
|
914
966
|
var _a, _b, _c;
|
|
915
|
-
if (
|
|
967
|
+
if (this.process) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
if (!this.tempConfigPath) {
|
|
916
971
|
throw new Error("tsconfig was not initialized");
|
|
972
|
+
}
|
|
917
973
|
const { root, watch, typecheck } = this.ctx.config;
|
|
918
974
|
const args = ["--noEmit", "--pretty", "false", "-p", this.tempConfigPath];
|
|
919
|
-
if (watch)
|
|
975
|
+
if (watch) {
|
|
920
976
|
args.push("--watch");
|
|
921
|
-
|
|
977
|
+
}
|
|
978
|
+
if (typecheck.allowJs) {
|
|
922
979
|
args.push("--allowJs", "--checkJs");
|
|
980
|
+
}
|
|
923
981
|
this._output = "";
|
|
924
982
|
this._startTime = performance.now();
|
|
925
983
|
const child = execa(typecheck.checker, args, {
|
|
@@ -933,8 +991,9 @@ class Typechecker {
|
|
|
933
991
|
(_b = child.stdout) == null ? void 0 : _b.on("data", (chunk) => {
|
|
934
992
|
var _a2;
|
|
935
993
|
this._output += chunk;
|
|
936
|
-
if (!watch)
|
|
994
|
+
if (!watch) {
|
|
937
995
|
return;
|
|
996
|
+
}
|
|
938
997
|
if (this._output.includes("File change detected") && !rerunTriggered) {
|
|
939
998
|
(_a2 = this._onWatcherRerun) == null ? void 0 : _a2.call(this);
|
|
940
999
|
this._startTime = performance.now();
|
|
@@ -975,18 +1034,26 @@ const HELP_HINT = `${c.dim("press ")}${c.bold("h")}${c.dim(" to show help")}`;
|
|
|
975
1034
|
const HELP_UPDATE_SNAP = c.dim("press ") + c.bold(c.yellow("u")) + c.dim(" to update snapshot");
|
|
976
1035
|
const HELP_QUITE = `${c.dim("press ")}${c.bold("q")}${c.dim(" to quit")}`;
|
|
977
1036
|
const WAIT_FOR_CHANGE_PASS = `
|
|
978
|
-
${c.bold(
|
|
1037
|
+
${c.bold(
|
|
1038
|
+
c.inverse(c.green(" PASS "))
|
|
1039
|
+
)}${c.green(" Waiting for file changes...")}`;
|
|
979
1040
|
const WAIT_FOR_CHANGE_FAIL = `
|
|
980
|
-
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(
|
|
1041
|
+
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(
|
|
1042
|
+
" Tests failed. Watching for file changes..."
|
|
1043
|
+
)}`;
|
|
981
1044
|
const WAIT_FOR_CHANGE_CANCELLED = `
|
|
982
|
-
${c.bold(
|
|
1045
|
+
${c.bold(
|
|
1046
|
+
c.inverse(c.red(" CANCELLED "))
|
|
1047
|
+
)}${c.red(" Test run cancelled. Watching for file changes...")}`;
|
|
983
1048
|
const LAST_RUN_LOG_TIMEOUT = 1500;
|
|
984
1049
|
class BaseReporter {
|
|
985
1050
|
start = 0;
|
|
986
1051
|
end = 0;
|
|
987
1052
|
watchFilters;
|
|
1053
|
+
failedUnwatchedFiles = [];
|
|
988
1054
|
isTTY;
|
|
989
1055
|
ctx = void 0;
|
|
1056
|
+
verbose = false;
|
|
990
1057
|
_filesInWatchMode = /* @__PURE__ */ new Map();
|
|
991
1058
|
_lastRunTimeout = 0;
|
|
992
1059
|
_lastRunTimer;
|
|
@@ -995,7 +1062,7 @@ class BaseReporter {
|
|
|
995
1062
|
_offUnhandledRejection;
|
|
996
1063
|
constructor(options = {}) {
|
|
997
1064
|
var _a;
|
|
998
|
-
this.isTTY = options.isTTY ?? (isNode && ((_a = process.stdout) == null ? void 0 : _a.isTTY) && !isCI);
|
|
1065
|
+
this.isTTY = options.isTTY ?? ((isNode || isDeno) && ((_a = process.stdout) == null ? void 0 : _a.isTTY) && !isCI);
|
|
999
1066
|
this.registerUnhandledRejection();
|
|
1000
1067
|
}
|
|
1001
1068
|
get mode() {
|
|
@@ -1017,67 +1084,85 @@ class BaseReporter {
|
|
|
1017
1084
|
this.end = performance.now();
|
|
1018
1085
|
this.reportSummary(files, errors);
|
|
1019
1086
|
if (errors.length) {
|
|
1020
|
-
if (!this.ctx.config.dangerouslyIgnoreUnhandledErrors)
|
|
1087
|
+
if (!this.ctx.config.dangerouslyIgnoreUnhandledErrors) {
|
|
1021
1088
|
process.exitCode = 1;
|
|
1089
|
+
}
|
|
1022
1090
|
}
|
|
1023
1091
|
}
|
|
1024
1092
|
onTaskUpdate(packs) {
|
|
1025
|
-
|
|
1026
|
-
if (this.isTTY)
|
|
1093
|
+
if (this.isTTY) {
|
|
1027
1094
|
return;
|
|
1028
|
-
|
|
1095
|
+
}
|
|
1029
1096
|
for (const pack of packs) {
|
|
1030
1097
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
1031
|
-
if (task
|
|
1032
|
-
|
|
1033
|
-
const failed = tests.filter((t) => {
|
|
1034
|
-
var _a2;
|
|
1035
|
-
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
|
|
1036
|
-
});
|
|
1037
|
-
const skipped = tests.filter((t) => t.mode === "skip" || t.mode === "todo");
|
|
1038
|
-
let state = c.dim(`${tests.length} test${tests.length > 1 ? "s" : ""}`);
|
|
1039
|
-
if (failed.length)
|
|
1040
|
-
state += ` ${c.dim("|")} ${c.red(`${failed.length} failed`)}`;
|
|
1041
|
-
if (skipped.length)
|
|
1042
|
-
state += ` ${c.dim("|")} ${c.yellow(`${skipped.length} skipped`)}`;
|
|
1043
|
-
let suffix = c.dim(" (") + state + c.dim(")");
|
|
1044
|
-
if (task.result.duration) {
|
|
1045
|
-
const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.gray;
|
|
1046
|
-
suffix += color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
|
|
1047
|
-
}
|
|
1048
|
-
if (this.ctx.config.logHeapUsage && task.result.heap != null)
|
|
1049
|
-
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
1050
|
-
let title = ` ${getStateSymbol(task)} `;
|
|
1051
|
-
if (task.projectName)
|
|
1052
|
-
title += formatProjectName(task.projectName);
|
|
1053
|
-
title += `${task.name} ${suffix}`;
|
|
1054
|
-
logger.log(title);
|
|
1055
|
-
for (const test of failed) {
|
|
1056
|
-
logger.log(c.red(` ${pointer} ${getFullName(test, c.dim(" > "))}`));
|
|
1057
|
-
(_d = (_c = test.result) == null ? void 0 : _c.errors) == null ? void 0 : _d.forEach((e) => {
|
|
1058
|
-
logger.log(c.red(` ${F_RIGHT} ${e == null ? void 0 : e.message}`));
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1098
|
+
if (task) {
|
|
1099
|
+
this.printTask(task);
|
|
1061
1100
|
}
|
|
1062
1101
|
}
|
|
1063
1102
|
}
|
|
1103
|
+
printTask(task) {
|
|
1104
|
+
var _a, _b, _c, _d;
|
|
1105
|
+
if (!("filepath" in task) || !((_a = task.result) == null ? void 0 : _a.state) || ((_b = task.result) == null ? void 0 : _b.state) === "run") {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const logger = this.ctx.logger;
|
|
1109
|
+
const tests = getTests(task);
|
|
1110
|
+
const failed = tests.filter((t) => {
|
|
1111
|
+
var _a2;
|
|
1112
|
+
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
|
|
1113
|
+
});
|
|
1114
|
+
const skipped = tests.filter(
|
|
1115
|
+
(t) => t.mode === "skip" || t.mode === "todo"
|
|
1116
|
+
);
|
|
1117
|
+
let state = c.dim(`${tests.length} test${tests.length > 1 ? "s" : ""}`);
|
|
1118
|
+
if (failed.length) {
|
|
1119
|
+
state += ` ${c.dim("|")} ${c.red(`${failed.length} failed`)}`;
|
|
1120
|
+
}
|
|
1121
|
+
if (skipped.length) {
|
|
1122
|
+
state += ` ${c.dim("|")} ${c.yellow(`${skipped.length} skipped`)}`;
|
|
1123
|
+
}
|
|
1124
|
+
let suffix = c.dim(" (") + state + c.dim(")");
|
|
1125
|
+
if (task.result.duration) {
|
|
1126
|
+
const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.gray;
|
|
1127
|
+
suffix += color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
|
|
1128
|
+
}
|
|
1129
|
+
if (this.ctx.config.logHeapUsage && task.result.heap != null) {
|
|
1130
|
+
suffix += c.magenta(
|
|
1131
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
let title = ` ${getStateSymbol(task)} `;
|
|
1135
|
+
if (task.projectName) {
|
|
1136
|
+
title += formatProjectName(task.projectName);
|
|
1137
|
+
}
|
|
1138
|
+
title += `${task.name} ${suffix}`;
|
|
1139
|
+
logger.log(title);
|
|
1140
|
+
for (const test of failed) {
|
|
1141
|
+
logger.log(c.red(` ${taskFail} ${getTestName(test, c.dim(" > "))}`));
|
|
1142
|
+
(_d = (_c = test.result) == null ? void 0 : _c.errors) == null ? void 0 : _d.forEach((e) => {
|
|
1143
|
+
logger.log(c.red(` ${F_RIGHT} ${e == null ? void 0 : e.message}`));
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1064
1147
|
onWatcherStart(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
1065
1148
|
this.resetLastRunLog();
|
|
1066
1149
|
const failed = errors.length > 0 || hasFailed(files);
|
|
1067
1150
|
const failedSnap = hasFailedSnapshot(files);
|
|
1068
1151
|
const cancelled = this.ctx.isCancelling;
|
|
1069
|
-
if (failed)
|
|
1152
|
+
if (failed) {
|
|
1070
1153
|
this.ctx.logger.log(WAIT_FOR_CHANGE_FAIL);
|
|
1071
|
-
else if (cancelled)
|
|
1154
|
+
} else if (cancelled) {
|
|
1072
1155
|
this.ctx.logger.log(WAIT_FOR_CHANGE_CANCELLED);
|
|
1073
|
-
else
|
|
1156
|
+
} else {
|
|
1074
1157
|
this.ctx.logger.log(WAIT_FOR_CHANGE_PASS);
|
|
1158
|
+
}
|
|
1075
1159
|
const hints = [];
|
|
1076
1160
|
hints.push(HELP_HINT);
|
|
1077
|
-
if (failedSnap)
|
|
1161
|
+
if (failedSnap) {
|
|
1078
1162
|
hints.unshift(HELP_UPDATE_SNAP);
|
|
1079
|
-
else
|
|
1163
|
+
} else {
|
|
1080
1164
|
hints.push(HELP_QUITE);
|
|
1165
|
+
}
|
|
1081
1166
|
this.ctx.logger.log(BADGE_PADDING + hints.join(c.dim(", ")));
|
|
1082
1167
|
if (this._lastRunCount) {
|
|
1083
1168
|
const LAST_RUN_TEXT = `rerun x${this._lastRunCount}`;
|
|
@@ -1089,16 +1174,16 @@ class BaseReporter {
|
|
|
1089
1174
|
this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]);
|
|
1090
1175
|
this._lastRunTimeout = 0;
|
|
1091
1176
|
const { setInterval } = getSafeTimers();
|
|
1092
|
-
this._lastRunTimer = setInterval(
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
);
|
|
1177
|
+
this._lastRunTimer = setInterval(() => {
|
|
1178
|
+
this._lastRunTimeout += 1;
|
|
1179
|
+
if (this._lastRunTimeout >= LAST_RUN_TEXTS.length) {
|
|
1180
|
+
this.resetLastRunLog();
|
|
1181
|
+
} else {
|
|
1182
|
+
this.ctx.logger.logUpdate(
|
|
1183
|
+
BADGE_PADDING + LAST_RUN_TEXTS[this._lastRunTimeout]
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
}, LAST_RUN_LOG_TIMEOUT / LAST_RUN_TEXTS.length);
|
|
1102
1187
|
}
|
|
1103
1188
|
}
|
|
1104
1189
|
resetLastRunLog() {
|
|
@@ -1110,132 +1195,216 @@ class BaseReporter {
|
|
|
1110
1195
|
onWatcherRerun(files, trigger) {
|
|
1111
1196
|
this.resetLastRunLog();
|
|
1112
1197
|
this.watchFilters = files;
|
|
1198
|
+
this.failedUnwatchedFiles = this.ctx.state.getFiles().filter((file) => {
|
|
1199
|
+
return !files.includes(file.filepath) && hasFailed(file);
|
|
1200
|
+
});
|
|
1113
1201
|
files.forEach((filepath) => {
|
|
1114
1202
|
let reruns = this._filesInWatchMode.get(filepath) ?? 0;
|
|
1115
1203
|
this._filesInWatchMode.set(filepath, ++reruns);
|
|
1116
1204
|
});
|
|
1117
1205
|
const BADGE = c.inverse(c.bold(c.blue(" RERUN ")));
|
|
1118
1206
|
const TRIGGER = trigger ? c.dim(` ${this.relative(trigger)}`) : "";
|
|
1119
|
-
const FILENAME_PATTERN = this.ctx.filenamePattern ? `${BADGE_PADDING} ${c.dim("Filename pattern: ")}${c.blue(
|
|
1207
|
+
const FILENAME_PATTERN = this.ctx.filenamePattern ? `${BADGE_PADDING} ${c.dim("Filename pattern: ")}${c.blue(
|
|
1208
|
+
this.ctx.filenamePattern
|
|
1209
|
+
)}
|
|
1120
1210
|
` : "";
|
|
1121
|
-
const TESTNAME_PATTERN = this.ctx.configOverride.testNamePattern ? `${BADGE_PADDING} ${c.dim("Test name pattern: ")}${c.blue(
|
|
1211
|
+
const TESTNAME_PATTERN = this.ctx.configOverride.testNamePattern ? `${BADGE_PADDING} ${c.dim("Test name pattern: ")}${c.blue(
|
|
1212
|
+
String(this.ctx.configOverride.testNamePattern)
|
|
1213
|
+
)}
|
|
1122
1214
|
` : "";
|
|
1123
|
-
const PROJECT_FILTER = this.ctx.configOverride.project ? `${BADGE_PADDING} ${c.dim("Project name: ")}${c.blue(
|
|
1215
|
+
const PROJECT_FILTER = this.ctx.configOverride.project ? `${BADGE_PADDING} ${c.dim("Project name: ")}${c.blue(
|
|
1216
|
+
toArray(this.ctx.configOverride.project).join(", ")
|
|
1217
|
+
)}
|
|
1124
1218
|
` : "";
|
|
1125
1219
|
if (files.length > 1 || !files.length) {
|
|
1126
|
-
this.ctx.logger.clearFullScreen(
|
|
1220
|
+
this.ctx.logger.clearFullScreen(
|
|
1221
|
+
`
|
|
1127
1222
|
${BADGE}${TRIGGER}
|
|
1128
|
-
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1223
|
+
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1224
|
+
);
|
|
1129
1225
|
this._lastRunCount = 0;
|
|
1130
1226
|
} else if (files.length === 1) {
|
|
1131
1227
|
const rerun = this._filesInWatchMode.get(files[0]) ?? 1;
|
|
1132
1228
|
this._lastRunCount = rerun;
|
|
1133
|
-
this.ctx.logger.clearFullScreen(
|
|
1134
|
-
|
|
1135
|
-
${
|
|
1229
|
+
this.ctx.logger.clearFullScreen(
|
|
1230
|
+
`
|
|
1231
|
+
${BADGE}${TRIGGER} ${c.blue(
|
|
1232
|
+
`x${rerun}`
|
|
1233
|
+
)}
|
|
1234
|
+
${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
if (!this.isTTY) {
|
|
1238
|
+
for (const task of this.failedUnwatchedFiles) {
|
|
1239
|
+
this.printTask(task);
|
|
1240
|
+
}
|
|
1136
1241
|
}
|
|
1137
1242
|
this._timeStart = /* @__PURE__ */ new Date();
|
|
1138
1243
|
this.start = performance.now();
|
|
1139
1244
|
}
|
|
1140
1245
|
onUserConsoleLog(log) {
|
|
1141
|
-
|
|
1246
|
+
var _a;
|
|
1247
|
+
if (!this.shouldLog(log)) {
|
|
1142
1248
|
return;
|
|
1249
|
+
}
|
|
1143
1250
|
const task = log.taskId ? this.ctx.state.idMap.get(log.taskId) : void 0;
|
|
1144
|
-
const header = c.gray(
|
|
1251
|
+
const header = c.gray(
|
|
1252
|
+
log.type + c.dim(
|
|
1253
|
+
` | ${task ? getFullName(task, c.dim(" > ")) : log.taskId !== UNKNOWN_TEST_ID ? log.taskId : "unknown test"}`
|
|
1254
|
+
)
|
|
1255
|
+
);
|
|
1145
1256
|
const output = log.type === "stdout" ? this.ctx.logger.outputStream : this.ctx.logger.errorStream;
|
|
1146
1257
|
const write = (msg) => output.write(msg);
|
|
1147
1258
|
write(`${header}
|
|
1148
1259
|
${log.content}`);
|
|
1149
1260
|
if (log.origin) {
|
|
1150
|
-
if (log.browser)
|
|
1261
|
+
if (log.browser) {
|
|
1151
1262
|
write("\n");
|
|
1263
|
+
}
|
|
1152
1264
|
const project = log.taskId ? this.ctx.getProjectByTaskId(log.taskId) : this.ctx.getCoreWorkspaceProject();
|
|
1153
|
-
const stack = parseStacktrace(log.origin
|
|
1154
|
-
getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
|
|
1155
|
-
frameFilter: project.config.onStackTrace
|
|
1156
|
-
});
|
|
1265
|
+
const stack = log.browser ? ((_a = project.browser) == null ? void 0 : _a.parseStacktrace(log.origin)) || [] : parseStacktrace(log.origin);
|
|
1157
1266
|
const highlight = task ? stack.find((i) => i.file === task.file.filepath) : null;
|
|
1158
1267
|
for (const frame of stack) {
|
|
1159
1268
|
const color = frame === highlight ? c.cyan : c.gray;
|
|
1160
1269
|
const path = relative(project.config.root, frame.file);
|
|
1161
|
-
write(
|
|
1162
|
-
|
|
1270
|
+
write(
|
|
1271
|
+
color(
|
|
1272
|
+
` ${c.dim(F_POINTER)} ${[
|
|
1273
|
+
frame.method,
|
|
1274
|
+
`${path}:${c.dim(`${frame.line}:${frame.column}`)}`
|
|
1275
|
+
].filter(Boolean).join(" ")}
|
|
1276
|
+
`
|
|
1277
|
+
)
|
|
1278
|
+
);
|
|
1163
1279
|
}
|
|
1164
1280
|
}
|
|
1165
1281
|
write("\n");
|
|
1166
1282
|
}
|
|
1167
1283
|
shouldLog(log) {
|
|
1168
1284
|
var _a, _b;
|
|
1169
|
-
if (this.ctx.config.silent)
|
|
1285
|
+
if (this.ctx.config.silent) {
|
|
1170
1286
|
return false;
|
|
1287
|
+
}
|
|
1171
1288
|
const shouldLog = (_b = (_a = this.ctx.config).onConsoleLog) == null ? void 0 : _b.call(_a, log.content, log.type);
|
|
1172
|
-
if (shouldLog === false)
|
|
1289
|
+
if (shouldLog === false) {
|
|
1173
1290
|
return shouldLog;
|
|
1291
|
+
}
|
|
1174
1292
|
return true;
|
|
1175
1293
|
}
|
|
1176
1294
|
onServerRestart(reason) {
|
|
1177
|
-
this.ctx.logger.log(
|
|
1178
|
-
|
|
1179
|
-
|
|
1295
|
+
this.ctx.logger.log(
|
|
1296
|
+
c.bold(
|
|
1297
|
+
c.magenta(
|
|
1298
|
+
reason === "config" ? "\nRestarting due to config changes..." : "\nRestarting Vitest..."
|
|
1299
|
+
)
|
|
1300
|
+
)
|
|
1301
|
+
);
|
|
1180
1302
|
}
|
|
1181
1303
|
reportSummary(files, errors) {
|
|
1182
1304
|
this.printErrorsSummary(files, errors);
|
|
1183
|
-
if (this.mode === "benchmark")
|
|
1305
|
+
if (this.mode === "benchmark") {
|
|
1184
1306
|
this.reportBenchmarkSummary(files);
|
|
1185
|
-
else
|
|
1307
|
+
} else {
|
|
1186
1308
|
this.reportTestSummary(files, errors);
|
|
1309
|
+
}
|
|
1187
1310
|
}
|
|
1188
1311
|
reportTestSummary(files, errors) {
|
|
1189
|
-
const
|
|
1312
|
+
const affectedFiles = [
|
|
1313
|
+
...this.failedUnwatchedFiles,
|
|
1314
|
+
...files
|
|
1315
|
+
];
|
|
1316
|
+
const tests = getTests(affectedFiles);
|
|
1190
1317
|
const logger = this.ctx.logger;
|
|
1191
1318
|
const executionTime = this.end - this.start;
|
|
1192
|
-
const collectTime = files.reduce(
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1319
|
+
const collectTime = files.reduce(
|
|
1320
|
+
(acc, test) => acc + Math.max(0, test.collectDuration || 0),
|
|
1321
|
+
0
|
|
1322
|
+
);
|
|
1323
|
+
const setupTime = files.reduce(
|
|
1324
|
+
(acc, test) => acc + Math.max(0, test.setupDuration || 0),
|
|
1325
|
+
0
|
|
1326
|
+
);
|
|
1327
|
+
const testsTime = files.reduce(
|
|
1328
|
+
(acc, test) => {
|
|
1329
|
+
var _a;
|
|
1330
|
+
return acc + Math.max(0, ((_a = test.result) == null ? void 0 : _a.duration) || 0);
|
|
1331
|
+
},
|
|
1332
|
+
0
|
|
1333
|
+
);
|
|
1198
1334
|
const transformTime = this.ctx.projects.flatMap((w) => w.vitenode.getTotalDuration()).reduce((a, b) => a + b, 0);
|
|
1199
|
-
const environmentTime = files.reduce(
|
|
1200
|
-
|
|
1335
|
+
const environmentTime = files.reduce(
|
|
1336
|
+
(acc, file) => acc + Math.max(0, file.environmentLoad || 0),
|
|
1337
|
+
0
|
|
1338
|
+
);
|
|
1339
|
+
const prepareTime = files.reduce(
|
|
1340
|
+
(acc, file) => acc + Math.max(0, file.prepareDuration || 0),
|
|
1341
|
+
0
|
|
1342
|
+
);
|
|
1201
1343
|
const threadTime = collectTime + testsTime + setupTime;
|
|
1202
1344
|
const padTitle = (str) => c.dim(`${str.padStart(11)} `);
|
|
1203
1345
|
const time = (time2) => {
|
|
1204
|
-
if (time2 > 1e3)
|
|
1346
|
+
if (time2 > 1e3) {
|
|
1205
1347
|
return `${(time2 / 1e3).toFixed(2)}s`;
|
|
1348
|
+
}
|
|
1206
1349
|
return `${Math.round(time2)}ms`;
|
|
1207
1350
|
};
|
|
1208
|
-
const snapshotOutput = renderSnapshotSummary(
|
|
1351
|
+
const snapshotOutput = renderSnapshotSummary(
|
|
1352
|
+
this.ctx.config.root,
|
|
1353
|
+
this.ctx.snapshot.summary
|
|
1354
|
+
);
|
|
1209
1355
|
if (snapshotOutput.length) {
|
|
1210
|
-
logger.log(
|
|
1211
|
-
(
|
|
1212
|
-
|
|
1213
|
-
|
|
1356
|
+
logger.log(
|
|
1357
|
+
snapshotOutput.map(
|
|
1358
|
+
(t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`
|
|
1359
|
+
).join("\n")
|
|
1360
|
+
);
|
|
1361
|
+
if (snapshotOutput.length > 1) {
|
|
1214
1362
|
logger.log();
|
|
1363
|
+
}
|
|
1215
1364
|
}
|
|
1216
|
-
logger.log(padTitle("Test Files"), getStateString(
|
|
1365
|
+
logger.log(padTitle("Test Files"), getStateString(affectedFiles));
|
|
1217
1366
|
logger.log(padTitle("Tests"), getStateString(tests));
|
|
1218
1367
|
if (this.ctx.projects.some((c2) => c2.config.typecheck.enabled)) {
|
|
1219
|
-
const failed = tests.filter(
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1368
|
+
const failed = tests.filter(
|
|
1369
|
+
(t) => {
|
|
1370
|
+
var _a, _b, _c;
|
|
1371
|
+
return ((_a = t.meta) == null ? void 0 : _a.typecheck) && ((_c = (_b = t.result) == null ? void 0 : _b.errors) == null ? void 0 : _c.length);
|
|
1372
|
+
}
|
|
1373
|
+
);
|
|
1374
|
+
logger.log(
|
|
1375
|
+
padTitle("Type Errors"),
|
|
1376
|
+
failed.length ? c.bold(c.red(`${failed.length} failed`)) : c.dim("no errors")
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
if (errors.length) {
|
|
1380
|
+
logger.log(
|
|
1381
|
+
padTitle("Errors"),
|
|
1382
|
+
c.bold(c.red(`${errors.length} error${errors.length > 1 ? "s" : ""}`))
|
|
1383
|
+
);
|
|
1224
1384
|
}
|
|
1225
|
-
if (errors.length)
|
|
1226
|
-
logger.log(padTitle("Errors"), c.bold(c.red(`${errors.length} error${errors.length > 1 ? "s" : ""}`)));
|
|
1227
1385
|
logger.log(padTitle("Start at"), formatTimeString(this._timeStart));
|
|
1228
1386
|
if (this.watchFilters) {
|
|
1229
1387
|
logger.log(padTitle("Duration"), time(threadTime));
|
|
1230
1388
|
} else {
|
|
1231
|
-
let timers = `transform ${time(transformTime)}, setup ${time(
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
},
|
|
1236
|
-
|
|
1389
|
+
let timers = `transform ${time(transformTime)}, setup ${time(
|
|
1390
|
+
setupTime
|
|
1391
|
+
)}, collect ${time(collectTime)}, tests ${time(
|
|
1392
|
+
testsTime
|
|
1393
|
+
)}, environment ${time(environmentTime)}, prepare ${time(prepareTime)}`;
|
|
1394
|
+
const typecheck = this.ctx.projects.reduce(
|
|
1395
|
+
(acc, c2) => {
|
|
1396
|
+
var _a;
|
|
1397
|
+
return acc + (((_a = c2.typechecker) == null ? void 0 : _a.getResult().time) || 0);
|
|
1398
|
+
},
|
|
1399
|
+
0
|
|
1400
|
+
);
|
|
1401
|
+
if (typecheck) {
|
|
1237
1402
|
timers += `, typecheck ${time(typecheck)}`;
|
|
1238
|
-
|
|
1403
|
+
}
|
|
1404
|
+
logger.log(
|
|
1405
|
+
padTitle("Duration"),
|
|
1406
|
+
time(executionTime) + c.dim(` (${timers})`)
|
|
1407
|
+
);
|
|
1239
1408
|
}
|
|
1240
1409
|
logger.log();
|
|
1241
1410
|
}
|
|
@@ -1253,15 +1422,27 @@ ${log.content}`);
|
|
|
1253
1422
|
});
|
|
1254
1423
|
const failedTotal = countTestErrors(failedSuites) + countTestErrors(failedTests);
|
|
1255
1424
|
let current = 1;
|
|
1256
|
-
const errorDivider = () => logger.error(
|
|
1257
|
-
|
|
1425
|
+
const errorDivider = () => logger.error(
|
|
1426
|
+
`${c.red(
|
|
1427
|
+
c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1))
|
|
1428
|
+
)}
|
|
1429
|
+
`
|
|
1430
|
+
);
|
|
1258
1431
|
if (failedSuites.length) {
|
|
1259
|
-
logger.error(
|
|
1432
|
+
logger.error(
|
|
1433
|
+
c.red(
|
|
1434
|
+
divider(c.bold(c.inverse(` Failed Suites ${failedSuites.length} `)))
|
|
1435
|
+
)
|
|
1436
|
+
);
|
|
1260
1437
|
logger.error();
|
|
1261
1438
|
this.printTaskErrors(failedSuites, errorDivider);
|
|
1262
1439
|
}
|
|
1263
1440
|
if (failedTests.length) {
|
|
1264
|
-
logger.error(
|
|
1441
|
+
logger.error(
|
|
1442
|
+
c.red(
|
|
1443
|
+
divider(c.bold(c.inverse(` Failed Tests ${failedTests.length} `)))
|
|
1444
|
+
)
|
|
1445
|
+
);
|
|
1265
1446
|
logger.error();
|
|
1266
1447
|
this.printTaskErrors(failedTests, errorDivider);
|
|
1267
1448
|
}
|
|
@@ -1278,13 +1459,16 @@ ${log.content}`);
|
|
|
1278
1459
|
var _a, _b;
|
|
1279
1460
|
return ((_b = (_a = i.result) == null ? void 0 : _a.benchmark) == null ? void 0 : _b.rank) === 1;
|
|
1280
1461
|
});
|
|
1281
|
-
logger.log(
|
|
1462
|
+
logger.log(
|
|
1463
|
+
`
|
|
1282
1464
|
${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
1283
|
-
`
|
|
1465
|
+
`
|
|
1466
|
+
);
|
|
1284
1467
|
for (const bench of topBenches) {
|
|
1285
1468
|
const group = bench.suite || bench.file;
|
|
1286
|
-
if (!group)
|
|
1469
|
+
if (!group) {
|
|
1287
1470
|
continue;
|
|
1471
|
+
}
|
|
1288
1472
|
const groupName = getFullName(group, c.dim(" > "));
|
|
1289
1473
|
logger.log(` ${bench.name}${c.dim(` - ${groupName}`)}`);
|
|
1290
1474
|
const siblings = group.tasks.filter((i) => {
|
|
@@ -1297,7 +1481,9 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1297
1481
|
}
|
|
1298
1482
|
for (const sibling of siblings) {
|
|
1299
1483
|
const number = `${(sibling.result.benchmark.mean / bench.result.benchmark.mean).toFixed(2)}x`;
|
|
1300
|
-
logger.log(
|
|
1484
|
+
logger.log(
|
|
1485
|
+
` ${c.green(number)} ${c.gray("faster than")} ${sibling.name}`
|
|
1486
|
+
);
|
|
1301
1487
|
}
|
|
1302
1488
|
logger.log("");
|
|
1303
1489
|
}
|
|
@@ -1310,16 +1496,18 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1310
1496
|
const errorItem = (error == null ? void 0 : error.stackStr) && errorsQueue.find((i) => {
|
|
1311
1497
|
var _a2, _b2, _c2, _d;
|
|
1312
1498
|
const hasStr = ((_a2 = i[0]) == null ? void 0 : _a2.stackStr) === error.stackStr;
|
|
1313
|
-
if (!hasStr)
|
|
1499
|
+
if (!hasStr) {
|
|
1314
1500
|
return false;
|
|
1501
|
+
}
|
|
1315
1502
|
const currentProjectName = (task == null ? void 0 : task.projectName) || ((_b2 = task.file) == null ? void 0 : _b2.projectName) || "";
|
|
1316
1503
|
const projectName = ((_c2 = i[1][0]) == null ? void 0 : _c2.projectName) || ((_d = i[1][0].file) == null ? void 0 : _d.projectName) || "";
|
|
1317
1504
|
return projectName === currentProjectName;
|
|
1318
1505
|
});
|
|
1319
|
-
if (errorItem)
|
|
1506
|
+
if (errorItem) {
|
|
1320
1507
|
errorItem[1].push(task);
|
|
1321
|
-
else
|
|
1508
|
+
} else {
|
|
1322
1509
|
errorsQueue.push([error, [task]]);
|
|
1510
|
+
}
|
|
1323
1511
|
});
|
|
1324
1512
|
}
|
|
1325
1513
|
for (const [error, tasks2] of errorsQueue) {
|
|
@@ -1327,21 +1515,41 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1327
1515
|
const filepath = (task == null ? void 0 : task.filepath) || "";
|
|
1328
1516
|
const projectName = (task == null ? void 0 : task.projectName) || ((_c = task.file) == null ? void 0 : _c.projectName) || "";
|
|
1329
1517
|
let name = getFullName(task, c.dim(" > "));
|
|
1330
|
-
if (filepath)
|
|
1518
|
+
if (filepath) {
|
|
1331
1519
|
name = `${name} ${c.dim(`[ ${this.relative(filepath)} ]`)}`;
|
|
1332
|
-
|
|
1520
|
+
}
|
|
1521
|
+
this.ctx.logger.error(
|
|
1522
|
+
`${c.red(c.bold(c.inverse(" FAIL ")))} ${formatProjectName(
|
|
1523
|
+
projectName
|
|
1524
|
+
)}${name}`
|
|
1525
|
+
);
|
|
1333
1526
|
}
|
|
1527
|
+
const screenshots = tasks2.filter((t) => {
|
|
1528
|
+
var _a2;
|
|
1529
|
+
return (_a2 = t.meta) == null ? void 0 : _a2.failScreenshotPath;
|
|
1530
|
+
}).map((t) => {
|
|
1531
|
+
var _a2;
|
|
1532
|
+
return (_a2 = t.meta) == null ? void 0 : _a2.failScreenshotPath;
|
|
1533
|
+
});
|
|
1334
1534
|
const project = this.ctx.getProjectByTaskId(tasks2[0].id);
|
|
1335
|
-
this.ctx.logger.printError(error, {
|
|
1535
|
+
this.ctx.logger.printError(error, {
|
|
1536
|
+
project,
|
|
1537
|
+
verbose: this.verbose,
|
|
1538
|
+
screenshotPaths: screenshots,
|
|
1539
|
+
task: tasks2[0]
|
|
1540
|
+
});
|
|
1336
1541
|
errorDivider();
|
|
1337
1542
|
}
|
|
1338
1543
|
}
|
|
1339
1544
|
registerUnhandledRejection() {
|
|
1340
1545
|
const onUnhandledRejection = async (err) => {
|
|
1341
1546
|
process.exitCode = 1;
|
|
1342
|
-
this.ctx.logger.printError(err, {
|
|
1547
|
+
this.ctx.logger.printError(err, {
|
|
1548
|
+
fullStack: true,
|
|
1549
|
+
type: "Unhandled Rejection"
|
|
1550
|
+
});
|
|
1343
1551
|
this.ctx.logger.error("\n\n");
|
|
1344
|
-
process.exit(
|
|
1552
|
+
process.exit();
|
|
1345
1553
|
};
|
|
1346
1554
|
process.on("unhandledRejection", onUnhandledRejection);
|
|
1347
1555
|
this._offUnhandledRejection = () => {
|
|
@@ -1351,7 +1559,10 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
|
|
|
1351
1559
|
}
|
|
1352
1560
|
|
|
1353
1561
|
class BasicReporter extends BaseReporter {
|
|
1354
|
-
|
|
1562
|
+
constructor() {
|
|
1563
|
+
super();
|
|
1564
|
+
this.isTTY = false;
|
|
1565
|
+
}
|
|
1355
1566
|
reportSummary(files, errors) {
|
|
1356
1567
|
this.ctx.logger.log();
|
|
1357
1568
|
return super.reportSummary(files, errors);
|
|
@@ -2258,8 +2469,9 @@ function formatFilepath$1(path) {
|
|
|
2258
2469
|
const lastSlash = Math.max(path.lastIndexOf("/") + 1, 0);
|
|
2259
2470
|
const basename = path.slice(lastSlash);
|
|
2260
2471
|
let firstDot = basename.indexOf(".");
|
|
2261
|
-
if (firstDot < 0)
|
|
2472
|
+
if (firstDot < 0) {
|
|
2262
2473
|
firstDot = basename.length;
|
|
2474
|
+
}
|
|
2263
2475
|
firstDot += lastSlash;
|
|
2264
2476
|
return c.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + c.dim(path.slice(firstDot));
|
|
2265
2477
|
}
|
|
@@ -2270,8 +2482,11 @@ function formatNumber$1(number) {
|
|
|
2270
2482
|
function renderHookState(task, hookName, level = 0) {
|
|
2271
2483
|
var _a, _b;
|
|
2272
2484
|
const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
|
|
2273
|
-
if (state && state === "run")
|
|
2274
|
-
return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${c.dim(
|
|
2485
|
+
if (state && state === "run") {
|
|
2486
|
+
return `${" ".repeat(level)} ${getHookStateSymbol(task, hookName)} ${c.dim(
|
|
2487
|
+
`[ ${hookName} ]`
|
|
2488
|
+
)}`;
|
|
2489
|
+
}
|
|
2275
2490
|
return "";
|
|
2276
2491
|
}
|
|
2277
2492
|
function renderBenchmarkItems$1(result) {
|
|
@@ -2286,8 +2501,9 @@ function renderBenchmarkItems$1(result) {
|
|
|
2286
2501
|
function renderBenchmark$1(task, tasks) {
|
|
2287
2502
|
var _a;
|
|
2288
2503
|
const result = (_a = task.result) == null ? void 0 : _a.benchmark;
|
|
2289
|
-
if (!result)
|
|
2504
|
+
if (!result) {
|
|
2290
2505
|
return task.name;
|
|
2506
|
+
}
|
|
2291
2507
|
const benches = tasks.map((i) => {
|
|
2292
2508
|
var _a2, _b;
|
|
2293
2509
|
return ((_a2 = i.meta) == null ? void 0 : _a2.benchmark) ? (_b = i.result) == null ? void 0 : _b.benchmark : void 0;
|
|
@@ -2317,27 +2533,38 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2317
2533
|
const taskOutput = [];
|
|
2318
2534
|
let suffix = "";
|
|
2319
2535
|
let prefix = ` ${getStateSymbol(task)} `;
|
|
2320
|
-
if (level === 0 && task.type === "suite" && "projectName" in task)
|
|
2536
|
+
if (level === 0 && task.type === "suite" && "projectName" in task) {
|
|
2321
2537
|
prefix += formatProjectName(task.projectName);
|
|
2322
|
-
|
|
2538
|
+
}
|
|
2539
|
+
if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.retryCount) && task.result.retryCount > 0) {
|
|
2323
2540
|
suffix += c.yellow(` (retry x${task.result.retryCount})`);
|
|
2541
|
+
}
|
|
2324
2542
|
if (task.type === "suite") {
|
|
2325
2543
|
const tests = getTests(task);
|
|
2326
2544
|
suffix += c.dim(` (${tests.length})`);
|
|
2327
2545
|
}
|
|
2328
|
-
if (task.mode === "skip" || task.mode === "todo")
|
|
2546
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
2329
2547
|
suffix += ` ${c.dim(c.gray("[skipped]"))}`;
|
|
2330
|
-
|
|
2548
|
+
}
|
|
2549
|
+
if (task.type === "test" && ((_b = task.result) == null ? void 0 : _b.repeatCount) && task.result.repeatCount > 0) {
|
|
2331
2550
|
suffix += c.yellow(` (repeat x${task.result.repeatCount})`);
|
|
2551
|
+
}
|
|
2332
2552
|
if (((_c = task.result) == null ? void 0 : _c.duration) != null) {
|
|
2333
|
-
if (task.result.duration > options.slowTestThreshold)
|
|
2334
|
-
suffix += c.yellow(
|
|
2553
|
+
if (task.result.duration > options.slowTestThreshold) {
|
|
2554
|
+
suffix += c.yellow(
|
|
2555
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
2556
|
+
);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
if (options.showHeap && ((_d = task.result) == null ? void 0 : _d.heap) != null) {
|
|
2560
|
+
suffix += c.magenta(
|
|
2561
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
2562
|
+
);
|
|
2335
2563
|
}
|
|
2336
|
-
if (options.showHeap && ((_d = task.result) == null ? void 0 : _d.heap) != null)
|
|
2337
|
-
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
2338
2564
|
let name = task.name;
|
|
2339
|
-
if (level === 0)
|
|
2565
|
+
if (level === 0) {
|
|
2340
2566
|
name = formatFilepath$1(name);
|
|
2567
|
+
}
|
|
2341
2568
|
const padding = " ".repeat(level);
|
|
2342
2569
|
const body = ((_e = task.meta) == null ? void 0 : _e.benchmark) ? renderBenchmark$1(task, tasks) : name;
|
|
2343
2570
|
taskOutput.push(padding + prefix + body + suffix);
|
|
@@ -2345,8 +2572,9 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2345
2572
|
let data = outputMap$1.get(task);
|
|
2346
2573
|
if (typeof data === "string") {
|
|
2347
2574
|
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
2348
|
-
if (data === "")
|
|
2575
|
+
if (data === "") {
|
|
2349
2576
|
data = void 0;
|
|
2577
|
+
}
|
|
2350
2578
|
}
|
|
2351
2579
|
if (data != null) {
|
|
2352
2580
|
const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
|
|
@@ -2358,8 +2586,12 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2358
2586
|
if (task.type === "suite" && task.tasks.length > 0) {
|
|
2359
2587
|
if (((_g = task.result) == null ? void 0 : _g.state) === "fail" || ((_h = task.result) == null ? void 0 : _h.state) === "run" || options.renderSucceed) {
|
|
2360
2588
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2361
|
-
const filteredTasks = task.tasks.filter(
|
|
2362
|
-
|
|
2589
|
+
const filteredTasks = task.tasks.filter(
|
|
2590
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2591
|
+
);
|
|
2592
|
+
taskOutput.push(
|
|
2593
|
+
renderTree$1(filteredTasks, options, level + 1, maxRows)
|
|
2594
|
+
);
|
|
2363
2595
|
} else {
|
|
2364
2596
|
taskOutput.push(renderTree$1(task.tasks, options, level + 1, maxRows));
|
|
2365
2597
|
}
|
|
@@ -2370,8 +2602,9 @@ function renderTree$1(tasks, options, level = 0, maxRows) {
|
|
|
2370
2602
|
const rows = taskOutput.filter(Boolean);
|
|
2371
2603
|
output.push(rows.join("\n"));
|
|
2372
2604
|
currentRowCount += rows.length;
|
|
2373
|
-
if (maxRows && currentRowCount >= maxRows)
|
|
2605
|
+
if (maxRows && currentRowCount >= maxRows) {
|
|
2374
2606
|
break;
|
|
2607
|
+
}
|
|
2375
2608
|
}
|
|
2376
2609
|
return output.reverse().join("\n");
|
|
2377
2610
|
}
|
|
@@ -2381,30 +2614,37 @@ function createListRenderer(_tasks, options) {
|
|
|
2381
2614
|
const log = options.logger.logUpdate;
|
|
2382
2615
|
function update() {
|
|
2383
2616
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2384
|
-
const filteredTasks = tasks.filter(
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2617
|
+
const filteredTasks = tasks.filter(
|
|
2618
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2619
|
+
);
|
|
2620
|
+
log(
|
|
2621
|
+
renderTree$1(
|
|
2622
|
+
filteredTasks,
|
|
2623
|
+
options,
|
|
2624
|
+
0,
|
|
2625
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
2626
|
+
// but we can optimize performance by doing it ourselves
|
|
2627
|
+
process.stdout.rows
|
|
2628
|
+
)
|
|
2629
|
+
);
|
|
2393
2630
|
} else {
|
|
2394
|
-
log(
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2631
|
+
log(
|
|
2632
|
+
renderTree$1(
|
|
2633
|
+
tasks,
|
|
2634
|
+
options,
|
|
2635
|
+
0,
|
|
2636
|
+
// log-update already limits the amount of printed rows to fit the current terminal
|
|
2637
|
+
// but we can optimize performance by doing it ourselves
|
|
2638
|
+
process.stdout.rows
|
|
2639
|
+
)
|
|
2640
|
+
);
|
|
2402
2641
|
}
|
|
2403
2642
|
}
|
|
2404
2643
|
return {
|
|
2405
2644
|
start() {
|
|
2406
|
-
if (timer)
|
|
2645
|
+
if (timer) {
|
|
2407
2646
|
return this;
|
|
2647
|
+
}
|
|
2408
2648
|
timer = setInterval(update, 16);
|
|
2409
2649
|
return this;
|
|
2410
2650
|
},
|
|
@@ -2419,7 +2659,9 @@ function createListRenderer(_tasks, options) {
|
|
|
2419
2659
|
}
|
|
2420
2660
|
log.clear();
|
|
2421
2661
|
if (options.logger.ctx.config.hideSkippedTests) {
|
|
2422
|
-
const filteredTasks = tasks.filter(
|
|
2662
|
+
const filteredTasks = tasks.filter(
|
|
2663
|
+
(t) => t.mode !== "skip" && t.mode !== "todo"
|
|
2664
|
+
);
|
|
2423
2665
|
options.logger.log(renderTree$1(filteredTasks, options));
|
|
2424
2666
|
} else {
|
|
2425
2667
|
options.logger.log(renderTree$1(tasks, options));
|
|
@@ -2438,16 +2680,21 @@ class DefaultReporter extends BaseReporter {
|
|
|
2438
2680
|
renderSucceedDefault;
|
|
2439
2681
|
onPathsCollected(paths = []) {
|
|
2440
2682
|
if (this.isTTY) {
|
|
2441
|
-
if (this.renderSucceedDefault === void 0)
|
|
2683
|
+
if (this.renderSucceedDefault === void 0) {
|
|
2442
2684
|
this.renderSucceedDefault = !!this.rendererOptions.renderSucceed;
|
|
2443
|
-
|
|
2685
|
+
}
|
|
2686
|
+
if (this.renderSucceedDefault !== true) {
|
|
2444
2687
|
this.rendererOptions.renderSucceed = paths.length <= 1;
|
|
2688
|
+
}
|
|
2445
2689
|
}
|
|
2446
2690
|
}
|
|
2447
2691
|
async onTestRemoved(trigger) {
|
|
2448
2692
|
this.stopListRender();
|
|
2449
|
-
this.ctx.logger.clearScreen(
|
|
2450
|
-
|
|
2693
|
+
this.ctx.logger.clearScreen(
|
|
2694
|
+
c.yellow("Test removed...") + (trigger ? c.dim(` [ ${this.relative(trigger)} ]
|
|
2695
|
+
`) : ""),
|
|
2696
|
+
true
|
|
2697
|
+
);
|
|
2451
2698
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2452
2699
|
createListRenderer(files, this.rendererOptions).stop();
|
|
2453
2700
|
this.ctx.logger.log();
|
|
@@ -2461,13 +2708,19 @@ class DefaultReporter extends BaseReporter {
|
|
|
2461
2708
|
this.rendererOptions.slowTestThreshold = this.ctx.config.slowTestThreshold;
|
|
2462
2709
|
this.rendererOptions.mode = this.mode;
|
|
2463
2710
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2464
|
-
if (!this.renderer)
|
|
2711
|
+
if (!this.renderer) {
|
|
2465
2712
|
this.renderer = createListRenderer(files, this.rendererOptions).start();
|
|
2466
|
-
else
|
|
2713
|
+
} else {
|
|
2467
2714
|
this.renderer.update(files);
|
|
2715
|
+
}
|
|
2468
2716
|
}
|
|
2469
2717
|
}
|
|
2470
2718
|
onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
2719
|
+
var _a;
|
|
2720
|
+
(_a = this.renderer) == null ? void 0 : _a.update([
|
|
2721
|
+
...this.failedUnwatchedFiles,
|
|
2722
|
+
...files
|
|
2723
|
+
]);
|
|
2471
2724
|
this.stopListRender();
|
|
2472
2725
|
this.ctx.logger.log();
|
|
2473
2726
|
super.onFinished(files, errors);
|
|
@@ -2487,8 +2740,9 @@ class DefaultReporter extends BaseReporter {
|
|
|
2487
2740
|
}
|
|
2488
2741
|
onUserConsoleLog(log) {
|
|
2489
2742
|
var _a;
|
|
2490
|
-
if (!this.shouldLog(log))
|
|
2743
|
+
if (!this.shouldLog(log)) {
|
|
2491
2744
|
return;
|
|
2745
|
+
}
|
|
2492
2746
|
(_a = this.renderer) == null ? void 0 : _a.clear();
|
|
2493
2747
|
super.onUserConsoleLog(log);
|
|
2494
2748
|
}
|
|
@@ -2500,8 +2754,9 @@ const pending = { char: "*", color: c.yellow };
|
|
|
2500
2754
|
const skip = { char: "-", color: (char) => c.dim(c.gray(char)) };
|
|
2501
2755
|
function getIcon(task) {
|
|
2502
2756
|
var _a;
|
|
2503
|
-
if (task.mode === "skip" || task.mode === "todo")
|
|
2757
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
2504
2758
|
return skip;
|
|
2759
|
+
}
|
|
2505
2760
|
switch ((_a = task.result) == null ? void 0 : _a.state) {
|
|
2506
2761
|
case "pass":
|
|
2507
2762
|
return check;
|
|
@@ -2563,8 +2818,9 @@ function createDotRenderer(_tasks, options) {
|
|
|
2563
2818
|
}
|
|
2564
2819
|
return {
|
|
2565
2820
|
start() {
|
|
2566
|
-
if (timer)
|
|
2821
|
+
if (timer) {
|
|
2567
2822
|
return this;
|
|
2823
|
+
}
|
|
2568
2824
|
timer = setInterval(update, 16);
|
|
2569
2825
|
return this;
|
|
2570
2826
|
},
|
|
@@ -2592,10 +2848,13 @@ class DotReporter extends BaseReporter {
|
|
|
2592
2848
|
onCollected() {
|
|
2593
2849
|
if (this.isTTY) {
|
|
2594
2850
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
2595
|
-
if (!this.renderer)
|
|
2596
|
-
this.renderer = createDotRenderer(files, {
|
|
2597
|
-
|
|
2851
|
+
if (!this.renderer) {
|
|
2852
|
+
this.renderer = createDotRenderer(files, {
|
|
2853
|
+
logger: this.ctx.logger
|
|
2854
|
+
}).start();
|
|
2855
|
+
} else {
|
|
2598
2856
|
this.renderer.update(files);
|
|
2857
|
+
}
|
|
2599
2858
|
}
|
|
2600
2859
|
}
|
|
2601
2860
|
async onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
|
|
@@ -2654,34 +2913,50 @@ class JsonReporter {
|
|
|
2654
2913
|
return (_a2 = s.result) == null ? void 0 : _a2.errors;
|
|
2655
2914
|
}).length;
|
|
2656
2915
|
const numPassedTestSuites = numTotalTestSuites - numFailedTestSuites;
|
|
2657
|
-
const numPendingTestSuites = suites.filter(
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2916
|
+
const numPendingTestSuites = suites.filter(
|
|
2917
|
+
(s) => {
|
|
2918
|
+
var _a2;
|
|
2919
|
+
return ((_a2 = s.result) == null ? void 0 : _a2.state) === "run";
|
|
2920
|
+
}
|
|
2921
|
+
).length;
|
|
2922
|
+
const numFailedTests = tests.filter(
|
|
2923
|
+
(t) => {
|
|
2924
|
+
var _a2;
|
|
2925
|
+
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
|
|
2926
|
+
}
|
|
2927
|
+
).length;
|
|
2665
2928
|
const numPassedTests = numTotalTests - numFailedTests;
|
|
2666
|
-
const numPendingTests = tests.filter(
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2929
|
+
const numPendingTests = tests.filter(
|
|
2930
|
+
(t) => {
|
|
2931
|
+
var _a2;
|
|
2932
|
+
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
|
|
2933
|
+
}
|
|
2934
|
+
).length;
|
|
2670
2935
|
const numTodoTests = tests.filter((t) => t.mode === "todo").length;
|
|
2671
2936
|
const testResults = [];
|
|
2672
2937
|
const success = numFailedTestSuites === 0 && numFailedTests === 0;
|
|
2673
2938
|
for (const file of files) {
|
|
2674
2939
|
const tests2 = getTests([file]);
|
|
2675
|
-
let startTime = tests2.reduce(
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2940
|
+
let startTime = tests2.reduce(
|
|
2941
|
+
(prev, next) => {
|
|
2942
|
+
var _a2;
|
|
2943
|
+
return Math.min(prev, ((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? Number.POSITIVE_INFINITY);
|
|
2944
|
+
},
|
|
2945
|
+
Number.POSITIVE_INFINITY
|
|
2946
|
+
);
|
|
2947
|
+
if (startTime === Number.POSITIVE_INFINITY) {
|
|
2680
2948
|
startTime = this.start;
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2949
|
+
}
|
|
2950
|
+
const endTime = tests2.reduce(
|
|
2951
|
+
(prev, next) => {
|
|
2952
|
+
var _a2, _b2;
|
|
2953
|
+
return Math.max(
|
|
2954
|
+
prev,
|
|
2955
|
+
(((_a2 = next.result) == null ? void 0 : _a2.startTime) ?? 0) + (((_b2 = next.result) == null ? void 0 : _b2.duration) ?? 0)
|
|
2956
|
+
);
|
|
2957
|
+
},
|
|
2958
|
+
startTime
|
|
2959
|
+
);
|
|
2685
2960
|
const assertionResults = tests2.map((t) => {
|
|
2686
2961
|
var _a2, _b2, _c2, _d2;
|
|
2687
2962
|
const ancestorTitles = [];
|
|
@@ -2706,7 +2981,9 @@ class JsonReporter {
|
|
|
2706
2981
|
var _a2;
|
|
2707
2982
|
return ((_a2 = t.result) == null ? void 0 : _a2.state) === "run";
|
|
2708
2983
|
})) {
|
|
2709
|
-
this.ctx.logger.warn(
|
|
2984
|
+
this.ctx.logger.warn(
|
|
2985
|
+
"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"
|
|
2986
|
+
);
|
|
2710
2987
|
}
|
|
2711
2988
|
const hasFailedTests = tests2.some((t) => {
|
|
2712
2989
|
var _a2;
|
|
@@ -2751,8 +3028,9 @@ class JsonReporter {
|
|
|
2751
3028
|
if (outputFile) {
|
|
2752
3029
|
const reportFile = resolve(this.ctx.config.root, outputFile);
|
|
2753
3030
|
const outputDirectory = dirname(reportFile);
|
|
2754
|
-
if (!existsSync(outputDirectory))
|
|
3031
|
+
if (!existsSync(outputDirectory)) {
|
|
2755
3032
|
await promises.mkdir(outputDirectory, { recursive: true });
|
|
3033
|
+
}
|
|
2756
3034
|
await promises.writeFile(reportFile, report, "utf-8");
|
|
2757
3035
|
this.ctx.logger.log(`JSON report written to ${reportFile}`);
|
|
2758
3036
|
} else {
|
|
@@ -2762,25 +3040,34 @@ class JsonReporter {
|
|
|
2762
3040
|
}
|
|
2763
3041
|
|
|
2764
3042
|
class VerboseReporter extends DefaultReporter {
|
|
3043
|
+
verbose = true;
|
|
2765
3044
|
constructor() {
|
|
2766
3045
|
super();
|
|
2767
3046
|
this.rendererOptions.renderSucceed = true;
|
|
2768
3047
|
}
|
|
2769
3048
|
onTaskUpdate(packs) {
|
|
2770
3049
|
var _a, _b, _c;
|
|
2771
|
-
if (this.isTTY)
|
|
3050
|
+
if (this.isTTY) {
|
|
2772
3051
|
return;
|
|
3052
|
+
}
|
|
2773
3053
|
for (const pack of packs) {
|
|
2774
3054
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
2775
3055
|
if (task && task.type === "test" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
|
|
2776
3056
|
let title = ` ${getStateSymbol(task)} `;
|
|
2777
|
-
if (task.file.projectName)
|
|
3057
|
+
if (task.file.projectName) {
|
|
2778
3058
|
title += formatProjectName(task.file.projectName);
|
|
3059
|
+
}
|
|
2779
3060
|
title += getFullName(task, c.dim(" > "));
|
|
2780
|
-
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold)
|
|
2781
|
-
title += c.yellow(
|
|
2782
|
-
|
|
2783
|
-
|
|
3061
|
+
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold) {
|
|
3062
|
+
title += c.yellow(
|
|
3063
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
3064
|
+
);
|
|
3065
|
+
}
|
|
3066
|
+
if (this.ctx.config.logHeapUsage && task.result.heap != null) {
|
|
3067
|
+
title += c.magenta(
|
|
3068
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
2784
3071
|
this.ctx.logger.log(title);
|
|
2785
3072
|
if (task.result.state === "fail") {
|
|
2786
3073
|
(_c = task.result.errors) == null ? void 0 : _c.forEach((error) => {
|
|
@@ -2801,7 +3088,10 @@ class IndentedLogger {
|
|
|
2801
3088
|
this.currentIndent += " ";
|
|
2802
3089
|
}
|
|
2803
3090
|
unindent() {
|
|
2804
|
-
this.currentIndent = this.currentIndent.substring(
|
|
3091
|
+
this.currentIndent = this.currentIndent.substring(
|
|
3092
|
+
0,
|
|
3093
|
+
this.currentIndent.length - 4
|
|
3094
|
+
);
|
|
2805
3095
|
}
|
|
2806
3096
|
log(text) {
|
|
2807
3097
|
return this.baseLog(this.currentIndent + text);
|
|
@@ -2823,21 +3113,24 @@ class TapReporter {
|
|
|
2823
3113
|
}
|
|
2824
3114
|
static getComment(task) {
|
|
2825
3115
|
var _a;
|
|
2826
|
-
if (task.mode === "skip")
|
|
3116
|
+
if (task.mode === "skip") {
|
|
2827
3117
|
return " # SKIP";
|
|
2828
|
-
else if (task.mode === "todo")
|
|
3118
|
+
} else if (task.mode === "todo") {
|
|
2829
3119
|
return " # TODO";
|
|
2830
|
-
else if (((_a = task.result) == null ? void 0 : _a.duration) != null)
|
|
3120
|
+
} else if (((_a = task.result) == null ? void 0 : _a.duration) != null) {
|
|
2831
3121
|
return ` # time=${task.result.duration.toFixed(2)}ms`;
|
|
2832
|
-
else
|
|
3122
|
+
} else {
|
|
2833
3123
|
return "";
|
|
3124
|
+
}
|
|
2834
3125
|
}
|
|
2835
3126
|
logErrorDetails(error, stack) {
|
|
2836
3127
|
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
2837
3128
|
this.logger.log(`name: ${yamlString(String(errorName))}`);
|
|
2838
3129
|
this.logger.log(`message: ${yamlString(String(error.message))}`);
|
|
2839
3130
|
if (stack) {
|
|
2840
|
-
this.logger.log(
|
|
3131
|
+
this.logger.log(
|
|
3132
|
+
`stack: ${yamlString(`${stack.file}:${stack.line}:${stack.column}`)}`
|
|
3133
|
+
);
|
|
2841
3134
|
}
|
|
2842
3135
|
}
|
|
2843
3136
|
logTasks(tasks) {
|
|
@@ -2859,8 +3152,8 @@ class TapReporter {
|
|
|
2859
3152
|
if (((_b = task.result) == null ? void 0 : _b.state) === "fail" && task.result.errors) {
|
|
2860
3153
|
this.logger.indent();
|
|
2861
3154
|
task.result.errors.forEach((error) => {
|
|
2862
|
-
|
|
2863
|
-
|
|
3155
|
+
var _a2;
|
|
3156
|
+
const stacks = task.file.pool === "browser" ? ((_a2 = project.browser) == null ? void 0 : _a2.parseErrorStacktrace(error)) || [] : parseErrorStacktrace(error, {
|
|
2864
3157
|
frameFilter: this.ctx.config.onStackTrace
|
|
2865
3158
|
});
|
|
2866
3159
|
const stack = stacks[0];
|
|
@@ -2869,8 +3162,13 @@ class TapReporter {
|
|
|
2869
3162
|
this.logger.indent();
|
|
2870
3163
|
this.logErrorDetails(error);
|
|
2871
3164
|
this.logger.unindent();
|
|
2872
|
-
if (stack)
|
|
2873
|
-
this.logger.log(
|
|
3165
|
+
if (stack) {
|
|
3166
|
+
this.logger.log(
|
|
3167
|
+
`at: ${yamlString(
|
|
3168
|
+
`${stack.file}:${stack.line}:${stack.column}`
|
|
3169
|
+
)}`
|
|
3170
|
+
);
|
|
3171
|
+
}
|
|
2874
3172
|
if (error.showDiff) {
|
|
2875
3173
|
this.logger.log(`actual: ${yamlString(error.actual)}`);
|
|
2876
3174
|
this.logger.log(`expected: ${yamlString(error.expected)}`);
|
|
@@ -4087,18 +4385,21 @@ createLogUpdate(process$2.stdout);
|
|
|
4087
4385
|
|
|
4088
4386
|
createLogUpdate(process$2.stderr);
|
|
4089
4387
|
|
|
4090
|
-
const HIGHLIGHT_SUPPORTED_EXTS = new Set(
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4388
|
+
const HIGHLIGHT_SUPPORTED_EXTS = new Set(
|
|
4389
|
+
["js", "ts"].flatMap((lang) => [
|
|
4390
|
+
`.${lang}`,
|
|
4391
|
+
`.m${lang}`,
|
|
4392
|
+
`.c${lang}`,
|
|
4393
|
+
`.${lang}x`,
|
|
4394
|
+
`.m${lang}x`,
|
|
4395
|
+
`.c${lang}x`
|
|
4396
|
+
])
|
|
4397
|
+
);
|
|
4098
4398
|
function highlightCode(id, source, colors) {
|
|
4099
4399
|
const ext = extname(id);
|
|
4100
|
-
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
|
|
4400
|
+
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext)) {
|
|
4101
4401
|
return source;
|
|
4402
|
+
}
|
|
4102
4403
|
const isJsx = ext.endsWith("x");
|
|
4103
4404
|
return highlight(source, { jsx: isJsx, colors: c });
|
|
4104
4405
|
}
|
|
@@ -4135,14 +4436,17 @@ class BaseSequencer {
|
|
|
4135
4436
|
if (!aState || !bState) {
|
|
4136
4437
|
const statsA = cache.getFileStats(keyA);
|
|
4137
4438
|
const statsB = cache.getFileStats(keyB);
|
|
4138
|
-
if (!statsA || !statsB)
|
|
4439
|
+
if (!statsA || !statsB) {
|
|
4139
4440
|
return !statsA && statsB ? -1 : !statsB && statsA ? 1 : 0;
|
|
4441
|
+
}
|
|
4140
4442
|
return statsB.size - statsA.size;
|
|
4141
4443
|
}
|
|
4142
|
-
if (aState.failed && !bState.failed)
|
|
4444
|
+
if (aState.failed && !bState.failed) {
|
|
4143
4445
|
return -1;
|
|
4144
|
-
|
|
4446
|
+
}
|
|
4447
|
+
if (!aState.failed && bState.failed) {
|
|
4145
4448
|
return 1;
|
|
4449
|
+
}
|
|
4146
4450
|
return bState.duration - aState.duration;
|
|
4147
4451
|
});
|
|
4148
4452
|
}
|
|
@@ -4190,7 +4494,7 @@ class Logger {
|
|
|
4190
4494
|
this.console.log(message);
|
|
4191
4495
|
return;
|
|
4192
4496
|
}
|
|
4193
|
-
this.console.log(`${
|
|
4497
|
+
this.console.log(`${CLEAR_SCREEN}${ERASE_SCROLLBACK}${message}`);
|
|
4194
4498
|
}
|
|
4195
4499
|
clearScreen(message, force = false) {
|
|
4196
4500
|
if (!this.ctx.config.clearScreen) {
|
|
@@ -4198,12 +4502,14 @@ class Logger {
|
|
|
4198
4502
|
return;
|
|
4199
4503
|
}
|
|
4200
4504
|
this._clearScreenPending = message;
|
|
4201
|
-
if (force)
|
|
4505
|
+
if (force) {
|
|
4202
4506
|
this._clearScreen();
|
|
4507
|
+
}
|
|
4203
4508
|
}
|
|
4204
4509
|
_clearScreen() {
|
|
4205
|
-
if (this._clearScreenPending == null)
|
|
4510
|
+
if (this._clearScreenPending == null) {
|
|
4206
4511
|
return;
|
|
4512
|
+
}
|
|
4207
4513
|
const log = this._clearScreenPending;
|
|
4208
4514
|
this._clearScreenPending = void 0;
|
|
4209
4515
|
this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
|
|
@@ -4211,22 +4517,37 @@ class Logger {
|
|
|
4211
4517
|
printError(err, options = {}) {
|
|
4212
4518
|
const { fullStack = false, type } = options;
|
|
4213
4519
|
const project = options.project ?? this.ctx.getCoreWorkspaceProject() ?? this.ctx.projects[0];
|
|
4214
|
-
printError(err, project, {
|
|
4215
|
-
fullStack,
|
|
4520
|
+
return printError(err, project, {
|
|
4216
4521
|
type,
|
|
4217
|
-
showCodeFrame: true,
|
|
4218
|
-
logger: this
|
|
4522
|
+
showCodeFrame: options.showCodeFrame ?? true,
|
|
4523
|
+
logger: this,
|
|
4524
|
+
printProperties: options.verbose,
|
|
4525
|
+
screenshotPaths: options.screenshotPaths,
|
|
4526
|
+
parseErrorStacktrace: (error) => {
|
|
4527
|
+
var _a;
|
|
4528
|
+
if (((_a = options.task) == null ? void 0 : _a.file.pool) === "browser" && project.browser) {
|
|
4529
|
+
return project.browser.parseErrorStacktrace(error, {
|
|
4530
|
+
ignoreStackEntries: fullStack ? [] : void 0
|
|
4531
|
+
});
|
|
4532
|
+
}
|
|
4533
|
+
return parseErrorStacktrace(error, {
|
|
4534
|
+
frameFilter: project.config.onStackTrace,
|
|
4535
|
+
ignoreStackEntries: fullStack ? [] : void 0
|
|
4536
|
+
});
|
|
4537
|
+
}
|
|
4219
4538
|
});
|
|
4220
4539
|
}
|
|
4221
4540
|
clearHighlightCache(filename) {
|
|
4222
|
-
if (filename)
|
|
4541
|
+
if (filename) {
|
|
4223
4542
|
this._highlights.delete(filename);
|
|
4224
|
-
else
|
|
4543
|
+
} else {
|
|
4225
4544
|
this._highlights.clear();
|
|
4545
|
+
}
|
|
4226
4546
|
}
|
|
4227
4547
|
highlight(filename, source) {
|
|
4228
|
-
if (this._highlights.has(filename))
|
|
4548
|
+
if (this._highlights.has(filename)) {
|
|
4229
4549
|
return this._highlights.get(filename);
|
|
4550
|
+
}
|
|
4230
4551
|
const code = highlightCode(filename, source);
|
|
4231
4552
|
this._highlights.set(filename, code);
|
|
4232
4553
|
return code;
|
|
@@ -4235,36 +4556,54 @@ class Logger {
|
|
|
4235
4556
|
var _a;
|
|
4236
4557
|
const config = this.ctx.config;
|
|
4237
4558
|
const comma = c.dim(", ");
|
|
4238
|
-
if (filters == null ? void 0 : filters.length)
|
|
4559
|
+
if (filters == null ? void 0 : filters.length) {
|
|
4239
4560
|
this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
4561
|
+
}
|
|
4240
4562
|
const projectsFilter = toArray(config.project);
|
|
4241
|
-
if (projectsFilter.length)
|
|
4242
|
-
this.console.error(
|
|
4563
|
+
if (projectsFilter.length) {
|
|
4564
|
+
this.console.error(
|
|
4565
|
+
c.dim("projects: ") + c.yellow(projectsFilter.join(comma))
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4243
4568
|
this.ctx.projects.forEach((project) => {
|
|
4244
4569
|
const config2 = project.config;
|
|
4245
4570
|
const name = project.getName();
|
|
4246
4571
|
const output = project.isCore() || !name ? "" : `[${name}]`;
|
|
4247
|
-
if (output)
|
|
4572
|
+
if (output) {
|
|
4248
4573
|
this.console.error(c.bgCyan(`${output} Config`));
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4574
|
+
}
|
|
4575
|
+
if (config2.include) {
|
|
4576
|
+
this.console.error(
|
|
4577
|
+
c.dim("include: ") + c.yellow(config2.include.join(comma))
|
|
4578
|
+
);
|
|
4579
|
+
}
|
|
4580
|
+
if (config2.exclude) {
|
|
4581
|
+
this.console.error(
|
|
4582
|
+
c.dim("exclude: ") + c.yellow(config2.exclude.join(comma))
|
|
4583
|
+
);
|
|
4584
|
+
}
|
|
4253
4585
|
if (config2.typecheck.enabled) {
|
|
4254
|
-
this.console.error(
|
|
4255
|
-
|
|
4586
|
+
this.console.error(
|
|
4587
|
+
c.dim("typecheck include: ") + c.yellow(config2.typecheck.include.join(comma))
|
|
4588
|
+
);
|
|
4589
|
+
this.console.error(
|
|
4590
|
+
c.dim("typecheck exclude: ") + c.yellow(config2.typecheck.exclude.join(comma))
|
|
4591
|
+
);
|
|
4256
4592
|
}
|
|
4257
4593
|
});
|
|
4258
4594
|
if (config.watch && (config.changed || ((_a = config.related) == null ? void 0 : _a.length))) {
|
|
4259
4595
|
this.log(`No affected ${config.mode} files found
|
|
4260
4596
|
`);
|
|
4261
4597
|
} else {
|
|
4262
|
-
if (config.passWithNoTests)
|
|
4598
|
+
if (config.passWithNoTests) {
|
|
4263
4599
|
this.log(`No ${config.mode} files found, exiting with code 0
|
|
4264
4600
|
`);
|
|
4265
|
-
else
|
|
4266
|
-
this.error(
|
|
4267
|
-
|
|
4601
|
+
} else {
|
|
4602
|
+
this.error(
|
|
4603
|
+
c.red(`
|
|
4604
|
+
No ${config.mode} files found, exiting with code 1`)
|
|
4605
|
+
);
|
|
4606
|
+
}
|
|
4268
4607
|
}
|
|
4269
4608
|
}
|
|
4270
4609
|
printBanner() {
|
|
@@ -4272,52 +4611,89 @@ No ${config.mode} files found, exiting with code 1`));
|
|
|
4272
4611
|
this.log();
|
|
4273
4612
|
const versionTest = this.ctx.config.watch ? c.blue(`v${this.ctx.version}`) : c.cyan(`v${this.ctx.version}`);
|
|
4274
4613
|
const mode = this.ctx.config.watch ? c.blue(" DEV ") : c.cyan(" RUN ");
|
|
4275
|
-
this.log(
|
|
4276
|
-
|
|
4277
|
-
|
|
4614
|
+
this.log(
|
|
4615
|
+
`${c.inverse(c.bold(mode))} ${versionTest} ${c.gray(
|
|
4616
|
+
this.ctx.config.root
|
|
4617
|
+
)}`
|
|
4618
|
+
);
|
|
4619
|
+
if (this.ctx.config.sequence.sequencer === RandomSequencer) {
|
|
4620
|
+
this.log(
|
|
4621
|
+
c.gray(
|
|
4622
|
+
` Running tests with seed "${this.ctx.config.sequence.seed}"`
|
|
4623
|
+
)
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4278
4626
|
this.ctx.projects.forEach((project) => {
|
|
4279
|
-
if (!project.browser)
|
|
4627
|
+
if (!project.browser) {
|
|
4280
4628
|
return;
|
|
4629
|
+
}
|
|
4281
4630
|
const name = project.getName();
|
|
4282
4631
|
const output = project.isCore() ? "" : ` [${name}]`;
|
|
4283
|
-
const resolvedUrls = project.browser.resolvedUrls;
|
|
4632
|
+
const resolvedUrls = project.browser.vite.resolvedUrls;
|
|
4284
4633
|
const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
|
|
4285
|
-
this.log(
|
|
4634
|
+
this.log(
|
|
4635
|
+
c.dim(
|
|
4636
|
+
c.green(
|
|
4637
|
+
` ${output} Browser runner started at ${new URL("/", origin)}`
|
|
4638
|
+
)
|
|
4639
|
+
)
|
|
4640
|
+
);
|
|
4286
4641
|
});
|
|
4287
4642
|
if (this.ctx.config.ui) {
|
|
4288
|
-
this.log(
|
|
4643
|
+
this.log(
|
|
4644
|
+
c.dim(
|
|
4645
|
+
c.green(
|
|
4646
|
+
` 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}`
|
|
4647
|
+
)
|
|
4648
|
+
)
|
|
4649
|
+
);
|
|
4289
4650
|
} else if ((_b = this.ctx.config.api) == null ? void 0 : _b.port) {
|
|
4290
4651
|
const resolvedUrls = this.ctx.server.resolvedUrls;
|
|
4291
4652
|
const fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`;
|
|
4292
4653
|
const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]) ?? fallbackUrl;
|
|
4293
4654
|
this.log(c.dim(c.green(` API started at ${new URL("/", origin)}`)));
|
|
4294
4655
|
}
|
|
4295
|
-
if (this.ctx.coverageProvider)
|
|
4296
|
-
this.log(
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4656
|
+
if (this.ctx.coverageProvider) {
|
|
4657
|
+
this.log(
|
|
4658
|
+
c.dim(" Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name)
|
|
4659
|
+
);
|
|
4660
|
+
}
|
|
4661
|
+
if (this.ctx.config.standalone) {
|
|
4662
|
+
this.log(
|
|
4663
|
+
c.yellow(
|
|
4664
|
+
`
|
|
4665
|
+
Vitest is running in standalone mode. Edit a test file to rerun tests.`
|
|
4666
|
+
)
|
|
4667
|
+
);
|
|
4668
|
+
} else {
|
|
4301
4669
|
this.log();
|
|
4670
|
+
}
|
|
4302
4671
|
}
|
|
4303
4672
|
printUnhandledErrors(errors) {
|
|
4304
|
-
const errorMessage = c.red(
|
|
4305
|
-
|
|
4673
|
+
const errorMessage = c.red(
|
|
4674
|
+
c.bold(
|
|
4675
|
+
`
|
|
4306
4676
|
Vitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
4307
4677
|
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`
|
|
4308
|
-
|
|
4678
|
+
)
|
|
4679
|
+
);
|
|
4309
4680
|
this.log(c.red(divider(c.bold(c.inverse(" Unhandled Errors ")))));
|
|
4310
4681
|
this.log(errorMessage);
|
|
4311
4682
|
errors.forEach((err) => {
|
|
4312
|
-
this.printError(err, {
|
|
4683
|
+
this.printError(err, {
|
|
4684
|
+
fullStack: true,
|
|
4685
|
+
type: err.type || "Unhandled Error"
|
|
4686
|
+
});
|
|
4313
4687
|
});
|
|
4314
4688
|
this.log(c.red(divider()));
|
|
4315
4689
|
}
|
|
4316
4690
|
printSourceTypeErrors(errors) {
|
|
4317
|
-
const errorMessage = c.red(
|
|
4318
|
-
|
|
4691
|
+
const errorMessage = c.red(
|
|
4692
|
+
c.bold(
|
|
4693
|
+
`
|
|
4319
4694
|
Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`
|
|
4320
|
-
|
|
4695
|
+
)
|
|
4696
|
+
);
|
|
4321
4697
|
this.log(c.red(divider(c.bold(c.inverse(" Source Errors ")))));
|
|
4322
4698
|
this.log(errorMessage);
|
|
4323
4699
|
errors.forEach((err) => {
|
|
@@ -4327,7 +4703,7 @@ Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related t
|
|
|
4327
4703
|
}
|
|
4328
4704
|
}
|
|
4329
4705
|
|
|
4330
|
-
function capturePrintError(error, ctx,
|
|
4706
|
+
function capturePrintError(error, ctx, options) {
|
|
4331
4707
|
let output = "";
|
|
4332
4708
|
const writable = new Writable({
|
|
4333
4709
|
write(chunk, _encoding, callback) {
|
|
@@ -4335,14 +4711,16 @@ function capturePrintError(error, ctx, project) {
|
|
|
4335
4711
|
callback();
|
|
4336
4712
|
}
|
|
4337
4713
|
});
|
|
4338
|
-
const
|
|
4714
|
+
const logger = new Logger(ctx, writable, writable);
|
|
4715
|
+
const result = logger.printError(error, {
|
|
4339
4716
|
showCodeFrame: false,
|
|
4340
|
-
|
|
4717
|
+
...options
|
|
4341
4718
|
});
|
|
4342
4719
|
return { nearest: result == null ? void 0 : result.nearest, output };
|
|
4343
4720
|
}
|
|
4344
4721
|
function printError(error, project, options) {
|
|
4345
|
-
|
|
4722
|
+
var _a;
|
|
4723
|
+
const { showCodeFrame = true, type, printProperties = true } = options;
|
|
4346
4724
|
const logger = options.logger;
|
|
4347
4725
|
let e = error;
|
|
4348
4726
|
if (isPrimitive(e)) {
|
|
@@ -4362,58 +4740,88 @@ function printError(error, project, options) {
|
|
|
4362
4740
|
printErrorMessage(e, logger);
|
|
4363
4741
|
return;
|
|
4364
4742
|
}
|
|
4365
|
-
const
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
parserOptions.ignoreStackEntries = [];
|
|
4372
|
-
const stacks = parseErrorStacktrace(e, parserOptions);
|
|
4373
|
-
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find(
|
|
4374
|
-
(stack) => {
|
|
4375
|
-
try {
|
|
4376
|
-
return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
|
|
4377
|
-
} catch {
|
|
4378
|
-
return false;
|
|
4379
|
-
}
|
|
4743
|
+
const stacks = options.parseErrorStacktrace(e);
|
|
4744
|
+
const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => {
|
|
4745
|
+
try {
|
|
4746
|
+
return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
|
|
4747
|
+
} catch {
|
|
4748
|
+
return false;
|
|
4380
4749
|
}
|
|
4381
|
-
);
|
|
4382
|
-
|
|
4383
|
-
if (type)
|
|
4750
|
+
});
|
|
4751
|
+
if (type) {
|
|
4384
4752
|
printErrorType(type, project.ctx);
|
|
4753
|
+
}
|
|
4385
4754
|
printErrorMessage(e, logger);
|
|
4386
|
-
if (
|
|
4755
|
+
if ((_a = options.screenshotPaths) == null ? void 0 : _a.length) {
|
|
4756
|
+
const length = options.screenshotPaths.length;
|
|
4757
|
+
logger.error(`
|
|
4758
|
+
Failure screenshot${length > 1 ? "s" : ""}:`);
|
|
4759
|
+
logger.error(options.screenshotPaths.map((p) => ` - ${c.dim(relative(process.cwd(), p))}`).join("\n"));
|
|
4760
|
+
if (!e.diff) {
|
|
4761
|
+
logger.error();
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
if (e.codeFrame) {
|
|
4387
4765
|
logger.error(`${e.codeFrame}
|
|
4388
4766
|
`);
|
|
4389
|
-
|
|
4767
|
+
}
|
|
4768
|
+
if (e.diff) {
|
|
4390
4769
|
displayDiff(e.diff, logger.console);
|
|
4770
|
+
}
|
|
4391
4771
|
if (e.frame) {
|
|
4392
4772
|
logger.error(c.yellow(e.frame));
|
|
4393
4773
|
} else {
|
|
4774
|
+
const errorProperties = printProperties ? getErrorProperties(e) : {};
|
|
4394
4775
|
printStack(logger, project, stacks, nearest, errorProperties, (s) => {
|
|
4395
4776
|
if (showCodeFrame && s === nearest && nearest) {
|
|
4396
4777
|
const sourceCode = readFileSync(nearest.file, "utf-8");
|
|
4397
|
-
logger.error(
|
|
4778
|
+
logger.error(
|
|
4779
|
+
generateCodeFrame(
|
|
4780
|
+
sourceCode.length > 1e5 ? sourceCode : logger.highlight(nearest.file, sourceCode),
|
|
4781
|
+
4,
|
|
4782
|
+
s
|
|
4783
|
+
)
|
|
4784
|
+
);
|
|
4398
4785
|
}
|
|
4399
4786
|
});
|
|
4400
4787
|
}
|
|
4401
4788
|
const testPath = e.VITEST_TEST_PATH;
|
|
4402
4789
|
const testName = e.VITEST_TEST_NAME;
|
|
4403
4790
|
const afterEnvTeardown = e.VITEST_AFTER_ENV_TEARDOWN;
|
|
4404
|
-
if (testPath)
|
|
4405
|
-
logger.error(
|
|
4791
|
+
if (testPath) {
|
|
4792
|
+
logger.error(
|
|
4793
|
+
c.red(
|
|
4794
|
+
`This error originated in "${c.bold(
|
|
4795
|
+
testPath
|
|
4796
|
+
)}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`
|
|
4797
|
+
)
|
|
4798
|
+
);
|
|
4799
|
+
}
|
|
4406
4800
|
if (testName) {
|
|
4407
|
-
logger.error(
|
|
4801
|
+
logger.error(
|
|
4802
|
+
c.red(
|
|
4803
|
+
`The latest test that might've caused the error is "${c.bold(
|
|
4804
|
+
testName
|
|
4805
|
+
)}". It might mean one of the following:
|
|
4408
4806
|
- The error was thrown, while Vitest was running this test.
|
|
4409
|
-
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.`
|
|
4807
|
+
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.`
|
|
4808
|
+
)
|
|
4809
|
+
);
|
|
4410
4810
|
}
|
|
4411
4811
|
if (afterEnvTeardown) {
|
|
4412
|
-
logger.error(
|
|
4812
|
+
logger.error(
|
|
4813
|
+
c.red(
|
|
4814
|
+
"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"
|
|
4815
|
+
)
|
|
4816
|
+
);
|
|
4413
4817
|
}
|
|
4414
4818
|
if (typeof e.cause === "object" && e.cause && "name" in e.cause) {
|
|
4415
4819
|
e.cause.name = `Caused by: ${e.cause.name}`;
|
|
4416
|
-
printError(e.cause, project, {
|
|
4820
|
+
printError(e.cause, project, {
|
|
4821
|
+
showCodeFrame: false,
|
|
4822
|
+
logger: options.logger,
|
|
4823
|
+
parseErrorStacktrace: options.parseErrorStacktrace
|
|
4824
|
+
});
|
|
4417
4825
|
}
|
|
4418
4826
|
handleImportOutsideModuleError(e.stack || e.stackStr || "", logger);
|
|
4419
4827
|
return { nearest };
|
|
@@ -4445,11 +4853,13 @@ const skipErrorProperties = /* @__PURE__ */ new Set([
|
|
|
4445
4853
|
]);
|
|
4446
4854
|
function getErrorProperties(e) {
|
|
4447
4855
|
const errorObject = /* @__PURE__ */ Object.create(null);
|
|
4448
|
-
if (e.name === "AssertionError")
|
|
4856
|
+
if (e.name === "AssertionError") {
|
|
4449
4857
|
return errorObject;
|
|
4858
|
+
}
|
|
4450
4859
|
for (const key of Object.getOwnPropertyNames(e)) {
|
|
4451
|
-
if (!skipErrorProperties.has(key))
|
|
4860
|
+
if (!skipErrorProperties.has(key)) {
|
|
4452
4861
|
errorObject[key] = e[key];
|
|
4862
|
+
}
|
|
4453
4863
|
}
|
|
4454
4864
|
return errorObject;
|
|
4455
4865
|
}
|
|
@@ -4458,22 +4868,28 @@ const esmErrors = [
|
|
|
4458
4868
|
"Unexpected token 'export'"
|
|
4459
4869
|
];
|
|
4460
4870
|
function handleImportOutsideModuleError(stack, logger) {
|
|
4461
|
-
if (!esmErrors.some((e) => stack.includes(e)))
|
|
4871
|
+
if (!esmErrors.some((e) => stack.includes(e))) {
|
|
4462
4872
|
return;
|
|
4873
|
+
}
|
|
4463
4874
|
const path = normalize(stack.split("\n")[0].trim());
|
|
4464
4875
|
let name = path.split("/node_modules/").pop() || "";
|
|
4465
|
-
if (name == null ? void 0 : name.startsWith("@"))
|
|
4876
|
+
if (name == null ? void 0 : name.startsWith("@")) {
|
|
4466
4877
|
name = name.split("/").slice(0, 2).join("/");
|
|
4467
|
-
else
|
|
4878
|
+
} else {
|
|
4468
4879
|
name = name.split("/")[0];
|
|
4469
|
-
|
|
4880
|
+
}
|
|
4881
|
+
if (name) {
|
|
4470
4882
|
printModuleWarningForPackage(logger, path, name);
|
|
4471
|
-
else
|
|
4883
|
+
} else {
|
|
4472
4884
|
printModuleWarningForSourceCode(logger, path);
|
|
4885
|
+
}
|
|
4473
4886
|
}
|
|
4474
4887
|
function printModuleWarningForPackage(logger, path, name) {
|
|
4475
|
-
logger.error(
|
|
4476
|
-
|
|
4888
|
+
logger.error(
|
|
4889
|
+
c.yellow(
|
|
4890
|
+
`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(
|
|
4891
|
+
`"${name}"`
|
|
4892
|
+
)} asking them to ship the file in .mjs extension or add "type": "module" in their package.json.
|
|
4477
4893
|
|
|
4478
4894
|
As a temporary workaround you can try to inline the package by updating your config:
|
|
4479
4895
|
|
|
@@ -4489,18 +4905,22 @@ As a temporary workaround you can try to inline the package by updating your con
|
|
|
4489
4905
|
}
|
|
4490
4906
|
}
|
|
4491
4907
|
`)
|
|
4492
|
-
|
|
4908
|
+
)
|
|
4909
|
+
);
|
|
4493
4910
|
}
|
|
4494
4911
|
function printModuleWarningForSourceCode(logger, path) {
|
|
4495
|
-
logger.error(
|
|
4496
|
-
|
|
4497
|
-
|
|
4912
|
+
logger.error(
|
|
4913
|
+
c.yellow(
|
|
4914
|
+
`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.`
|
|
4915
|
+
)
|
|
4916
|
+
);
|
|
4498
4917
|
}
|
|
4499
4918
|
function displayDiff(diff, console) {
|
|
4500
|
-
if (diff)
|
|
4919
|
+
if (diff) {
|
|
4501
4920
|
console.error(`
|
|
4502
4921
|
${diff}
|
|
4503
4922
|
`);
|
|
4923
|
+
}
|
|
4504
4924
|
}
|
|
4505
4925
|
function printErrorMessage(error, logger) {
|
|
4506
4926
|
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
@@ -4518,18 +4938,31 @@ function printStack(logger, project, stack, highlight, errorProperties, onStack)
|
|
|
4518
4938
|
for (const frame of stack) {
|
|
4519
4939
|
const color = frame === highlight ? c.cyan : c.gray;
|
|
4520
4940
|
const path = relative(project.config.root, frame.file);
|
|
4521
|
-
logger.error(
|
|
4941
|
+
logger.error(
|
|
4942
|
+
color(
|
|
4943
|
+
` ${c.dim(F_POINTER)} ${[
|
|
4944
|
+
frame.method,
|
|
4945
|
+
`${path}:${c.dim(`${frame.line}:${frame.column}`)}`
|
|
4946
|
+
].filter(Boolean).join(" ")}`
|
|
4947
|
+
)
|
|
4948
|
+
);
|
|
4522
4949
|
onStack == null ? void 0 : onStack(frame);
|
|
4523
4950
|
}
|
|
4524
|
-
if (stack.length)
|
|
4951
|
+
if (stack.length) {
|
|
4525
4952
|
logger.error();
|
|
4526
|
-
|
|
4527
|
-
if (hasProperties) {
|
|
4953
|
+
}
|
|
4954
|
+
if (hasProperties(errorProperties)) {
|
|
4528
4955
|
logger.error(c.red(c.dim(divider())));
|
|
4529
4956
|
const propertiesString = inspect(errorProperties);
|
|
4530
4957
|
logger.error(c.red(c.bold("Serialized Error:")), c.gray(propertiesString));
|
|
4531
4958
|
}
|
|
4532
4959
|
}
|
|
4960
|
+
function hasProperties(obj) {
|
|
4961
|
+
for (const _key in obj) {
|
|
4962
|
+
return true;
|
|
4963
|
+
}
|
|
4964
|
+
return false;
|
|
4965
|
+
}
|
|
4533
4966
|
function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
4534
4967
|
var _a;
|
|
4535
4968
|
const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc;
|
|
@@ -4546,15 +4979,22 @@ function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
|
4546
4979
|
count += lines[i].length + nl;
|
|
4547
4980
|
if (count >= start) {
|
|
4548
4981
|
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
4549
|
-
if (j < 0 || j >= lines.length)
|
|
4982
|
+
if (j < 0 || j >= lines.length) {
|
|
4550
4983
|
continue;
|
|
4984
|
+
}
|
|
4551
4985
|
const lineLength = lines[j].length;
|
|
4552
|
-
if (stripAnsi(lines[j]).length > 200)
|
|
4986
|
+
if (stripAnsi(lines[j]).length > 200) {
|
|
4553
4987
|
return "";
|
|
4554
|
-
|
|
4988
|
+
}
|
|
4989
|
+
res.push(
|
|
4990
|
+
lineNo(j + 1) + cliTruncate(lines[j].replace(/\t/g, " "), columns - 5 - indent)
|
|
4991
|
+
);
|
|
4555
4992
|
if (j === i) {
|
|
4556
4993
|
const pad = start - (count - lineLength) + (nl - 1);
|
|
4557
|
-
const length = Math.max(
|
|
4994
|
+
const length = Math.max(
|
|
4995
|
+
1,
|
|
4996
|
+
end > count ? lineLength - pad : end - start
|
|
4997
|
+
);
|
|
4558
4998
|
res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
|
|
4559
4999
|
} else if (j > i) {
|
|
4560
5000
|
if (end > count) {
|
|
@@ -4567,20 +5007,25 @@ function generateCodeFrame(source, indent = 0, loc, range = 2) {
|
|
|
4567
5007
|
break;
|
|
4568
5008
|
}
|
|
4569
5009
|
}
|
|
4570
|
-
if (indent)
|
|
5010
|
+
if (indent) {
|
|
4571
5011
|
res = res.map((line) => " ".repeat(indent) + line);
|
|
5012
|
+
}
|
|
4572
5013
|
return res.join("\n");
|
|
4573
5014
|
}
|
|
4574
5015
|
|
|
4575
5016
|
function flattenTasks$1(task, baseName = "") {
|
|
4576
5017
|
const base = baseName ? `${baseName} > ` : "";
|
|
4577
5018
|
if (task.type === "suite") {
|
|
4578
|
-
return task.tasks.flatMap(
|
|
5019
|
+
return task.tasks.flatMap(
|
|
5020
|
+
(child) => flattenTasks$1(child, `${base}${task.name}`)
|
|
5021
|
+
);
|
|
4579
5022
|
} else {
|
|
4580
|
-
return [
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
5023
|
+
return [
|
|
5024
|
+
{
|
|
5025
|
+
...task,
|
|
5026
|
+
name: `${base}${task.name}`
|
|
5027
|
+
}
|
|
5028
|
+
];
|
|
4584
5029
|
}
|
|
4585
5030
|
}
|
|
4586
5031
|
function removeInvalidXMLCharacters(value, removeDiscouragedChars) {
|
|
@@ -4602,7 +5047,10 @@ function escapeXML(value) {
|
|
|
4602
5047
|
String(value).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">"));
|
|
4603
5048
|
}
|
|
4604
5049
|
function executionTime(durationMS) {
|
|
4605
|
-
return (durationMS / 1e3).toLocaleString("en-US", {
|
|
5050
|
+
return (durationMS / 1e3).toLocaleString("en-US", {
|
|
5051
|
+
useGrouping: false,
|
|
5052
|
+
maximumFractionDigits: 10
|
|
5053
|
+
});
|
|
4606
5054
|
}
|
|
4607
5055
|
function getDuration(task) {
|
|
4608
5056
|
var _a;
|
|
@@ -4628,13 +5076,15 @@ class JUnitReporter {
|
|
|
4628
5076
|
if (outputFile) {
|
|
4629
5077
|
this.reportFile = resolve(this.ctx.config.root, outputFile);
|
|
4630
5078
|
const outputDirectory = dirname(this.reportFile);
|
|
4631
|
-
if (!existsSync(outputDirectory))
|
|
5079
|
+
if (!existsSync(outputDirectory)) {
|
|
4632
5080
|
await promises.mkdir(outputDirectory, { recursive: true });
|
|
5081
|
+
}
|
|
4633
5082
|
const fileFd = await promises.open(this.reportFile, "w+");
|
|
4634
5083
|
this.fileFd = fileFd;
|
|
4635
5084
|
this.baseLog = async (text) => {
|
|
4636
|
-
if (!this.fileFd)
|
|
5085
|
+
if (!this.fileFd) {
|
|
4637
5086
|
this.fileFd = await promises.open(this.reportFile, "w+");
|
|
5087
|
+
}
|
|
4638
5088
|
await promises.writeFile(this.fileFd, `${text}
|
|
4639
5089
|
`);
|
|
4640
5090
|
};
|
|
@@ -4648,62 +5098,80 @@ class JUnitReporter {
|
|
|
4648
5098
|
const pairs = [];
|
|
4649
5099
|
for (const key in attrs) {
|
|
4650
5100
|
const attr = attrs[key];
|
|
4651
|
-
if (attr === void 0)
|
|
5101
|
+
if (attr === void 0) {
|
|
4652
5102
|
continue;
|
|
5103
|
+
}
|
|
4653
5104
|
pairs.push(`${key}="${escapeXML(attr)}"`);
|
|
4654
5105
|
}
|
|
4655
|
-
await this.logger.log(
|
|
5106
|
+
await this.logger.log(
|
|
5107
|
+
`<${name}${pairs.length ? ` ${pairs.join(" ")}` : ""}>`
|
|
5108
|
+
);
|
|
4656
5109
|
this.logger.indent();
|
|
4657
5110
|
await children.call(this);
|
|
4658
5111
|
this.logger.unindent();
|
|
4659
5112
|
await this.logger.log(`</${name}>`);
|
|
4660
5113
|
}
|
|
4661
5114
|
async writeLogs(task, type) {
|
|
4662
|
-
if (task.logs == null || task.logs.length === 0)
|
|
5115
|
+
if (task.logs == null || task.logs.length === 0) {
|
|
4663
5116
|
return;
|
|
5117
|
+
}
|
|
4664
5118
|
const logType = type === "err" ? "stderr" : "stdout";
|
|
4665
5119
|
const logs = task.logs.filter((log) => log.type === logType);
|
|
4666
|
-
if (logs.length === 0)
|
|
5120
|
+
if (logs.length === 0) {
|
|
4667
5121
|
return;
|
|
5122
|
+
}
|
|
4668
5123
|
await this.writeElement(`system-${type}`, {}, async () => {
|
|
4669
|
-
for (const log of logs)
|
|
5124
|
+
for (const log of logs) {
|
|
4670
5125
|
await this.baseLog(escapeXML(log.content));
|
|
5126
|
+
}
|
|
4671
5127
|
});
|
|
4672
5128
|
}
|
|
4673
5129
|
async writeTasks(tasks, filename) {
|
|
4674
5130
|
for (const task of tasks) {
|
|
4675
|
-
await this.writeElement(
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
5131
|
+
await this.writeElement(
|
|
5132
|
+
"testcase",
|
|
5133
|
+
{
|
|
5134
|
+
classname: this.options.classname ?? filename,
|
|
5135
|
+
file: this.options.addFileAttribute ? filename : void 0,
|
|
5136
|
+
name: task.name,
|
|
5137
|
+
time: getDuration(task)
|
|
5138
|
+
},
|
|
5139
|
+
async () => {
|
|
5140
|
+
var _a;
|
|
5141
|
+
if (this.options.includeConsoleOutput) {
|
|
5142
|
+
await this.writeLogs(task, "out");
|
|
5143
|
+
await this.writeLogs(task, "err");
|
|
5144
|
+
}
|
|
5145
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
5146
|
+
await this.logger.log("<skipped/>");
|
|
5147
|
+
}
|
|
5148
|
+
if (((_a = task.result) == null ? void 0 : _a.state) === "fail") {
|
|
5149
|
+
const errors = task.result.errors || [];
|
|
5150
|
+
for (const error of errors) {
|
|
5151
|
+
await this.writeElement(
|
|
5152
|
+
"failure",
|
|
5153
|
+
{
|
|
5154
|
+
message: error == null ? void 0 : error.message,
|
|
5155
|
+
type: (error == null ? void 0 : error.name) ?? (error == null ? void 0 : error.nameStr)
|
|
5156
|
+
},
|
|
5157
|
+
async () => {
|
|
5158
|
+
if (!error) {
|
|
5159
|
+
return;
|
|
5160
|
+
}
|
|
5161
|
+
const result = capturePrintError(
|
|
5162
|
+
error,
|
|
5163
|
+
this.ctx,
|
|
5164
|
+
{ project: this.ctx.getProjectByTaskId(task.id), task }
|
|
5165
|
+
);
|
|
5166
|
+
await this.baseLog(
|
|
5167
|
+
escapeXML(stripAnsi(result.output.trim()))
|
|
5168
|
+
);
|
|
5169
|
+
}
|
|
4701
5170
|
);
|
|
4702
|
-
|
|
4703
|
-
});
|
|
5171
|
+
}
|
|
4704
5172
|
}
|
|
4705
5173
|
}
|
|
4706
|
-
|
|
5174
|
+
);
|
|
4707
5175
|
}
|
|
4708
5176
|
}
|
|
4709
5177
|
async onFinished(files = this.ctx.state.getFiles()) {
|
|
@@ -4712,18 +5180,21 @@ class JUnitReporter {
|
|
|
4712
5180
|
const transformed = files.map((file) => {
|
|
4713
5181
|
var _a2, _b;
|
|
4714
5182
|
const tasks = file.tasks.flatMap((task) => flattenTasks$1(task));
|
|
4715
|
-
const stats2 = tasks.reduce(
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
5183
|
+
const stats2 = tasks.reduce(
|
|
5184
|
+
(stats3, task) => {
|
|
5185
|
+
var _a3, _b2;
|
|
5186
|
+
return {
|
|
5187
|
+
passed: stats3.passed + Number(((_a3 = task.result) == null ? void 0 : _a3.state) === "pass"),
|
|
5188
|
+
failures: stats3.failures + Number(((_b2 = task.result) == null ? void 0 : _b2.state) === "fail"),
|
|
5189
|
+
skipped: stats3.skipped + Number(task.mode === "skip" || task.mode === "todo")
|
|
5190
|
+
};
|
|
5191
|
+
},
|
|
5192
|
+
{
|
|
5193
|
+
passed: 0,
|
|
5194
|
+
failures: 0,
|
|
5195
|
+
skipped: 0
|
|
5196
|
+
}
|
|
5197
|
+
);
|
|
4727
5198
|
const suites = getSuites(file);
|
|
4728
5199
|
for (const suite of suites) {
|
|
4729
5200
|
if ((_a2 = suite.result) == null ? void 0 : _a2.errors) {
|
|
@@ -4752,38 +5223,46 @@ class JUnitReporter {
|
|
|
4752
5223
|
stats: stats2
|
|
4753
5224
|
};
|
|
4754
5225
|
});
|
|
4755
|
-
const stats = transformed.reduce(
|
|
4756
|
-
stats2
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
5226
|
+
const stats = transformed.reduce(
|
|
5227
|
+
(stats2, file) => {
|
|
5228
|
+
stats2.tests += file.tasks.length;
|
|
5229
|
+
stats2.failures += file.stats.failures;
|
|
5230
|
+
return stats2;
|
|
5231
|
+
},
|
|
5232
|
+
{
|
|
5233
|
+
name: this.options.suiteName || "vitest tests",
|
|
5234
|
+
tests: 0,
|
|
5235
|
+
failures: 0,
|
|
5236
|
+
errors: 0,
|
|
5237
|
+
// we cannot detect those
|
|
5238
|
+
time: executionTime((/* @__PURE__ */ new Date()).getTime() - this._timeStart.getTime())
|
|
5239
|
+
}
|
|
5240
|
+
);
|
|
4767
5241
|
await this.writeElement("testsuites", stats, async () => {
|
|
4768
5242
|
for (const file of transformed) {
|
|
4769
5243
|
const filename = relative(this.ctx.config.root, file.filepath);
|
|
4770
|
-
await this.writeElement(
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
5244
|
+
await this.writeElement(
|
|
5245
|
+
"testsuite",
|
|
5246
|
+
{
|
|
5247
|
+
name: filename,
|
|
5248
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5249
|
+
hostname: hostname(),
|
|
5250
|
+
tests: file.tasks.length,
|
|
5251
|
+
failures: file.stats.failures,
|
|
5252
|
+
errors: 0,
|
|
5253
|
+
// An errored test is one that had an unanticipated problem. We cannot detect those.
|
|
5254
|
+
skipped: file.stats.skipped,
|
|
5255
|
+
time: getDuration(file)
|
|
5256
|
+
},
|
|
5257
|
+
async () => {
|
|
5258
|
+
await this.writeTasks(file.tasks, filename);
|
|
5259
|
+
}
|
|
5260
|
+
);
|
|
4783
5261
|
}
|
|
4784
5262
|
});
|
|
4785
|
-
if (this.reportFile)
|
|
5263
|
+
if (this.reportFile) {
|
|
4786
5264
|
this.ctx.logger.log(`JUNIT report written to ${this.reportFile}`);
|
|
5265
|
+
}
|
|
4787
5266
|
await ((_a = this.fileFd) == null ? void 0 : _a.close());
|
|
4788
5267
|
this.fileFd = void 0;
|
|
4789
5268
|
}
|
|
@@ -4792,12 +5271,16 @@ class JUnitReporter {
|
|
|
4792
5271
|
function flattenTasks(task, baseName = "") {
|
|
4793
5272
|
const base = baseName ? `${baseName} > ` : "";
|
|
4794
5273
|
if (task.type === "suite" && task.tasks.length > 0) {
|
|
4795
|
-
return task.tasks.flatMap(
|
|
5274
|
+
return task.tasks.flatMap(
|
|
5275
|
+
(child) => flattenTasks(child, `${base}${task.name}`)
|
|
5276
|
+
);
|
|
4796
5277
|
} else {
|
|
4797
|
-
return [
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
5278
|
+
return [
|
|
5279
|
+
{
|
|
5280
|
+
...task,
|
|
5281
|
+
name: `${base}${task.name}`
|
|
5282
|
+
}
|
|
5283
|
+
];
|
|
4801
5284
|
}
|
|
4802
5285
|
}
|
|
4803
5286
|
class TapFlatReporter extends TapReporter {
|
|
@@ -4842,23 +5325,26 @@ class GithubActionsReporter {
|
|
|
4842
5325
|
const tasks = getTasks(file);
|
|
4843
5326
|
const project = this.ctx.getProjectByTaskId(file.id);
|
|
4844
5327
|
for (const task of tasks) {
|
|
4845
|
-
if (((_a = task.result) == null ? void 0 : _a.state) !== "fail")
|
|
5328
|
+
if (((_a = task.result) == null ? void 0 : _a.state) !== "fail") {
|
|
4846
5329
|
continue;
|
|
5330
|
+
}
|
|
4847
5331
|
const title = getFullName(task, " > ");
|
|
4848
5332
|
for (const error of ((_b = task.result) == null ? void 0 : _b.errors) ?? []) {
|
|
4849
5333
|
projectErrors.push({
|
|
4850
5334
|
project,
|
|
4851
5335
|
title,
|
|
4852
|
-
error
|
|
5336
|
+
error,
|
|
5337
|
+
file
|
|
4853
5338
|
});
|
|
4854
5339
|
}
|
|
4855
5340
|
}
|
|
4856
5341
|
}
|
|
4857
|
-
for (const { project, title, error } of projectErrors) {
|
|
4858
|
-
const result = capturePrintError(error, this.ctx, project);
|
|
5342
|
+
for (const { project, title, error, file } of projectErrors) {
|
|
5343
|
+
const result = capturePrintError(error, this.ctx, { project, task: file });
|
|
4859
5344
|
const stack = result == null ? void 0 : result.nearest;
|
|
4860
|
-
if (!stack)
|
|
5345
|
+
if (!stack) {
|
|
4861
5346
|
continue;
|
|
5347
|
+
}
|
|
4862
5348
|
const formatted = formatMessage({
|
|
4863
5349
|
command: "error",
|
|
4864
5350
|
properties: {
|
|
@@ -4901,8 +5387,9 @@ class BlobReporter {
|
|
|
4901
5387
|
this.options = options;
|
|
4902
5388
|
}
|
|
4903
5389
|
onInit(ctx) {
|
|
4904
|
-
if (ctx.config.watch)
|
|
5390
|
+
if (ctx.config.watch) {
|
|
4905
5391
|
throw new Error("Blob reporter is not supported in watch mode");
|
|
5392
|
+
}
|
|
4906
5393
|
this.ctx = ctx;
|
|
4907
5394
|
}
|
|
4908
5395
|
async onFinished(files = [], errors = [], coverage) {
|
|
@@ -4911,19 +5398,27 @@ class BlobReporter {
|
|
|
4911
5398
|
const shard = this.ctx.config.shard;
|
|
4912
5399
|
outputFile = shard ? `.vitest-reports/blob-${shard.index}-${shard.count}.json` : ".vitest-reports/blob.json";
|
|
4913
5400
|
}
|
|
4914
|
-
const moduleKeys = this.ctx.projects.map(
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
5401
|
+
const moduleKeys = this.ctx.projects.map(
|
|
5402
|
+
(project) => {
|
|
5403
|
+
return [
|
|
5404
|
+
project.getName(),
|
|
5405
|
+
[...project.server.moduleGraph.idToModuleMap.keys()]
|
|
5406
|
+
];
|
|
5407
|
+
}
|
|
5408
|
+
);
|
|
5409
|
+
const report = stringify([
|
|
5410
|
+
this.ctx.version,
|
|
5411
|
+
files,
|
|
5412
|
+
errors,
|
|
5413
|
+
moduleKeys,
|
|
5414
|
+
coverage
|
|
5415
|
+
]);
|
|
4918
5416
|
const reportFile = resolve(this.ctx.config.root, outputFile);
|
|
4919
5417
|
const dir = dirname(reportFile);
|
|
4920
|
-
if (!existsSync(dir))
|
|
5418
|
+
if (!existsSync(dir)) {
|
|
4921
5419
|
await mkdir(dir, { recursive: true });
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
report,
|
|
4925
|
-
"utf-8"
|
|
4926
|
-
);
|
|
5420
|
+
}
|
|
5421
|
+
await writeFile(reportFile, report, "utf-8");
|
|
4927
5422
|
this.ctx.logger.log("blob report written to", reportFile);
|
|
4928
5423
|
}
|
|
4929
5424
|
}
|
|
@@ -4932,18 +5427,26 @@ async function readBlobs(blobsDirectory, projectsArray) {
|
|
|
4932
5427
|
const blobsFiles = await readdir(resolvedDir);
|
|
4933
5428
|
const promises = blobsFiles.map(async (file) => {
|
|
4934
5429
|
const content = await readFile(resolve(resolvedDir, file), "utf-8");
|
|
4935
|
-
const [version, files2, errors2, moduleKeys, coverage] = parse(
|
|
5430
|
+
const [version, files2, errors2, moduleKeys, coverage] = parse(
|
|
5431
|
+
content
|
|
5432
|
+
);
|
|
4936
5433
|
return { version, files: files2, errors: errors2, moduleKeys, coverage };
|
|
4937
5434
|
});
|
|
4938
5435
|
const blobs = await Promise.all(promises);
|
|
4939
|
-
if (!blobs.length)
|
|
4940
|
-
throw new Error(
|
|
4941
|
-
|
|
5436
|
+
if (!blobs.length) {
|
|
5437
|
+
throw new Error(
|
|
5438
|
+
`vitest.mergeReports() requires at least one blob file paths in the config`
|
|
5439
|
+
);
|
|
5440
|
+
}
|
|
5441
|
+
const projects = Object.fromEntries(
|
|
5442
|
+
projectsArray.map((p) => [p.getName(), p])
|
|
5443
|
+
);
|
|
4942
5444
|
blobs.forEach((blob) => {
|
|
4943
5445
|
blob.moduleKeys.forEach(([projectName, moduleIds]) => {
|
|
4944
5446
|
const project = projects[projectName];
|
|
4945
|
-
if (!project)
|
|
5447
|
+
if (!project) {
|
|
4946
5448
|
return;
|
|
5449
|
+
}
|
|
4947
5450
|
moduleIds.forEach((moduleId) => {
|
|
4948
5451
|
project.server.moduleGraph.idToModuleMap.set(moduleId, {
|
|
4949
5452
|
id: moduleId,
|
|
@@ -4987,8 +5490,9 @@ function formatFilepath(path) {
|
|
|
4987
5490
|
const lastSlash = Math.max(path.lastIndexOf("/") + 1, 0);
|
|
4988
5491
|
const basename = path.slice(lastSlash);
|
|
4989
5492
|
let firstDot = basename.indexOf(".");
|
|
4990
|
-
if (firstDot < 0)
|
|
5493
|
+
if (firstDot < 0) {
|
|
4991
5494
|
firstDot = basename.length;
|
|
5495
|
+
}
|
|
4992
5496
|
firstDot += lastSlash;
|
|
4993
5497
|
return c.dim(path.slice(0, lastSlash)) + path.slice(lastSlash, firstDot) + c.dim(path.slice(firstDot));
|
|
4994
5498
|
}
|
|
@@ -4996,7 +5500,19 @@ function formatNumber(number) {
|
|
|
4996
5500
|
const res = String(number.toFixed(number < 100 ? 4 : 2)).split(".");
|
|
4997
5501
|
return res[0].replace(/(?=(?:\d{3})+$)\B/g, ",") + (res[1] ? `.${res[1]}` : "");
|
|
4998
5502
|
}
|
|
4999
|
-
const tableHead = [
|
|
5503
|
+
const tableHead = [
|
|
5504
|
+
"name",
|
|
5505
|
+
"hz",
|
|
5506
|
+
"min",
|
|
5507
|
+
"max",
|
|
5508
|
+
"mean",
|
|
5509
|
+
"p75",
|
|
5510
|
+
"p99",
|
|
5511
|
+
"p995",
|
|
5512
|
+
"p999",
|
|
5513
|
+
"rme",
|
|
5514
|
+
"samples"
|
|
5515
|
+
];
|
|
5000
5516
|
function renderBenchmarkItems(result) {
|
|
5001
5517
|
return [
|
|
5002
5518
|
result.name,
|
|
@@ -5013,14 +5529,8 @@ function renderBenchmarkItems(result) {
|
|
|
5013
5529
|
];
|
|
5014
5530
|
}
|
|
5015
5531
|
function computeColumnWidths(results) {
|
|
5016
|
-
const rows = [
|
|
5017
|
-
|
|
5018
|
-
...results.map((v) => renderBenchmarkItems(v))
|
|
5019
|
-
];
|
|
5020
|
-
return Array.from(
|
|
5021
|
-
tableHead,
|
|
5022
|
-
(_, i) => Math.max(...rows.map((row) => stripAnsi(row[i]).length))
|
|
5023
|
-
);
|
|
5532
|
+
const rows = [tableHead, ...results.map((v) => renderBenchmarkItems(v))];
|
|
5533
|
+
return Array.from(tableHead, (_, i) => Math.max(...rows.map((row) => stripAnsi(row[i]).length)));
|
|
5024
5534
|
}
|
|
5025
5535
|
function padRow(row, widths) {
|
|
5026
5536
|
return row.map(
|
|
@@ -5084,24 +5594,34 @@ function renderTree(tasks, options, level = 0, shallow = false) {
|
|
|
5084
5594
|
for (const task of tasks) {
|
|
5085
5595
|
const padding = " ".repeat(level ? 1 : 0);
|
|
5086
5596
|
let prefix = "";
|
|
5087
|
-
if (idx === 0 && ((_c = task.meta) == null ? void 0 : _c.benchmark))
|
|
5597
|
+
if (idx === 0 && ((_c = task.meta) == null ? void 0 : _c.benchmark)) {
|
|
5088
5598
|
prefix += `${renderTableHead(columnWidths)}
|
|
5089
5599
|
${padding}`;
|
|
5600
|
+
}
|
|
5090
5601
|
prefix += ` ${getStateSymbol(task)} `;
|
|
5091
5602
|
let suffix = "";
|
|
5092
|
-
if (task.type === "suite")
|
|
5603
|
+
if (task.type === "suite") {
|
|
5093
5604
|
suffix += c.dim(` (${getTests(task).length})`);
|
|
5094
|
-
|
|
5605
|
+
}
|
|
5606
|
+
if (task.mode === "skip" || task.mode === "todo") {
|
|
5095
5607
|
suffix += ` ${c.dim(c.gray("[skipped]"))}`;
|
|
5608
|
+
}
|
|
5096
5609
|
if (((_d = task.result) == null ? void 0 : _d.duration) != null) {
|
|
5097
|
-
if (task.result.duration > options.slowTestThreshold)
|
|
5098
|
-
suffix += c.yellow(
|
|
5610
|
+
if (task.result.duration > options.slowTestThreshold) {
|
|
5611
|
+
suffix += c.yellow(
|
|
5612
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
5613
|
+
);
|
|
5614
|
+
}
|
|
5615
|
+
}
|
|
5616
|
+
if (options.showHeap && ((_e = task.result) == null ? void 0 : _e.heap) != null) {
|
|
5617
|
+
suffix += c.magenta(
|
|
5618
|
+
` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
|
|
5619
|
+
);
|
|
5099
5620
|
}
|
|
5100
|
-
if (options.showHeap && ((_e = task.result) == null ? void 0 : _e.heap) != null)
|
|
5101
|
-
suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
5102
5621
|
let name = task.name;
|
|
5103
|
-
if (level === 0)
|
|
5622
|
+
if (level === 0) {
|
|
5104
5623
|
name = formatFilepath(name);
|
|
5624
|
+
}
|
|
5105
5625
|
const bench = benchMap[task.id];
|
|
5106
5626
|
if (bench) {
|
|
5107
5627
|
let body = renderBenchmark(bench.current, columnWidths);
|
|
@@ -5109,21 +5629,25 @@ ${padding}`;
|
|
|
5109
5629
|
if (bench.current.hz) {
|
|
5110
5630
|
const diff = bench.current.hz / bench.baseline.hz;
|
|
5111
5631
|
const diffFixed = diff.toFixed(2);
|
|
5112
|
-
if (diffFixed === "1.0.0")
|
|
5632
|
+
if (diffFixed === "1.0.0") {
|
|
5113
5633
|
body += ` ${c.gray(`[${diffFixed}x]`)}`;
|
|
5114
|
-
|
|
5634
|
+
}
|
|
5635
|
+
if (diff > 1) {
|
|
5115
5636
|
body += ` ${c.blue(`[${diffFixed}x] \u21D1`)}`;
|
|
5116
|
-
else
|
|
5637
|
+
} else {
|
|
5117
5638
|
body += ` ${c.red(`[${diffFixed}x] \u21D3`)}`;
|
|
5639
|
+
}
|
|
5118
5640
|
}
|
|
5119
5641
|
output.push(padding + prefix + body + suffix);
|
|
5120
5642
|
const bodyBaseline = renderBenchmark(bench.baseline, columnWidths);
|
|
5121
5643
|
output.push(`${padding} ${bodyBaseline} ${c.dim("(baseline)")}`);
|
|
5122
5644
|
} else {
|
|
5123
|
-
if (bench.current.rank === 1 && benchCount > 1)
|
|
5645
|
+
if (bench.current.rank === 1 && benchCount > 1) {
|
|
5124
5646
|
body += ` ${c.bold(c.green(" fastest"))}`;
|
|
5125
|
-
|
|
5647
|
+
}
|
|
5648
|
+
if (bench.current.rank === benchCount && benchCount > 2) {
|
|
5126
5649
|
body += ` ${c.bold(c.gray(" slowest"))}`;
|
|
5650
|
+
}
|
|
5127
5651
|
output.push(padding + prefix + body + suffix);
|
|
5128
5652
|
}
|
|
5129
5653
|
} else {
|
|
@@ -5133,8 +5657,9 @@ ${padding}`;
|
|
|
5133
5657
|
let data = outputMap.get(task);
|
|
5134
5658
|
if (typeof data === "string") {
|
|
5135
5659
|
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
5136
|
-
if (data === "")
|
|
5660
|
+
if (data === "") {
|
|
5137
5661
|
data = void 0;
|
|
5662
|
+
}
|
|
5138
5663
|
}
|
|
5139
5664
|
if (data != null) {
|
|
5140
5665
|
const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
|
|
@@ -5142,8 +5667,9 @@ ${padding}`;
|
|
|
5142
5667
|
}
|
|
5143
5668
|
}
|
|
5144
5669
|
if (!shallow && task.type === "suite" && task.tasks.length > 0) {
|
|
5145
|
-
if ((_g = task.result) == null ? void 0 : _g.state)
|
|
5670
|
+
if ((_g = task.result) == null ? void 0 : _g.state) {
|
|
5146
5671
|
output.push(renderTree(task.tasks, options, level + 1));
|
|
5672
|
+
}
|
|
5147
5673
|
}
|
|
5148
5674
|
idx++;
|
|
5149
5675
|
}
|
|
@@ -5158,8 +5684,9 @@ function createTableRenderer(_tasks, options) {
|
|
|
5158
5684
|
}
|
|
5159
5685
|
return {
|
|
5160
5686
|
start() {
|
|
5161
|
-
if (timer)
|
|
5687
|
+
if (timer) {
|
|
5162
5688
|
return this;
|
|
5689
|
+
}
|
|
5163
5690
|
timer = setInterval(update, 200);
|
|
5164
5691
|
return this;
|
|
5165
5692
|
},
|
|
@@ -5188,8 +5715,11 @@ class TableReporter extends BaseReporter {
|
|
|
5188
5715
|
rendererOptions = {};
|
|
5189
5716
|
onTestRemoved(trigger) {
|
|
5190
5717
|
this.stopListRender();
|
|
5191
|
-
this.ctx.logger.clearScreen(
|
|
5192
|
-
|
|
5718
|
+
this.ctx.logger.clearScreen(
|
|
5719
|
+
c.yellow("Test removed...") + (trigger ? c.dim(` [ ${this.relative(trigger)} ]
|
|
5720
|
+
`) : ""),
|
|
5721
|
+
true
|
|
5722
|
+
);
|
|
5193
5723
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
5194
5724
|
createTableRenderer(files, this.rendererOptions).stop();
|
|
5195
5725
|
this.ctx.logger.log();
|
|
@@ -5202,9 +5732,12 @@ class TableReporter extends BaseReporter {
|
|
|
5202
5732
|
this.rendererOptions.showHeap = this.ctx.config.logHeapUsage;
|
|
5203
5733
|
this.rendererOptions.slowTestThreshold = this.ctx.config.slowTestThreshold;
|
|
5204
5734
|
if ((_a = this.ctx.config.benchmark) == null ? void 0 : _a.compare) {
|
|
5205
|
-
const compareFile = pathe.resolve(
|
|
5735
|
+
const compareFile = pathe.resolve(
|
|
5736
|
+
this.ctx.config.root,
|
|
5737
|
+
(_b = this.ctx.config.benchmark) == null ? void 0 : _b.compare
|
|
5738
|
+
);
|
|
5206
5739
|
try {
|
|
5207
|
-
this.rendererOptions.compare =
|
|
5740
|
+
this.rendererOptions.compare = flattenFormattedBenchmarkReport(
|
|
5208
5741
|
JSON.parse(
|
|
5209
5742
|
await fs.promises.readFile(compareFile, "utf-8")
|
|
5210
5743
|
)
|
|
@@ -5215,16 +5748,21 @@ class TableReporter extends BaseReporter {
|
|
|
5215
5748
|
}
|
|
5216
5749
|
if (this.isTTY) {
|
|
5217
5750
|
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
5218
|
-
if (!this.renderer)
|
|
5219
|
-
this.renderer = createTableRenderer(
|
|
5220
|
-
|
|
5751
|
+
if (!this.renderer) {
|
|
5752
|
+
this.renderer = createTableRenderer(
|
|
5753
|
+
files,
|
|
5754
|
+
this.rendererOptions
|
|
5755
|
+
).start();
|
|
5756
|
+
} else {
|
|
5221
5757
|
this.renderer.update(files);
|
|
5758
|
+
}
|
|
5222
5759
|
}
|
|
5223
5760
|
}
|
|
5224
5761
|
onTaskUpdate(packs) {
|
|
5225
5762
|
var _a, _b;
|
|
5226
|
-
if (this.isTTY)
|
|
5763
|
+
if (this.isTTY) {
|
|
5227
5764
|
return;
|
|
5765
|
+
}
|
|
5228
5766
|
for (const pack of packs) {
|
|
5229
5767
|
const task = this.ctx.state.idMap.get(pack[0]);
|
|
5230
5768
|
if (task && task.type === "suite" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
|
|
@@ -5233,11 +5771,19 @@ class TableReporter extends BaseReporter {
|
|
|
5233
5771
|
var _a2;
|
|
5234
5772
|
return ((_a2 = t.result) == null ? void 0 : _a2.state) !== "run";
|
|
5235
5773
|
})) {
|
|
5236
|
-
let title = ` ${getStateSymbol(task)} ${getFullName(
|
|
5237
|
-
|
|
5238
|
-
|
|
5774
|
+
let title = ` ${getStateSymbol(task)} ${getFullName(
|
|
5775
|
+
task,
|
|
5776
|
+
c.dim(" > ")
|
|
5777
|
+
)}`;
|
|
5778
|
+
if (task.result.duration != null && task.result.duration > this.ctx.config.slowTestThreshold) {
|
|
5779
|
+
title += c.yellow(
|
|
5780
|
+
` ${Math.round(task.result.duration)}${c.dim("ms")}`
|
|
5781
|
+
);
|
|
5782
|
+
}
|
|
5239
5783
|
this.ctx.logger.log(title);
|
|
5240
|
-
this.ctx.logger.log(
|
|
5784
|
+
this.ctx.logger.log(
|
|
5785
|
+
renderTree(benches, this.rendererOptions, 1, true)
|
|
5786
|
+
);
|
|
5241
5787
|
}
|
|
5242
5788
|
}
|
|
5243
5789
|
}
|
|
@@ -5251,9 +5797,10 @@ class TableReporter extends BaseReporter {
|
|
|
5251
5797
|
if (outputFile) {
|
|
5252
5798
|
outputFile = pathe.resolve(this.ctx.config.root, outputFile);
|
|
5253
5799
|
const outputDirectory = pathe.dirname(outputFile);
|
|
5254
|
-
if (!fs.existsSync(outputDirectory))
|
|
5800
|
+
if (!fs.existsSync(outputDirectory)) {
|
|
5255
5801
|
await fs.promises.mkdir(outputDirectory, { recursive: true });
|
|
5256
|
-
|
|
5802
|
+
}
|
|
5803
|
+
const output = createFormattedBenchmarkReport(files);
|
|
5257
5804
|
await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
|
|
5258
5805
|
this.ctx.logger.log(`Benchmark report written to ${outputFile}`);
|
|
5259
5806
|
}
|
|
@@ -5273,13 +5820,14 @@ class TableReporter extends BaseReporter {
|
|
|
5273
5820
|
}
|
|
5274
5821
|
onUserConsoleLog(log) {
|
|
5275
5822
|
var _a;
|
|
5276
|
-
if (!this.shouldLog(log))
|
|
5823
|
+
if (!this.shouldLog(log)) {
|
|
5277
5824
|
return;
|
|
5825
|
+
}
|
|
5278
5826
|
(_a = this.renderer) == null ? void 0 : _a.clear();
|
|
5279
5827
|
super.onUserConsoleLog(log);
|
|
5280
5828
|
}
|
|
5281
5829
|
}
|
|
5282
|
-
function
|
|
5830
|
+
function createFormattedBenchmarkReport(files) {
|
|
5283
5831
|
var _a;
|
|
5284
5832
|
const report = { files: [] };
|
|
5285
5833
|
for (const file of files) {
|
|
@@ -5314,12 +5862,13 @@ function createFormattedBenchamrkReport(files) {
|
|
|
5314
5862
|
}
|
|
5315
5863
|
return report;
|
|
5316
5864
|
}
|
|
5317
|
-
function
|
|
5865
|
+
function flattenFormattedBenchmarkReport(report) {
|
|
5318
5866
|
const flat = {};
|
|
5319
5867
|
for (const file of report.files) {
|
|
5320
5868
|
for (const group of file.groups) {
|
|
5321
|
-
for (const t of group.benchmarks)
|
|
5869
|
+
for (const t of group.benchmarks) {
|
|
5322
5870
|
flat[t.id] = t;
|
|
5871
|
+
}
|
|
5323
5872
|
}
|
|
5324
5873
|
}
|
|
5325
5874
|
return flat;
|
|
@@ -5344,4 +5893,4 @@ const ReportersMap = {
|
|
|
5344
5893
|
"github-actions": GithubActionsReporter
|
|
5345
5894
|
};
|
|
5346
5895
|
|
|
5347
|
-
export {
|
|
5896
|
+
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 };
|