diff --git a/docs/config/index.md b/docs/config/index.md index a89a383bf..ca613da7d 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -1065,17 +1065,30 @@ Beware that the global setup is running in a different global scope, so your tes :::code-group ```js [globalSetup.js] -export default function setup({ provide }) { - provide('wsPort', 3000) +export default function setup(project) { + project.provide('wsPort', 3000) } ``` -```ts [globalSetup.ts] +```ts [globalSetup.ts 2.0.0] import type { GlobalSetupContext } from 'vitest/node' export default function setup({ provide }: GlobalSetupContext) { provide('wsPort', 3000) } +declare module 'vitest' { + export interface ProvidedContext { + wsPort: number + } +} +``` +```ts [globalSetup.ts 2.2.0] +import type { TestProject } from 'vitest/node' + +export default function setup(project: TestProject) { + project.provide('wsPort', 3000) +} + declare module 'vitest' { export interface ProvidedContext { wsPort: number @@ -1089,13 +1102,13 @@ inject('wsPort') === 3000 ``` ::: -Since Vitest 2.2.0, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing the tests. +Since Vitest 2.2.0, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing tests. Note that you cannot destruct the `project` like `{ onTestsRerun }` because it relies on the context. ```ts -import type { GlobalSetupContext } from 'vitest/node' +import type { TestProject } from 'vitest/node' -export default function setup({ onTestsRerun }: GlobalSetupContext) { - onTestsRerun(async () => { +export default function setup(project: TestProject) { + project.onTestsRerun(async () => { await restartDb() }) } diff --git a/packages/vitest/src/node/globalSetup.ts b/packages/vitest/src/node/globalSetup.ts index 295b8a862..435dbbe19 100644 --- a/packages/vitest/src/node/globalSetup.ts +++ b/packages/vitest/src/node/globalSetup.ts @@ -1,29 +1,13 @@ import type { ViteNodeRunner } from 'vite-node/client' -import type { OnTestsRerunHandler, ProvidedContext } from '../types/general' -import type { ResolvedConfig } from './types/config' +import type { TestProject } from './project' import { toArray } from '@vitest/utils' -export interface GlobalSetupContext { - /** - * Config of the current project. - */ - config: ResolvedConfig - /** - * Provide a value to the test context. This value will be available to all tests via `inject`. - */ - provide: ( - key: T, - value: ProvidedContext[T] - ) => void - /** - * Register a function that will be called before tests run again in watch mode. - */ - onTestsRerun: (cb: OnTestsRerunHandler) => void -} +/** @deprecated use `TestProject` instead */ +export type GlobalSetupContext = TestProject export interface GlobalSetupFile { file: string - setup?: (context: GlobalSetupContext) => Promise | void + setup?: (context: TestProject) => Promise | void teardown?: Function } diff --git a/packages/vitest/src/node/project.ts b/packages/vitest/src/node/project.ts index 23bf9566b..e25c03992 100644 --- a/packages/vitest/src/node/project.ts +++ b/packages/vitest/src/node/project.ts @@ -5,9 +5,10 @@ import type { InlineConfig as ViteInlineConfig, } from 'vite' import type { Typechecker } from '../typecheck/typechecker' -import type { ProvidedContext } from '../types/general' +import type { OnTestsRerunHandler, ProvidedContext } from '../types/general' import type { Vitest } from './core' import type { GlobalSetupFile } from './globalSetup' +import type { Logger } from './logger' import type { BrowserServer } from './types/browser' import type { ResolvedConfig, @@ -87,13 +88,15 @@ export class TestProject { this.globalConfig = vitest.config } + // "provide" is a property, not a method to keep the context when destructed in the global setup, + // making it a method would be a breaking change, and can be done in Vitest 3 at minimum /** * Provide a value to the test context. This value will be available to all tests with `inject`. */ - provide( + provide = ( key: T, value: ProvidedContext[T], - ): void { + ): void => { try { structuredClone(value) } @@ -217,11 +220,7 @@ export class TestProject { ) for (const globalSetupFile of this._globalSetups) { - const teardown = await globalSetupFile.setup?.({ - provide: (key, value) => this.provide(key, value), - config: this.config, - onTestsRerun: cb => this.vitest.onTestsRerun(cb), - }) + const teardown = await globalSetupFile.setup?.(this) if (teardown == null || !!globalSetupFile.teardown) { continue } @@ -234,13 +233,17 @@ export class TestProject { } } + onTestsRerun(cb: OnTestsRerunHandler): void { + this.vitest.onTestsRerun(cb) + } + /** @deprecated */ - teardownGlobalSetup() { + teardownGlobalSetup(): Promise { return this._teardownGlobalSetup() } /** @internal */ - async _teardownGlobalSetup() { + async _teardownGlobalSetup(): Promise { if (!this._globalSetups) { return } @@ -250,7 +253,7 @@ export class TestProject { } /** @deprecated use `vitest.logger` instead */ - get logger() { + get logger(): Logger { return this.vitest.logger } diff --git a/test/watch/fixtures/global-setup.ts b/test/watch/fixtures/global-setup.ts index b86537e95..4d9c33792 100644 --- a/test/watch/fixtures/global-setup.ts +++ b/test/watch/fixtures/global-setup.ts @@ -1,12 +1,12 @@ -import { GlobalSetupContext } from 'vitest/node'; +import { TestProject } from 'vitest/node'; const calls: string[] = []; (globalThis as any).__CALLS = calls -export default ({ onTestsRerun }: GlobalSetupContext) => { +export default (project: TestProject) => { calls.push('start') - onTestsRerun(() => { + project.onTestsRerun(() => { calls.push('rerun') }) return () => {