Skip to content

Commit

Permalink
fix(reporter): prevent deleting test reports stored in coverage direc…
Browse files Browse the repository at this point in the history
…tory (#3331)
  • Loading branch information
AriPerkkio committed May 10, 2023
1 parent 5bf7eb6 commit ddbba39
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 10 deletions.
13 changes: 8 additions & 5 deletions packages/vitest/src/node/core.ts
Expand Up @@ -285,11 +285,14 @@ export class Vitest {
return
}

await this.report('onInit', this)

await this.initCoverageProvider()
await this.coverageProvider?.clean(this.config.coverage.clean)
await this.initBrowserProviders()
try {
await this.initCoverageProvider()
await this.coverageProvider?.clean(this.config.coverage.clean)
await this.initBrowserProviders()
}
finally {
await this.report('onInit', this)
}

const files = await this.filterTestsBySource(
await this.globTestFiles(filters),
Expand Down
4 changes: 4 additions & 0 deletions packages/vitest/src/node/reporters/junit.ts
Expand Up @@ -75,6 +75,7 @@ export class JUnitReporter implements Reporter {
private baseLog!: (text: string) => Promise<void>
private logger!: IndentedLogger<Promise<void>>
private _timeStart = new Date()
private fileFd?: fs.FileHandle

async onInit(ctx: Vitest): Promise<void> {
this.ctx = ctx
Expand All @@ -89,6 +90,7 @@ export class JUnitReporter implements Reporter {
await fs.mkdir(outputDirectory, { recursive: true })

const fileFd = await fs.open(this.reportFile, 'w+')
this.fileFd = fileFd

this.baseLog = async (text: string) => await fs.writeFile(fileFd, `${text}\n`)
}
Expand Down Expand Up @@ -244,5 +246,7 @@ export class JUnitReporter implements Reporter {

if (this.reportFile)
this.ctx.logger.log(`JUNIT report written to ${this.reportFile}`)

await this.fileFd?.close()
}
}
2 changes: 1 addition & 1 deletion test/config/package.json
Expand Up @@ -2,7 +2,7 @@
"name": "@vitest/test-config",
"private": true,
"scripts": {
"test": "vitest run test/**"
"test": "vitest run"
},
"devDependencies": {
"execa": "^7.0.0",
Expand Down
14 changes: 14 additions & 0 deletions test/config/test/failures.test.ts
@@ -1,4 +1,5 @@
import { expect, test } from 'vitest'
import { version } from 'vitest/package.json'

import { runVitest } from './utils'

Expand Down Expand Up @@ -57,3 +58,16 @@ test('boolean browser flag without dot notation, with more dot notation options'
expect(error).toMatch('Error: A boolean argument "--browser" was used with dot notation arguments "--browser.name".')
expect(error).toMatch('Please specify the "--browser" argument with dot notation as well: "--browser.enabled"')
})

test('version number is printed when coverage provider fails to load', async () => {
const { error, output } = await runVitest('run', [
'--coverage.enabled',
'--coverage.provider',
'custom',
'--coverage.customProviderModule',
'./non-existing-module.ts',
])

expect(output).toMatch(`RUN v${version}`)
expect(error).toMatch('Error: Failed to load custom CoverageProviderModule from ./non-existing-module.ts')
})
10 changes: 6 additions & 4 deletions test/config/test/utils.ts
Expand Up @@ -4,15 +4,17 @@ import stripAnsi from 'strip-ansi'
export async function runVitest(mode: 'run' | 'watch', cliArguments: string[]) {
const subprocess = execa('vitest', [mode, 'fixtures/test/', ...cliArguments])
let error = ''
let output = ''

subprocess.stdout?.on('data', (data) => {
output += stripAnsi(data.toString())
})

subprocess.stderr?.on('data', (data) => {
error += stripAnsi(data.toString())

// Sometimes on Windows CI execa doesn't exit properly. Force exit when stderr is caught.
subprocess.kill()
})

await new Promise(resolve => subprocess.on('exit', resolve))

return { error }
return { output, error }
}
1 change: 1 addition & 0 deletions test/config/vitest.config.ts
Expand Up @@ -2,6 +2,7 @@ import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
include: ['test/**.test.ts'],
testTimeout: 60_000,
chaiConfig: {
truncateThreshold: 999,
Expand Down
Expand Up @@ -94,3 +94,10 @@ test('function count is correct', async () => {
expect(functions.total).toBe(5)
expect(functions.covered).toBe(3)
})

test('coverage provider does not conflict with built-in reporter\'s outputFile', async () => {
const coveragePath = resolve('./coverage')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('junit.xml')
})
4 changes: 4 additions & 0 deletions test/coverage-test/testing.mjs
Expand Up @@ -17,6 +17,10 @@ const configs = [
].filter(Boolean),
coverage: { enabled: true },
browser: { enabled: isBrowser, name: 'chrome', headless: true },

// Regression vitest#3330
reporters: ['default', 'junit'],
outputFile: { junit: 'coverage/junit.xml' },
}],

// Run tests for checking coverage report contents.
Expand Down

0 comments on commit ddbba39

Please sign in to comment.