Skip to content

Commit 751e2dc

Browse files
authoredDec 9, 2024··
feat(cli): Support location filters for suites (#7048)
1 parent 91d2f93 commit 751e2dc

File tree

2 files changed

+107
-18
lines changed

2 files changed

+107
-18
lines changed
 

‎packages/runner/src/utils/collect.ts

+22-16
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function interpretTaskModes(
1515
): void {
1616
const matchedLocations: number[] = []
1717

18-
const traverseSuite = (suite: Suite, parentIsOnly?: boolean) => {
18+
const traverseSuite = (suite: Suite, parentIsOnly?: boolean, parentMatchedWithLocation?: boolean) => {
1919
const suiteIsOnly = parentIsOnly || suite.mode === 'only'
2020

2121
suite.tasks.forEach((t) => {
@@ -37,30 +37,36 @@ export function interpretTaskModes(
3737
t.mode = 'run'
3838
}
3939
}
40-
if (t.type === 'test') {
41-
if (namePattern && !getTaskFullName(t).match(namePattern)) {
40+
41+
let hasLocationMatch = parentMatchedWithLocation
42+
// Match test location against provided locations, only run if present
43+
// in `testLocations`. Note: if `includeTaskLocations` is not enabled,
44+
// all test will be skipped.
45+
if (testLocations !== undefined && testLocations.length !== 0) {
46+
if (t.location && testLocations?.includes(t.location.line)) {
47+
t.mode = 'run'
48+
matchedLocations.push(t.location.line)
49+
hasLocationMatch = true
50+
}
51+
else if (parentMatchedWithLocation) {
52+
t.mode = 'run'
53+
}
54+
else if (t.type === 'test') {
4255
t.mode = 'skip'
4356
}
57+
}
4458

45-
// Match test location against provided locations, only run if present
46-
// in `testLocations`. Note: if `includeTaskLocations` is not enabled,
47-
// all test will be skipped.
48-
if (testLocations !== undefined && testLocations.length !== 0) {
49-
if (t.location && testLocations?.includes(t.location.line)) {
50-
t.mode = 'run'
51-
matchedLocations.push(t.location.line)
52-
}
53-
else {
54-
t.mode = 'skip'
55-
}
59+
if (t.type === 'test') {
60+
if (namePattern && !getTaskFullName(t).match(namePattern)) {
61+
t.mode = 'skip'
5662
}
5763
}
5864
else if (t.type === 'suite') {
5965
if (t.mode === 'skip') {
6066
skipAllTasks(t)
6167
}
6268
else {
63-
traverseSuite(t, includeTask)
69+
traverseSuite(t, includeTask, hasLocationMatch)
6470
}
6571
}
6672
})
@@ -73,7 +79,7 @@ export function interpretTaskModes(
7379
}
7480
}
7581

76-
traverseSuite(file, parentIsOnly)
82+
traverseSuite(file, parentIsOnly, false)
7783

7884
const nonMatching = testLocations?.filter(loc => !matchedLocations.includes(loc))
7985
if (nonMatching && nonMatching.length !== 0) {

‎test/cli/test/location-filters.test.ts

+85-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,54 @@ describe('location filter with list command', () => {
1818
expect(stderr).toEqual('')
1919
})
2020

21+
test('finds "basic suite" at correct line number', async () => {
22+
const { stdout, stderr } = await runVitestCli(
23+
'list',
24+
`-r=${fixturePath}`,
25+
`${fixturePath}/basic.test.ts:3`,
26+
)
27+
28+
expect(stdout).toMatchInlineSnapshot(`
29+
"basic.test.ts > basic suite > inner suite > some test
30+
basic.test.ts > basic suite > inner suite > another test
31+
basic.test.ts > basic suite > basic test
32+
"
33+
`)
34+
expect(stderr).toEqual('')
35+
})
36+
37+
test('finds "inner suite" at correct line number', async () => {
38+
const { stdout, stderr } = await runVitestCli(
39+
'list',
40+
`-r=${fixturePath}`,
41+
`${fixturePath}/basic.test.ts:4`,
42+
)
43+
44+
expect(stdout).toMatchInlineSnapshot(`
45+
"basic.test.ts > basic suite > inner suite > some test
46+
basic.test.ts > basic suite > inner suite > another test
47+
"
48+
`)
49+
expect(stderr).toEqual('')
50+
})
51+
52+
test('handles matching test inside a suite', async () => {
53+
const { stdout, stderr } = await runVitestCli(
54+
'list',
55+
`-r=${fixturePath}`,
56+
`${fixturePath}/basic.test.ts:3`,
57+
`${fixturePath}/basic.test.ts:9`,
58+
)
59+
60+
expect(stdout).toMatchInlineSnapshot(`
61+
"basic.test.ts > basic suite > inner suite > some test
62+
basic.test.ts > basic suite > inner suite > another test
63+
basic.test.ts > basic suite > basic test
64+
"
65+
`)
66+
expect(stderr).toEqual('')
67+
})
68+
2169
test('handles file with a dash in the name', async () => {
2270
const { stdout, stderr } = await runVitestCli(
2371
'list',
@@ -120,13 +168,48 @@ describe('location filter with run command', () => {
120168
`${fixturePath}/math.test.ts:3`,
121169
)
122170

123-
// expect(`${stdout}\n--------------------\n${stderr}`).toEqual('')
124-
125171
expect(stdout).contain('1 passed')
126172
expect(stdout).contain('1 skipped')
127173
expect(stderr).toEqual('')
128174
})
129175

176+
test('finds "basic suite" at correct line number', async () => {
177+
const { stdout, stderr } = await runVitestCli(
178+
'run',
179+
`-r=${fixturePath}`,
180+
`${fixturePath}/basic.test.ts:3`,
181+
)
182+
183+
expect(stdout).contain('3 passed')
184+
expect(stdout).contain('1 skipped')
185+
expect(stderr).toEqual('')
186+
})
187+
188+
test('finds "inner suite" at correct line number', async () => {
189+
const { stdout, stderr } = await runVitestCli(
190+
'run',
191+
`-r=${fixturePath}`,
192+
`${fixturePath}/basic.test.ts:4`,
193+
)
194+
195+
expect(stdout).contain('2 passed')
196+
expect(stdout).contain('2 skipped')
197+
expect(stderr).toEqual('')
198+
})
199+
200+
test('handles matching test inside a suite', async () => {
201+
const { stdout, stderr } = await runVitestCli(
202+
'run',
203+
`-r=${fixturePath}`,
204+
`${fixturePath}/basic.test.ts:3`,
205+
`${fixturePath}/basic.test.ts:9`,
206+
)
207+
208+
expect(stdout).contain('3 passed')
209+
expect(stdout).contain('1 skipped')
210+
expect(stderr).toEqual('')
211+
})
212+
130213
test('handles file with a dash in the name', async () => {
131214
const { stdout, stderr } = await runVitestCli(
132215
'run',

0 commit comments

Comments
 (0)
Please sign in to comment.