From f020b8f25aee2b261da43836c94b2eaf8dd1a64f Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 3 Sep 2022 14:30:32 +0300 Subject: [PATCH 1/8] feat: allow custom environments --- docs/.vitepress/config.ts | 4 ++ docs/config/index.md | 31 ++++++++++- docs/guide/environment.md | 55 +++++++++++++++++++ packages/vitest/rollup.config.js | 1 + packages/vitest/src/environments.ts | 2 + .../vitest/src/integrations/chai/index.ts | 5 +- packages/vitest/src/integrations/env/index.ts | 9 +++ packages/vitest/src/integrations/env/utils.ts | 8 +-- packages/vitest/src/node/cli-api.ts | 13 ++--- packages/vitest/src/runtime/entry.ts | 16 +++--- packages/vitest/src/runtime/setup.ts | 16 +++++- packages/vitest/src/types/chai.ts | 2 + packages/vitest/src/types/config.ts | 7 ++- pnpm-lock.yaml | 32 ++++++++++- test/env-custom/package.json | 12 ++++ test/env-custom/test/base.test.ts | 7 +++ .../vitest-environment-custom/index.mjs | 13 +++++ .../vitest-environment-custom/package.json | 5 ++ test/env-custom/vitest.config.ts | 12 ++++ 19 files changed, 225 insertions(+), 25 deletions(-) create mode 100644 docs/guide/environment.md create mode 100644 packages/vitest/src/environments.ts create mode 100644 test/env-custom/package.json create mode 100644 test/env-custom/test/base.test.ts create mode 100644 test/env-custom/vitest-environment-custom/index.mjs create mode 100644 test/env-custom/vitest-environment-custom/package.json create mode 100644 test/env-custom/vitest.config.ts diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 82b813ae291e..1193810fdf88 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -147,6 +147,10 @@ export default defineConfig({ text: 'Test Context', link: '/guide/test-context', }, + { + text: 'Environment', + link: '/guide/environment', + }, { text: 'Extending Matchers', link: '/guide/extending-matchers', diff --git a/docs/config/index.md b/docs/config/index.md index a868895c87a7..6471d37cc3b2 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -186,7 +186,7 @@ export default defineConfig({ ### environment -- **Type:** `'node' | 'jsdom' | 'happy-dom' | 'edge-runtime'` +- **Type:** `'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string` - **Default:** `'node'` The environment that will be used for testing. The default environment in Vitest @@ -235,7 +235,34 @@ test('use jsdom in this test file', () => { }) ``` -If you are running Vitest with [`--no-threads`](#threads) flag, your tests will be run in this order: `node`, `jsdom`, `happy-dom`. Meaning, that every test with the same environment is grouped together, but is still run sequentially. +If you are running Vitest with [`--no-threads`](#threads) flag, your tests will be run in this order: `node`, `jsdom`, `happy-dom`, `edge-runtime`, `custom environments`. Meaning, that every test with the same environment is grouped together, but is still running sequentially. + +Starting from 0.23.0, you can also define custom environment. When non-builtin environment is used, Vitest will try to load package `vitest-environment-${name}`. That package should export an object with the shape of `Environment`: + +```ts +import type { Environment } from 'vitest' + +export default { + name: 'custom', + setup() { + // cusotm setup + return { + teardown() { + // called after all tests with this env have been run + } + } + } +} +``` + +Vitest also exposes `environments` variable with built-in environments throught `vitest/environments`, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment). + +### environmentOptions + +- **Type:** `Record<'jsdom' | string, string>` +- **Default:** `{}` + +These options are passed down to `setup` method of current [`environment`](/#environment). By default, you can configure only JSDOM options, if you are using it as your test environment. ### update diff --git a/docs/guide/environment.md b/docs/guide/environment.md new file mode 100644 index 000000000000..ad8f9cdd8160 --- /dev/null +++ b/docs/guide/environment.md @@ -0,0 +1,55 @@ +# Test Environment + +Vitest provides [`environment`](/config/#environment) option to run code inside a specific environment. You can modify how environment behaves with [`environmentOptions`](/config/#environmentoptions) option. + +By default, you can use this environments: + +- `node` is default environment +- `jsdon` emulates browser environment by providing Browser API, uses [`jsdom`](https://github.com/jsdom/jsdom) package +- `happy-dom` emulates browser environment by providing Browser API, and considered to be faster than jsdom, but lacks some browser API, uses [`happy-dom`](https://github.com/capricorn86/happy-dom) package +- `edge-runtime` emulates Vercel's [edge-runtime](https://edge-runtime.vercel.app/), uses [`@edge-runtime/vm`](https://www.npmjs.com/package/@edge-runtime/vm) package + +Starting from 0.23.0, you can create your own package to extend Vitest environment. To do so, create package with the name `vitest-environment-${name}`. That package should export an object with the shape of `Environment`: + +```ts +import type { Environment } from 'vitest' + +export default { + name: 'custom', + setup() { + // cusotm setup + return { + teardown() { + // called after all tests with this env have been run + } + } + } +} +``` + +You also have access to default Vitest environments through `vitest/environments` entry: + +```ts +import { environments, populateGlobal } from 'vitest/environments' + +console.log(environments) // { jsdom, happy-dom, node, edge-runtime } +``` + +Vitest also provides `populateGlobal` utility function, which can be used to move properties from one object into the global namespace: + +```ts +interface PopulateOptions { + // should non-class functions be bind to the global namespace + bindFunctions?: boolean +} + +interface PopulateResult { + // a list of all keys that were copied, even if value doesn't exist on original object + keys: Set + // a map of original object that might have been overriden with keys + // you can return these values inside `teardown` function + originals: Map +} + +export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult +``` \ No newline at end of file diff --git a/packages/vitest/rollup.config.js b/packages/vitest/rollup.config.js index c5d4b6de82ac..462441bfd11a 100644 --- a/packages/vitest/rollup.config.js +++ b/packages/vitest/rollup.config.js @@ -20,6 +20,7 @@ const entries = [ 'src/node/cli.ts', 'src/node/cli-wrapper.ts', 'src/node.ts', + 'src/environments.ts', 'src/runtime/worker.ts', 'src/runtime/loader.ts', 'src/runtime/entry.ts', diff --git a/packages/vitest/src/environments.ts b/packages/vitest/src/environments.ts new file mode 100644 index 000000000000..79bff1b3eb85 --- /dev/null +++ b/packages/vitest/src/environments.ts @@ -0,0 +1,2 @@ +export { environments } from './integrations/env/index' +export { populateGlobal } from './integrations/env/utils' diff --git a/packages/vitest/src/integrations/chai/index.ts b/packages/vitest/src/integrations/chai/index.ts index a502d3ee8aa2..c3290c4f13f3 100644 --- a/packages/vitest/src/integrations/chai/index.ts +++ b/packages/vitest/src/integrations/chai/index.ts @@ -1,11 +1,13 @@ import * as chai from 'chai' import './setup' import type { Test } from '../../types' -import { getFullName } from '../../utils' +import { getFullName, getWorkerState } from '../../utils' import type { MatcherState } from '../../types/chai' import { getState, setState } from './jest-expect' import { GLOBAL_EXPECT } from './constants' +const workerState = getWorkerState() + export function createExpect(test?: Test) { const expect = ((value: any, message?: string): Vi.Assertion => { const { assertionCalls } = getState(expect) @@ -28,6 +30,7 @@ export function createExpect(test?: Test) { isExpectingAssertionsError: null, expectedAssertionsNumber: null, expectedAssertionsNumberErrorGen: null, + environment: workerState.config.environment, testPath: test?.suite.file?.filepath, currentTestName: test ? getFullName(test) : undefined, }, expect) diff --git a/packages/vitest/src/integrations/env/index.ts b/packages/vitest/src/integrations/env/index.ts index aa130e77e3ee..3e45c194f92e 100644 --- a/packages/vitest/src/integrations/env/index.ts +++ b/packages/vitest/src/integrations/env/index.ts @@ -1,3 +1,4 @@ +import type { VitestEnvironment } from '../../types/config' import node from './node' import jsdom from './jsdom' import happy from './happy-dom' @@ -17,3 +18,11 @@ export const envPackageNames: Record, 'happy-dom': 'happy-dom', 'edge-runtime': '@edge-runtime/vm', } + +export const getEnvPackageName = (env: VitestEnvironment) => { + if (env === 'node') + return null + if (env in envPackageNames) + return (envPackageNames as any)[env] + return `vitest-environment-${env}` +} diff --git a/packages/vitest/src/integrations/env/utils.ts b/packages/vitest/src/integrations/env/utils.ts index 6ba0659cce96..966837fde69d 100644 --- a/packages/vitest/src/integrations/env/utils.ts +++ b/packages/vitest/src/integrations/env/utils.ts @@ -34,6 +34,10 @@ function isClassLikeName(name: string) { } interface PopulateOptions { + // we bind functions such as addEventListener and others + // because they rely on `this` in happy-dom, and in jsdom it + // has a priority for getting implementation from symbols + // (global doesn't have these symbols, but window - does) bindFunctions?: boolean } @@ -47,10 +51,6 @@ export function populateGlobal(global: any, win: any, options: PopulateOptions = const overrideObject = new Map() for (const key of keys) { - // we bind functions such as addEventListener and others - // because they rely on `this` in happy-dom, and in jsdom it - // has a priority for getting implementation from symbols - // (global doesn't have these symbols, but window - does) const boundFunction = bindFunctions && typeof win[key] === 'function' && !isClassLikeName(key) diff --git a/packages/vitest/src/node/cli-api.ts b/packages/vitest/src/node/cli-api.ts index 1241d0551461..fc19fbfce6d4 100644 --- a/packages/vitest/src/node/cli-api.ts +++ b/packages/vitest/src/node/cli-api.ts @@ -2,7 +2,7 @@ import { resolve } from 'pathe' import type { UserConfig as ViteUserConfig } from 'vite' import { EXIT_CODE_RESTART } from '../constants' import { CoverageProviderMap } from '../integrations/coverage' -import { envPackageNames } from '../integrations/env' +import { getEnvPackageName } from '../integrations/env' import type { UserConfig } from '../types' import { ensurePackageInstalled } from '../utils' import { createVitest } from './create' @@ -50,12 +50,11 @@ export async function startVitest(cliFilters: string[], options: CliOptions, vit } } - if (ctx.config.environment && ctx.config.environment !== 'node') { - const packageName = envPackageNames[ctx.config.environment] - if (!await ensurePackageInstalled(packageName, root)) { - process.exitCode = 1 - return false - } + const environmentPackage = getEnvPackageName(ctx.config.environment) + + if (environmentPackage && !await ensurePackageInstalled(environmentPackage, root)) { + process.exitCode = 1 + return false } if (process.stdin.isTTY && ctx.config.watch) diff --git a/packages/vitest/src/runtime/entry.ts b/packages/vitest/src/runtime/entry.ts index aab9c5d24105..d08d9ce07409 100644 --- a/packages/vitest/src/runtime/entry.ts +++ b/packages/vitest/src/runtime/entry.ts @@ -1,5 +1,5 @@ import { promises as fs } from 'fs' -import type { BuiltinEnvironment, ResolvedConfig } from '../types' +import type { ResolvedConfig, VitestEnvironment } from '../types' import { getWorkerState, resetModules } from '../utils' import { envs } from '../integrations/env' import { setupGlobalEnv, withEnv } from './setup' @@ -22,11 +22,9 @@ export async function run(files: string[], config: ResolvedConfig): Promise { const code = await fs.readFile(file, 'utf-8') const env = code.match(/@(?:vitest|jest)-environment\s+?([\w-]+)\b/)?.[1] || config.environment || 'node' - if (!envs.includes(env)) - throw new Error(`Unsupported environment: "${env}" in ${file}`) return { file, - env: env as BuiltinEnvironment, + env: env as VitestEnvironment, } })) @@ -34,10 +32,14 @@ export async function run(files: string[], config: ResolvedConfig): Promise) + }, {} as Record) - for (const env of envs) { - const environment = env as BuiltinEnvironment + const orderedEnvs = envs.concat( + Object.keys(filesByEnv).filter(env => !envs.includes(env)), + ) + + for (const env of orderedEnvs) { + const environment = env as VitestEnvironment const files = filesByEnv[environment] if (!files || !files.length) diff --git a/packages/vitest/src/runtime/setup.ts b/packages/vitest/src/runtime/setup.ts index 61c1a17848b4..c86501828557 100644 --- a/packages/vitest/src/runtime/setup.ts +++ b/packages/vitest/src/runtime/setup.ts @@ -1,5 +1,5 @@ import { environments } from '../integrations/env' -import type { ResolvedConfig } from '../types' +import type { Environment, ResolvedConfig } from '../types' import { clearTimeout, getWorkerState, isNode, setTimeout, toArray } from '../utils' import * as VitestIndex from '../index' import { resetRunOnceCounter } from '../integrations/run-once' @@ -151,12 +151,24 @@ export async function setupConsoleLogSpy() { }) } +async function loadEnvironment(name: string) { + const pkg = await import(`vitest-environment-${name}`) + if (!pkg || !pkg.default || typeof pkg.default !== 'object' || typeof pkg.default.setup !== 'function') { + throw new Error( + `Environment "${name}" is not a valid environment. ` + + `Package "vitest-environment-${name}" should have default export with "setup" method.`, + ) + } + return pkg.default +} + export async function withEnv( name: ResolvedConfig['environment'], options: ResolvedConfig['environmentOptions'], fn: () => Promise, ) { - const env = await environments[name].setup(globalThis, options) + const config: Environment = (environments as any)[name] || await loadEnvironment(name) + const env = await config.setup(globalThis, options) try { await fn() } diff --git a/packages/vitest/src/types/chai.ts b/packages/vitest/src/types/chai.ts index f602c878dadd..0d96ab3af5c9 100644 --- a/packages/vitest/src/types/chai.ts +++ b/packages/vitest/src/types/chai.ts @@ -10,6 +10,7 @@ import type { use as chaiUse } from 'chai' import type * as jestMatcherUtils from '../integrations/chai/jest-matcher-utils' import type SnapshotState from '../integrations/snapshot/port/state' +import type { VitestEnvironment } from './config' export type FirstFunctionArgument = T extends (arg: infer A) => unknown ? A : never export type ChaiPlugin = FirstFunctionArgument @@ -33,6 +34,7 @@ export interface MatcherState { isExpectingAssertions?: boolean isExpectingAssertionsError?: Error | null isNot: boolean + environment: VitestEnvironment promise: string snapshotState: SnapshotState suppressedErrors: Array diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index 4fbea1384add..db8767fde28f 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -10,6 +10,8 @@ import type { SnapshotStateOptions } from './snapshot' import type { Arrayable } from './general' export type BuiltinEnvironment = 'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' +// Record is used, so user can get intellisense for builtin environments, but still allow custom environments +export type VitestEnvironment = BuiltinEnvironment | (string & Record) export type ApiConfig = Pick @@ -20,6 +22,7 @@ export interface EnvironmentOptions { * jsdom options. */ jsdom?: JSDOMOptions + [x: string]: unknown } export interface InlineConfig { @@ -107,9 +110,11 @@ export interface InlineConfig { * * Supports 'node', 'jsdom', 'happy-dom', 'edge-runtime' * + * If used unsupported string, will try to load the package `vitest-environment-${env}` + * * @default 'node' */ - environment?: BuiltinEnvironment + environment?: VitestEnvironment /** * Environment options. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f607f609035..7aefb30ea826 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -566,7 +566,7 @@ importers: vue: latest devDependencies: '@vitejs/plugin-vue': 3.0.3_vite@3.0.9+vue@3.2.38 - '@vitejs/plugin-vue-jsx': 2.0.0_vite@3.0.9+vue@3.2.38 + '@vitejs/plugin-vue-jsx': 2.0.1_vite@3.0.9+vue@3.2.38 '@vue/test-utils': 2.0.2_vue@3.2.38 jsdom: 20.0.0 vite: 3.0.9 @@ -942,6 +942,14 @@ importers: '@vitest/web-worker': link:../../packages/web-worker vitest: link:../../packages/vitest + test/env-custom: + specifiers: + vitest: workspace:* + vitest-environment-custom: file:./vitest-environment-custom + devDependencies: + vitest: link:../../packages/vitest + vitest-environment-custom: file:test/env-custom/vitest-environment-custom + test/esm: specifiers: css-what: 6.1.0 @@ -6337,6 +6345,23 @@ packages: - supports-color dev: true + /@vitejs/plugin-vue-jsx/2.0.1_vite@3.0.9+vue@3.2.38: + resolution: {integrity: sha512-lmiR1k9+lrF7LMczO0pxtQ8mOn6XeppJDHxnpxkJQpT5SiKz4SKhKdeNstXaTNuR8qZhUo5X0pJlcocn72Y4Jg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^3.0.0 + vue: ^3.0.0 + dependencies: + '@babel/core': 7.18.13 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.18.13 + '@babel/plugin-transform-typescript': 7.18.12_@babel+core@7.18.13 + '@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.18.13 + vite: 3.0.9 + vue: 3.2.38 + transitivePeerDependencies: + - supports-color + dev: true + /@vitejs/plugin-vue/3.0.3_vite@3.0.9+vue@3.2.38: resolution: {integrity: sha512-U4zNBlz9mg+TA+i+5QPc3N5lQvdUXENZLO2h0Wdzp56gI1MWhqJOv+6R+d4kOzoaSSq6TnGPBdZAXKOe4lXy6g==} engines: {node: ^14.18.0 || >=16.0.0} @@ -19239,3 +19264,8 @@ packages: /zwitch/1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: true + + file:test/env-custom/vitest-environment-custom: + resolution: {directory: test/env-custom/vitest-environment-custom, type: directory} + name: vitest-environment-custom + dev: true diff --git a/test/env-custom/package.json b/test/env-custom/package.json new file mode 100644 index 000000000000..f80be0434a0c --- /dev/null +++ b/test/env-custom/package.json @@ -0,0 +1,12 @@ +{ + "name": "@vitest/test-env-custom", + "private": true, + "scripts": { + "test": "vitest", + "coverage": "vitest run --coverage" + }, + "devDependencies": { + "vitest": "workspace:*", + "vitest-environment-custom": "file:./vitest-environment-custom" + } +} diff --git a/test/env-custom/test/base.test.ts b/test/env-custom/test/base.test.ts new file mode 100644 index 000000000000..aa6443e33e02 --- /dev/null +++ b/test/env-custom/test/base.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +test('custom env is defined', () => { + expect(expect.getState().environment).toBe('custom') + expect((globalThis as any).testEnvironment).toBe('custom') + expect((globalThis as any).option).toBe('config-option') +}) diff --git a/test/env-custom/vitest-environment-custom/index.mjs b/test/env-custom/vitest-environment-custom/index.mjs new file mode 100644 index 000000000000..7fc3b0755779 --- /dev/null +++ b/test/env-custom/vitest-environment-custom/index.mjs @@ -0,0 +1,13 @@ +export default { + name: 'custom', + setup(global, { custom }) { + global.testEnvironment = 'custom' + global.option = custom.option + return { + teardown() { + delete global.testEnvironment + delete global.option + }, + } + }, +} diff --git a/test/env-custom/vitest-environment-custom/package.json b/test/env-custom/vitest-environment-custom/package.json new file mode 100644 index 000000000000..370b6ad6d6d2 --- /dev/null +++ b/test/env-custom/vitest-environment-custom/package.json @@ -0,0 +1,5 @@ +{ + "name": "vitest-environment-custom", + "private": true, + "main": "index.mjs" +} \ No newline at end of file diff --git a/test/env-custom/vitest.config.ts b/test/env-custom/vitest.config.ts new file mode 100644 index 000000000000..7703df7c1d44 --- /dev/null +++ b/test/env-custom/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + environment: 'custom', + environmentOptions: { + custom: { + option: 'config-option', + }, + }, + }, +}) From aca268c33e03cad2fa31a16de05ae053baa4d378 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 3 Sep 2022 14:33:53 +0300 Subject: [PATCH 2/8] chore: linting --- test/env-custom/vitest-environment-custom/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/env-custom/vitest-environment-custom/package.json b/test/env-custom/vitest-environment-custom/package.json index 370b6ad6d6d2..62caa1e2b142 100644 --- a/test/env-custom/vitest-environment-custom/package.json +++ b/test/env-custom/vitest-environment-custom/package.json @@ -2,4 +2,4 @@ "name": "vitest-environment-custom", "private": true, "main": "index.mjs" -} \ No newline at end of file +} From 40351aa1e4014e0a0cc40ad499e9cdd47a4bde0d Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 3 Sep 2022 15:09:44 +0300 Subject: [PATCH 3/8] chore: cleanup Co-authored-by: Ivan Demchuk --- docs/config/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config/index.md b/docs/config/index.md index 6471d37cc3b2..d6716092e57a 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -245,7 +245,7 @@ import type { Environment } from 'vitest' export default { name: 'custom', setup() { - // cusotm setup + // custom setup return { teardown() { // called after all tests with this env have been run From 544cdf3c0e95de6d882a3a9c95cc55f1e0a07099 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sat, 3 Sep 2022 15:09:48 +0300 Subject: [PATCH 4/8] chore: cleanup Co-authored-by: Ivan Demchuk --- docs/guide/environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/environment.md b/docs/guide/environment.md index ad8f9cdd8160..b6f979162c6c 100644 --- a/docs/guide/environment.md +++ b/docs/guide/environment.md @@ -2,7 +2,7 @@ Vitest provides [`environment`](/config/#environment) option to run code inside a specific environment. You can modify how environment behaves with [`environmentOptions`](/config/#environmentoptions) option. -By default, you can use this environments: +By default, you can use these environments: - `node` is default environment - `jsdon` emulates browser environment by providing Browser API, uses [`jsdom`](https://github.com/jsdom/jsdom) package From 8aee39d5d175b1d3432b53a42c74850edb39939b Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sun, 4 Sep 2022 08:19:59 +0300 Subject: [PATCH 5/8] chore: cleanup --- docs/config/index.md | 2 +- docs/guide/environment.md | 4 ++-- packages/vitest/package.json | 4 ++++ packages/vitest/rollup.config.js | 1 + packages/vitest/src/environments.ts | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index d6716092e57a..28700bf28d15 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -255,7 +255,7 @@ export default { } ``` -Vitest also exposes `environments` variable with built-in environments throught `vitest/environments`, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment). +Vitest also exposes `builtinEnvironments` variable with built-in environments through `vitest/environments`, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment). ### environmentOptions diff --git a/docs/guide/environment.md b/docs/guide/environment.md index b6f979162c6c..2a78169d9d85 100644 --- a/docs/guide/environment.md +++ b/docs/guide/environment.md @@ -30,9 +30,9 @@ export default { You also have access to default Vitest environments through `vitest/environments` entry: ```ts -import { environments, populateGlobal } from 'vitest/environments' +import { builtinEnvironments, populateGlobal } from 'vitest/environments' -console.log(environments) // { jsdom, happy-dom, node, edge-runtime } +console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime } ``` Vitest also provides `populateGlobal` utility function, which can be used to move properties from one object into the global namespace: diff --git a/packages/vitest/package.json b/packages/vitest/package.json index b669a5de033e..cf1d256cd8e9 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -36,6 +36,10 @@ "types": "./dist/node.d.ts", "import": "./dist/node.mjs" }, + "./environments": { + "types": "./dist/environments.d.ts", + "import": "./dist/environments.mjs" + }, "./browser": { "types": "./dist/browser.d.ts", "import": "./dist/browser.mjs" diff --git a/packages/vitest/rollup.config.js b/packages/vitest/rollup.config.js index 462441bfd11a..1dcb7b49eab5 100644 --- a/packages/vitest/rollup.config.js +++ b/packages/vitest/rollup.config.js @@ -32,6 +32,7 @@ const dtsEntries = [ 'src/index.ts', 'src/node.ts', 'src/browser.ts', + 'src/environments.ts', 'src/config.ts', ] diff --git a/packages/vitest/src/environments.ts b/packages/vitest/src/environments.ts index 79bff1b3eb85..827be772d3c2 100644 --- a/packages/vitest/src/environments.ts +++ b/packages/vitest/src/environments.ts @@ -1,2 +1,2 @@ -export { environments } from './integrations/env/index' +export { environments as builtinEnvironments } from './integrations/env/index' export { populateGlobal } from './integrations/env/utils' From 27f947a4ba40eb277fce3aa01d0225d5105f46fe Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sun, 4 Sep 2022 08:23:36 +0300 Subject: [PATCH 6/8] docs: cleanup --- docs/config/index.md | 2 +- docs/guide/environment.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 28700bf28d15..96fbc1e12709 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -255,7 +255,7 @@ export default { } ``` -Vitest also exposes `builtinEnvironments` variable with built-in environments through `vitest/environments`, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment). +Vitest also exposes `builtinEnvironments` through `vitest/environments` entry, in case you just want to extend it. You can read more about extending environments in [our guide](/guide/environment). ### environmentOptions diff --git a/docs/guide/environment.md b/docs/guide/environment.md index 2a78169d9d85..2e1a61700f8f 100644 --- a/docs/guide/environment.md +++ b/docs/guide/environment.md @@ -6,7 +6,7 @@ By default, you can use these environments: - `node` is default environment - `jsdon` emulates browser environment by providing Browser API, uses [`jsdom`](https://github.com/jsdom/jsdom) package -- `happy-dom` emulates browser environment by providing Browser API, and considered to be faster than jsdom, but lacks some browser API, uses [`happy-dom`](https://github.com/capricorn86/happy-dom) package +- `happy-dom` emulates browser environment by providing Browser API, and considered to be faster than jsdom, but lacks some API, uses [`happy-dom`](https://github.com/capricorn86/happy-dom) package - `edge-runtime` emulates Vercel's [edge-runtime](https://edge-runtime.vercel.app/), uses [`@edge-runtime/vm`](https://www.npmjs.com/package/@edge-runtime/vm) package Starting from 0.23.0, you can create your own package to extend Vitest environment. To do so, create package with the name `vitest-environment-${name}`. That package should export an object with the shape of `Environment`: @@ -35,7 +35,7 @@ import { builtinEnvironments, populateGlobal } from 'vitest/environments' console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime } ``` -Vitest also provides `populateGlobal` utility function, which can be used to move properties from one object into the global namespace: +Vitest also provides `populateGlobal` utility function, which can be used to move properties from object into the global namespace: ```ts interface PopulateOptions { From 487d568318dccfffa6cfaaf60380fae2589bae81 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sun, 4 Sep 2022 09:23:18 +0300 Subject: [PATCH 7/8] docs: cleanup --- docs/config/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config/index.md b/docs/config/index.md index 96fbc1e12709..cfd33bd63090 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -259,7 +259,7 @@ Vitest also exposes `builtinEnvironments` through `vitest/environments` entry, i ### environmentOptions -- **Type:** `Record<'jsdom' | string, string>` +- **Type:** `Record<'jsdom' | string, unknown>` - **Default:** `{}` These options are passed down to `setup` method of current [`environment`](/#environment). By default, you can configure only JSDOM options, if you are using it as your test environment. From ce8926c264896452cd6f1f583817f962caa296dc Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sun, 4 Sep 2022 09:36:47 +0300 Subject: [PATCH 8/8] Update docs/guide/environment.md Co-authored-by: Ivan Demchuk --- docs/guide/environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/environment.md b/docs/guide/environment.md index 2e1a61700f8f..af8f4055f536 100644 --- a/docs/guide/environment.md +++ b/docs/guide/environment.md @@ -17,7 +17,7 @@ import type { Environment } from 'vitest' export default { name: 'custom', setup() { - // cusotm setup + // custom setup return { teardown() { // called after all tests with this env have been run