diff --git a/docs/config/index.md b/docs/config/index.md index 4593b0310676..ff3747ff21b8 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -21,6 +21,18 @@ export default defineConfig({ }) ``` +You can retrieve Vitest's default options to expand them if needed: + +```ts +import { defineConfig, configDefaults } from 'vitest' + +export default defineConfig({ + test: { + exclude: [...configDefaults.exclude, 'packages/template/*'], + }, +}) +``` + ## Options ### include diff --git a/packages/vitest/src/constants.ts b/packages/vitest/src/constants.ts index ab74b956b6fc..d9c6c3d78cbe 100644 --- a/packages/vitest/src/constants.ts +++ b/packages/vitest/src/constants.ts @@ -1,11 +1,64 @@ import { fileURLToPath } from 'url' import { resolve } from 'pathe' +import type { ResolvedC8Options, UserConfig } from './types' export const distDir = resolve(fileURLToPath(import.meta.url), '../../dist') export const defaultInclude = ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'] export const defaultExclude = ['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**'] +const defaultCoverageExcludes = [ + 'coverage/**', + 'packages/*/test{,s}/**', + '**/*.d.ts', + 'cypress/**', + 'test{,s}/**', + 'test{,-*}.{js,cjs,mjs,ts,tsx,jsx}', + '**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx}', + '**/__tests__/**', + '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc}.config.{js,cjs,mjs,ts}', + '**/.{eslint,mocha}rc.{js,cjs}', +] + +export const coverageConfigDefaults = Object.freeze({ + enabled: false, + clean: true, + cleanOnRerun: false, + reportsDirectory: './coverage', + excludeNodeModules: true, + exclude: defaultCoverageExcludes, + reporter: ['text', 'html'], + allowExternal: false, + // default extensions used by c8, plus '.vue' and '.svelte' + // see https://github.com/istanbuljs/schema/blob/master/default-extension.js + extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', 'svelte'], +}) as ResolvedC8Options + +export const configDefaults: UserConfig = Object.freeze({ + allowOnly: !process.env.CI, + globals: false, + environment: 'node', + threads: true, + clearMocks: false, + restoreMocks: false, + mockReset: false, + include: defaultInclude, + exclude: defaultExclude, + testTimeout: 5_000, + hookTimeout: 10_000, + isolate: true, + watchIgnore: [/\/node_modules\//, /\/dist\//], + update: false, + watch: !process.env.CI, + reporters: 'default', + silent: false, + api: false, + ui: false, + uiBase: '/__vitest__/', + open: true, + coverage: coverageConfigDefaults, +}) + // if changed, update also jsdocs and docs export const defaultPort = 51204 diff --git a/packages/vitest/src/index.ts b/packages/vitest/src/index.ts index 35db361a9f94..22e7c75640e9 100644 --- a/packages/vitest/src/index.ts +++ b/packages/vitest/src/index.ts @@ -16,6 +16,8 @@ export * from './integrations/vi' export * from './types' export * from './api/types' +export { configDefaults } from './constants' + declare module 'vite' { interface UserConfig { /** diff --git a/packages/vitest/src/integrations/coverage.ts b/packages/vitest/src/integrations/coverage.ts index 162b7df62174..912294b6977e 100644 --- a/packages/vitest/src/integrations/coverage.ts +++ b/packages/vitest/src/integrations/coverage.ts @@ -7,33 +7,11 @@ import type { RawSourceMap } from 'vite-node' import type { Vitest } from '../node' import { toArray } from '../utils' import type { C8Options, ResolvedC8Options } from '../types' - -const defaultExcludes = [ - 'coverage/**', - 'packages/*/test{,s}/**', - '**/*.d.ts', - 'cypress/**', - 'test{,s}/**', - 'test{,-*}.{js,cjs,mjs,ts,tsx,jsx}', - '**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx}', - '**/__tests__/**', - '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc}.config.{js,cjs,mjs,ts}', - '**/.{eslint,mocha}rc.{js,cjs}', -] +import { coverageConfigDefaults } from '../constants' export function resolveC8Options(options: C8Options, root: string): ResolvedC8Options { const resolved: ResolvedC8Options = { - enabled: false, - clean: true, - cleanOnRerun: false, - reportsDirectory: './coverage', - excludeNodeModules: true, - exclude: defaultExcludes, - reporter: ['text', 'html'], - allowExternal: false, - // default extensions used by c8, plus '.vue' and '.svelte' - // see https://github.com/istanbuljs/schema/blob/master/default-extension.js - extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', 'svelte'], + ...coverageConfigDefaults, ...options as any, } diff --git a/packages/vitest/src/node/cli.ts b/packages/vitest/src/node/cli.ts index c2490619d179..f8522e0c41af 100644 --- a/packages/vitest/src/node/cli.ts +++ b/packages/vitest/src/node/cli.ts @@ -16,11 +16,11 @@ cli .option('-w, --watch', 'watch mode') .option('-t, --testNamePattern ', 'run test names with the specified pattern') .option('--ui', 'enable UI') - .option('--open', 'open UI automatically', { default: true }) + .option('--open', 'open UI automatically (default: !process.env.CI))') .option('--api [api]', 'serve API, available options: --api.port , --api.host [host] and --api.strictPort') - .option('--threads', 'enabled threads', { default: true }) + .option('--threads', 'enabled threads (default: true)') .option('--silent', 'silent console output from tests') - .option('--isolate', 'isolate environment for each test file', { default: true }) + .option('--isolate', 'isolate environment for each test file (default: true)') .option('--reporter ', 'reporter') .option('--outputFile ', 'write test results to a file when the --reporter=json option is also specified') .option('--coverage', 'use c8 for coverage') @@ -28,9 +28,9 @@ cli .option('--globals', 'inject apis globally') .option('--global', 'deprecated, use --globals') .option('--dom', 'mock browser api with happy-dom') - .option('--environment ', 'runner environment', { default: 'node' }) + .option('--environment ', 'runner environment (default: node)') .option('--passWithNoTests', 'pass when no tests found') - .option('--allowOnly', 'Allow tests and suites that are marked as only', { default: !process.env.CI }) + .option('--allowOnly', 'Allow tests and suites that are marked as only (default: !process.env.CI)') .help() cli @@ -62,8 +62,6 @@ async function runRelated(relatedFiles: string[] | string, argv: UserConfig) { } async function dev(cliFilters: string[], argv: UserConfig) { - if (argv.watch == null) - argv.watch = !process.env.CI && !argv.run await run(cliFilters, argv) } diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 5b7025f88c40..5d119efb580a 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -2,7 +2,7 @@ import { resolve } from 'pathe' import type { ResolvedConfig as ResolvedViteConfig } from 'vite' import type { ApiConfig, ResolvedConfig, UserConfig } from '../types' -import { defaultExclude, defaultInclude, defaultPort } from '../constants' +import { configDefaults, defaultPort } from '../constants' import { resolveC8Options } from '../integrations/coverage' import { toArray } from '../utils' @@ -50,6 +50,7 @@ export function resolveConfig( const globals = options?.global ?? options.globals const resolved = { + ...configDefaults, ...options, root: viteConfig.root, globals, @@ -59,7 +60,7 @@ export function resolveConfig( if (viteConfig.base !== '/') resolved.base = viteConfig.base - resolved.coverage = resolveC8Options(resolved.coverage, resolved.root) + resolved.coverage = resolveC8Options(options.coverage || {}, resolved.root) resolved.deps = resolved.deps || {} // vitenode will try to import such file with native node, @@ -73,29 +74,12 @@ export function resolveConfig( /vitest-virtual-\w+\/dist/, ) - resolved.environment = resolved.environment || 'node' - resolved.threads = resolved.threads ?? true - - resolved.clearMocks = resolved.clearMocks ?? false - resolved.restoreMocks = resolved.restoreMocks ?? false - resolved.mockReset = resolved.mockReset ?? false - - resolved.include = resolved.include ?? defaultInclude - resolved.exclude = resolved.exclude ?? defaultExclude - - resolved.testTimeout = resolved.testTimeout ?? 5_000 - resolved.hookTimeout = resolved.hookTimeout ?? 10_000 - - resolved.isolate = resolved.isolate ?? true - resolved.testNamePattern = resolved.testNamePattern ? resolved.testNamePattern instanceof RegExp ? resolved.testNamePattern : new RegExp(resolved.testNamePattern) : undefined - resolved.watchIgnore = resolved.watchIgnore ?? [/\/node_modules\//, /\/dist\//] - const CI = !!process.env.CI const UPDATE_SNAPSHOT = resolved.update || process.env.UPDATE_SNAPSHOT resolved.snapshotOptions = { diff --git a/packages/vitest/src/node/plugins/index.ts b/packages/vitest/src/node/plugins/index.ts index fc99a17d583c..262cf4d52d8d 100644 --- a/packages/vitest/src/node/plugins/index.ts +++ b/packages/vitest/src/node/plugins/index.ts @@ -1,4 +1,5 @@ import type { Plugin as VitePlugin } from 'vite' +import { configDefaults } from '../../constants' import type { UserConfig } from '../../types' import { deepMerge, ensurePackageInstalled, notNullish } from '../../utils' import { resolveApiConfig } from '../config' @@ -48,8 +49,14 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest()) }, async configResolved(viteConfig) { // viteConfig.test is final now, merge it for real - options = deepMerge(options, viteConfig.test as any || {}) + options = deepMerge( + {}, + configDefaults, + (viteConfig.test as any) || {}, + options, + ) options.api = resolveApiConfig(options) + options.watch = options.watch && !options.run }, async configureServer(server) { if (haveStarted) diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index 2f3281565c57..a7c4274a32ae 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -159,7 +159,7 @@ export interface InlineConfig { /** * Default timeout of a hook in milliseconds * - * @default 5000 + * @default 10000 */ hookTimeout?: number