[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): use project specific `vitenode` for uncovered files (#6044)

authored by

Ari Perkkiö and committed by
GitHub
(Aug 20, 2024, 9:43 AM +0200) da52d23f 2c926bf2

+962 -7
+1 -3
docs/guide/workspace.md
··· 231 231 232 232 ## Coverage 233 233 234 - Coverage for workspace projects works out of the box. But if you have [`all`](/config/#coverage-all) option enabled and use non-conventional extensions in some of your projects, you will need to have a plugin that handles this extension in your root configuration file. 235 - 236 - For example, if you have a package that uses Vue files and it has its own config file, but some of the files are not imported in your tests, coverage will fail trying to analyze the usage of unused files, because it relies on the root configuration rather than project configuration. 234 + Coverage for workspace projects works out of the box.
+3 -1
packages/coverage-istanbul/src/provider.ts
··· 414 414 const cacheKey = new Date().getTime() 415 415 const coverageMap = libCoverage.createCoverageMap({}) 416 416 417 + const transform = this.createUncoveredFileTransformer(this.ctx) 418 + 417 419 // Note that these cannot be run parallel as synchronous instrumenter.lastFileCoverage 418 420 // returns the coverage of the last transformed file 419 421 for (const [index, filename] of uncoveredFiles.entries()) { 420 422 debug('Uncovered file %s %d/%d', filename, index, uncoveredFiles.length) 421 423 422 424 // Make sure file is not served from cache so that instrumenter loads up requested file coverage 423 - await this.ctx.vitenode.transformRequest(`${filename}?v=${cacheKey}`) 425 + await transform(`${filename}?v=${cacheKey}`) 424 426 const lastCoverage = this.instrumenter.lastFileCoverage() 425 427 coverageMap.addFileCoverage(lastCoverage) 426 428 }
+2 -1
packages/coverage-v8/src/provider.ts
··· 368 368 const transformResults = normalizeTransformResults( 369 369 this.ctx.vitenode.fetchCache, 370 370 ) 371 + const transform = this.createUncoveredFileTransformer(this.ctx) 371 372 372 373 const allFiles = await this.testExclude.glob(this.ctx.config.root) 373 374 let includedFiles = allFiles.map(file => ··· 401 402 const { originalSource } = await this.getSources( 402 403 filename.href, 403 404 transformResults, 404 - file => this.ctx.vitenode.transformRequest(file), 405 + transform, 405 406 ) 406 407 407 408 const coverage = {
+2 -2
test/coverage-test/test/all.test.ts
··· 4 4 test('{ all: true } includes uncovered files', async () => { 5 5 await runVitest({ 6 6 include: ['fixtures/test/**'], 7 - exclude: ['**/virtual-files-**'], 7 + exclude: ['**/virtual-files-**', '**/custom-1-syntax**'], 8 8 coverage: { 9 9 include: ['fixtures/src/**'], 10 10 all: true, ··· 25 25 test('{ all: false } excludes uncovered files', async () => { 26 26 await runVitest({ 27 27 include: ['fixtures/test/**'], 28 - exclude: ['**/virtual-files-**'], 28 + exclude: ['**/virtual-files-**', '**/custom-1-syntax**'], 29 29 coverage: { 30 30 include: ['fixtures/src/**'], 31 31 all: false,
+1
test/coverage-test/test/changed.test.ts
··· 33 33 test('{ changed: "HEAD" }', async () => { 34 34 await runVitest({ 35 35 include: ['fixtures/test/**'], 36 + exclude: ['**/custom-1-syntax**'], 36 37 changed: 'HEAD', 37 38 coverage: { 38 39 include: ['fixtures/src/**'],
+43
test/coverage-test/test/workspace.multi-transform.test.ts
··· 1 + import { expect } from 'vitest' 2 + import { isV8Provider, readCoverageMap, runVitest, test } from '../utils' 3 + 4 + test('{ all: true } includes uncovered files that require custom transform', async () => { 5 + await runVitest({ 6 + workspace: 'fixtures/configs/vitest.workspace.multi-transforms.ts', 7 + coverage: { 8 + all: true, 9 + extension: ['.ts', '.custom-1', '.custom-2'], 10 + reporter: ['json', 'html'], 11 + include: ['**/*.custom-1', '**/*.custom-2', '**/math.ts'], 12 + }, 13 + }) 14 + 15 + const coverageMap = await readCoverageMap() 16 + const files = coverageMap.files() 17 + 18 + // All files from workspace should be picked 19 + expect(files).toMatchInlineSnapshot(` 20 + [ 21 + "<process-cwd>/fixtures/src/covered.custom-1", 22 + "<process-cwd>/fixtures/src/math.ts", 23 + "<process-cwd>/fixtures/src/uncovered.custom-1", 24 + "<process-cwd>/fixtures/workspaces/custom-2/src/covered.custom-2", 25 + "<process-cwd>/fixtures/workspaces/custom-2/src/uncovered.custom-2", 26 + ] 27 + `) 28 + 29 + const covered1 = coverageMap.fileCoverageFor('<process-cwd>/fixtures/src/covered.custom-1') 30 + const uncovered1 = coverageMap.fileCoverageFor('<process-cwd>/fixtures/src/uncovered.custom-1') 31 + const covered2 = coverageMap.fileCoverageFor('<process-cwd>/fixtures/workspaces/custom-2/src/covered.custom-2') 32 + const uncovered2 = coverageMap.fileCoverageFor('<process-cwd>/fixtures/workspaces/custom-2/src/uncovered.custom-2') 33 + 34 + // Coverage maps indicate whether source maps are correct. Check html-report if these change 35 + expect(JSON.stringify(covered1, null, 2)).toMatchFileSnapshot(snapshotName('covered-1')) 36 + expect(JSON.stringify(uncovered1, null, 2)).toMatchFileSnapshot(snapshotName('uncovered-1')) 37 + expect(JSON.stringify(covered2, null, 2)).toMatchFileSnapshot(snapshotName('covered-2')) 38 + expect(JSON.stringify(uncovered2, null, 2)).toMatchFileSnapshot(snapshotName('uncovered-2')) 39 + }) 40 + 41 + function snapshotName(label: string) { 42 + return `__snapshots__/custom-file-${label}-${isV8Provider() ? 'v8' : 'istanbul'}.snapshot.json` 43 + }
+32
packages/vitest/src/utils/coverage.ts
··· 1 1 import { relative } from 'pathe' 2 2 import mm from 'micromatch' 3 3 import type { CoverageMap } from 'istanbul-lib-coverage' 4 + import type { Vitest } from '../node/core' 4 5 import type { BaseCoverageOptions, ResolvedCoverageOptions } from '../node/types/coverage' 5 6 import { resolveCoverageReporters } from '../node/config/resolveConfig' 6 7 ··· 271 272 272 273 return chunks 273 274 }, []) 275 + } 276 + 277 + createUncoveredFileTransformer(ctx: Vitest) { 278 + const servers = [ 279 + ...ctx.projects.map(project => ({ 280 + root: project.config.root, 281 + vitenode: project.vitenode, 282 + })), 283 + // Check core last as it will match all files anyway 284 + { root: ctx.config.root, vitenode: ctx.vitenode }, 285 + ] 286 + 287 + return async function transformFile(filename: string) { 288 + let lastError 289 + 290 + for (const { root, vitenode } of servers) { 291 + if (!filename.startsWith(root)) { 292 + continue 293 + } 294 + 295 + try { 296 + return await vitenode.transformRequest(filename) 297 + } 298 + catch (error) { 299 + lastError = error 300 + } 301 + } 302 + 303 + // All vite-node servers failed to transform the file 304 + throw lastError 305 + } 274 306 } 275 307 } 276 308
+78
test/coverage-test/fixtures/configs/vitest.workspace.multi-transforms.ts
··· 1 + import { readFileSync } from "node:fs"; 2 + import { Plugin, defineWorkspace } from "vitest/config"; 3 + import MagicString from "magic-string"; 4 + 5 + export default defineWorkspace([ 6 + // Project that uses its own "root" and custom transform plugin 7 + { 8 + test: { 9 + name: "custom-with-root", 10 + root: "fixtures/workspaces/custom-2", 11 + }, 12 + plugins: [customFilePlugin("2")], 13 + }, 14 + 15 + // Project that cannot transform "*.custom-x" files 16 + { 17 + test: { 18 + name: "normal", 19 + include: ["fixtures/test/math.test.ts"], 20 + }, 21 + }, 22 + 23 + // Project that uses default "root" and has custom transform plugin 24 + { 25 + test: { 26 + name: "custom", 27 + include: ["fixtures/test/custom-1-syntax.test.ts"], 28 + }, 29 + plugins: [customFilePlugin("1")], 30 + }, 31 + ]); 32 + 33 + /** 34 + * Plugin for transforming `.custom-1` and/or `.custom-2` files to Javascript 35 + */ 36 + function customFilePlugin(postfix: "1" | "2"): Plugin { 37 + function transform(code: MagicString) { 38 + code.replaceAll( 39 + "<function covered>", 40 + ` 41 + function covered() { 42 + return "Custom-${postfix} file loaded!" 43 + } 44 + `.trim() 45 + ); 46 + 47 + code.replaceAll( 48 + "<function uncovered>", 49 + ` 50 + function uncovered() { 51 + return "This should be uncovered!" 52 + } 53 + `.trim() 54 + ); 55 + 56 + code.replaceAll("<default export covered>", "export default covered()"); 57 + code.replaceAll("<default export uncovered>", "export default uncovered()"); 58 + } 59 + 60 + return { 61 + name: `custom-${postfix}-file-plugin`, 62 + transform(_, id) { 63 + const filename = id.split("?")[0]; 64 + 65 + if (filename.endsWith(`.custom-${postfix}`)) { 66 + const content = readFileSync(filename, "utf8"); 67 + 68 + const s = new MagicString(content); 69 + transform(s); 70 + 71 + return { 72 + code: s.toString(), 73 + map: s.generateMap({ hires: "boundary" }), 74 + }; 75 + } 76 + }, 77 + }; 78 + }
+5
test/coverage-test/fixtures/src/covered.custom-1
··· 1 + <function covered> 2 + 3 + <function uncovered> 4 + 5 + <default export covered>
+3
test/coverage-test/fixtures/src/uncovered.custom-1
··· 1 + <function uncovered> 2 + 3 + <default export uncovered>
+8
test/coverage-test/fixtures/test/custom-1-syntax.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + // @ts-expect-error -- untyped 4 + import output from '../src/covered.custom-1' 5 + 6 + test('custom file loads fine', () => { 7 + expect(output).toMatch('Custom-1 file loaded!') 8 + })
+83
test/coverage-test/test/__snapshots__/custom-file-covered-1-istanbul.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/src/covered.custom-1", 3 + "statementMap": { 4 + "0": { 5 + "start": { 6 + "line": 1, 7 + "column": 0 8 + }, 9 + "end": { 10 + "line": 1, 11 + "column": 18 12 + } 13 + }, 14 + "1": { 15 + "start": { 16 + "line": 3, 17 + "column": 0 18 + }, 19 + "end": { 20 + "line": 3, 21 + "column": 20 22 + } 23 + } 24 + }, 25 + "fnMap": { 26 + "0": { 27 + "name": "covered", 28 + "decl": { 29 + "start": { 30 + "line": 1, 31 + "column": 0 32 + }, 33 + "end": { 34 + "line": 1, 35 + "column": 18 36 + } 37 + }, 38 + "loc": { 39 + "start": { 40 + "line": 1, 41 + "column": 0 42 + }, 43 + "end": { 44 + "line": 1, 45 + "column": 18 46 + } 47 + } 48 + }, 49 + "1": { 50 + "name": "uncovered", 51 + "decl": { 52 + "start": { 53 + "line": 3, 54 + "column": 0 55 + }, 56 + "end": { 57 + "line": 3, 58 + "column": 20 59 + } 60 + }, 61 + "loc": { 62 + "start": { 63 + "line": 3, 64 + "column": 0 65 + }, 66 + "end": { 67 + "line": 3, 68 + "column": 20 69 + } 70 + } 71 + } 72 + }, 73 + "branchMap": {}, 74 + "s": { 75 + "0": 1, 76 + "1": 0 77 + }, 78 + "f": { 79 + "0": 1, 80 + "1": 0 81 + }, 82 + "b": {} 83 + }
+150
test/coverage-test/test/__snapshots__/custom-file-covered-1-v8.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/src/covered.custom-1", 3 + "all": false, 4 + "statementMap": { 5 + "0": { 6 + "start": { 7 + "line": 1, 8 + "column": 0 9 + }, 10 + "end": { 11 + "line": 1, 12 + "column": 18 13 + } 14 + }, 15 + "1": { 16 + "start": { 17 + "line": 2, 18 + "column": 0 19 + }, 20 + "end": { 21 + "line": 2, 22 + "column": 0 23 + } 24 + }, 25 + "2": { 26 + "start": { 27 + "line": 3, 28 + "column": 0 29 + }, 30 + "end": { 31 + "line": 3, 32 + "column": 20 33 + } 34 + }, 35 + "3": { 36 + "start": { 37 + "line": 4, 38 + "column": 0 39 + }, 40 + "end": { 41 + "line": 4, 42 + "column": 0 43 + } 44 + }, 45 + "4": { 46 + "start": { 47 + "line": 5, 48 + "column": 0 49 + }, 50 + "end": { 51 + "line": 5, 52 + "column": 24 53 + } 54 + } 55 + }, 56 + "s": { 57 + "0": 1, 58 + "1": 1, 59 + "2": 0, 60 + "3": 1, 61 + "4": 1 62 + }, 63 + "branchMap": { 64 + "0": { 65 + "type": "branch", 66 + "line": 1, 67 + "loc": { 68 + "start": { 69 + "line": 1, 70 + "column": 0 71 + }, 72 + "end": { 73 + "line": 1, 74 + "column": 18 75 + } 76 + }, 77 + "locations": [ 78 + { 79 + "start": { 80 + "line": 1, 81 + "column": 0 82 + }, 83 + "end": { 84 + "line": 1, 85 + "column": 18 86 + } 87 + } 88 + ] 89 + } 90 + }, 91 + "b": { 92 + "0": [ 93 + 1 94 + ] 95 + }, 96 + "fnMap": { 97 + "0": { 98 + "name": "covered", 99 + "decl": { 100 + "start": { 101 + "line": 1, 102 + "column": 0 103 + }, 104 + "end": { 105 + "line": 1, 106 + "column": 18 107 + } 108 + }, 109 + "loc": { 110 + "start": { 111 + "line": 1, 112 + "column": 0 113 + }, 114 + "end": { 115 + "line": 1, 116 + "column": 18 117 + } 118 + }, 119 + "line": 1 120 + }, 121 + "1": { 122 + "name": "uncovered", 123 + "decl": { 124 + "start": { 125 + "line": 3, 126 + "column": 0 127 + }, 128 + "end": { 129 + "line": 3, 130 + "column": 20 131 + } 132 + }, 133 + "loc": { 134 + "start": { 135 + "line": 3, 136 + "column": 0 137 + }, 138 + "end": { 139 + "line": 3, 140 + "column": 20 141 + } 142 + }, 143 + "line": 3 144 + } 145 + }, 146 + "f": { 147 + "0": 1, 148 + "1": 0 149 + } 150 + }
+83
test/coverage-test/test/__snapshots__/custom-file-covered-2-istanbul.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/workspaces/custom-2/src/covered.custom-2", 3 + "statementMap": { 4 + "0": { 5 + "start": { 6 + "line": 1, 7 + "column": 0 8 + }, 9 + "end": { 10 + "line": 1, 11 + "column": 18 12 + } 13 + }, 14 + "1": { 15 + "start": { 16 + "line": 3, 17 + "column": 0 18 + }, 19 + "end": { 20 + "line": 3, 21 + "column": 20 22 + } 23 + } 24 + }, 25 + "fnMap": { 26 + "0": { 27 + "name": "covered", 28 + "decl": { 29 + "start": { 30 + "line": 1, 31 + "column": 0 32 + }, 33 + "end": { 34 + "line": 1, 35 + "column": 18 36 + } 37 + }, 38 + "loc": { 39 + "start": { 40 + "line": 1, 41 + "column": 0 42 + }, 43 + "end": { 44 + "line": 1, 45 + "column": 18 46 + } 47 + } 48 + }, 49 + "1": { 50 + "name": "uncovered", 51 + "decl": { 52 + "start": { 53 + "line": 3, 54 + "column": 0 55 + }, 56 + "end": { 57 + "line": 3, 58 + "column": 20 59 + } 60 + }, 61 + "loc": { 62 + "start": { 63 + "line": 3, 64 + "column": 0 65 + }, 66 + "end": { 67 + "line": 3, 68 + "column": 20 69 + } 70 + } 71 + } 72 + }, 73 + "branchMap": {}, 74 + "s": { 75 + "0": 1, 76 + "1": 0 77 + }, 78 + "f": { 79 + "0": 1, 80 + "1": 0 81 + }, 82 + "b": {} 83 + }
+150
test/coverage-test/test/__snapshots__/custom-file-covered-2-v8.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/workspaces/custom-2/src/covered.custom-2", 3 + "all": false, 4 + "statementMap": { 5 + "0": { 6 + "start": { 7 + "line": 1, 8 + "column": 0 9 + }, 10 + "end": { 11 + "line": 1, 12 + "column": 18 13 + } 14 + }, 15 + "1": { 16 + "start": { 17 + "line": 2, 18 + "column": 0 19 + }, 20 + "end": { 21 + "line": 2, 22 + "column": 0 23 + } 24 + }, 25 + "2": { 26 + "start": { 27 + "line": 3, 28 + "column": 0 29 + }, 30 + "end": { 31 + "line": 3, 32 + "column": 20 33 + } 34 + }, 35 + "3": { 36 + "start": { 37 + "line": 4, 38 + "column": 0 39 + }, 40 + "end": { 41 + "line": 4, 42 + "column": 0 43 + } 44 + }, 45 + "4": { 46 + "start": { 47 + "line": 5, 48 + "column": 0 49 + }, 50 + "end": { 51 + "line": 5, 52 + "column": 24 53 + } 54 + } 55 + }, 56 + "s": { 57 + "0": 1, 58 + "1": 1, 59 + "2": 0, 60 + "3": 1, 61 + "4": 1 62 + }, 63 + "branchMap": { 64 + "0": { 65 + "type": "branch", 66 + "line": 1, 67 + "loc": { 68 + "start": { 69 + "line": 1, 70 + "column": 0 71 + }, 72 + "end": { 73 + "line": 1, 74 + "column": 18 75 + } 76 + }, 77 + "locations": [ 78 + { 79 + "start": { 80 + "line": 1, 81 + "column": 0 82 + }, 83 + "end": { 84 + "line": 1, 85 + "column": 18 86 + } 87 + } 88 + ] 89 + } 90 + }, 91 + "b": { 92 + "0": [ 93 + 1 94 + ] 95 + }, 96 + "fnMap": { 97 + "0": { 98 + "name": "covered", 99 + "decl": { 100 + "start": { 101 + "line": 1, 102 + "column": 0 103 + }, 104 + "end": { 105 + "line": 1, 106 + "column": 18 107 + } 108 + }, 109 + "loc": { 110 + "start": { 111 + "line": 1, 112 + "column": 0 113 + }, 114 + "end": { 115 + "line": 1, 116 + "column": 18 117 + } 118 + }, 119 + "line": 1 120 + }, 121 + "1": { 122 + "name": "uncovered", 123 + "decl": { 124 + "start": { 125 + "line": 3, 126 + "column": 0 127 + }, 128 + "end": { 129 + "line": 3, 130 + "column": 20 131 + } 132 + }, 133 + "loc": { 134 + "start": { 135 + "line": 3, 136 + "column": 0 137 + }, 138 + "end": { 139 + "line": 3, 140 + "column": 20 141 + } 142 + }, 143 + "line": 3 144 + } 145 + }, 146 + "f": { 147 + "0": 1, 148 + "1": 0 149 + } 150 + }
+48
test/coverage-test/test/__snapshots__/custom-file-uncovered-1-istanbul.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/src/uncovered.custom-1", 3 + "statementMap": { 4 + "0": { 5 + "start": { 6 + "line": 1, 7 + "column": 0 8 + }, 9 + "end": { 10 + "line": 1, 11 + "column": 20 12 + } 13 + } 14 + }, 15 + "fnMap": { 16 + "0": { 17 + "name": "uncovered", 18 + "decl": { 19 + "start": { 20 + "line": 1, 21 + "column": 0 22 + }, 23 + "end": { 24 + "line": 1, 25 + "column": 20 26 + } 27 + }, 28 + "loc": { 29 + "start": { 30 + "line": 1, 31 + "column": 0 32 + }, 33 + "end": { 34 + "line": 1, 35 + "column": 20 36 + } 37 + } 38 + } 39 + }, 40 + "branchMap": {}, 41 + "s": { 42 + "0": 0 43 + }, 44 + "f": { 45 + "0": 0 46 + }, 47 + "b": {} 48 + }
+103
test/coverage-test/test/__snapshots__/custom-file-uncovered-1-v8.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/src/uncovered.custom-1", 3 + "all": true, 4 + "statementMap": { 5 + "0": { 6 + "start": { 7 + "line": 1, 8 + "column": 0 9 + }, 10 + "end": { 11 + "line": 1, 12 + "column": 20 13 + } 14 + }, 15 + "1": { 16 + "start": { 17 + "line": 2, 18 + "column": 0 19 + }, 20 + "end": { 21 + "line": 2, 22 + "column": 0 23 + } 24 + }, 25 + "2": { 26 + "start": { 27 + "line": 3, 28 + "column": 0 29 + }, 30 + "end": { 31 + "line": 3, 32 + "column": 26 33 + } 34 + } 35 + }, 36 + "s": { 37 + "0": 0, 38 + "1": 0, 39 + "2": 0 40 + }, 41 + "branchMap": { 42 + "0": { 43 + "type": "branch", 44 + "line": 1, 45 + "loc": { 46 + "start": { 47 + "line": 1, 48 + "column": 0 49 + }, 50 + "end": { 51 + "line": 3, 52 + "column": 26 53 + } 54 + }, 55 + "locations": [ 56 + { 57 + "start": { 58 + "line": 1, 59 + "column": 0 60 + }, 61 + "end": { 62 + "line": 3, 63 + "column": 26 64 + } 65 + } 66 + ] 67 + } 68 + }, 69 + "b": { 70 + "0": [ 71 + 0 72 + ] 73 + }, 74 + "fnMap": { 75 + "0": { 76 + "name": "(empty-report)", 77 + "decl": { 78 + "start": { 79 + "line": 1, 80 + "column": 0 81 + }, 82 + "end": { 83 + "line": 3, 84 + "column": 26 85 + } 86 + }, 87 + "loc": { 88 + "start": { 89 + "line": 1, 90 + "column": 0 91 + }, 92 + "end": { 93 + "line": 3, 94 + "column": 26 95 + } 96 + }, 97 + "line": 1 98 + } 99 + }, 100 + "f": { 101 + "0": 0 102 + } 103 + }
+48
test/coverage-test/test/__snapshots__/custom-file-uncovered-2-istanbul.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/workspaces/custom-2/src/uncovered.custom-2", 3 + "statementMap": { 4 + "0": { 5 + "start": { 6 + "line": 1, 7 + "column": 0 8 + }, 9 + "end": { 10 + "line": 1, 11 + "column": 20 12 + } 13 + } 14 + }, 15 + "fnMap": { 16 + "0": { 17 + "name": "uncovered", 18 + "decl": { 19 + "start": { 20 + "line": 1, 21 + "column": 0 22 + }, 23 + "end": { 24 + "line": 1, 25 + "column": 20 26 + } 27 + }, 28 + "loc": { 29 + "start": { 30 + "line": 1, 31 + "column": 0 32 + }, 33 + "end": { 34 + "line": 1, 35 + "column": 20 36 + } 37 + } 38 + } 39 + }, 40 + "branchMap": {}, 41 + "s": { 42 + "0": 0 43 + }, 44 + "f": { 45 + "0": 0 46 + }, 47 + "b": {} 48 + }
+103
test/coverage-test/test/__snapshots__/custom-file-uncovered-2-v8.snapshot.json
··· 1 + { 2 + "path": "<process-cwd>/fixtures/workspaces/custom-2/src/uncovered.custom-2", 3 + "all": true, 4 + "statementMap": { 5 + "0": { 6 + "start": { 7 + "line": 1, 8 + "column": 0 9 + }, 10 + "end": { 11 + "line": 1, 12 + "column": 20 13 + } 14 + }, 15 + "1": { 16 + "start": { 17 + "line": 2, 18 + "column": 0 19 + }, 20 + "end": { 21 + "line": 2, 22 + "column": 0 23 + } 24 + }, 25 + "2": { 26 + "start": { 27 + "line": 3, 28 + "column": 0 29 + }, 30 + "end": { 31 + "line": 3, 32 + "column": 26 33 + } 34 + } 35 + }, 36 + "s": { 37 + "0": 0, 38 + "1": 0, 39 + "2": 0 40 + }, 41 + "branchMap": { 42 + "0": { 43 + "type": "branch", 44 + "line": 1, 45 + "loc": { 46 + "start": { 47 + "line": 1, 48 + "column": 0 49 + }, 50 + "end": { 51 + "line": 3, 52 + "column": 26 53 + } 54 + }, 55 + "locations": [ 56 + { 57 + "start": { 58 + "line": 1, 59 + "column": 0 60 + }, 61 + "end": { 62 + "line": 3, 63 + "column": 26 64 + } 65 + } 66 + ] 67 + } 68 + }, 69 + "b": { 70 + "0": [ 71 + 0 72 + ] 73 + }, 74 + "fnMap": { 75 + "0": { 76 + "name": "(empty-report)", 77 + "decl": { 78 + "start": { 79 + "line": 1, 80 + "column": 0 81 + }, 82 + "end": { 83 + "line": 3, 84 + "column": 26 85 + } 86 + }, 87 + "loc": { 88 + "start": { 89 + "line": 1, 90 + "column": 0 91 + }, 92 + "end": { 93 + "line": 3, 94 + "column": 26 95 + } 96 + }, 97 + "line": 1 98 + } 99 + }, 100 + "f": { 101 + "0": 0 102 + } 103 + }
+5
test/coverage-test/fixtures/workspaces/custom-2/src/covered.custom-2
··· 1 + <function covered> 2 + 3 + <function uncovered> 4 + 5 + <default export covered>
+3
test/coverage-test/fixtures/workspaces/custom-2/src/uncovered.custom-2
··· 1 + <function uncovered> 2 + 3 + <default export uncovered>
+8
test/coverage-test/fixtures/workspaces/custom-2/test/custom-2-syntax.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + 3 + // @ts-expect-error -- untyped 4 + import output from '../src/covered.custom-2' 5 + 6 + test('custom-2 file loads fine', () => { 7 + expect(output).toMatch('Custom-2 file loaded!') 8 + })