Skip to content

Commit 5932a7f

Browse files
authored
feat(coverage): add --exclude-after-remap (#6309)
1 parent 34199bd commit 5932a7f

File tree

6 files changed

+105
-3
lines changed

6 files changed

+105
-3
lines changed

docs/config/index.md

+12
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,18 @@ Generate coverage report even when tests fail.
13131313

13141314
Collect coverage of files outside the [project `root`](#root).
13151315

1316+
#### coverage.excludeAfterRemap <Version>2.1.0</Version> {#coverage-exclude-after-remap}
1317+
1318+
- **Type:** `boolean`
1319+
- **Default:** `false`
1320+
- **Available for providers:** `'v8' | 'istanbul'`
1321+
- **CLI:** `--coverage.excludeAfterRemap`, `--coverage.excludeAfterRemap=false`
1322+
1323+
Apply exclusions again after coverage has been remapped to original sources.
1324+
This is useful when your source files are transpiled and may contain source maps of non-source files.
1325+
1326+
Use this option when you are seeing files that show up in report even if they match your `coverage.exclude` patterns.
1327+
13161328
#### coverage.skipFull
13171329

13181330
- **Type:** `boolean`

packages/coverage-istanbul/src/provider.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
109109
lines: config.thresholds['100'] ? 100 : config.thresholds.lines,
110110
branches: config.thresholds['100'] ? 100 : config.thresholds.branches,
111111
functions: config.thresholds['100'] ? 100 : config.thresholds.functions,
112-
statements: config.thresholds['100']
113-
? 100
114-
: config.thresholds.statements,
112+
statements: config.thresholds['100'] ? 100 : config.thresholds.statements,
115113
},
116114
}
117115

@@ -292,6 +290,10 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
292290
coverageMap.merge(await transformCoverage(uncoveredCoverage))
293291
}
294292

293+
if (this.options.excludeAfterRemap) {
294+
coverageMap.filter(filename => this.testExclude.shouldInstrument(filename))
295+
}
296+
295297
return coverageMap
296298
}
297299

packages/coverage-v8/src/provider.ts

+4
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
253253
coverageMap.merge(await transformCoverage(converted))
254254
}
255255

256+
if (this.options.excludeAfterRemap) {
257+
coverageMap.filter(filename => this.testExclude.shouldInstrument(filename))
258+
}
259+
256260
return coverageMap
257261
}
258262

packages/vitest/src/defaults.ts

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export const coverageConfigDefaults: ResolvedCoverageOptions = {
7575
'.marko',
7676
],
7777
allowExternal: false,
78+
excludeAfterRemap: false,
7879
ignoreEmptyLines: true,
7980
processingConcurrency: Math.min(
8081
20,

packages/vitest/src/node/types/coverage.ts

+12
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,18 @@ export interface BaseCoverageOptions {
251251
*/
252252
allowExternal?: boolean
253253

254+
/**
255+
* Apply exclusions again after coverage has been remapped to original sources.
256+
* This is useful when your source files are transpiled and may contain source maps
257+
* of non-source files.
258+
*
259+
* Use this option when you are seeing files that show up in report even if they
260+
* match your `coverage.exclude` patterns.
261+
*
262+
* @default false
263+
*/
264+
excludeAfterRemap?: boolean
265+
254266
/**
255267
* Concurrency limit used when processing the coverage results.
256268
* Defaults to `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { expect } from 'vitest'
2+
import { coverageTest, normalizeURL, readCoverageMap, runVitest, test } from '../utils.js'
3+
import * as transpiled from '../fixtures/src/pre-bundle/bundle.js'
4+
5+
test('{ excludeAfterRemap: true } should exclude files that come up after remapping', async () => {
6+
await runVitest({
7+
include: [normalizeURL(import.meta.url)],
8+
coverage: {
9+
include: ['fixtures/src/**'],
10+
exclude: ['fixtures/src/pre-bundle/second.ts'],
11+
excludeAfterRemap: true,
12+
reporter: 'json',
13+
all: false,
14+
},
15+
})
16+
17+
const coverageMap = await readCoverageMap()
18+
const files = coverageMap.files()
19+
20+
expect(files).toMatchInlineSnapshot(`
21+
[
22+
"<process-cwd>/fixtures/src/pre-bundle/first.ts",
23+
]
24+
`)
25+
})
26+
27+
test('{ excludeAfterRemap: false } should not exclude files that come up after remapping', async () => {
28+
await runVitest({
29+
include: [normalizeURL(import.meta.url)],
30+
coverage: {
31+
include: ['fixtures/src/**'],
32+
exclude: ['fixtures/src/pre-bundle/second.ts'],
33+
reporter: 'json',
34+
all: false,
35+
},
36+
})
37+
38+
const coverageMap = await readCoverageMap()
39+
const files = coverageMap.files()
40+
41+
expect(files).toMatchInlineSnapshot(`
42+
[
43+
"<process-cwd>/fixtures/src/pre-bundle/first.ts",
44+
"<process-cwd>/fixtures/src/pre-bundle/second.ts",
45+
]
46+
`)
47+
})
48+
49+
test('{ excludeAfterRemap: true } should exclude uncovered files that come up after remapping', async () => {
50+
await runVitest({
51+
include: ['fixtures/test/math.test.ts'],
52+
coverage: {
53+
include: ['fixtures/src/pre-bundle/**'],
54+
exclude: ['fixtures/src/pre-bundle/second.ts'],
55+
excludeAfterRemap: true,
56+
reporter: 'json',
57+
all: true,
58+
},
59+
})
60+
61+
const coverageMap = await readCoverageMap()
62+
const files = coverageMap.files()
63+
64+
expect(files).contains('<process-cwd>/fixtures/src/pre-bundle/first.ts')
65+
expect(files).not.contains('<process-cwd>/fixtures/src/pre-bundle/second.ts')
66+
})
67+
68+
coverageTest('run bundled sources', () => {
69+
expect(transpiled.first.covered()).toBe('First')
70+
expect(transpiled.second.covered()).toBe('Second')
71+
})

0 commit comments

Comments
 (0)