diff --git a/packages/runner/src/suite.ts b/packages/runner/src/suite.ts index 4cb428106..301bb962e 100644 --- a/packages/runner/src/suite.ts +++ b/packages/runner/src/suite.ts @@ -247,7 +247,7 @@ function parseArguments any>( optionsOrTest: object | T | number | undefined, ) { let options: TestOptions = {} - let fn: T = (() => {}) as T + let fn: T | undefined // it('', () => {}, { retry: 2 }) if (typeof optionsOrTest === 'object') { @@ -329,6 +329,9 @@ function createSuiteCollector( annotations: [], } const handler = options.handler + if (task.mode === 'run' && !handler) { + task.mode = 'todo' + } if ( options.concurrent || (!options.sequential && runner.config.sequence.concurrent) @@ -533,7 +536,7 @@ function createSuite() { factoryOrOptions?: SuiteFactory | TestOptions, optionsOrFactory?: number | TestOptions | SuiteFactory, ) { - const mode: RunMode = this.only + let mode: RunMode = this.only ? 'only' : this.skip ? 'skip' @@ -547,6 +550,10 @@ function createSuite() { optionsOrFactory, ) + if (mode === 'run' && !factory) { + mode = 'todo' + } + const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false @@ -606,20 +613,20 @@ function createSuite() { if (arrayOnlyCases) { suite( formatTitle(_name, items, idx), - () => handler(...items), + handler ? () => handler(...items) : undefined, options, ) } else { - suite(formatTitle(_name, items, idx), () => handler(i), options) + suite(formatTitle(_name, items, idx), handler ? () => handler(i) : undefined, options) } } else { if (arrayOnlyCases) { - suite(formatTitle(_name, items, idx), options, () => handler(...items)) + suite(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : undefined) } else { - suite(formatTitle(_name, items, idx), options, () => handler(i)) + suite(formatTitle(_name, items, idx), options, handler ? () => handler(i) : undefined) } } }) @@ -648,7 +655,7 @@ function createSuite() { const name_ = formatName(name) const { options, handler } = parseArguments(optionsOrFn, fnOrOptions) cases.forEach((item, idx) => { - suite(formatTitle(name_, toArray(item), idx), options, () => handler(item)) + suite(formatTitle(name_, toArray(item), idx), options, handler ? () => handler(item) : undefined) }) } } @@ -704,20 +711,20 @@ export function createTaskCollector( if (arrayOnlyCases) { test( formatTitle(_name, items, idx), - () => handler(...items), + handler ? () => handler(...items) : undefined, options, ) } else { - test(formatTitle(_name, items, idx), () => handler(i), options) + test(formatTitle(_name, items, idx), handler ? () => handler(i) : undefined, options) } } else { if (arrayOnlyCases) { - test(formatTitle(_name, items, idx), options, () => handler(...items)) + test(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : undefined) } else { - test(formatTitle(_name, items, idx), options, () => handler(i)) + test(formatTitle(_name, items, idx), options, handler ? () => handler(i) : undefined) } } }) @@ -749,9 +756,11 @@ export function createTaskCollector( const { options, handler } = parseArguments(optionsOrFn, fnOrOptions) cases.forEach((item, idx) => { // monkey-patch handler to allow parsing fixture - const handlerWrapper = (ctx: any) => handler(item, ctx); - (handlerWrapper as any).__VITEST_FIXTURE_INDEX__ = 1; - (handlerWrapper as any).toString = () => handler.toString() + const handlerWrapper = handler ? (ctx: any) => handler(item, ctx) : undefined + if (handlerWrapper) { + (handlerWrapper as any).__VITEST_FIXTURE_INDEX__ = 1; + (handlerWrapper as any).toString = () => handler!.toString() + } test(formatTitle(_name, toArray(item), idx), options, handlerWrapper) }) } diff --git a/packages/vitest/src/runtime/benchmark.ts b/packages/vitest/src/runtime/benchmark.ts index 0d2d65d5d..d2b340eec 100644 --- a/packages/vitest/src/runtime/benchmark.ts +++ b/packages/vitest/src/runtime/benchmark.ts @@ -33,6 +33,11 @@ export const bench: BenchmarkAPI = createBenchmark(function ( }) benchFns.set(task, fn) benchOptsMap.set(task, options) + // vitest runner sets mode to `todo` if handler is not passed down + // but we store handler separetly + if (!this.todo && task.mode === 'todo') { + task.mode = 'run' + } }) function createBenchmark( diff --git a/test/browser/fixtures/timeout-hooks/hooks-timeout.test.ts b/test/browser/fixtures/timeout-hooks/hooks-timeout.test.ts index 7ee586252..c7c51c55b 100644 --- a/test/browser/fixtures/timeout-hooks/hooks-timeout.test.ts +++ b/test/browser/fixtures/timeout-hooks/hooks-timeout.test.ts @@ -17,7 +17,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly await page.getByTestId('non-existing').click() }, 500) - it('skipped') + it('skipped', () => {}) }) describe('afterEach', () => { @@ -26,7 +26,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly await page.getByTestId('non-existing').click() }, 500) - it('skipped') + it('skipped', () => {}) }) describe('beforeAll', () => { @@ -35,7 +35,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly await page.getByTestId('non-existing').click() }, 500) - it('skipped') + it('skipped', () => {}) }) describe('afterAll', () => { @@ -44,7 +44,7 @@ describe.runIf(server.provider === 'playwright')('timeouts are failing correctly await page.getByTestId('non-existing').click() }, 500) - it('skipped') + it('skipped', () => {}) }) describe('onTestFinished', () => { diff --git a/test/cli/fixtures/browser-multiple/basic.test.js b/test/cli/fixtures/browser-multiple/basic.test.js index 567901243..4093e384a 100644 --- a/test/cli/fixtures/browser-multiple/basic.test.js +++ b/test/cli/fixtures/browser-multiple/basic.test.js @@ -1,3 +1,3 @@ import { test } from 'vitest'; -test('passes') +test('passes', () => {}) diff --git a/test/cli/fixtures/fails/no-assertions.test.ts b/test/cli/fixtures/fails/no-assertions.test.ts index 2536624ce..a87df3228 100644 --- a/test/cli/fixtures/fails/no-assertions.test.ts +++ b/test/cli/fixtures/fails/no-assertions.test.ts @@ -1,3 +1,3 @@ import { it } from 'vitest' -it('test without assertions') \ No newline at end of file +it('test without assertions', () => {}) \ No newline at end of file diff --git a/test/cli/test/group-order.test.ts b/test/cli/test/group-order.test.ts index 984f283c8..4d5c1d033 100644 --- a/test/cli/test/group-order.test.ts +++ b/test/cli/test/group-order.test.ts @@ -3,10 +3,10 @@ import { runInlineTests } from '../../test-utils' test('tests run according to the group order', async () => { const { stdout, stderr } = await runInlineTests({ - 'example.1.test.ts': `test('1')`, - 'example.2.test.ts': `test('2')`, - 'example.2-2.test.ts': `test('2-2')`, - 'example.3.test.ts': `test('3')`, + 'example.1.test.ts': `test('1', () => {})`, + 'example.2.test.ts': `test('2', () => {})`, + 'example.2-2.test.ts': `test('2-2', () => {})`, + 'example.3.test.ts': `test('3', () => {})`, }, { globals: true, // run projects in the opposite order! diff --git a/test/core/test/task-collector.test.ts b/test/core/test/task-collector.test.ts index 3b990ed8e..82af9755b 100644 --- a/test/core/test/task-collector.test.ts +++ b/test/core/test/task-collector.test.ts @@ -1,3 +1,4 @@ +import type { RunnerTestCase, RunnerTestSuite } from 'vitest' import { assert, describe, expect, test, vi } from 'vitest' import { createTaskCollector, getCurrentSuite } from 'vitest/suite' @@ -49,3 +50,19 @@ describe('collector.extend should preserve handler wrapping', () => { expect(flag).toBe(true) }) }) + +describe('empty tests and suites are todos', () => { + describe('suite should be todo') + test('test should be todo') + + test('this suite has correct modes', ({ task }) => { + const todoSuite = task.suite!.tasks[0] as RunnerTestSuite + const todoTest = task.suite!.tasks[0] as RunnerTestCase + + expect(todoSuite.name).toBe('suite should be todo') + expect(todoSuite.mode).toBe('todo') + + expect(todoTest.name).toBe('suite should be todo') + expect(todoTest.mode).toBe('todo') + }) +}) diff --git a/test/reporters/fixtures/long-loading-task.test.ts b/test/reporters/fixtures/long-loading-task.test.ts index 11aa80554..2109bb44d 100644 --- a/test/reporters/fixtures/long-loading-task.test.ts +++ b/test/reporters/fixtures/long-loading-task.test.ts @@ -2,4 +2,4 @@ import { test } from 'vitest' await new Promise(r => setTimeout(r, 500)) -test('works') +test('works', () => {}) diff --git a/test/watch/test/workspaces.test.ts b/test/watch/test/workspaces.test.ts index 52c416cb5..20a01cfc6 100644 --- a/test/watch/test/workspaces.test.ts +++ b/test/watch/test/workspaces.test.ts @@ -129,8 +129,8 @@ it('adding a new test file matching project specific config triggers re-run', as it('editing a setup file inside the project reruns tests', async () => { const { fs, vitest } = await runInlineTests({ 'setupFile.js': '', - 'project-1/basic.test.js': `test("[p1] reruns")`, - 'project-2/basic.test.js': `test("[p2] doesn\'t rerun")`, + 'project-1/basic.test.js': `test("[p1] reruns", () => {})`, + 'project-2/basic.test.js': `test("[p2] doesn\'t rerun", () => {})`, 'vitest.config.js': { test: { projects: [