Skip to content

Commit 407c0e4

Browse files
authored
fix(coverage): in-source test cases excluded (#7985)
1 parent 797be1f commit 407c0e4

File tree

6 files changed

+70
-25
lines changed

6 files changed

+70
-25
lines changed

packages/coverage-istanbul/src/provider.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,12 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider<ResolvedCover
7575
const sourceMap = pluginCtx.getCombinedSourcemap()
7676
sourceMap.sources = sourceMap.sources.map(removeQueryParameters)
7777

78-
// Exclude SWC's decorators that are left in source maps
79-
sourceCode = sourceCode.replaceAll(
80-
'_ts_decorate',
81-
'/* istanbul ignore next */_ts_decorate',
82-
)
78+
sourceCode = sourceCode
79+
// Exclude SWC's decorators that are left in source maps
80+
.replaceAll('_ts_decorate', '/* istanbul ignore next */_ts_decorate')
81+
82+
// Exclude in-source test's test cases
83+
.replaceAll(/(if +\(import\.meta\.vitest\))/g, '/* istanbul ignore next */ $1')
8384

8485
const code = this.instrumenter.instrumentSync(
8586
sourceCode,

packages/coverage-v8/src/provider.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,46 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
292292
) {
293293
return true
294294
}
295+
296+
// in-source test with "if (import.meta.vitest)"
297+
if (
298+
(type === 'branch' || type === 'statement')
299+
&& node.type === 'IfStatement'
300+
&& node.test.type === 'MemberExpression'
301+
&& node.test.property.type === 'Identifier'
302+
&& node.test.property.name === 'vitest'
303+
) {
304+
// SSR
305+
if (
306+
node.test.object.type === 'Identifier'
307+
&& node.test.object.name === '__vite_ssr_import_meta__'
308+
) {
309+
return 'ignore-this-and-nested-nodes'
310+
}
311+
312+
// Web
313+
if (
314+
node.test.object.type === 'MetaProperty'
315+
&& node.test.object.meta.name === 'import'
316+
&& node.test.object.property.name === 'meta'
317+
) {
318+
return 'ignore-this-and-nested-nodes'
319+
}
320+
}
321+
322+
// Browser mode's "import.meta.env ="
323+
if (
324+
type === 'statement'
325+
&& node.type === 'ExpressionStatement'
326+
&& node.expression.type === 'AssignmentExpression'
327+
&& node.expression.left.type === 'MemberExpression'
328+
&& node.expression.left.object.type === 'MetaProperty'
329+
&& node.expression.left.object.meta.name === 'import'
330+
&& node.expression.left.object.property.name === 'meta'
331+
&& node.expression.left.property.type === 'Identifier'
332+
&& node.expression.left.property.name === 'env') {
333+
return true
334+
}
295335
},
296336
},
297337
)

test/coverage-test/fixtures/src/in-source.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export function add(a: number, b: number) {
1111
if (import.meta.vitest) {
1212
const { test, expect } = import.meta.vitest
1313

14-
test('in source test running add function', () => {
14+
// Name of the callback test function is checked in tests
15+
test('in source test running add function', function customNamedTestFunction() {
1516
expect(add(10, 19)).toBe(29)
1617
})
1718
}

test/coverage-test/test/in-source.test.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ test('in-source tests work', async () => {
1919
]
2020
`)
2121

22-
const fileCoverage = coverageMap.fileCoverageFor('<process-cwd>/fixtures/src/in-source.ts')
22+
const fileCoverage = coverageMap.fileCoverageFor(files[0])
23+
const functions = Object.values(fileCoverage.fnMap).map(fn => fn.name)
2324

2425
// If-branch is not taken - makes sure source maps are correct in in-source testing too
2526
expect(fileCoverage.getUncoveredLines()).toContain('5')
@@ -28,7 +29,7 @@ test('in-source tests work', async () => {
2829
expect(fileCoverage).toMatchInlineSnapshot(`
2930
{
3031
"branches": "2/4 (50%)",
31-
"functions": "1/1 (100%)",
32+
"functions": "2/2 (100%)",
3233
"lines": "10/12 (83.33%)",
3334
"statements": "10/12 (83.33%)",
3435
}
@@ -37,11 +38,23 @@ test('in-source tests work', async () => {
3738
else {
3839
expect(fileCoverage).toMatchInlineSnapshot(`
3940
{
40-
"branches": "3/6 (50%)",
41-
"functions": "2/2 (100%)",
42-
"lines": "6/7 (85.71%)",
43-
"statements": "6/7 (85.71%)",
41+
"branches": "2/4 (50%)",
42+
"functions": "1/1 (100%)",
43+
"lines": "2/3 (66.66%)",
44+
"statements": "2/3 (66.66%)",
4445
}
4546
`)
4647
}
48+
49+
// v8-to-istanbul cannot exclude whole if-block
50+
if (isV8Provider()) {
51+
return
52+
}
53+
54+
// The "customNamedTestFunction" should be excluded by auto-generated ignore hints
55+
expect(functions).toMatchInlineSnapshot(`
56+
[
57+
"add",
58+
]
59+
`)
4760
})

test/coverage-test/test/vue.test.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { readdirSync } from 'node:fs'
22
import { resolve } from 'node:path'
33
import { beforeAll, expect } from 'vitest'
4-
import { isBrowser, isV8Provider, readCoverageMap, runVitest, test } from '../utils'
4+
import { isV8Provider, readCoverageMap, runVitest, test } from '../utils'
55

66
beforeAll(async () => {
77
await runVitest({
@@ -23,17 +23,7 @@ test('files should not contain query parameters', () => {
2323
test('coverage results matches snapshot', async () => {
2424
const coverageMap = await readCoverageMap()
2525

26-
if (isV8Provider() && isBrowser()) {
27-
expect(coverageMap).toMatchInlineSnapshot(`
28-
{
29-
"branches": "5/7 (71.42%)",
30-
"functions": "3/5 (60%)",
31-
"lines": "37/46 (80.43%)",
32-
"statements": "37/46 (80.43%)",
33-
}
34-
`)
35-
}
36-
else if (isV8Provider()) {
26+
if (isV8Provider()) {
3727
expect(coverageMap).toMatchInlineSnapshot(`
3828
{
3929
"branches": "5/7 (71.42%)",

test/coverage-test/vitest.workspace.custom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default defineWorkspace([
108108
test: {
109109
...config.test,
110110
name: { label: 'v8-browser', color: 'red' },
111-
env: { COVERAGE_PROVIDER: 'v8', COVERAGE_BROWSER: 'true' },
111+
env: { COVERAGE_PROVIDER: 'v8-ast-aware', COVERAGE_BROWSER: 'true' },
112112
include: [
113113
BROWSER_TESTS,
114114

0 commit comments

Comments
 (0)