Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 10 additions & 9 deletions packages/runner/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import type {
WriteableTestContext,
} from './types/tasks'
import { getSafeTimers } from '@vitest/utils'
import { parseSingleStack } from '@vitest/utils/source-map'
import { PendingError } from './errors'
import { finishSendTasksUpdate } from './run'
import { getRunner } from './suite'
import { findTestFileStackTrace } from './utils'

const now = Date.now

Expand Down Expand Up @@ -200,17 +200,18 @@ export function createTestContext(
throw new Error(`Cannot annotate tests outside of the test run. The test "${test.name}" finished running with the "${test.result.state}" state already.`)
}

const stack = findTestFileStackTrace(
test.file.filepath,
new Error('STACK_TRACE').stack!,
)

let location: undefined | TestAnnotationLocation

const stack = new Error('STACK_TRACE').stack!
const index = stack.includes('STACK_TRACE') ? 2 : 1
const stackLine = stack.split('\n')[index]
const parsed = parseSingleStack(stackLine)
if (parsed) {
if (stack) {
location = {
file: parsed.file,
line: parsed.line,
column: parsed.column,
file: stack.file,
line: stack.line,
column: stack.column,
}
}

Expand Down
31 changes: 11 additions & 20 deletions packages/runner/src/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
objectAttr,
toArray,
} from '@vitest/utils'
import { parseSingleStack } from '@vitest/utils/source-map'
import {
abortIfTimeout,
collectorContext,
Expand All @@ -37,6 +36,7 @@ import {
import { mergeContextFixtures, mergeScopedFixtures, withFixtures } from './fixture'
import { getHooks, setFn, setHooks, setTestFixture } from './map'
import { getCurrentTest } from './test-state'
import { findTestFileStackTrace } from './utils'
import { createChainable } from './utils/chain'

/**
Expand Down Expand Up @@ -366,9 +366,12 @@ function createSuiteCollector(

if (runner.config.includeTaskLocation) {
const error = stackTraceError.stack!
const stack = findTestFileStackTrace(error)
const stack = findTestFileStackTrace(currentTestFilepath, error)
if (stack) {
task.location = stack
task.location = {
line: stack.line,
column: stack.column,
}
}
}

Expand Down Expand Up @@ -460,9 +463,12 @@ function createSuiteCollector(
Error.stackTraceLimit = 15
const error = new Error('stacktrace').stack!
Error.stackTraceLimit = limit
const stack = findTestFileStackTrace(error)
const stack = findTestFileStackTrace(currentTestFilepath, error)
if (stack) {
suite.location = stack
suite.location = {
line: stack.line,
column: stack.column,
}
}
}

Expand Down Expand Up @@ -887,18 +893,3 @@ function formatTemplateString(cases: any[], args: any[]): any[] {
}
return res
}

function findTestFileStackTrace(error: string) {
const testFilePath = getTestFilepath()
// first line is the error message
const lines = error.split('\n').slice(1)
for (const line of lines) {
const stack = parseSingleStack(line)
if (stack && stack.file === testFilePath) {
return {
line: stack.line,
column: stack.column,
}
}
}
}
13 changes: 13 additions & 0 deletions packages/runner/src/utils/collect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ParsedStack } from '@vitest/utils'
import type { File, Suite, TaskBase } from '../types/tasks'
import { processError } from '@vitest/utils/error'
import { parseSingleStack } from '@vitest/utils/source-map'
import { relative } from 'pathe'
import { setFileContext } from '../context'

Expand Down Expand Up @@ -210,3 +212,14 @@ export function generateFileHash(
): string {
return generateHash(`${file}${projectName || ''}`)
}

export function findTestFileStackTrace(testFilePath: string, error: string): ParsedStack | undefined {
// first line is the error message
const lines = error.split('\n').slice(1)
for (const line of lines) {
const stack = parseSingleStack(line)
if (stack && stack.file === testFilePath) {
return stack
}
}
}
1 change: 1 addition & 0 deletions packages/runner/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { type ChainableFunction, createChainable } from './chain'
export {
calculateSuiteHash,
createFileTask,
findTestFileStackTrace,
generateFileHash,
generateHash,
interpretTaskModes,
Expand Down
74 changes: 50 additions & 24 deletions test/cli/test/annotations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ import type { TestAnnotation } from 'vitest'
import { describe, expect, test } from 'vitest'
import { runInlineTests } from '../../test-utils'

const test3Content = /* ts */`
export async function externalAnnotate(annotate) {
await annotate('external')
}
`

const annotationTest = /* ts */`
import { test, describe } from 'vitest'
import { externalAnnotate } from './test-3.js'

test('simple', async ({ annotate }) => {
await annotate('1')
await annotate('2', 'warning')
await annotate('3', { path: './test-3.js' })
await annotate('4', 'warning', { path: './test-4.js' })
await externalAnnotate(annotate)
})

describe('suite', () => {
Expand Down Expand Up @@ -42,7 +50,7 @@ describe('API', () => {
const { stderr } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{
Expand Down Expand Up @@ -92,6 +100,7 @@ describe('API', () => {
"[annotate] simple 2 warning undefined",
"[annotate] simple 3 notice <root>/.vitest-attachments/3-<hash>.js",
"[annotate] simple 4 warning <root>/.vitest-attachments/4-<hash>.js",
"[annotate] simple external notice undefined",
"[result] simple",
"[ready] second",
"[annotate] second 5 notice undefined",
Expand All @@ -107,7 +116,7 @@ describe('API', () => {
"location": {
"column": 11,
"file": "<root>/basic.test.ts",
"line": 13,
"line": 15,
},
"message": "5",
"type": "notice",
Expand All @@ -119,7 +128,7 @@ describe('API', () => {
"location": {
"column": 11,
"file": "<root>/basic.test.ts",
"line": 14,
"line": 16,
},
"message": "6",
"type": "notice",
Expand All @@ -130,7 +139,7 @@ describe('API', () => {
"location": {
"column": 9,
"file": "<root>/basic.test.ts",
"line": 5,
"line": 6,
},
"message": "1",
"type": "notice",
Expand All @@ -139,7 +148,7 @@ describe('API', () => {
"location": {
"column": 9,
"file": "<root>/basic.test.ts",
"line": 6,
"line": 7,
},
"message": "2",
"type": "warning",
Expand All @@ -152,7 +161,7 @@ describe('API', () => {
"location": {
"column": 9,
"file": "<root>/basic.test.ts",
"line": 7,
"line": 8,
},
"message": "3",
"type": "notice",
Expand All @@ -165,11 +174,20 @@ describe('API', () => {
"location": {
"column": 9,
"file": "<root>/basic.test.ts",
"line": 8,
"line": 9,
},
"message": "4",
"type": "warning",
},
{
"location": {
"column": 9,
"file": "<root>/basic.test.ts",
"line": 10,
},
"message": "external",
"type": "notice",
},
],
}
`)
Expand Down Expand Up @@ -198,7 +216,7 @@ describe('reporters', () => {
const { stdout } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{ reporters: ['tap'] },
Expand All @@ -214,6 +232,7 @@ describe('reporters', () => {
# warning: 2
# notice: 3
# warning: 4
# notice: external
ok 2 - suite # time=<time> {
1..1
ok 1 - second # time=<time>
Expand All @@ -229,7 +248,7 @@ describe('reporters', () => {
const { stdout } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{ reporters: ['tap-flat'] },
Expand All @@ -243,6 +262,7 @@ describe('reporters', () => {
# warning: 2
# notice: 3
# warning: 4
# notice: external
ok 2 - basic.test.ts > suite > second # time=<time>
# notice: 5
# notice: 6
Expand All @@ -254,7 +274,7 @@ describe('reporters', () => {
const { stdout } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{ reporters: ['junit'] },
Expand All @@ -279,6 +299,8 @@ describe('reporters', () => {
</property>
<property name="warning" value="4">
</property>
<property name="notice" value="external">
</property>
</properties>
</testcase>
<testcase classname="basic.test.ts" name="suite &gt; second" time="0">
Expand All @@ -299,7 +321,7 @@ describe('reporters', () => {
const { stdout, ctx } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{ reporters: ['github-actions'] },
Expand All @@ -313,17 +335,19 @@ describe('reporters', () => {
.replace(new RegExp(ctx!.config.root, 'g'), '<root>')
expect(result).toMatchInlineSnapshot(`
"
::notice file=<root>/basic.test.ts,line=5,column=9::1
::notice file=<root>/basic.test.ts,line=6,column=9::1

::warning file=<root>/basic.test.ts,line=7,column=9::2

::warning file=<root>/basic.test.ts,line=6,column=9::2
::notice file=<root>/basic.test.ts,line=8,column=9::3

::notice file=<root>/basic.test.ts,line=7,column=9::3
::warning file=<root>/basic.test.ts,line=9,column=9::4

::warning file=<root>/basic.test.ts,line=8,column=9::4
::notice file=<root>/basic.test.ts,line=10,column=9::external

::notice file=<root>/basic.test.ts,line=13,column=11::5
::notice file=<root>/basic.test.ts,line=15,column=11::5

::notice file=<root>/basic.test.ts,line=14,column=11::6
::notice file=<root>/basic.test.ts,line=16,column=11::6
"
`)
})
Expand All @@ -332,7 +356,7 @@ describe('reporters', () => {
const { stdout } = await runInlineTests(
{
'basic.test.ts': annotationTest,
'test-3.js': '',
'test-3.js': test3Content,
'test-4.js': '',
},
{ reporters: [['verbose', { isTTY: false }]] },
Expand All @@ -348,20 +372,22 @@ describe('reporters', () => {
expect(result).toMatchInlineSnapshot(`
" ✓ basic.test.ts > simple <time>

❯ basic.test.ts:5:9 notice
❯ basic.test.ts:6:9 notice
↳ 1
❯ basic.test.ts:6:9 warning
❯ basic.test.ts:7:9 warning
↳ 2
❯ basic.test.ts:7:9 notice
❯ basic.test.ts:8:9 notice
↳ 3
❯ basic.test.ts:8:9 warning
❯ basic.test.ts:9:9 warning
↳ 4
❯ basic.test.ts:10:9 notice
↳ external

✓ basic.test.ts > suite > second <time>

❯ basic.test.ts:13:11 notice
❯ basic.test.ts:15:11 notice
↳ 5
❯ basic.test.ts:14:11 notice
❯ basic.test.ts:16:11 notice
↳ 6

"
Expand Down
Loading