Skip to content

Commit

Permalink
fix(coverage): don't crash when re-run removes earlier run's reports
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Jan 21, 2024
1 parent 52cffda commit 2138cc4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
26 changes: 26 additions & 0 deletions packages/coverage-istanbul/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
coverageFilesDirectory!: string
pendingPromises: Promise<void>[] = []

onRunFinish: (() => void) | null = null
runningPromise: Promise<void> | null = null
cancelRun = false

initialize(ctx: Vitest) {
const config: CoverageIstanbulOptions = ctx.config.coverage

Expand Down Expand Up @@ -145,6 +149,20 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
}

async clean(clean = true) {
if (this.runningPromise) {
this.cancelRun = true
await this.runningPromise
}

this.runningPromise = new Promise<void>((resolve) => {
this.onRunFinish = () => {
resolve()
this.onRunFinish = null
this.runningPromise = null
this.cancelRun = false
}
})

if (clean && existsSync(this.options.reportsDirectory))
await fs.rm(this.options.reportsDirectory, { recursive: true, force: true, maxRetries: 10 })

Expand Down Expand Up @@ -179,11 +197,18 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
// TODO: Remove
this.ctx.logger.log(c.yellow(`Checking ${filename}`))
await new Promise(r => setTimeout(r, 1000))

if (this.cancelRun)
return

const contents = await fs.readFile(filename, 'utf-8')
const coverage = JSON.parse(contents) as CoverageMap

coverageMapByTransformMode.merge(coverage)
}))

if (this.cancelRun)
return this.onRunFinish?.()
}

// Source maps can change based on projectName and transform mode.
Expand Down Expand Up @@ -250,6 +275,7 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co

await fs.rm(this.coverageFilesDirectory, { recursive: true })
this.coverageFiles = new Map()
this.onRunFinish?.()
}

async getCoverageMapForUncoveredFiles(coveredFiles: string[]) {
Expand Down
19 changes: 8 additions & 11 deletions packages/vitest/src/node/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ export class Vitest {

try {
await this.initCoverageProvider()
await this.coverageProvider?.clean(this.config.coverage.clean)
await this.initBrowserProviders()
}
finally {
Expand Down Expand Up @@ -377,7 +376,7 @@ export class Vitest {
// populate once, update cache on watch
await this.cache.stats.populateStats(this.config.root, files)

await this.runFiles(files)
await this.runFiles(files, true)
}

await this.reportCoverage(true)
Expand Down Expand Up @@ -472,7 +471,7 @@ export class Vitest {
await project.initializeGlobalSetup()
}

async runFiles(paths: WorkspaceSpec[]) {
async runFiles(paths: WorkspaceSpec[], isFirstRun = false) {
const filepaths = paths.map(([, file]) => file)
this.state.collectPaths(filepaths)

Expand All @@ -492,6 +491,10 @@ export class Vitest {
this.invalidates.clear()
this.snapshot.clear()
this.state.clearErrors()

if (this.coverageProvider)
await this.coverageProvider.clean(isFirstRun ? this.config.coverage.clean : this.config.coverage.cleanOnRerun)

await this.initializeGlobalSetup(paths)

try {
Expand Down Expand Up @@ -530,11 +533,8 @@ export class Vitest {
files = files.filter(file => filteredFiles.some(f => f[1] === file))
}

if (this.coverageProvider && this.config.coverage.cleanOnRerun)
await this.coverageProvider.clean()

await this.report('onWatcherRerun', files, trigger)
await this.runFiles(files.flatMap(file => this.getProjectsByTestFile(file)))
await this.runFiles(files.flatMap(file => this.getProjectsByTestFile(file)), false)

await this.reportCoverage(!trigger)

Expand Down Expand Up @@ -632,14 +632,11 @@ export class Vitest {

this.changedTests.clear()

if (this.coverageProvider && this.config.coverage.cleanOnRerun)
await this.coverageProvider.clean()

const triggerIds = new Set(triggerId.map(id => relative(this.config.root, id)))
const triggerLabel = Array.from(triggerIds).join(', ')
await this.report('onWatcherRerun', files, triggerLabel)

await this.runFiles(files.flatMap(file => this.getProjectsByTestFile(file)))
await this.runFiles(files.flatMap(file => this.getProjectsByTestFile(file)), false)

await this.reportCoverage(false)

Expand Down

0 comments on commit 2138cc4

Please sign in to comment.