[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix(coverage): in-source test cases excluded (#7985)

authored by

Ari Perkkiö and committed by
GitHub
(May 31, 2025, 11:16 AM +0300) 407c0e4d 797be1f1

+70 -25
+1 -1
test/coverage-test/vitest.workspace.custom.ts
··· 108 108 test: { 109 109 ...config.test, 110 110 name: { label: 'v8-browser', color: 'red' }, 111 - env: { COVERAGE_PROVIDER: 'v8', COVERAGE_BROWSER: 'true' }, 111 + env: { COVERAGE_PROVIDER: 'v8-ast-aware', COVERAGE_BROWSER: 'true' }, 112 112 include: [ 113 113 BROWSER_TESTS, 114 114
+6 -5
packages/coverage-istanbul/src/provider.ts
··· 75 75 const sourceMap = pluginCtx.getCombinedSourcemap() 76 76 sourceMap.sources = sourceMap.sources.map(removeQueryParameters) 77 77 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') 83 84 84 85 const code = this.instrumenter.instrumentSync( 85 86 sourceCode,
+40
packages/coverage-v8/src/provider.ts
··· 292 292 ) { 293 293 return true 294 294 } 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 + } 295 335 }, 296 336 }, 297 337 )
+19 -6
test/coverage-test/test/in-source.test.ts
··· 19 19 ] 20 20 `) 21 21 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) 23 24 24 25 // If-branch is not taken - makes sure source maps are correct in in-source testing too 25 26 expect(fileCoverage.getUncoveredLines()).toContain('5') ··· 28 29 expect(fileCoverage).toMatchInlineSnapshot(` 29 30 { 30 31 "branches": "2/4 (50%)", 31 - "functions": "1/1 (100%)", 32 + "functions": "2/2 (100%)", 32 33 "lines": "10/12 (83.33%)", 33 34 "statements": "10/12 (83.33%)", 34 35 } ··· 37 38 else { 38 39 expect(fileCoverage).toMatchInlineSnapshot(` 39 40 { 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%)", 44 45 } 45 46 `) 46 47 } 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 + `) 47 60 })
+2 -12
test/coverage-test/test/vue.test.ts
··· 1 1 import { readdirSync } from 'node:fs' 2 2 import { resolve } from 'node:path' 3 3 import { beforeAll, expect } from 'vitest' 4 - import { isBrowser, isV8Provider, readCoverageMap, runVitest, test } from '../utils' 4 + import { isV8Provider, readCoverageMap, runVitest, test } from '../utils' 5 5 6 6 beforeAll(async () => { 7 7 await runVitest({ ··· 23 23 test('coverage results matches snapshot', async () => { 24 24 const coverageMap = await readCoverageMap() 25 25 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()) { 37 27 expect(coverageMap).toMatchInlineSnapshot(` 38 28 { 39 29 "branches": "5/7 (71.42%)",
+2 -1
test/coverage-test/fixtures/src/in-source.ts
··· 11 11 if (import.meta.vitest) { 12 12 const { test, expect } = import.meta.vitest 13 13 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() { 15 16 expect(add(10, 19)).toBe(29) 16 17 }) 17 18 }