Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
Something went wrong. Try again.
3.6 kB · 121 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'import { normalize, resolve, sep } from 'node:path'import { AfterSuiteRunMeta } from 'vitest'import type { CoverageProvider, CoverageProviderModule, ReportContext, ResolvedCoverageOptions, Vitest } from 'vitest/node'
const CustomCoverageProviderModule: CoverageProviderModule = { getProvider(): CoverageProvider { return new CustomCoverageProvider() },
takeCoverage() { // @ts-expect-error -- untyped globalThis.CUSTOM_PROVIDER_TAKE_COVERAGE = true
// @ts-expect-error -- untyped if (!globalThis.CUSTOM_PROVIDER_START_COVERAGE) { throw new Error('takeCoverage was called before startCoverage!') }
return { customCoverage: 'Coverage report passed from workers to main thread' } },
startCoverage() { // @ts-expect-error -- untyped globalThis.CUSTOM_PROVIDER_START_COVERAGE = true },
stopCoverage() { // @ts-expect-error -- untyped if (!globalThis.CUSTOM_PROVIDER_START_COVERAGE) { throw new Error('stopCoverage was called before startCoverage!') }
// @ts-expect-error -- untyped if (!globalThis.CUSTOM_PROVIDER_TAKE_COVERAGE) { throw new Error('stopCoverage was called before takeCoverage!') } },}
/** * Provider that simply keeps track of the functions that were called */class CustomCoverageProvider implements CoverageProvider { name = 'custom-coverage-provider'
options!: ResolvedCoverageOptions calls: Set<string> = new Set() coverageReports: Set<string> = new Set() transformedFiles: Set<string> = new Set()
initialize(ctx: Vitest) { this.options = ctx.config.coverage
this.calls.add(`initialized ${ctx ? 'with' : 'without'} context`) }
clean(force?: boolean) { this.calls.add(`clean ${force ? 'with' : 'without'} force`) }
onAfterSuiteRun(meta: AfterSuiteRunMeta) { // Do not include coverage info here, as order of tests is not guaranteed this.calls.add('onAfterSuiteRun')
// Keep coverage info separate from calls and ignore its order this.coverageReports.add(JSON.stringify({ ...meta,
// Project name keeps changing so let's simply check that its present projectName: meta.projectName && typeof meta.projectName === 'string', })) }
generateCoverage(_reportContext: ReportContext) { return {} }
reportCoverage(coverage: unknown, reportContext?: ReportContext) { this.calls.add(`reportCoverage with ${JSON.stringify(reportContext)}`)
const jsonReport = JSON.stringify({ calls: Array.from(this.calls.values()), coverageReports: Array.from(this.coverageReports.values()).sort(), transformedFiles: Array.from(this.transformedFiles.values()).sort(), }, null, 2)
if (existsSync('./coverage')) { rmSync('./coverage', { maxRetries: 10, recursive: true }) }
mkdirSync('./coverage') writeFileSync('./coverage/custom-coverage-provider-report.json', jsonReport, 'utf-8') }
onFileTransform(code: string, id: string) { const filename = normalizeFilename(id).split('?')[0]
if (/\/fixtures\/src\//.test(filename)) { this.transformedFiles.add(filename) }
return { code } }
resolveOptions(): ResolvedCoverageOptions { this.calls.add('resolveOptions')
return this.options }}
export default CustomCoverageProviderModule
function normalizeFilename(filename: string) { return normalize(filename) .replace(normalize(process.cwd()), '<process-cwd>') .replace(normalize(resolve(process.cwd(), '../../')), '<project-root>') .replaceAll(sep, "/")}