From a5bbc0a94aa0f7f99e1698118c012b823712fb88 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Mon, 25 Nov 2024 17:01:03 +0100 Subject: [PATCH] feat: provide the current project to the global setup (#6942) --- docs/config/index.md | 27 ++++++++++++++++++------- packages/vitest/src/node/globalSetup.ts | 24 ++++------------------ packages/vitest/src/node/project.ts | 25 +++++++++++++---------- test/watch/fixtures/global-setup.ts | 6 +++--- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index a89a383bf959..ca613da7dd84 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 295b8a862035..435dbbe19e55 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 23bf9566b6e5..e25c03992735 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 b86537e952dc..4d9c33792e65 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 () => {