Skip to content

Commit bcccce6

Browse files
authored
fix!: add correct location and snapshot fields in json reporter (#5434)
1 parent 3199494 commit bcccce6

File tree

8 files changed

+139
-50
lines changed

8 files changed

+139
-50
lines changed

packages/vitest/src/node/reporters/json.ts

+14-27
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { existsSync, promises as fs } from 'node:fs'
22
import { dirname, resolve } from 'pathe'
33
import type { Vitest } from '../../node'
4-
import type { File, Reporter, Suite, Task, TaskState } from '../../types'
4+
import type { File, Reporter, SnapshotSummary, Suite, TaskState } from '../../types'
55
import { getSuites, getTests } from '../../utils'
66
import { getOutputFile } from '../../utils/config-helpers'
7-
import { parseErrorStacktrace } from '../../utils/source-map'
87

98
// for compatibility reasons, the reporter produces a JSON similar to the one produced by the Jest JSON reporter
109
// the following types are extracted from the Jest repository (and simplified)
1110
// the commented-out fields are the missing ones
1211

1312
type Status = 'passed' | 'failed' | 'skipped' | 'pending' | 'todo' | 'disabled'
1413
type Milliseconds = number
15-
interface Callsite { line: number; column: number }
14+
interface Callsite {
15+
line: number
16+
column: number
17+
}
18+
1619
const StatusMap: Record<TaskState, Status> = {
1720
fail: 'failed',
1821
only: 'pending',
@@ -28,7 +31,7 @@ export interface JsonAssertionResult {
2831
status: Status
2932
title: string
3033
duration?: Milliseconds | null
31-
failureMessages: Array<string>
34+
failureMessages: Array<string> | null
3235
location?: Callsite | null
3336
}
3437

@@ -56,9 +59,9 @@ export interface JsonTestResults {
5659
startTime: number
5760
success: boolean
5861
testResults: Array<JsonTestResult>
62+
snapshot: SnapshotSummary
5963
// coverageMap?: CoverageMap | null | undefined
6064
// numRuntimeErrorTestSuites: number
61-
// snapshot: SnapshotSummary
6265
// wasInterrupted: boolean
6366
}
6467

@@ -104,7 +107,7 @@ export class JsonReporter implements Reporter {
104107

105108
const endTime = tests.reduce((prev, next) => Math.max(prev, (next.result?.startTime ?? 0) + (next.result?.duration ?? 0)), startTime)
106109
const assertionResults = tests.map((t) => {
107-
const ancestorTitles = [] as string[]
110+
const ancestorTitles: string[] = []
108111
let iter: Suite | undefined = t.suite
109112
while (iter) {
110113
ancestorTitles.push(iter.name)
@@ -114,13 +117,13 @@ export class JsonReporter implements Reporter {
114117

115118
return {
116119
ancestorTitles,
117-
fullName: ancestorTitles.length > 0 ? `${ancestorTitles.join(' ')} ${t.name}` : t.name,
120+
fullName: t.name ? [...ancestorTitles, t.name].join(' ') : ancestorTitles.join(' '),
118121
status: StatusMap[t.result?.state || t.mode] || 'skipped',
119122
title: t.name,
120123
duration: t.result?.duration,
121-
failureMessages: t.result?.errors?.map(e => e.message) || [],
122-
location: this.getFailureLocation(t),
123-
} as JsonAssertionResult
124+
failureMessages: t.result?.errors?.map(e => e.stack || e.message) || [],
125+
location: t.location,
126+
} satisfies JsonAssertionResult
124127
})
125128

126129
if (tests.some(t => t.result?.state === 'run')) {
@@ -153,6 +156,7 @@ export class JsonReporter implements Reporter {
153156
numFailedTests,
154157
numPendingTests,
155158
numTodoTests,
159+
snapshot: this.ctx.snapshot.summary,
156160
startTime: this.start,
157161
success,
158162
testResults,
@@ -187,21 +191,4 @@ export class JsonReporter implements Reporter {
187191
this.ctx.logger.log(report)
188192
}
189193
}
190-
191-
protected getFailureLocation(test: Task): Callsite | undefined {
192-
const error = test.result?.errors?.[0]
193-
if (!error)
194-
return
195-
196-
const project = this.ctx.getProjectByTaskId(test.id)
197-
const stack = parseErrorStacktrace(error, {
198-
getSourceMap: file => project.getBrowserSourceMapModuleById(file),
199-
frameFilter: this.ctx.config.onStackTrace,
200-
})
201-
const frame = stack[0]
202-
if (!frame)
203-
return
204-
205-
return { line: frame.line, column: frame.column }
206-
}
207194
}

pnpm-lock.yaml

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/reporters/src/context.ts

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export function getContext(): Context {
3333
config: config as ResolvedConfig,
3434
server: server as ViteDevServer,
3535
getProjectByTaskId: () => ({ getBrowserSourceMapModuleById: () => undefined }) as any,
36+
snapshot: {
37+
summary: { added: 100, _test: true },
38+
} as any,
3639
}
3740

3841
context.logger = {

test/reporters/src/data.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const file: File = {
1616
file.file = file
1717

1818
const suite: Suite = {
19-
id: '',
19+
id: '1223128da3_0',
2020
type: 'suite',
2121
name: 'suite',
2222
mode: 'run',
@@ -47,7 +47,7 @@ error.stack = 'AssertionError: expected 2.23606797749979 to equal 2\n'
4747

4848
const tasks: Task[] = [
4949
{
50-
id: '1223128da3_0',
50+
id: '1223128da3_0_0',
5151
type: 'test',
5252
name: 'Math.sqrt()',
5353
mode: 'run',
@@ -60,10 +60,14 @@ const tasks: Task[] = [
6060
errors: [error],
6161
duration: 1.4422860145568848,
6262
},
63+
location: {
64+
column: 32,
65+
line: 8,
66+
},
6367
context: null as any,
6468
},
6569
{
66-
id: '1223128da3_1',
70+
id: '1223128da3_0_1',
6771
type: 'test',
6872
name: 'JSON',
6973
mode: 'run',
@@ -75,7 +79,7 @@ const tasks: Task[] = [
7579
context: null as any,
7680
},
7781
{
78-
id: '1223128da3_3',
82+
id: '1223128da3_0_3',
7983
type: 'test',
8084
name: 'async with timeout',
8185
mode: 'skip',
@@ -87,7 +91,7 @@ const tasks: Task[] = [
8791
context: null as any,
8892
},
8993
{
90-
id: '1223128da3_4',
94+
id: '1223128da3_0_4',
9195
type: 'test',
9296
name: 'timeout',
9397
mode: 'run',
@@ -99,7 +103,7 @@ const tasks: Task[] = [
99103
context: null as any,
100104
},
101105
{
102-
id: '1223128da3_5',
106+
id: '1223128da3_0_5',
103107
type: 'test',
104108
name: 'callback setup success ',
105109
mode: 'run',
@@ -111,7 +115,7 @@ const tasks: Task[] = [
111115
context: null as any,
112116
},
113117
{
114-
id: '1223128da3_6',
118+
id: '1223128da3_0_6',
115119
type: 'test',
116120
name: 'callback test success ',
117121
mode: 'run',
@@ -123,7 +127,7 @@ const tasks: Task[] = [
123127
context: null as any,
124128
},
125129
{
126-
id: '1223128da3_7',
130+
id: '1223128da3_0_7',
127131
type: 'test',
128132
name: 'callback setup success done(false)',
129133
mode: 'run',
@@ -135,7 +139,7 @@ const tasks: Task[] = [
135139
context: null as any,
136140
},
137141
{
138-
id: '1223128da3_8',
142+
id: '1223128da3_0_8',
139143
type: 'test',
140144
name: 'callback test success done(false)',
141145
mode: 'run',
@@ -155,7 +159,7 @@ const tasks: Task[] = [
155159
],
156160
},
157161
{
158-
id: '1223128da3_9',
162+
id: '1223128da3_0_9',
159163
type: 'test',
160164
name: 'todo test',
161165
mode: 'todo',

test/reporters/tests/__snapshots__/json.test.ts.snap

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ exports[`json reporter > generates correct report 1`] = `
44
{
55
"ancestorTitles": [],
66
"failureMessages": [
7-
"expected 2 to deeply equal 1",
7+
"AssertionError: expected 2 to deeply equal 1
8+
at <root>/test/reporters/fixtures/json-fail.test.ts:8:13",
89
],
910
"fullName": "should fail",
1011
"location": {
11-
"column": 13,
12-
"line": 8,
12+
"column": 1,
13+
"line": 5,
1314
},
1415
"status": "failed",
1516
"title": "should fail",

0 commit comments

Comments
 (0)