[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix(runner): fix and simplify `Task.suite` initialization (#7414)

authored by

Hiroshi Ogawa and committed by
GitHub
(Mar 6, 2025, 4:03 PM +0100) ca9ffac5 2edc18a8

+73 -12
-8
packages/runner/src/collect.ts
··· 89 89 90 90 calculateSuiteHash(file) 91 91 92 - file.tasks.forEach((task) => { 93 - // task.suite refers to the internal default suite object 94 - // it should not be reported 95 - if (task.suite?.id === '') { 96 - delete task.suite 97 - } 98 - }) 99 - 100 92 const hasOnlyTasks = someTasksAreOnly(file) 101 93 interpretTaskModes( 102 94 file,
+8 -4
packages/runner/src/suite.ts
··· 205 205 206 206 function createDefaultSuite(runner: VitestRunner) { 207 207 const config = runner.config.sequence 208 - return suite('', { concurrent: config.concurrent }, () => {}) 208 + const collector = suite('', { concurrent: config.concurrent }, () => {}) 209 + // no parent suite for top-level tests 210 + delete collector.suite 211 + return collector 209 212 } 210 213 211 214 export function clearCollectorContext( ··· 295 298 ) { 296 299 const tasks: (Test | Suite | SuiteCollector)[] = [] 297 300 298 - let suite: Suite 301 + let suite!: Suite 299 302 300 303 initSuite(true) 301 304 ··· 303 306 const task: Test = { 304 307 id: '', 305 308 name, 306 - suite: undefined!, 309 + suite: collectorContext.currentSuite?.suite, 307 310 each: options.each, 308 311 fails: options.fails, 309 312 context: undefined!, ··· 394 397 type: 'collector', 395 398 name, 396 399 mode, 400 + suite, 397 401 options: suiteOptions, 398 402 test, 399 403 tasks, ··· 416 420 id: '', 417 421 type: 'suite', 418 422 name, 423 + suite: collectorContext.currentSuite?.suite, 419 424 mode, 420 425 each, 421 426 file: undefined!, ··· 463 468 suite.tasks = allChildren 464 469 465 470 allChildren.forEach((task) => { 466 - task.suite = suite 467 471 task.file = file 468 472 }) 469 473
+11
test/cli/test/custom-runner.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import { runVitest } from '../../test-utils' 3 + 4 + test('extendTaskContext provides correct context.task.suite', async () => { 5 + const vitest = await runVitest({ 6 + root: './fixtures/custom-runner', 7 + reporters: [['default', { isTTY: false }]], 8 + }) 9 + expect(vitest.stderr).toBe('') 10 + expect(vitest.stdout).toContain('✓ custom-runner.test.ts') 11 + })
+1
packages/runner/src/types/tasks.ts
··· 612 612 | Test<ExtraContext> 613 613 | SuiteCollector<ExtraContext> 614 614 )[] 615 + suite?: Suite 615 616 task: (name: string, options?: TaskCustomOptions) => Test<ExtraContext> 616 617 collect: (file: File) => Promise<Suite> 617 618 clear: () => void
+23
test/cli/fixtures/custom-runner/custom-runner.test.ts
··· 1 + import {describe, expect, test as baseTest, type TestAPI} from 'vitest' 2 + import { getSuiteNames } from './utils'; 3 + 4 + const test = baseTest as TestAPI<{__suiteNames: string[]}> 5 + 6 + test("test-a", (ctx) => { 7 + expect(ctx.__suiteNames).toEqual([]); 8 + expect(ctx.__suiteNames).toEqual(getSuiteNames(ctx.task.suite)) 9 + }) 10 + 11 + describe("suite-x", () => { 12 + test("test-b", (ctx) => { 13 + expect(ctx.__suiteNames).toEqual(['suite-x']) 14 + expect(ctx.__suiteNames).toEqual(getSuiteNames(ctx.task.suite)) 15 + }) 16 + 17 + describe("suite-y", () => { 18 + test("test-c", (ctx) => { 19 + expect(ctx.__suiteNames).toEqual(['suite-y', 'suite-x']) 20 + expect(ctx.__suiteNames).toEqual(getSuiteNames(ctx.task.suite)) 21 + }) 22 + }) 23 + })
+13
test/cli/fixtures/custom-runner/test-runner.ts
··· 1 + import type { Suite, TestContext } from '@vitest/runner' 2 + import { VitestTestRunner } from 'vitest/runners' 3 + import { getSuiteNames } from './utils'; 4 + 5 + class CustomTestRunner extends VitestTestRunner { 6 + extendTaskContext(context: TestContext) { 7 + super.extendTaskContext(context); 8 + (context as any).__suiteNames = getSuiteNames(context.task.suite) 9 + return context 10 + } 11 + } 12 + 13 + export default CustomTestRunner
+10
test/cli/fixtures/custom-runner/utils.ts
··· 1 + import { Suite } from "@vitest/runner" 2 + 3 + export function getSuiteNames(suite?: Suite) { 4 + const names = [] 5 + while (suite) { 6 + names.push(suite.name) 7 + suite = suite.suite 8 + } 9 + return names 10 + }
+7
test/cli/fixtures/custom-runner/vitest.config.ts
··· 1 + import { defineConfig } from 'vitest/config' 2 + 3 + export default defineConfig({ 4 + test: { 5 + runner: './test-runner.ts', 6 + }, 7 + })