Skip to content

Commit

Permalink
feat: capture syntax errors
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Dec 4, 2021
1 parent dfcd5a2 commit af91577
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 34 deletions.
66 changes: 43 additions & 23 deletions src/reporters/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ora from 'ora'
import { File, Reporter, RunnerContext, Suite, Task } from '../types'

const DOT = '· '
const CHECK = '✔ '
const CROSS = '⤫ '

export class DefaultReporter implements Reporter {
indent = 0
Expand All @@ -19,26 +21,6 @@ export class DefaultReporter implements Reporter {
this.start = performance.now()
}

onFinished({ files }: RunnerContext) {
this.end = performance.now()
const tasks = files.reduce((acc, file) => acc.concat(file.suites.flatMap(i => i.tasks)), [] as Task[])
const passed = tasks.filter(i => i.status === 'pass')
const failed = tasks.filter(i => i.status === 'fail')
const skipped = tasks.filter(i => i.status === 'skip')
const todo = tasks.filter(i => i.status === 'todo')

this.indent = 0

this.log(c.green(`Passed ${passed.length} / ${tasks.length}`))
if (skipped.length)
this.log(c.yellow(`Skipped ${skipped.length}`))
if (todo.length)
this.log(c.dim(`Todo ${todo.length}`))
if (failed.length)
this.log(c.red(`Failed ${failed.length} / ${tasks.length}`))
this.log(`Time ${(this.end - this.start).toFixed(2)}ms`)
}

onSuiteBegin(suite: Suite) {
if (suite.name) {
this.indent += 1
Expand Down Expand Up @@ -76,7 +58,7 @@ export class DefaultReporter implements Reporter {
task.__ora?.stop()

if (task.status === 'pass') {
this.log(`${c.green(`✔ ${task.name}`)}`)
this.log(`${c.green(CHECK + task.name)}`)
}
else if (task.status === 'skip') {
this.log(c.dim(c.yellow(`${DOT + task.name} (skipped)`)))
Expand All @@ -85,13 +67,51 @@ export class DefaultReporter implements Reporter {
this.log(c.dim(`${DOT + task.name} (todo)`))
}
else {
this.error(`${c.red(`⤫ ${c.inverse(c.red(' FAIL '))} ${task.name}`)}`)
this.error(String(task.error), 1)
this.error(`${c.red(`${CROSS}${task.name}`)}`)
process.exitCode = 1
}
this.indent -= 1
}

onFinished({ files }: RunnerContext) {
this.end = performance.now()
const failedFiles = files.filter(i => i.error)
const tasks = files.reduce((acc, file) => acc.concat(file.suites.flatMap(i => i.tasks)), [] as Task[])
const passed = tasks.filter(i => i.status === 'pass')
const failed = tasks.filter(i => i.status === 'fail')
const skipped = tasks.filter(i => i.status === 'skip')
const todo = tasks.filter(i => i.status === 'todo')

this.indent = 0

if (failedFiles.length) {
this.error(c.bold(`\nFailed to parse ${failedFiles.length} files:`))
failedFiles.forEach((i) => {
this.error(`\n- ${i.filepath}`)
console.error(i.error || 'Unknown error')
this.log()
})
}

if (failed.length) {
this.error(c.bold(`\nFailed Tests (${failed.length})`))
failed.forEach((task) => {
this.error(`\n${CROSS + c.inverse(c.red(' FAIL '))} ${[task.suite.name, task.name].filter(Boolean).join(' > ')} ${c.gray(`${task.file?.filepath}`)}`)
console.error(task.error || 'Unknown error')
this.log()
})
}

this.log(c.green(`Passed ${passed.length} / ${tasks.length}`))
if (failed.length)
this.log(c.red(`Failed ${failed.length} / ${tasks.length}`))
if (skipped.length)
this.log(c.yellow(`Skipped ${skipped.length}`))
if (todo.length)
this.log(c.dim(`Todo ${todo.length}`))
this.log(`Time ${(this.end - this.start).toFixed(2)}ms`)
}

private getIndent(offest = 0) {
return ' '.repeat((this.indent + offest) * 2)
}
Expand Down
29 changes: 18 additions & 11 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fg from 'fast-glob'
import SinonChai from 'sinon-chai'
import { clearContext, defaultSuite } from './suite'
import { context } from './context'
import { File, Options, Suite, Task, Reporter, RunnerContext } from './types'
import { File, Options, Task, Reporter, RunnerContext } from './types'
import { afterEachHook, afterFileHook, afterAllHook, afterSuiteHook, beforeEachHook, beforeFileHook, beforeAllHook, beforeSuiteHook } from './hooks'
import { SnapshotPlugin } from './snapshot'
import { DefaultReporter } from './reporters/default'
Expand Down Expand Up @@ -39,22 +39,29 @@ export async function collectFiles(files: string[]) {
const result: File[] = []

for (const filepath of files) {
clearContext()
await import(filepath)
const collectors = [defaultSuite, ...context.suites]
const suites: Suite[] = []

const file: File = {
filepath,
suites: [],
collected: false,
}

for (const c of collectors) {
context.currentSuite = c
suites.push(await c.collect(file))
}
clearContext()
try {
await import(filepath)

file.suites = suites
const collectors = [defaultSuite, ...context.suites]
for (const c of collectors) {
context.currentSuite = c
file.suites.push(await c.collect(file))
}

file.collected = true
}
catch (e) {
file.error = e
file.collected = false
process.exitCode = 1
}

result.push(file)
}
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export type TestFactory = (test: (name: string, fn: TestFunction) => void) => Aw
export interface File {
filepath: string
suites: Suite[]
collected: boolean
error?: unknown
}

export interface RunnerContext {
Expand Down

0 comments on commit af91577

Please sign in to comment.