Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 49 additions & 3 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,54 @@ afterEach(() => {
globalThis.resetBeforeEachTest = true
```

### provide <Version>2.1.0</Version> {#provide}

- **Type:** `Partial<ProvidedContext>`

Define values that can be accessed inside your tests using `inject` method.

:::code-group
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
provide: {
API_KEY: '123',
},
},
})
```
```ts [my.test.js]
import { expect, inject, test } from 'vitest'

test('api key is defined', () => {
expect(inject('API_KEY')).toBe('123')
})
```
:::

::: warning
Properties have to be strings and values need to be [serializable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types) because this object will be transferred between different processes.
:::

::: tip
If you are using TypeScript, you will need to augment `ProvidedContext` type for type safe access:

```ts
// vitest.shims.d.ts

declare module 'vitest' {
export interface ProvidedContext {
API_KEY: string
}
}

// mark this file as a module so augmentation works correctly
export {}
```
:::

### globalSetup

- **Type:** `string | string[]`
Expand All @@ -1018,7 +1066,7 @@ Multiple globalSetup files are possible. setup and teardown are executed sequent
::: warning
Global setup runs only if there is at least one running test. This means that global setup might start running during watch mode after test file is changed (the test file will wait for global setup to finish before running).

Beware that the global setup is running in a different global scope, so your tests don't have access to variables defined here. However, you can pass down serializable data to tests via `provide` method:
Beware that the global setup is running in a different global scope, so your tests don't have access to variables defined here. However, you can pass down serializable data to tests via [`provide`](#provide) method:

:::code-group
```js [globalSetup.js]
Expand All @@ -1033,8 +1081,6 @@ export default function setup({ provide }: GlobalSetupContext) {
provide('wsPort', 3000)
}

// You can also extend `ProvidedContext` type
// to have type safe access to `provide/inject` methods:
declare module 'vitest' {
export interface ProvidedContext {
wsPort: number
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/node/cli/cli-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ export const cliOptionsConfig: VitestCLIOptions = {
compare: null,
outputJson: null,
json: null,
provide: null,
}

export const benchCliOptionsConfig: Pick<
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/node/config/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ export function resolveConfig(
mode,
} as any as ResolvedConfig

resolved.provide ??= {}

const inspector = resolved.inspect || resolved.inspectBrk

resolved.inspector = {
Expand Down
23 changes: 22 additions & 1 deletion packages/vitest/src/node/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
} from '../reporters'
import type { TestSequencerConstructor } from '../sequencers/types'
import type { ChaiConfig } from '../../integrations/chai/config'
import type { Arrayable, ErrorWithDiff, ParsedStack } from '../../types/general'
import type { Arrayable, ErrorWithDiff, ParsedStack, ProvidedContext } from '../../types/general'
import type { JSDOMOptions } from '../../types/jsdom-options'
import type { HappyDOMOptions } from '../../types/happy-dom-options'
import type { EnvironmentOptions } from '../../types/environment'
Expand Down Expand Up @@ -731,6 +731,27 @@ export interface InlineConfig {
waitForDebugger?: boolean
}

/**
* Define variables that will be returned from `inject` in the test environment.
* @example
* ```ts
* // vitest.config.ts
* export default defineConfig({
* test: {
* provide: {
* someKey: 'someValue'
* }
* }
* })
* ```
* ```ts
* // test file
* import { inject } from 'vitest'
* const value = inject('someKey') // 'someValue'
* ```
*/
provide?: Partial<ProvidedContext>

/**
* Configuration options for expect() matches.
*/
Expand Down
17 changes: 17 additions & 0 deletions packages/vitest/src/node/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,14 @@ export class WorkspaceProject {
project.server = ctx.server
project.runner = ctx.runner
project.config = ctx.config
for (const _providedKey in ctx.config.provide) {
const providedKey = _providedKey as keyof ProvidedContext
// type is very strict here, so we cast it to any
(project.provide as (key: string, value: unknown) => void)(
providedKey,
ctx.config.provide[providedKey],
)
}
project.testProject = new TestProject(project)
return project
}
Expand All @@ -384,6 +392,15 @@ export class WorkspaceProject {
server.config,
this.ctx.logger,
)
for (const _providedKey in this.config.provide) {
const providedKey = _providedKey as keyof ProvidedContext
// type is very strict here, so we cast it to any
(this.provide as (key: string, value: unknown) => void)(
providedKey,
this.config.provide[providedKey],
)
}

this.testProject = new TestProject(this)

this.server = server
Expand Down
2 changes: 2 additions & 0 deletions test/workspaces/globalTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ declare module 'vitest' {
globalSetup: boolean
globalSetupOverriden: boolean
invalidValue: unknown
projectConfigValue: boolean
globalConfigValue: boolean
}
}

Expand Down
2 changes: 2 additions & 0 deletions test/workspaces/space_3/global-provide.space-3-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ import { expect, inject, test } from 'vitest'
test('global setup provides data correctly', () => {
expect(inject('globalSetup')).toBe(true)
expect(inject('globalSetupOverriden')).toBe(true)
expect(inject('projectConfigValue')).toBe(true)
expect(inject('globalConfigValue')).toBe(true)
expect(inject('invalidValue')).toBe(undefined)
})
3 changes: 3 additions & 0 deletions test/workspaces/space_3/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ export default defineProject({
include: ['**/*.space-3-test.ts'],
environment: 'node',
globalSetup: './localSetup.ts',
provide: {
projectConfigValue: true,
},
},
})
3 changes: 3 additions & 0 deletions test/workspaces/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ export default defineConfig({
CONFIG_VAR: 'root',
CONFIG_OVERRIDE: 'root',
},
provide: {
globalConfigValue: true,
},
},
})