Skip to content

Commit fbea520

Browse files
committed
fix(coverage): use project specific vitenode
1 parent 42bd4a2 commit fbea520

File tree

8 files changed

+113
-5
lines changed

8 files changed

+113
-5
lines changed

packages/coverage-istanbul/src/provider.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ export class IstanbulCoverageProvider
386386
resolve(this.ctx.config.root, file),
387387
)
388388

389+
const viteNodeServers = [
390+
this.ctx.vitenode,
391+
...this.ctx.projects.map(project => project.vitenode),
392+
]
393+
389394
if (this.ctx.config.changed) {
390395
includedFiles = (this.ctx.config.related || []).filter(file =>
391396
includedFiles.includes(file),
@@ -396,16 +401,29 @@ export class IstanbulCoverageProvider
396401
.filter(file => !coveredFiles.includes(file))
397402
.sort()
398403

399-
const cacheKey = new Date().getTime()
400404
const coverageMap = libCoverage.createCoverageMap({})
401405

406+
// Make sure file is not served from cache so that instrumenter loads up requested file coverage
407+
const cacheKey = new Date().getTime()
408+
402409
// Note that these cannot be run parallel as synchronous instrumenter.lastFileCoverage
403410
// returns the coverage of the last transformed file
404411
for (const [index, filename] of uncoveredFiles.entries()) {
405412
debug('Uncovered file %s %d/%d', filename, index, uncoveredFiles.length)
406413

407-
// Make sure file is not served from cache so that instrumenter loads up requested file coverage
408-
await this.ctx.vitenode.transformRequest(`${filename}?v=${cacheKey}`)
414+
for (const vitenode of viteNodeServers) {
415+
try {
416+
await vitenode.transformRequest(`${filename}?v=${cacheKey}`)
417+
continue
418+
}
419+
catch (error) {
420+
// Try transforming with next ViteNode server, unless last
421+
if (viteNodeServers.indexOf(vitenode) === viteNodeServers.length - 1) {
422+
throw error
423+
}
424+
}
425+
}
426+
409427
const lastCoverage = this.instrumenter.lastFileCoverage()
410428
coverageMap.addFileCoverage(lastCoverage)
411429
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Plugin, defineWorkspace } from "vitest/config";
2+
import MagicString from "magic-string";
3+
import { readFileSync } from "fs";
4+
5+
export default defineWorkspace([
6+
{
7+
test: {
8+
name: 'normal',
9+
include: ['fixtures/test/math.test.ts']
10+
},
11+
},
12+
{
13+
test: {
14+
name: 'special',
15+
include: ['fixtures/test/custom-syntax.test.ts']
16+
},
17+
plugins: [customFilePlugin()]
18+
}
19+
])
20+
21+
function customFilePlugin(): Plugin {
22+
return {
23+
name: 'load-custom-files',
24+
load(id) {
25+
const filename = id.split("?")[0]
26+
27+
if(filename.endsWith(".custom")) {
28+
const content = readFileSync(filename, 'utf8')
29+
30+
const s = new MagicString(content)
31+
s.replaceAll('<function covered>', `
32+
function covered() {
33+
return "Custom file loaded!"
34+
}`.trim());
35+
36+
s.replaceAll('<function uncovered>', `
37+
function uncovered() {
38+
return "This should be uncovered!"
39+
}`.trim());
40+
41+
s.replaceAll('<default export covered>', 'export default covered()');
42+
s.replaceAll('<default export uncovered>', 'export default uncovered()');
43+
44+
return { code: s.toString(), map: s.generateMap({ hires: 'boundary'})}
45+
}
46+
},
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<function covered>
2+
3+
<function uncovered>
4+
5+
<default export covered>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<function uncovered>
2+
3+
<default export uncovered>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { expect, test } from 'vitest'
2+
3+
// @ts-expect-error -- untyped
4+
import output from '../src/covered.custom'
5+
6+
test('custom file loads fine', () => {
7+
expect(output).toMatch('Custom file loaded!')
8+
})

test/coverage-test/test/all.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { readCoverageMap, runVitest, test } from '../utils'
44
test('{ all: true } includes uncovered files', async () => {
55
await runVitest({
66
include: ['fixtures/test/**'],
7-
exclude: ['**/virtual-files-**'],
7+
exclude: ['**/virtual-files-**', '**/custom-syntax**'],
88
coverage: {
99
include: ['fixtures/src/**'],
1010
all: true,
@@ -25,7 +25,7 @@ test('{ all: true } includes uncovered files', async () => {
2525
test('{ all: false } excludes uncovered files', async () => {
2626
await runVitest({
2727
include: ['fixtures/test/**'],
28-
exclude: ['**/virtual-files-**'],
28+
exclude: ['**/virtual-files-**', '**/custom-syntax**'],
2929
coverage: {
3030
include: ['fixtures/src/**'],
3131
all: false,

test/coverage-test/test/changed.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ afterAll(() => {
2929
test('{ changed: "HEAD" }', async () => {
3030
await runVitest({
3131
include: ['fixtures/test/**'],
32+
exclude: ['**/custom-syntax**'],
3233
changed: 'HEAD',
3334
coverage: {
3435
include: ['fixtures/src/**'],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect } from 'vitest'
2+
import { 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'],
10+
reporter: 'json',
11+
include: ['**/*.custom', '**/math.ts'],
12+
},
13+
})
14+
15+
const coverageMap = await readCoverageMap()
16+
const files = coverageMap.files()
17+
18+
expect(files).toMatchInlineSnapshot(`
19+
[
20+
"<process-cwd>/fixtures/src/covered.custom",
21+
"<process-cwd>/fixtures/src/math.ts",
22+
"<process-cwd>/fixtures/src/uncovered.custom",
23+
]
24+
`)
25+
})

0 commit comments

Comments
 (0)