diff --git a/packages/coverage-c8/rollup.config.js b/packages/coverage-c8/rollup.config.js index 50cfe07d43f2..cbee35392bc8 100644 --- a/packages/coverage-c8/rollup.config.js +++ b/packages/coverage-c8/rollup.config.js @@ -21,6 +21,7 @@ const external = [ 'vitest', 'vitest/node', 'vitest/config', + 'vitest/coverage', ] const plugins = [ diff --git a/packages/coverage-c8/src/provider.ts b/packages/coverage-c8/src/provider.ts index 545fd304d2a3..cc4b9f0bb1f9 100644 --- a/packages/coverage-c8/src/provider.ts +++ b/packages/coverage-c8/src/provider.ts @@ -6,6 +6,7 @@ import c from 'picocolors' import { provider } from 'std-env' import type { EncodedSourceMap } from 'vite-node' import { coverageConfigDefaults } from 'vitest/config' +import { BaseCoverageProvider } from 'vitest/coverage' // eslint-disable-next-line no-restricted-imports import type { AfterSuiteRunMeta, CoverageC8Options, CoverageProvider, ReportContext, ResolvedCoverageOptions } from 'vitest' import type { Vitest } from 'vitest/node' @@ -17,7 +18,7 @@ import { checkCoverages } from 'c8/lib/commands/check-coverage.js' type Options = ResolvedCoverageOptions<'c8'> -export class C8CoverageProvider implements CoverageProvider { +export class C8CoverageProvider extends BaseCoverageProvider implements CoverageProvider { name = 'c8' ctx!: Vitest @@ -25,8 +26,28 @@ export class C8CoverageProvider implements CoverageProvider { coverages: Profiler.TakePreciseCoverageReturnType[] = [] initialize(ctx: Vitest) { + const config: CoverageC8Options = ctx.config.coverage + this.ctx = ctx - this.options = resolveC8Options(ctx.config.coverage, ctx.config.root) + this.options = { + ...coverageConfigDefaults, + + // Provider specific defaults + excludeNodeModules: true, + allowExternal: false, + + // User's options + ...config, + + // Resolved fields + provider: 'c8', + reporter: this.resolveReporters(config.reporter || coverageConfigDefaults.reporter), + reportsDirectory: resolve(ctx.config.root, config.reportsDirectory || coverageConfigDefaults.reportsDirectory), + lines: config['100'] ? 100 : config.lines, + functions: config['100'] ? 100 : config.functions, + branches: config['100'] ? 100 : config.branches, + statements: config['100'] ? 100 : config.statements, + } } resolveOptions() { @@ -158,53 +179,3 @@ export class C8CoverageProvider implements CoverageProvider { await checkCoverages(options, report) } } - -function resolveC8Options(options: CoverageC8Options, root: string): Options { - const reportsDirectory = resolve(root, options.reportsDirectory || coverageConfigDefaults.reportsDirectory) - - const resolved: Options = { - ...coverageConfigDefaults, - - // Provider specific defaults - excludeNodeModules: true, - allowExternal: false, - - // User's options - ...options, - - // Resolved fields - provider: 'c8', - reporter: resolveReporters(options.reporter || coverageConfigDefaults.reporter), - reportsDirectory, - } - - if (options['100']) { - resolved.lines = 100 - resolved.functions = 100 - resolved.branches = 100 - resolved.statements = 100 - } - - return resolved -} - -function resolveReporters(configReporters: NonNullable): Options['reporter'] { - // E.g. { reporter: "html" } - if (!Array.isArray(configReporters)) - return [[configReporters, {}]] - - const resolvedReporters: Options['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] || {}]) - } - else { - // E.g. { reporter: ["html", "json"]} - resolvedReporters.push([reporter, {}]) - } - } - - return resolvedReporters -} diff --git a/packages/coverage-istanbul/rollup.config.js b/packages/coverage-istanbul/rollup.config.js index 66fbbd080629..0372998f1117 100644 --- a/packages/coverage-istanbul/rollup.config.js +++ b/packages/coverage-istanbul/rollup.config.js @@ -19,6 +19,7 @@ const external = [ 'vitest', 'vitest/node', 'vitest/config', + 'vitest/coverage', ] const plugins = [ diff --git a/packages/coverage-istanbul/src/provider.ts b/packages/coverage-istanbul/src/provider.ts index 5abc0058a52b..f4e47b9f66ca 100644 --- a/packages/coverage-istanbul/src/provider.ts +++ b/packages/coverage-istanbul/src/provider.ts @@ -4,6 +4,7 @@ import { relative, resolve } from 'pathe' import type { TransformPluginContext } from 'rollup' import type { AfterSuiteRunMeta, CoverageIstanbulOptions, CoverageProvider, ReportContext, ResolvedCoverageOptions, Vitest } from 'vitest' import { coverageConfigDefaults, defaultExclude, defaultInclude } from 'vitest/config' +import { BaseCoverageProvider } from 'vitest/coverage' import libReport from 'istanbul-lib-report' import reports from 'istanbul-reports' import type { CoverageMap } from 'istanbul-lib-coverage' @@ -31,7 +32,7 @@ interface TestExclude { } } -export class IstanbulCoverageProvider implements CoverageProvider { +export class IstanbulCoverageProvider extends BaseCoverageProvider implements CoverageProvider { name = 'istanbul' ctx!: Vitest @@ -48,8 +49,20 @@ export class IstanbulCoverageProvider implements CoverageProvider { coverages: any[] = [] initialize(ctx: Vitest) { + const config: CoverageIstanbulOptions = ctx.config.coverage + this.ctx = ctx - this.options = resolveIstanbulOptions(ctx.config.coverage, ctx.config.root) + this.options = { + ...coverageConfigDefaults, + + // User's options + ...config, + + // Resolved fields + provider: 'istanbul', + reportsDirectory: resolve(ctx.config.root, config.reportsDirectory || coverageConfigDefaults.reportsDirectory), + reporter: this.resolveReporters(config.reporter || coverageConfigDefaults.reporter), + } this.instrumenter = createInstrumenter({ produceSourceMap: true, @@ -220,24 +233,6 @@ export class IstanbulCoverageProvider implements CoverageProvider { } } -function resolveIstanbulOptions(options: CoverageIstanbulOptions, root: string): Options { - const reportsDirectory = resolve(root, options.reportsDirectory || coverageConfigDefaults.reportsDirectory) - - const resolved: Options = { - ...coverageConfigDefaults, - - // User's options - ...options, - - // Resolved fields - provider: 'istanbul', - reportsDirectory, - reporter: resolveReporters(options.reporter || coverageConfigDefaults.reporter), - } - - return resolved -} - /** * Remove possible query parameters from filenames * - From `/src/components/Header.component.ts?vue&type=script&src=true&lang.ts` @@ -287,24 +282,3 @@ function isEmptyCoverageRange(range: libCoverage.Range) { || range.end.column === undefined ) } - -function resolveReporters(configReporters: NonNullable): Options['reporter'] { - // E.g. { reporter: "html" } - if (!Array.isArray(configReporters)) - return [[configReporters, {}]] - - const resolvedReporters: Options['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] || {}]) - } - else { - // E.g. { reporter: ["html", "json"]} - resolvedReporters.push([reporter, {}]) - } - } - - return resolvedReporters -} diff --git a/packages/vitest/coverage.d.ts b/packages/vitest/coverage.d.ts new file mode 100644 index 000000000000..cf1145ffa2f6 --- /dev/null +++ b/packages/vitest/coverage.d.ts @@ -0,0 +1 @@ +export * from './dist/coverage.js' diff --git a/packages/vitest/package.json b/packages/vitest/package.json index 0af61735b1f7..13c7686f133f 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -65,6 +65,10 @@ "types": "./config.d.ts", "require": "./dist/config.cjs", "import": "./dist/config.js" + }, + "./coverage": { + "types": "./coverage.d.ts", + "import": "./dist/coverage.js" } }, "main": "./dist/index.js", @@ -144,6 +148,7 @@ "@edge-runtime/vm": "2.0.2", "@sinonjs/fake-timers": "^10.0.2", "@types/diff": "^5.0.2", + "@types/istanbul-lib-coverage": "^2.0.4", "@types/istanbul-reports": "^3.0.1", "@types/jsdom": "^21.1.0", "@types/micromatch": "^4.0.2", diff --git a/packages/vitest/rollup.config.js b/packages/vitest/rollup.config.js index eb650f92df6e..d803b1ffa218 100644 --- a/packages/vitest/rollup.config.js +++ b/packages/vitest/rollup.config.js @@ -26,6 +26,7 @@ const entries = [ 'src/runtime/loader.ts', 'src/runtime/entry.ts', 'src/integrations/spy.ts', + 'src/coverage.ts', ] const dtsEntries = [ @@ -36,6 +37,7 @@ const dtsEntries = [ 'src/runners.ts', 'src/suite.ts', 'src/config.ts', + 'src/coverage.ts', ] const external = [ diff --git a/packages/vitest/src/coverage.ts b/packages/vitest/src/coverage.ts new file mode 100644 index 000000000000..5dccd7b1fd9e --- /dev/null +++ b/packages/vitest/src/coverage.ts @@ -0,0 +1 @@ +export { BaseCoverageProvider } from './utils/coverage' diff --git a/packages/vitest/src/utils/coverage.ts b/packages/vitest/src/utils/coverage.ts new file mode 100644 index 000000000000..e479df2e2203 --- /dev/null +++ b/packages/vitest/src/utils/coverage.ts @@ -0,0 +1,27 @@ +import type { BaseCoverageOptions, ResolvedCoverageOptions } from '../types' + +export class BaseCoverageProvider { + /** + * Resolve reporters from various configuration options + */ + 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] || {}]) + } + else { + // E.g. { reporter: ["html", "json"]} + resolvedReporters.push([reporter, {}]) + } + } + + return resolvedReporters + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f6247897dfa..3187cd0cce72 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -844,6 +844,7 @@ importers: '@types/chai': ^4.3.4 '@types/chai-subset': ^1.3.3 '@types/diff': ^5.0.2 + '@types/istanbul-lib-coverage': ^2.0.4 '@types/istanbul-reports': ^3.0.1 '@types/jsdom': ^21.1.0 '@types/micromatch': ^4.0.2 @@ -928,6 +929,7 @@ importers: '@edge-runtime/vm': 2.0.2 '@sinonjs/fake-timers': 10.0.2 '@types/diff': 5.0.2 + '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/jsdom': 21.1.0 '@types/micromatch': 4.0.2 diff --git a/tsconfig.json b/tsconfig.json index 54fbe9d3a339..aa7534d66b93 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,6 +29,7 @@ "vitest/globals": ["./packages/vitest/globals.d.ts"], "vitest/node": ["./packages/vitest/src/node/index.ts"], "vitest/config": ["./packages/vitest/src/config.ts"], + "vitest/coverage": ["./packages/vitest/src/coverage.ts"], "vitest/browser": ["./packages/vitest/src/browser.ts"], "vitest/runners": ["./packages/vitest/src/runners.ts"], "vite-node": ["./packages/vite-node/src/index.ts"],