Skip to content

Commit 1a81c21

Browse files
authored
feat(runner)!: set mode to todo if no function is passed down to test or describe (#8346)
1 parent 9be01ba commit 1a81c21

File tree

9 files changed

+58
-27
lines changed

9 files changed

+58
-27
lines changed

packages/runner/src/suite.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ function parseArguments<T extends (...args: any[]) => any>(
247247
optionsOrTest: object | T | number | undefined,
248248
) {
249249
let options: TestOptions = {}
250-
let fn: T = (() => {}) as T
250+
let fn: T | undefined
251251

252252
// it('', () => {}, { retry: 2 })
253253
if (typeof optionsOrTest === 'object') {
@@ -329,6 +329,9 @@ function createSuiteCollector(
329329
annotations: [],
330330
}
331331
const handler = options.handler
332+
if (task.mode === 'run' && !handler) {
333+
task.mode = 'todo'
334+
}
332335
if (
333336
options.concurrent
334337
|| (!options.sequential && runner.config.sequence.concurrent)
@@ -533,7 +536,7 @@ function createSuite() {
533536
factoryOrOptions?: SuiteFactory | TestOptions,
534537
optionsOrFactory?: number | TestOptions | SuiteFactory,
535538
) {
536-
const mode: RunMode = this.only
539+
let mode: RunMode = this.only
537540
? 'only'
538541
: this.skip
539542
? 'skip'
@@ -547,6 +550,10 @@ function createSuite() {
547550
optionsOrFactory,
548551
)
549552

553+
if (mode === 'run' && !factory) {
554+
mode = 'todo'
555+
}
556+
550557
const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false
551558
const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false
552559

@@ -606,20 +613,20 @@ function createSuite() {
606613
if (arrayOnlyCases) {
607614
suite(
608615
formatTitle(_name, items, idx),
609-
() => handler(...items),
616+
handler ? () => handler(...items) : undefined,
610617
options,
611618
)
612619
}
613620
else {
614-
suite(formatTitle(_name, items, idx), () => handler(i), options)
621+
suite(formatTitle(_name, items, idx), handler ? () => handler(i) : undefined, options)
615622
}
616623
}
617624
else {
618625
if (arrayOnlyCases) {
619-
suite(formatTitle(_name, items, idx), options, () => handler(...items))
626+
suite(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : undefined)
620627
}
621628
else {
622-
suite(formatTitle(_name, items, idx), options, () => handler(i))
629+
suite(formatTitle(_name, items, idx), options, handler ? () => handler(i) : undefined)
623630
}
624631
}
625632
})
@@ -648,7 +655,7 @@ function createSuite() {
648655
const name_ = formatName(name)
649656
const { options, handler } = parseArguments(optionsOrFn, fnOrOptions)
650657
cases.forEach((item, idx) => {
651-
suite(formatTitle(name_, toArray(item), idx), options, () => handler(item))
658+
suite(formatTitle(name_, toArray(item), idx), options, handler ? () => handler(item) : undefined)
652659
})
653660
}
654661
}
@@ -704,20 +711,20 @@ export function createTaskCollector(
704711
if (arrayOnlyCases) {
705712
test(
706713
formatTitle(_name, items, idx),
707-
() => handler(...items),
714+
handler ? () => handler(...items) : undefined,
708715
options,
709716
)
710717
}
711718
else {
712-
test(formatTitle(_name, items, idx), () => handler(i), options)
719+
test(formatTitle(_name, items, idx), handler ? () => handler(i) : undefined, options)
713720
}
714721
}
715722
else {
716723
if (arrayOnlyCases) {
717-
test(formatTitle(_name, items, idx), options, () => handler(...items))
724+
test(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : undefined)
718725
}
719726
else {
720-
test(formatTitle(_name, items, idx), options, () => handler(i))
727+
test(formatTitle(_name, items, idx), options, handler ? () => handler(i) : undefined)
721728
}
722729
}
723730
})
@@ -749,9 +756,11 @@ export function createTaskCollector(
749756
const { options, handler } = parseArguments(optionsOrFn, fnOrOptions)
750757
cases.forEach((item, idx) => {
751758
// monkey-patch handler to allow parsing fixture
752-
const handlerWrapper = (ctx: any) => handler(item, ctx);
753-
(handlerWrapper as any).__VITEST_FIXTURE_INDEX__ = 1;
754-
(handlerWrapper as any).toString = () => handler.toString()
759+
const handlerWrapper = handler ? (ctx: any) => handler(item, ctx) : undefined
760+
if (handlerWrapper) {
761+
(handlerWrapper as any).__VITEST_FIXTURE_INDEX__ = 1;
762+
(handlerWrapper as any).toString = () => handler!.toString()
763+
}
755764
test(formatTitle(_name, toArray(item), idx), options, handlerWrapper)
756765
})
757766
}

packages/vitest/src/runtime/benchmark.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export const bench: BenchmarkAPI = createBenchmark(function (
3333
})
3434
benchFns.set(task, fn)
3535
benchOptsMap.set(task, options)
36+
// vitest runner sets mode to `todo` if handler is not passed down
37+
// but we store handler separetly
38+
if (!this.todo && task.mode === 'todo') {
39+
task.mode = 'run'
40+
}
3641
})
3742

3843
function createBenchmark(

test/browser/fixtures/timeout-hooks/hooks-timeout.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly
1717
await page.getByTestId('non-existing').click()
1818
}, 500)
1919

20-
it('skipped')
20+
it('skipped', () => {})
2121
})
2222

2323
describe('afterEach', () => {
@@ -26,7 +26,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly
2626
await page.getByTestId('non-existing').click()
2727
}, 500)
2828

29-
it('skipped')
29+
it('skipped', () => {})
3030
})
3131

3232
describe('beforeAll', () => {
@@ -35,7 +35,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly
3535
await page.getByTestId('non-existing').click()
3636
}, 500)
3737

38-
it('skipped')
38+
it('skipped', () => {})
3939
})
4040

4141
describe('afterAll', () => {
@@ -44,7 +44,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly
4444
await page.getByTestId('non-existing').click()
4545
}, 500)
4646

47-
it('skipped')
47+
it('skipped', () => {})
4848
})
4949

5050
describe('onTestFinished', () => {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import { test } from 'vitest';
22

3-
test('passes')
3+
test('passes', () => {})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import { it } from 'vitest'
22

3-
it('test without assertions')
3+
it('test without assertions', () => {})

test/cli/test/group-order.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { runInlineTests } from '../../test-utils'
33

44
test('tests run according to the group order', async () => {
55
const { stdout, stderr } = await runInlineTests({
6-
'example.1.test.ts': `test('1')`,
7-
'example.2.test.ts': `test('2')`,
8-
'example.2-2.test.ts': `test('2-2')`,
9-
'example.3.test.ts': `test('3')`,
6+
'example.1.test.ts': `test('1', () => {})`,
7+
'example.2.test.ts': `test('2', () => {})`,
8+
'example.2-2.test.ts': `test('2-2', () => {})`,
9+
'example.3.test.ts': `test('3', () => {})`,
1010
}, {
1111
globals: true,
1212
// run projects in the opposite order!

test/core/test/task-collector.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { RunnerTestCase, RunnerTestSuite } from 'vitest'
12
import { assert, describe, expect, test, vi } from 'vitest'
23
import { createTaskCollector, getCurrentSuite } from 'vitest/suite'
34

@@ -49,3 +50,19 @@ describe('collector.extend should preserve handler wrapping', () => {
4950
expect(flag).toBe(true)
5051
})
5152
})
53+
54+
describe('empty tests and suites are todos', () => {
55+
describe('suite should be todo')
56+
test('test should be todo')
57+
58+
test('this suite has correct modes', ({ task }) => {
59+
const todoSuite = task.suite!.tasks[0] as RunnerTestSuite
60+
const todoTest = task.suite!.tasks[0] as RunnerTestCase
61+
62+
expect(todoSuite.name).toBe('suite should be todo')
63+
expect(todoSuite.mode).toBe('todo')
64+
65+
expect(todoTest.name).toBe('suite should be todo')
66+
expect(todoTest.mode).toBe('todo')
67+
})
68+
})

test/reporters/fixtures/long-loading-task.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import { test } from 'vitest'
22

33
await new Promise(r => setTimeout(r, 500))
44

5-
test('works')
5+
test('works', () => {})

test/watch/test/workspaces.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ it('adding a new test file matching project specific config triggers re-run', as
129129
it('editing a setup file inside the project reruns tests', async () => {
130130
const { fs, vitest } = await runInlineTests({
131131
'setupFile.js': '',
132-
'project-1/basic.test.js': `test("[p1] reruns")`,
133-
'project-2/basic.test.js': `test("[p2] doesn\'t rerun")`,
132+
'project-1/basic.test.js': `test("[p1] reruns", () => {})`,
133+
'project-2/basic.test.js': `test("[p2] doesn\'t rerun", () => {})`,
134134
'vitest.config.js': {
135135
test: {
136136
projects: [

0 commit comments

Comments
 (0)