Skip to content

Commit e4ca917

Browse files
authored
fix(coverage): istanbul provider to not break source maps (#9040)
1 parent 9ca74cf commit e4ca917

File tree

7 files changed

+116
-10
lines changed

7 files changed

+116
-10
lines changed

packages/coverage-istanbul/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
},
4646
"dependencies": {
4747
"@istanbuljs/schema": "^0.1.3",
48+
"@jridgewell/gen-mapping": "^0.3.13",
49+
"@jridgewell/trace-mapping": "catalog:",
4850
"istanbul-lib-coverage": "catalog:",
4951
"istanbul-lib-instrument": "^6.0.3",
5052
"istanbul-lib-report": "catalog:",

packages/coverage-istanbul/src/provider.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import type { CoverageProvider, ReportContext, ResolvedCoverageOptions, Vite, Vi
55
import { existsSync, promises as fs } from 'node:fs'
66
// @ts-expect-error missing types
77
import { defaults as istanbulDefaults } from '@istanbuljs/schema'
8+
import { addMapping, GenMapping, toEncodedMap } from '@jridgewell/gen-mapping'
9+
import { eachMapping, TraceMap } from '@jridgewell/trace-mapping'
810
import libCoverage from 'istanbul-lib-coverage'
911
import { createInstrumenter } from 'istanbul-lib-instrument'
1012
import libReport from 'istanbul-lib-report'
@@ -85,6 +87,30 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider<ResolvedCover
8587
id,
8688
sourceMap as any,
8789
)
90+
91+
const transformMap = new GenMapping(sourceMap)
92+
93+
eachMapping(new TraceMap(sourceMap as any), (mapping) => {
94+
addMapping(transformMap, {
95+
generated: { line: mapping.generatedLine, column: mapping.generatedColumn },
96+
original: { line: mapping.generatedLine, column: mapping.generatedColumn },
97+
content: sourceCode,
98+
name: mapping.name || '',
99+
source: mapping.source || '',
100+
})
101+
})
102+
103+
const encodedMap = toEncodedMap(transformMap)
104+
delete encodedMap.file
105+
delete encodedMap.ignoreList
106+
delete encodedMap.sourceRoot
107+
108+
this.instrumenter.instrumentSync(
109+
sourceCode,
110+
id,
111+
encodedMap as any,
112+
)
113+
88114
const map = this.instrumenter.lastSourceMap() as any
89115
this.transformedModuleIds.add(id)
90116

pnpm-lock.yaml

Lines changed: 8 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Some padding
3+
*/
4+
export function uncovered() {
5+
return "uncoverd";
6+
}
7+
8+
/**
9+
* Some padding
10+
*/
11+
12+
export function throwsError(condition: Boolean) {
13+
/**
14+
* Some padding
15+
*/
16+
17+
if(condition === false) {
18+
/**
19+
* Some padding
20+
*/
21+
22+
return;
23+
}
24+
25+
/**
26+
* Some padding
27+
*/
28+
function throws() {
29+
throw new Error("Expected error")
30+
}
31+
/**
32+
* Some padding
33+
*/
34+
throws()
35+
}
36+
37+
/**
38+
* Some padding
39+
*/
40+
export function uncovered2() {
41+
return "uncoverd";
42+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { test } from "vitest"
2+
import { throwsError } from "../src/throws-error"
3+
4+
test("throws error", async () => {
5+
throwsError(true)
6+
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect } from 'vitest'
2+
import { isBrowser, runVitest, test } from '../utils'
3+
4+
test('errors point to correct location', async () => {
5+
const { stderr } = await runVitest({
6+
include: ['fixtures/test/error-location.test.ts'],
7+
coverage: { reporter: 'json' },
8+
}, { throwOnError: false })
9+
10+
if (isBrowser()) {
11+
expect(stderr).toMatch(`
12+
❯ throws fixtures/src/throws-error.ts:29:11
13+
27| */
14+
28| function throws() {
15+
29| throw new Error("Expected error")
16+
| ^
17+
30| }
18+
`.trim())
19+
}
20+
else {
21+
expect(stderr).toMatch(`
22+
❯ throws fixtures/src/throws-error.ts:29:12
23+
27| */
24+
28| function throws() {
25+
29| throw new Error("Expected error")
26+
| ^
27+
30| }
28+
`.trim())
29+
}
30+
})

test/coverage-test/vitest.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export default defineConfig({
8787
'**/in-source.test.ts',
8888
'**/query-param-transforms.test.ts',
8989
'**/test/cjs-dependency.test.ts',
90+
'**/test/source-maps.test.ts',
9091
],
9192
exclude: [FIXTURES],
9293
},
@@ -118,6 +119,7 @@ export default defineConfig({
118119
'**/in-source.test.ts',
119120
'**/query-param-transforms.test.ts',
120121
'**/test/cjs-dependency.test.ts',
122+
'**/test/source-maps.test.ts',
121123
],
122124
exclude: [FIXTURES],
123125
},

0 commit comments

Comments
 (0)