From aaf9f18ae70e52b6e67aaf85f7f784d9dabd0acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Sun, 22 Mar 2026 08:09:38 +0200 Subject: [PATCH] fix(coverage): simplify provider types (#9931) --- docs/guide/cli-generated.md | 14 +++++ packages/coverage-istanbul/src/provider.ts | 4 +- packages/coverage-v8/src/provider.ts | 4 +- packages/vitest/src/node/cli/cli-config.ts | 7 +++ packages/vitest/src/node/coverage.ts | 8 +-- packages/vitest/src/node/types/coverage.ts | 60 ++++++++++--------- .../test/configuration-options.test-d.ts | 20 +------ 7 files changed, 61 insertions(+), 56 deletions(-) diff --git a/docs/guide/cli-generated.md b/docs/guide/cli-generated.md index 45f69a809..7b880b2a2 100644 --- a/docs/guide/cli-generated.md +++ b/docs/guide/cli-generated.md @@ -285,6 +285,20 @@ High and low watermarks for functions in the format of `,` Collect coverage only for files changed since a specified commit or branch (e.g., `origin/main` or `HEAD~1`). Inherits value from `--changed` by default. +### coverage.excludeAfterRemap + +- **CLI:** `--coverage.excludeAfterRemap` +- **Config:** [coverage.excludeAfterRemap](/config/coverage#coverage-excludeafterremap) + +Apply exclusions again after coverage has been remapped to original sources. (default: false) + +### coverage.htmlDir + +- **CLI:** `--coverage.htmlDir ` +- **Config:** [coverage.htmlDir](/config/coverage#coverage-htmldir) + +Directory of HTML coverage output to be served in UI mode and HTML reporter. + ### mode - **CLI:** `--mode ` diff --git a/packages/coverage-istanbul/src/provider.ts b/packages/coverage-istanbul/src/provider.ts index 6dddd5668..7c20e506a 100644 --- a/packages/coverage-istanbul/src/provider.ts +++ b/packages/coverage-istanbul/src/provider.ts @@ -1,7 +1,7 @@ import type { CoverageMap } from 'istanbul-lib-coverage' import type { Instrumenter } from 'istanbul-lib-instrument' import type { ProxifiedModule } from 'magicast' -import type { CoverageProvider, ReportContext, ResolvedCoverageOptions, Vite, Vitest } from 'vitest/node' +import type { CoverageProvider, ReportContext, Vite, Vitest } from 'vitest/node' import { existsSync, promises as fs } from 'node:fs' // @ts-expect-error missing types import { defaults as istanbulDefaults } from '@istanbuljs/schema' @@ -21,7 +21,7 @@ import { COVERAGE_STORE_KEY } from './constants' const debug = createDebug('vitest:coverage') -export class IstanbulCoverageProvider extends BaseCoverageProvider> implements CoverageProvider { +export class IstanbulCoverageProvider extends BaseCoverageProvider implements CoverageProvider { name = 'istanbul' as const version: string = version instrumenter!: Instrumenter diff --git a/packages/coverage-v8/src/provider.ts b/packages/coverage-v8/src/provider.ts index 265c997e1..f46be5d9b 100644 --- a/packages/coverage-v8/src/provider.ts +++ b/packages/coverage-v8/src/provider.ts @@ -1,7 +1,7 @@ import type { CoverageMap } from 'istanbul-lib-coverage' import type { ProxifiedModule } from 'magicast' import type { Profiler } from 'node:inspector' -import type { CoverageProvider, ReportContext, ResolvedCoverageOptions, TestProject, Vite, Vitest } from 'vitest/node' +import type { CoverageProvider, ReportContext, TestProject, Vite, Vitest } from 'vitest/node' import { existsSync, promises as fs } from 'node:fs' import { fileURLToPath } from 'node:url' // @ts-expect-error -- untyped @@ -28,7 +28,7 @@ const FILE_PROTOCOL = 'file://' const debug = createDebug('vitest:coverage') -export class V8CoverageProvider extends BaseCoverageProvider> implements CoverageProvider { +export class V8CoverageProvider extends BaseCoverageProvider implements CoverageProvider { name = 'v8' as const version: string = version diff --git a/packages/vitest/src/node/cli/cli-config.ts b/packages/vitest/src/node/cli/cli-config.ts index 194ecd8e5..43afbe380 100644 --- a/packages/vitest/src/node/cli/cli-config.ts +++ b/packages/vitest/src/node/cli/cli-config.ts @@ -320,6 +320,13 @@ export const cliOptionsConfig: VitestCLIOptions = { return value }, }, + excludeAfterRemap: { + description: 'Apply exclusions again after coverage has been remapped to original sources. (default: false)', + }, + htmlDir: { + description: 'Directory of HTML coverage output to be served in UI mode and HTML reporter.', + argument: '', + }, }, }, mode: { diff --git a/packages/vitest/src/node/coverage.ts b/packages/vitest/src/node/coverage.ts index 8a6cc1d79..eebbf7d51 100644 --- a/packages/vitest/src/node/coverage.ts +++ b/packages/vitest/src/node/coverage.ts @@ -74,11 +74,11 @@ export async function getCoverageProvider( return null } -export class BaseCoverageProvider> { +export class BaseCoverageProvider { ctx!: Vitest readonly name!: 'v8' | 'istanbul' version!: string - options!: Options + options!: ResolvedCoverageOptions globCache: Map = new Map() autoUpdateMarker = '\n// __VITEST_COVERAGE_MARKER__' @@ -101,7 +101,7 @@ export class BaseCoverageProvider - = T extends 'istanbul' - ? { provider: T } & CoverageIstanbulOptions - : T extends 'v8' ? { - /** - * Provider to use for coverage collection. - * - * @default 'v8' - */ - provider: T - } & CoverageV8Options - : T extends 'custom' - ? { provider: T } & CustomProviderOptions - : { provider?: T } & CoverageV8Options - /** Fields that have default values. Internally these will always be defined. */ type FieldsWithDefaultValues - = | 'enabled' + = | 'provider' + | 'enabled' | 'clean' | 'cleanOnRerun' | 'reportsDirectory' @@ -121,14 +107,23 @@ type FieldsWithDefaultValues | 'allowExternal' | 'processingConcurrency' -export type ResolvedCoverageOptions - = CoverageOptions - & Required, FieldsWithDefaultValues>> & { // Resolved fields which may have different typings as public configuration API has +export type ResolvedCoverageOptions + = CoverageOptions + & Required> + & { + // Resolved fields which may have different typings as public configuration API has reporter: CoverageReporterWithOptions[] htmlDir?: string } -export interface BaseCoverageOptions { +export interface CoverageOptions { + /** + * Coverage provider to use. + * + * @default 'v8' + */ + provider?: 'v8' | 'istanbul' | 'custom' + /** * Enables coverage collection. Can be overridden using `--coverage` CLI option. * @@ -285,16 +280,11 @@ export interface BaseCoverageOptions { * @default false */ changed?: boolean | string -} - -export interface CoverageIstanbulOptions extends BaseCoverageOptions {} -export interface CoverageV8Options extends BaseCoverageOptions {} - -export interface CustomProviderOptions - extends Pick { - /** Name of the module or path to a file to load the custom provider from */ - customProviderModule: string + /** + * Name of the module or path to a file to load the custom provider from + */ + customProviderModule?: string } interface Thresholds { @@ -324,3 +314,15 @@ interface Thresholds { /** Thresholds for lines */ lines?: number } + +/** @deprecated Use `CoverageOptions` instead */ +export interface CoverageV8Options extends CoverageOptions {} + +/** @deprecated Use `CoverageOptions` instead */ +export interface CoverageIstanbulOptions extends CoverageOptions {} + +/** @deprecated Use `CoverageOptions` instead */ +export interface BaseCoverageOptions extends CoverageOptions {} + +/** @deprecated Use `CoverageOptions` instead */ +export interface CustomProviderOptions extends CoverageOptions {} diff --git a/test/coverage-test/test/configuration-options.test-d.ts b/test/coverage-test/test/configuration-options.test-d.ts index 50d628074..ba1ab9f75 100644 --- a/test/coverage-test/test/configuration-options.test-d.ts +++ b/test/coverage-test/test/configuration-options.test-d.ts @@ -72,25 +72,6 @@ test('provider options, generic', () => { }) }) -test('provider specific options, custom', () => { - assertType({ - provider: 'custom', - customProviderModule: 'custom-provider-module.ts', - enabled: true, - }) - - // @ts-expect-error -- customProviderModule is required - assertType({ provider: 'custom' }) - - assertType({ - provider: 'custom', - customProviderModule: 'some-module', - - // @ts-expect-error -- typings of BaseCoverageOptions still apply - enabled: 'not boolean', - }) -}) - test('provider module', () => { assertType({ getProvider() { @@ -100,6 +81,7 @@ test('provider module', () => { generateCoverage() {}, resolveOptions(): ResolvedCoverageOptions { return { + provider: 'v8', clean: true, cleanOnRerun: true, enabled: true, -- 2.51.2