Skip to content

Commit 13d85bd

Browse files
authored
feat: introduce experimental reported tasks (#6149)
1 parent e7acd0c commit 13d85bd

34 files changed

+1258
-112
lines changed

packages/browser/src/node/rpc.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function setupBrowserRpc(
7070
ctx.state.catchError(error, type)
7171
},
7272
async onCollected(files) {
73-
ctx.state.collectFiles(files)
73+
ctx.state.collectFiles(project, files)
7474
await ctx.report('onCollected', files)
7575
},
7676
async onTaskUpdate(packs) {

packages/runner/src/collect.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { processError } from '@vitest/utils/error'
2+
import { toArray } from '@vitest/utils'
23
import type { File, SuiteHooks } from './types/tasks'
34
import type { VitestRunner } from './types/runner'
45
import {
@@ -34,11 +35,18 @@ export async function collectTests(
3435
clearCollectorContext(filepath, runner)
3536

3637
try {
37-
const setupStart = now()
38-
await runSetupFiles(config, runner)
38+
const setupFiles = toArray(config.setupFiles)
39+
if (setupFiles.length) {
40+
const setupStart = now()
41+
await runSetupFiles(config, setupFiles, runner)
42+
const setupEnd = now()
43+
file.setupDuration = setupEnd - setupStart
44+
}
45+
else {
46+
file.setupDuration = 0
47+
}
3948

4049
const collectStart = now()
41-
file.setupDuration = collectStart - setupStart
4250

4351
await runner.importFile(filepath, 'collect')
4452

packages/runner/src/setup.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { toArray } from '@vitest/utils'
21
import type { VitestRunner, VitestRunnerConfig } from './types/runner'
32

43
export async function runSetupFiles(
54
config: VitestRunnerConfig,
5+
files: string[],
66
runner: VitestRunner,
77
): Promise<void> {
8-
const files = toArray(config.setupFiles)
98
if (config.sequence.setupFiles === 'parallel') {
109
await Promise.all(
1110
files.map(async (fsPath) => {

packages/ui/client/composables/client/static.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
} from 'vitest'
1010
import { parse } from 'flatted'
1111
import { decompressSync, strFromU8 } from 'fflate'
12-
import { StateManager } from '../../../../vitest/src/node/state'
12+
import { StateManager } from '../../../../ws-client/src/state'
1313

1414
interface HTMLReportMetadata {
1515
paths: string[]
@@ -55,7 +55,6 @@ export function createStaticClient(): VitestClient {
5555
},
5656
getTransformResult: asyncNoop,
5757
onDone: noop,
58-
onCollected: asyncNoop,
5958
onTaskUpdate: noop,
6059
writeFile: asyncNoop,
6160
rerun: asyncNoop,

packages/utils/src/diff/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const FALLBACK_FORMAT_OPTIONS = {
6969
* @param options Diff options
7070
* @returns {string | null} a string diff
7171
*/
72-
export function diff(a: any, b: any, options?: DiffOptions): string | null {
72+
export function diff(a: any, b: any, options?: DiffOptions): string | undefined {
7373
if (Object.is(a, b)) {
7474
return ''
7575
}
@@ -80,11 +80,11 @@ export function diff(a: any, b: any, options?: DiffOptions): string | null {
8080
if (aType === 'object' && typeof a.asymmetricMatch === 'function') {
8181
if (a.$$typeof !== Symbol.for('jest.asymmetricMatcher')) {
8282
// Do not know expected type of user-defined asymmetric matcher.
83-
return null
83+
return undefined
8484
}
8585
if (typeof a.getExpectedType !== 'function') {
8686
// For example, expect.anything() matches either null or undefined
87-
return null
87+
return undefined
8888
}
8989
expectedType = a.getExpectedType()
9090
// Primitive types boolean and number omit difference below.
@@ -104,7 +104,7 @@ export function diff(a: any, b: any, options?: DiffOptions): string | null {
104104
}
105105

106106
if (omitDifference) {
107-
return null
107+
return undefined
108108
}
109109

110110
switch (aType) {
@@ -234,7 +234,7 @@ export function printDiffOrStringify(
234234
expected: unknown,
235235
received: unknown,
236236
options?: DiffOptions,
237-
): string | null {
237+
): string | undefined {
238238
const { aAnnotation, bAnnotation } = normalizeDiffOptions(options)
239239

240240
if (

packages/utils/src/error.ts

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { type DiffOptions, printDiffOrStringify } from './diff'
22
import { format, stringify } from './display'
3+
import type { TestError } from './types'
34

45
// utils is bundled for any environment and might not support `Element`
56
declare class Element {
@@ -26,7 +27,7 @@ function getUnserializableMessage(err: unknown) {
2627
}
2728

2829
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
29-
export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
30+
export function serializeValue(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
3031
if (!val || typeof val === 'string') {
3132
return val
3233
}
@@ -41,7 +42,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
4142
}
4243
// cannot serialize immutables as immutables
4344
if (isImmutable(val)) {
44-
return serializeError(val.toJSON(), seen)
45+
return serializeValue(val.toJSON(), seen)
4546
}
4647
if (
4748
val instanceof Promise
@@ -56,7 +57,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
5657
return `${val.toString()} ${format(val.sample)}`
5758
}
5859
if (typeof val.toJSON === 'function') {
59-
return serializeError(val.toJSON(), seen)
60+
return serializeValue(val.toJSON(), seen)
6061
}
6162

6263
if (seen.has(val)) {
@@ -69,7 +70,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
6970
seen.set(val, clone)
7071
val.forEach((e, i) => {
7172
try {
72-
clone[i] = serializeError(e, seen)
73+
clone[i] = serializeValue(e, seen)
7374
}
7475
catch (err) {
7576
clone[i] = getUnserializableMessage(err)
@@ -90,7 +91,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
9091
return
9192
}
9293
try {
93-
clone[key] = serializeError(val[key], seen)
94+
clone[key] = serializeValue(val[key], seen)
9495
}
9596
catch (err) {
9697
// delete in case it has a setter from prototype that might throw
@@ -104,18 +105,22 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
104105
}
105106
}
106107

108+
export { serializeValue as serializeError }
109+
107110
function normalizeErrorMessage(message: string) {
108111
return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, '')
109112
}
110113

111114
export function processError(
112-
err: any,
115+
_err: any,
113116
diffOptions?: DiffOptions,
114117
seen: WeakSet<WeakKey> = new WeakSet(),
115118
): any {
116-
if (!err || typeof err !== 'object') {
117-
return { message: err }
119+
if (!_err || typeof _err !== 'object') {
120+
return { message: String(_err) }
118121
}
122+
const err = _err as TestError
123+
119124
// stack is not serialized in worker communication
120125
// we stringify it first
121126
if (err.stack) {
@@ -133,7 +138,7 @@ export function processError(
133138
) {
134139
err.diff = printDiffOrStringify(err.actual, err.expected, {
135140
...diffOptions,
136-
...err.diffOptions,
141+
...err.diffOptions as DiffOptions,
137142
})
138143
}
139144

@@ -163,10 +168,10 @@ export function processError(
163168
catch {}
164169

165170
try {
166-
return serializeError(err)
171+
return serializeValue(err)
167172
}
168173
catch (e: any) {
169-
return serializeError(
174+
return serializeValue(
170175
new Error(
171176
`Failed to fully serialize error: ${e?.message}\nInner error message: ${err?.message}`,
172177
),

packages/utils/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ export type {
4747
Constructable,
4848
ParsedStack,
4949
ErrorWithDiff,
50+
SerializedError,
51+
TestError,
5052
} from './types'

packages/utils/src/source-map.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface StackTraceParserOptions {
1515
ignoreStackEntries?: (RegExp | string)[]
1616
getSourceMap?: (file: string) => unknown
1717
getFileName?: (id: string) => string
18-
frameFilter?: (error: Error, frame: ParsedStack) => boolean | void
18+
frameFilter?: (error: ErrorWithDiff, frame: ParsedStack) => boolean | void
1919
}
2020

2121
const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m

packages/utils/src/types.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,29 @@ export interface ParsedStack {
3232
column: number
3333
}
3434

35-
export interface ErrorWithDiff extends Error {
36-
name: string
35+
export interface SerializedError {
36+
message: string
37+
stack?: string
38+
name?: string
39+
stacks?: ParsedStack[]
40+
cause?: SerializedError
41+
[key: string]: unknown
42+
}
43+
44+
export interface TestError extends SerializedError {
45+
cause?: TestError
46+
diff?: string
47+
actual?: string
48+
expected?: string
49+
}
50+
51+
/**
52+
* @deprecated Use `TestError` instead
53+
*/
54+
export interface ErrorWithDiff {
55+
message: string
56+
name?: string
57+
cause?: unknown
3758
nameStr?: string
3859
stack?: string
3960
stackStr?: string

packages/vitest/rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const plugins = [
9595
json(),
9696
commonjs(),
9797
esbuild({
98-
target: 'node14',
98+
target: 'node18',
9999
}),
100100
]
101101

packages/vitest/src/api/setup.ts

-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ export function setup(ctx: Vitest, _server?: ViteDevServer) {
4646
function setupClient(ws: WebSocket) {
4747
const rpc = createBirpc<WebSocketEvents, WebSocketHandlers>(
4848
{
49-
async onCollected(files) {
50-
ctx.state.collectFiles(files)
51-
await ctx.report('onCollected', files)
52-
},
5349
async onTaskUpdate(packs) {
5450
ctx.state.updateTasks(packs)
5551
await ctx.report('onTaskUpdate', packs)

packages/vitest/src/api/types.ts

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface TransformResultWithSource {
2727
}
2828

2929
export interface WebSocketHandlers {
30-
onCollected: (files?: File[]) => Promise<void>
3130
onTaskUpdate: (packs: TaskResultPack[]) => void
3231
getFiles: () => File[]
3332
getTestFiles: () => Promise<SerializedSpec[]>

packages/vitest/src/node/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ export class Vitest {
440440
files.forEach((file) => {
441441
file.logs?.forEach(log => this.state.updateUserLog(log))
442442
})
443-
this.state.collectFiles(files)
443+
this.state.collectFiles(project, files)
444444
}
445445

446446
await this.report('onCollected', files).catch(noop)

packages/vitest/src/node/error.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ function printModuleWarningForSourceCode(logger: Logger, path: string) {
306306
)
307307
}
308308

309-
export function displayDiff(diff: string | null, console: Console) {
309+
export function displayDiff(diff: string | undefined, console: Console) {
310310
if (diff) {
311311
console.error(`\n${diff}\n`)
312312
}

packages/vitest/src/node/pools/forks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function createForksPool(
137137
&& error instanceof Error
138138
&& /The task has been cancelled/.test(error.message)
139139
) {
140-
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
140+
ctx.state.cancelFiles(files, project)
141141
}
142142
else {
143143
throw error

packages/vitest/src/node/pools/rpc.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function createMethodsRPC(project: WorkspaceProject, options: MethodsOpti
7676
return ctx.report('onPathsCollected', paths)
7777
},
7878
onCollected(files) {
79-
ctx.state.collectFiles(files)
79+
ctx.state.collectFiles(project, files)
8080
return ctx.report('onCollected', files)
8181
},
8282
onAfterSuiteRun(meta) {

packages/vitest/src/node/pools/threads.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export function createThreadsPool(
135135
&& error instanceof Error
136136
&& /The task has been cancelled/.test(error.message)
137137
) {
138-
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
138+
ctx.state.cancelFiles(files, project)
139139
}
140140
else {
141141
throw error

packages/vitest/src/node/pools/typecheck.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
6161
checker.setFiles(files)
6262

6363
checker.onParseStart(async () => {
64-
ctx.state.collectFiles(checker.getTestFiles())
64+
ctx.state.collectFiles(project, checker.getTestFiles())
6565
await ctx.report('onCollected')
6666
})
6767

@@ -80,7 +80,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
8080
}
8181

8282
await checker.collectTests()
83-
ctx.state.collectFiles(checker.getTestFiles())
83+
ctx.state.collectFiles(project, checker.getTestFiles())
8484

8585
await ctx.report('onTaskUpdate', checker.getTestPacks())
8686
await ctx.report('onCollected')
@@ -107,7 +107,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
107107
const checker = await createWorkspaceTypechecker(project, files)
108108
checker.setFiles(files)
109109
await checker.collectTests()
110-
ctx.state.collectFiles(checker.getTestFiles())
110+
ctx.state.collectFiles(project, checker.getTestFiles())
111111
await ctx.report('onCollected')
112112
}
113113
}
@@ -135,7 +135,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
135135
})
136136
const triggered = await _p
137137
if (project.typechecker && !triggered) {
138-
ctx.state.collectFiles(project.typechecker.getTestFiles())
138+
ctx.state.collectFiles(project, project.typechecker.getTestFiles())
139139
await ctx.report('onCollected')
140140
await onParseEnd(project, project.typechecker.getResult())
141141
continue

packages/vitest/src/node/pools/vmForks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function createVmForksPool(
147147
&& error instanceof Error
148148
&& /The task has been cancelled/.test(error.message)
149149
) {
150-
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
150+
ctx.state.cancelFiles(files, project)
151151
}
152152
else {
153153
throw error

packages/vitest/src/node/pools/vmThreads.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function createVmThreadsPool(
141141
&& error instanceof Error
142142
&& /The task has been cancelled/.test(error.message)
143143
) {
144-
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
144+
ctx.state.cancelFiles(files, project)
145145
}
146146
else {
147147
throw error

0 commit comments

Comments
 (0)