Skip to content

Commit 07ec377

Browse files
authoredMar 14, 2024··
fix(coverage): prevent reportsDirectory from removing user's project (#5376)
1 parent 38119b7 commit 07ec377

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed
 

‎docs/config/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,10 @@ Clean coverage report on watch rerun
11371137
- **Available for providers:** `'v8' | 'istanbul'`
11381138
- **CLI:** `--coverage.reportsDirectory=<path>`
11391139

1140+
::: warning
1141+
Vitest will delete this directory before running tests if `coverage.clean` is enabled (default value).
1142+
:::
1143+
11401144
Directory to write coverage report to.
11411145

11421146
To preview the coverage report in the output of [HTML reporter](/guide/reporters.html#html-reporter), this option must be set as a sub-directory of the html report directory (for example `./html/coverage`).

‎packages/vitest/src/node/config.ts

+8
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,21 @@ export function resolveConfig(
137137
}
138138
}
139139

140+
// TODO: V2.0.0 remove
140141
// @ts-expect-error -- check for removed API option
141142
if (resolved.coverage.provider === 'c8')
142143
throw new Error('"coverage.provider: c8" is not supported anymore. Use "coverage.provider: v8" instead')
143144

144145
if (resolved.coverage.provider === 'v8' && resolved.coverage.enabled && isBrowserEnabled(resolved))
145146
throw new Error('@vitest/coverage-v8 does not work with --browser. Use @vitest/coverage-istanbul instead')
146147

148+
if (resolved.coverage.enabled && resolved.coverage.reportsDirectory) {
149+
const reportsDirectory = resolve(resolved.root, resolved.coverage.reportsDirectory)
150+
151+
if (reportsDirectory === resolved.root || reportsDirectory === process.cwd())
152+
throw new Error(`You cannot set "coverage.reportsDirectory" as ${reportsDirectory}. Vitest needs to be able to remove this directory before test run`)
153+
}
154+
147155
resolved.deps ??= {}
148156
resolved.deps.moduleDirectories ??= []
149157
resolved.deps.moduleDirectories = resolved.deps.moduleDirectories.map((dir) => {

‎test/config/test/failures.test.ts

+38
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { expect, test } from 'vitest'
22
import type { UserConfig } from 'vitest/config'
33
import { version } from 'vitest/package.json'
44

5+
import { normalize, resolve } from 'pathe'
56
import * as testUtils from '../../test-utils'
67

78
function runVitest(config: NonNullable<UserConfig['test']> & { shard?: any }) {
@@ -67,6 +68,43 @@ test('v8 coverage provider cannot be used with browser in workspace', async () =
6768
expect(stderr).toMatch('Error: @vitest/coverage-v8 does not work with --browser. Use @vitest/coverage-istanbul instead')
6869
})
6970

71+
test('coverage reportsDirectory cannot be current working directory', async () => {
72+
const { stderr } = await runVitest({
73+
coverage: {
74+
enabled: true,
75+
reportsDirectory: './',
76+
77+
// Additional options to make sure this test doesn't accidentally remove whole vitest project
78+
clean: false,
79+
cleanOnRerun: false,
80+
provider: 'custom',
81+
customProviderModule: 'non-existing-provider-so-that-reportsDirectory-is-not-removed',
82+
},
83+
})
84+
85+
const directory = normalize(resolve('./'))
86+
expect(stderr).toMatch(`Error: You cannot set "coverage.reportsDirectory" as ${directory}. Vitest needs to be able to remove this directory before test run`)
87+
})
88+
89+
test('coverage reportsDirectory cannot be root', async () => {
90+
const { stderr } = await runVitest({
91+
root: './fixtures',
92+
coverage: {
93+
enabled: true,
94+
reportsDirectory: './',
95+
96+
// Additional options to make sure this test doesn't accidentally remove whole vitest project
97+
clean: false,
98+
cleanOnRerun: false,
99+
provider: 'custom',
100+
customProviderModule: 'non-existing-provider-so-that-reportsDirectory-is-not-removed',
101+
},
102+
})
103+
104+
const directory = normalize(resolve('./fixtures'))
105+
expect(stderr).toMatch(`Error: You cannot set "coverage.reportsDirectory" as ${directory}. Vitest needs to be able to remove this directory before test run`)
106+
})
107+
70108
test('version number is printed when coverage provider fails to load', async () => {
71109
const { stderr, stdout } = await runVitest({
72110
coverage: {

0 commit comments

Comments
 (0)
Please sign in to comment.