diff --git a/packages/vitest/src/node/config/resolveConfig.ts b/packages/vitest/src/node/config/resolveConfig.ts index c9745317388d..b9b4d1aef96b 100644 --- a/packages/vitest/src/node/config/resolveConfig.ts +++ b/packages/vitest/src/node/config/resolveConfig.ts @@ -24,6 +24,7 @@ import { RandomSequencer } from '../sequencers/RandomSequencer' import type { BenchmarkBuiltinReporters } from '../reporters' import { builtinPools } from '../pool' import type { Logger } from '../logger' +import type { BaseCoverageOptions, CoverageReporterWithOptions } from '../types/coverage' function resolvePath(path: string, root: string) { return normalize( @@ -229,6 +230,8 @@ export function resolveConfig( ) } + resolved.coverage.reporter = resolveCoverageReporters(resolved.coverage.reporter) + if (resolved.coverage.enabled && resolved.coverage.reportsDirectory) { const reportsDirectory = resolve( resolved.root, @@ -789,3 +792,25 @@ export function resolveConfig( export function isBrowserEnabled(config: ResolvedConfig): boolean { return Boolean(config.browser?.enabled) } + +export function resolveCoverageReporters(configReporters: NonNullable): CoverageReporterWithOptions[] { + // E.g. { reporter: "html" } + if (!Array.isArray(configReporters)) { + return [[configReporters, {}]] + } + + const resolvedReporters: CoverageReporterWithOptions[] = [] + + for (const reporter of configReporters) { + if (Array.isArray(reporter)) { + // E.g. { reporter: [ ["html", { skipEmpty: true }], ["lcov"], ["json", { file: "map.json" }] ]} + resolvedReporters.push([reporter[0], reporter[1] as Record || {}]) + } + else { + // E.g. { reporter: ["html", "json"]} + resolvedReporters.push([reporter, {}]) + } + } + + return resolvedReporters +} diff --git a/packages/vitest/src/node/types/coverage.ts b/packages/vitest/src/node/types/coverage.ts index d61e0715e2ec..a5d18dd152e2 100644 --- a/packages/vitest/src/node/types/coverage.ts +++ b/packages/vitest/src/node/types/coverage.ts @@ -78,7 +78,7 @@ export interface CoverageProviderModule { export type CoverageReporter = keyof ReportOptions | (string & {}) -type CoverageReporterWithOptions< +export type CoverageReporterWithOptions< ReporterName extends CoverageReporter = CoverageReporter, > = ReporterName extends keyof ReportOptions ? ReportOptions[ReporterName] extends never diff --git a/packages/vitest/src/utils/coverage.ts b/packages/vitest/src/utils/coverage.ts index c2556e467312..4d40855fdd6e 100644 --- a/packages/vitest/src/utils/coverage.ts +++ b/packages/vitest/src/utils/coverage.ts @@ -2,6 +2,7 @@ import { relative } from 'pathe' import mm from 'micromatch' import type { CoverageMap } from 'istanbul-lib-coverage' import type { BaseCoverageOptions, ResolvedCoverageOptions } from '../node/types/coverage' +import { resolveCoverageReporters } from '../node/config/resolveConfig' type Threshold = 'lines' | 'functions' | 'statements' | 'branches' @@ -242,25 +243,7 @@ export class BaseCoverageProvider { resolveReporters( configReporters: NonNullable, ): ResolvedCoverageOptions['reporter'] { - // E.g. { reporter: "html" } - if (!Array.isArray(configReporters)) { - return [[configReporters, {}]] - } - - const resolvedReporters: ResolvedCoverageOptions['reporter'] = [] - - for (const reporter of configReporters) { - if (Array.isArray(reporter)) { - // E.g. { reporter: [ ["html", { skipEmpty: true }], ["lcov"], ["json", { file: "map.json" }] ]} - resolvedReporters.push([reporter[0], reporter[1] as Record || {}]) - } - else { - // E.g. { reporter: ["html", "json"]} - resolvedReporters.push([reporter, {}]) - } - } - - return resolvedReporters + return resolveCoverageReporters(configReporters) as any } hasTerminalReporter(reporters: ResolvedCoverageOptions['reporter']) { diff --git a/test/coverage-test/test/reporters.test.ts b/test/coverage-test/test/reporters.test.ts index 518cd2c2b4cd..e93a3cd2f098 100644 --- a/test/coverage-test/test/reporters.test.ts +++ b/test/coverage-test/test/reporters.test.ts @@ -1,4 +1,5 @@ -import { readdirSync } from 'node:fs' +import { existsSync, readdirSync } from 'node:fs' +import { rm } from 'node:fs/promises' import { expect } from 'vitest' import { runVitest, test } from '../utils' @@ -17,6 +18,23 @@ test('reporter as string', async () => { expect(files).toContain('coverage-final.json') }) +test('reporter as string when coverage is disabled', async () => { + if (existsSync('./coverage')) { + await rm('./coverage', { recursive: true, force: true }) + } + + await runVitest({ + include, + coverage: { + enabled: false, + reporter: 'json', + all: false, + }, + }) + + expect(existsSync('./coverage')).toBe(false) +}) + test('reporter as list of strings', async () => { await runVitest({ include,