Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce experimental reported tasks #6149

Merged
merged 53 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4d6b488
feat: introduce server tasks
sheremet-va Jul 16, 2024
0b64214
fix: implement result for the TestCase
sheremet-va Jul 16, 2024
962d6b8
chore: allow dynamic mode in options for tests (allow `context.skip()`)
sheremet-va Jul 16, 2024
ea28932
chore: don't support parent in a file
sheremet-va Jul 16, 2024
503b506
chore: make meta dynamic
sheremet-va Jul 16, 2024
73519b4
chore: cleanup
sheremet-va Jul 16, 2024
e79abce
refactor: better naming
sheremet-va Jul 16, 2024
83138c2
chore: make children and tests iterators
sheremet-va Jul 16, 2024
1ac4469
chore: cleanup
sheremet-va Jul 16, 2024
e22012b
chore: add findTest/findSuite methods
sheremet-va Jul 16, 2024
03c96d0
chore: cleanup
sheremet-va Jul 16, 2024
1a74c2f
feat: allow filtering tests by state
sheremet-va Jul 16, 2024
df3e04b
refactor: cleanup
sheremet-va Jul 16, 2024
0f74fcd
refactor: make parent and file getters
sheremet-va Jul 16, 2024
b317187
chore: add a note for function/getter
sheremet-va Jul 16, 2024
b3346b1
refactor: make class shape predictable
sheremet-va Jul 16, 2024
53814cd
chore: don't export SuiteImplementation
sheremet-va Jul 16, 2024
f0f99ef
feat: task collection
sheremet-va Jul 16, 2024
e68ed50
chore: fix find lookup
sheremet-va Jul 16, 2024
8cad39a
feat: push deep*, suites methods
sheremet-va Jul 16, 2024
d62a8a8
chore: don't return result if test is still running, diagnistic is av…
sheremet-va Jul 17, 2024
1b40e06
chore: improve types for test result
sheremet-va Jul 17, 2024
c6a3a34
chore: add flaky prop
sheremet-va Jul 17, 2024
ca14ffc
chore: export server tasks
sheremet-va Jul 17, 2024
1ce77bf
feat: register server tasks
sheremet-va Jul 17, 2024
95c6e91
fix: correctly collect files
sheremet-va Jul 17, 2024
4fee8ac
chore: fix type error
sheremet-va Jul 17, 2024
6f4f70b
chore: cleanup
sheremet-va Jul 17, 2024
91caca0
chore: cleanup
sheremet-va Jul 17, 2024
881a248
chore: cleanup
sheremet-va Jul 17, 2024
02a0067
refactor: move stuff around
sheremet-va Jul 17, 2024
ad420cb
chore: cleanup
sheremet-va Jul 17, 2024
47048d2
chore: cleanup
sheremet-va Jul 17, 2024
3c2a477
refactor: remove `file` and `parent` from TestFile, add `at` and `siz…
sheremet-va Jul 17, 2024
a9d0dfe
chore: export FileDiagnostic
sheremet-va Jul 17, 2024
ad0bbc0
test: add more tests
sheremet-va Jul 17, 2024
7a2fdff
chore: export reporter task types
sheremet-va Jul 25, 2024
93ea531
refctor: remove deepFind, rename deepTests to allTests, deepSuites to…
sheremet-va Jul 25, 2024
c67e908
chore: better error
sheremet-va Jul 25, 2024
28c65b2
chore: cleanup
sheremet-va Jul 25, 2024
6763c0d
test: fix diff test
sheremet-va Jul 25, 2024
893f50b
chore: cleanup
sheremet-va Jul 25, 2024
71d4879
chore: export TestError/SerializedError
sheremet-va Jul 25, 2024
b260937
chore: cleanup
sheremet-va Jul 25, 2024
864dad2
feat: add public project API
sheremet-va Jul 30, 2024
b937226
chore: cleanup
sheremet-va Jul 30, 2024
2fb38e5
chore: cleanup
sheremet-va Jul 30, 2024
776576f
chore: cleanup
sheremet-va Jul 30, 2024
05e2b0f
chore: cleanup
sheremet-va Jul 30, 2024
34e2e81
chore: cleanup
sheremet-va Jul 30, 2024
9850e88
chore: cleanup
sheremet-va Jul 30, 2024
8d87774
chore: cleanup
sheremet-va Jul 30, 2024
a41da6b
chore: deprecate Custom, File, Suite, Test and Task types
sheremet-va Jul 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/browser/src/node/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function setupBrowserRpc(
ctx.state.catchError(error, type)
},
async onCollected(files) {
ctx.state.collectFiles(files)
ctx.state.collectFiles(project, files)
await ctx.report('onCollected', files)
},
async onTaskUpdate(packs) {
Expand Down
14 changes: 11 additions & 3 deletions packages/runner/src/collect.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { processError } from '@vitest/utils/error'
import { toArray } from '@vitest/utils'
import type { File, SuiteHooks } from './types/tasks'
import type { VitestRunner } from './types/runner'
import {
Expand Down Expand Up @@ -34,11 +35,18 @@ export async function collectTests(
clearCollectorContext(filepath, runner)

try {
const setupStart = now()
await runSetupFiles(config, runner)
const setupFiles = toArray(config.setupFiles)
if (setupFiles.length) {
const setupStart = now()
await runSetupFiles(config, setupFiles, runner)
const setupEnd = now()
file.setupDuration = setupEnd - setupStart
}
else {
file.setupDuration = 0
}

const collectStart = now()
file.setupDuration = collectStart - setupStart

await runner.importFile(filepath, 'collect')

Expand Down
3 changes: 1 addition & 2 deletions packages/runner/src/setup.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { toArray } from '@vitest/utils'
import type { VitestRunner, VitestRunnerConfig } from './types/runner'

export async function runSetupFiles(
config: VitestRunnerConfig,
files: string[],
runner: VitestRunner,
): Promise<void> {
const files = toArray(config.setupFiles)
if (config.sequence.setupFiles === 'parallel') {
await Promise.all(
files.map(async (fsPath) => {
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/client/composables/client/static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
} from 'vitest'
import { parse } from 'flatted'
import { decompressSync, strFromU8 } from 'fflate'
import { StateManager } from '../../../../vitest/src/node/state'
import { StateManager } from '../../../../ws-client/src/state'

interface HTMLReportMetadata {
paths: string[]
Expand Down Expand Up @@ -55,7 +55,6 @@ export function createStaticClient(): VitestClient {
},
getTransformResult: asyncNoop,
onDone: noop,
onCollected: asyncNoop,
onTaskUpdate: noop,
writeFile: asyncNoop,
rerun: asyncNoop,
Expand Down
10 changes: 5 additions & 5 deletions packages/utils/src/diff/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const FALLBACK_FORMAT_OPTIONS = {
* @param options Diff options
* @returns {string | null} a string diff
*/
export function diff(a: any, b: any, options?: DiffOptions): string | null {
export function diff(a: any, b: any, options?: DiffOptions): string | undefined {
if (Object.is(a, b)) {
return ''
}
Expand All @@ -80,11 +80,11 @@ export function diff(a: any, b: any, options?: DiffOptions): string | null {
if (aType === 'object' && typeof a.asymmetricMatch === 'function') {
if (a.$$typeof !== Symbol.for('jest.asymmetricMatcher')) {
// Do not know expected type of user-defined asymmetric matcher.
return null
return undefined
}
if (typeof a.getExpectedType !== 'function') {
// For example, expect.anything() matches either null or undefined
return null
return undefined
}
expectedType = a.getExpectedType()
// Primitive types boolean and number omit difference below.
Expand All @@ -104,7 +104,7 @@ export function diff(a: any, b: any, options?: DiffOptions): string | null {
}

if (omitDifference) {
return null
return undefined
}

switch (aType) {
Expand Down Expand Up @@ -234,7 +234,7 @@ export function printDiffOrStringify(
expected: unknown,
received: unknown,
options?: DiffOptions,
): string | null {
): string | undefined {
const { aAnnotation, bAnnotation } = normalizeDiffOptions(options)

if (
Expand Down
27 changes: 16 additions & 11 deletions packages/utils/src/error.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type DiffOptions, printDiffOrStringify } from './diff'
import { format, stringify } from './display'
import type { TestError } from './types'

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

// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
export function serializeValue(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
if (!val || typeof val === 'string') {
return val
}
Expand All @@ -41,7 +42,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
}
// cannot serialize immutables as immutables
if (isImmutable(val)) {
return serializeError(val.toJSON(), seen)
return serializeValue(val.toJSON(), seen)
}
if (
val instanceof Promise
Expand All @@ -56,7 +57,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
return `${val.toString()} ${format(val.sample)}`
}
if (typeof val.toJSON === 'function') {
return serializeError(val.toJSON(), seen)
return serializeValue(val.toJSON(), seen)
}

if (seen.has(val)) {
Expand All @@ -69,7 +70,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
seen.set(val, clone)
val.forEach((e, i) => {
try {
clone[i] = serializeError(e, seen)
clone[i] = serializeValue(e, seen)
}
catch (err) {
clone[i] = getUnserializableMessage(err)
Expand All @@ -90,7 +91,7 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
return
}
try {
clone[key] = serializeError(val[key], seen)
clone[key] = serializeValue(val[key], seen)
}
catch (err) {
// delete in case it has a setter from prototype that might throw
Expand All @@ -104,18 +105,22 @@ export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakM
}
}

export { serializeValue as serializeError }

function normalizeErrorMessage(message: string) {
return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, '')
}

export function processError(
err: any,
_err: any,
diffOptions?: DiffOptions,
seen: WeakSet<WeakKey> = new WeakSet(),
): any {
if (!err || typeof err !== 'object') {
return { message: err }
if (!_err || typeof _err !== 'object') {
return { message: String(_err) }
}
const err = _err as TestError

// stack is not serialized in worker communication
// we stringify it first
if (err.stack) {
Expand All @@ -133,7 +138,7 @@ export function processError(
) {
err.diff = printDiffOrStringify(err.actual, err.expected, {
...diffOptions,
...err.diffOptions,
...err.diffOptions as DiffOptions,
})
}

Expand Down Expand Up @@ -163,10 +168,10 @@ export function processError(
catch {}

try {
return serializeError(err)
return serializeValue(err)
}
catch (e: any) {
return serializeError(
return serializeValue(
new Error(
`Failed to fully serialize error: ${e?.message}\nInner error message: ${err?.message}`,
),
Expand Down
2 changes: 2 additions & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ export type {
Constructable,
ParsedStack,
ErrorWithDiff,
SerializedError,
TestError,
} from './types'
2 changes: 1 addition & 1 deletion packages/utils/src/source-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface StackTraceParserOptions {
ignoreStackEntries?: (RegExp | string)[]
getSourceMap?: (file: string) => unknown
getFileName?: (id: string) => string
frameFilter?: (error: Error, frame: ParsedStack) => boolean | void
frameFilter?: (error: ErrorWithDiff, frame: ParsedStack) => boolean | void
}

const CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m
Expand Down
25 changes: 23 additions & 2 deletions packages/utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,29 @@ export interface ParsedStack {
column: number
}

export interface ErrorWithDiff extends Error {
name: string
export interface SerializedError {
message: string
stack?: string
name?: string
stacks?: ParsedStack[]
cause?: SerializedError
[key: string]: unknown
}

export interface TestError extends SerializedError {
cause?: TestError
diff?: string
actual?: string
expected?: string
}

/**
* @deprecated Use `TestError` instead
*/
export interface ErrorWithDiff {
message: string
name?: string
cause?: unknown
nameStr?: string
stack?: string
stackStr?: string
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const plugins = [
json(),
commonjs(),
esbuild({
target: 'node14',
target: 'node18',
}),
]

Expand Down
4 changes: 0 additions & 4 deletions packages/vitest/src/api/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ export function setup(ctx: Vitest, _server?: ViteDevServer) {
function setupClient(ws: WebSocket) {
const rpc = createBirpc<WebSocketEvents, WebSocketHandlers>(
{
async onCollected(files) {
ctx.state.collectFiles(files)
await ctx.report('onCollected', files)
},
async onTaskUpdate(packs) {
ctx.state.updateTasks(packs)
await ctx.report('onTaskUpdate', packs)
Expand Down
1 change: 0 additions & 1 deletion packages/vitest/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export interface TransformResultWithSource {
}

export interface WebSocketHandlers {
onCollected: (files?: File[]) => Promise<void>
onTaskUpdate: (packs: TaskResultPack[]) => void
getFiles: () => File[]
getTestFiles: () => Promise<SerializedSpec[]>
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ export class Vitest {
files.forEach((file) => {
file.logs?.forEach(log => this.state.updateUserLog(log))
})
this.state.collectFiles(files)
this.state.collectFiles(project, files)
}

await this.report('onCollected', files).catch(noop)
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ function printModuleWarningForSourceCode(logger: Logger, path: string) {
)
}

export function displayDiff(diff: string | null, console: Console) {
export function displayDiff(diff: string | undefined, console: Console) {
if (diff) {
console.error(`\n${diff}\n`)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/pools/forks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export function createForksPool(
&& error instanceof Error
&& /The task has been cancelled/.test(error.message)
) {
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
ctx.state.cancelFiles(files, project)
}
else {
throw error
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/pools/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function createMethodsRPC(project: WorkspaceProject, options: MethodsOpti
return ctx.report('onPathsCollected', paths)
},
onCollected(files) {
ctx.state.collectFiles(files)
ctx.state.collectFiles(project, files)
return ctx.report('onCollected', files)
},
onAfterSuiteRun(meta) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/pools/threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function createThreadsPool(
&& error instanceof Error
&& /The task has been cancelled/.test(error.message)
) {
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
ctx.state.cancelFiles(files, project)
}
else {
throw error
Expand Down
8 changes: 4 additions & 4 deletions packages/vitest/src/node/pools/typecheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
checker.setFiles(files)

checker.onParseStart(async () => {
ctx.state.collectFiles(checker.getTestFiles())
ctx.state.collectFiles(project, checker.getTestFiles())
await ctx.report('onCollected')
})

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

await checker.collectTests()
ctx.state.collectFiles(checker.getTestFiles())
ctx.state.collectFiles(project, checker.getTestFiles())

await ctx.report('onTaskUpdate', checker.getTestPacks())
await ctx.report('onCollected')
Expand All @@ -107,7 +107,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
const checker = await createWorkspaceTypechecker(project, files)
checker.setFiles(files)
await checker.collectTests()
ctx.state.collectFiles(checker.getTestFiles())
ctx.state.collectFiles(project, checker.getTestFiles())
await ctx.report('onCollected')
}
}
Expand Down Expand Up @@ -135,7 +135,7 @@ export function createTypecheckPool(ctx: Vitest): ProcessPool {
})
const triggered = await _p
if (project.typechecker && !triggered) {
ctx.state.collectFiles(project.typechecker.getTestFiles())
ctx.state.collectFiles(project, project.typechecker.getTestFiles())
await ctx.report('onCollected')
await onParseEnd(project, project.typechecker.getResult())
continue
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/pools/vmForks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export function createVmForksPool(
&& error instanceof Error
&& /The task has been cancelled/.test(error.message)
) {
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
ctx.state.cancelFiles(files, project)
}
else {
throw error
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/pools/vmThreads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function createVmThreadsPool(
&& error instanceof Error
&& /The task has been cancelled/.test(error.message)
) {
ctx.state.cancelFiles(files, ctx.config.root, project.config.name)
ctx.state.cancelFiles(files, project)
}
else {
throw error
Expand Down
Loading
Loading