From 6eda473f30c4670ec72a06bd3b083a724712ae2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Tue, 12 Mar 2024 17:00:46 +0200 Subject: [PATCH] fix(coverage): respect source maps of pre-transpiled sources (#5367) --- eslint.config.js | 2 + packages/coverage-v8/src/provider.ts | 6 +- .../__snapshots__/custom.report.test.ts.snap | 1 + .../istanbul.report.test.ts.snap | 497 ++++++++++++++++++ .../__snapshots__/v8.report.test.ts.snap | 413 +++++++++++++++ test/coverage-test/src/original.ts | 21 + test/coverage-test/src/transpiled.d.ts | 1 + test/coverage-test/src/transpiled.js | 18 + test/coverage-test/src/transpiled.js.map | 13 + test/coverage-test/test/coverage.test.ts | 7 + 10 files changed, 978 insertions(+), 1 deletion(-) create mode 100644 test/coverage-test/src/original.ts create mode 100644 test/coverage-test/src/transpiled.d.ts create mode 100644 test/coverage-test/src/transpiled.js create mode 100644 test/coverage-test/src/transpiled.js.map diff --git a/eslint.config.js b/eslint.config.js index 0e308cd46160..2a7def112665 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -15,6 +15,8 @@ export default antfu( 'test/workspaces/results.json', 'test/reporters/fixtures/with-syntax-error.test.js', 'test/network-imports/public/slash@3.0.0.js', + 'test/coverage-test/src/transpiled.js', + 'test/coverage-test/src/original.ts', 'examples/**/mockServiceWorker.js', 'examples/sveltekit/.svelte-kit', ], diff --git a/packages/coverage-v8/src/provider.ts b/packages/coverage-v8/src/provider.ts index 2f52cf8bf386..11b904e9aa62 100644 --- a/packages/coverage-v8/src/provider.ts +++ b/packages/coverage-v8/src/provider.ts @@ -323,6 +323,10 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage } } + const sources = [url] + if (map.sources && map.sources[0] && !url.endsWith(map.sources[0])) + sources[0] = new URL(map.sources[0], url).href + return { originalSource: sourcesContent, source: code || sourcesContent, @@ -330,7 +334,7 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage sourcemap: excludeGeneratedCode(code, { ...map, version: 3, - sources: [url], + sources, sourcesContent: [sourcesContent], }), }, diff --git a/test/coverage-test/coverage-report-tests/__snapshots__/custom.report.test.ts.snap b/test/coverage-test/coverage-report-tests/__snapshots__/custom.report.test.ts.snap index ccb552fe1c92..befb6d92a3e6 100644 --- a/test/coverage-test/coverage-report-tests/__snapshots__/custom.report.test.ts.snap +++ b/test/coverage-test/coverage-report-tests/__snapshots__/custom.report.test.ts.snap @@ -29,6 +29,7 @@ exports[`custom json report 1`] = ` "/src/index.mts", "/src/multi-environment.ts", "/src/multi-suite.ts", + "/src/transpiled.js", "/src/utils.ts", ], } diff --git a/test/coverage-test/coverage-report-tests/__snapshots__/istanbul.report.test.ts.snap b/test/coverage-test/coverage-report-tests/__snapshots__/istanbul.report.test.ts.snap index 30ae7c39868a..c44a052caa49 100644 --- a/test/coverage-test/coverage-report-tests/__snapshots__/istanbul.report.test.ts.snap +++ b/test/coverage-test/coverage-report-tests/__snapshots__/istanbul.report.test.ts.snap @@ -2106,6 +2106,503 @@ exports[`istanbul json report 1`] = ` }, }, }, + "/src/original.ts": { + "b": { + "0": [ + 0, + 0, + ], + "1": [ + 0, + 0, + ], + "2": [ + 0, + 0, + ], + "3": [ + 0, + 0, + ], + "4": [ + 0, + 0, + ], + "5": [ + 0, + 0, + ], + }, + "branchMap": { + "0": { + "loc": { + "end": { + "column": null, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + "locations": [ + { + "end": { + "column": null, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + { + "end": { + "column": null, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + ], + "type": "if", + }, + "1": { + "loc": { + "end": { + "column": null, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + "locations": [ + { + "end": { + "column": null, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + { + "end": { + "column": null, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + ], + "type": "if", + }, + "2": { + "loc": { + "end": { + "column": null, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + "locations": [ + { + "end": { + "column": null, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + { + "end": { + "column": null, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + ], + "type": "if", + }, + "3": { + "loc": { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + "locations": [ + { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + ], + "type": "if", + }, + "4": { + "loc": { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + "locations": [ + { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + ], + "type": "if", + }, + "5": { + "loc": { + "end": { + "column": 3, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + "locations": [ + { + "end": { + "column": 3, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + { + "end": { + "column": 3, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + ], + "type": "if", + }, + }, + "f": { + "0": 0, + "1": 0, + "2": 0, + }, + "fnMap": { + "0": { + "decl": { + "end": { + "column": 22, + "line": 1, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "loc": { + "end": { + "column": null, + "line": 19, + }, + "start": { + "column": 40, + "line": 1, + }, + }, + "name": "(anonymous_0)", + }, + "1": { + "decl": { + "end": { + "column": 16, + "line": 21, + }, + "start": { + "column": 9, + "line": 21, + }, + }, + "loc": { + "end": { + "column": null, + "line": 21, + }, + "start": { + "column": 16, + "line": 21, + }, + }, + "name": "noop", + }, + "2": { + "decl": { + "end": { + "column": 13, + "line": 21, + }, + "start": { + "column": 9, + "line": 21, + }, + }, + "loc": { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 13, + "line": 21, + }, + }, + "name": "noop", + }, + }, + "path": "/src/original.ts", + "s": { + "0": 0, + "1": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0, + "9": 0, + }, + "statementMap": { + "0": { + "end": { + "column": null, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "1": { + "end": { + "column": null, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + "10": { + "end": { + "column": 11, + "line": 4, + }, + "start": { + "column": 4, + "line": 4, + }, + }, + "11": { + "end": { + "column": 9, + "line": 8, + }, + "start": { + "column": 2, + "line": 8, + }, + }, + "12": { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + "13": { + "end": { + "column": 11, + "line": 12, + }, + "start": { + "column": 4, + "line": 12, + }, + }, + "14": { + "end": { + "column": 3, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + "15": { + "end": { + "column": 11, + "line": 17, + }, + "start": { + "column": 4, + "line": 17, + }, + }, + "2": { + "end": { + "column": null, + "line": 4, + }, + "start": { + "column": 4, + "line": 4, + }, + }, + "3": { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 2, + "line": 8, + }, + }, + "4": { + "end": { + "column": null, + "line": 13, + }, + "start": { + "column": 2, + "line": 10, + }, + }, + "5": { + "end": { + "column": null, + "line": 12, + }, + "start": { + "column": 4, + "line": 12, + }, + }, + "6": { + "end": { + "column": null, + "line": 18, + }, + "start": { + "column": 2, + "line": 15, + }, + }, + "7": { + "end": { + "column": null, + "line": 17, + }, + "start": { + "column": 4, + "line": 17, + }, + }, + "8": { + "end": { + "column": 1, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "9": { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 2, + "line": 2, + }, + }, + }, + }, "/src/untested-file.ts": { "b": { "0": [ diff --git a/test/coverage-test/coverage-report-tests/__snapshots__/v8.report.test.ts.snap b/test/coverage-test/coverage-report-tests/__snapshots__/v8.report.test.ts.snap index 4ee530489568..f768be1c91d0 100644 --- a/test/coverage-test/coverage-report-tests/__snapshots__/v8.report.test.ts.snap +++ b/test/coverage-test/coverage-report-tests/__snapshots__/v8.report.test.ts.snap @@ -4733,6 +4733,419 @@ exports[`v8 json report 1`] = ` }, }, }, + "/src/original.ts": { + "all": false, + "b": { + "0": [ + 1, + ], + "1": [ + 0, + ], + "2": [ + 0, + ], + "3": [ + 2, + ], + }, + "branchMap": { + "0": { + "line": 1, + "loc": { + "end": { + "column": 2, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "locations": [ + { + "end": { + "column": 2, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + ], + "type": "branch", + }, + "1": { + "line": 2, + "loc": { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 11, + "line": 2, + }, + }, + "locations": [ + { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 11, + "line": 2, + }, + }, + ], + "type": "branch", + }, + "2": { + "line": 10, + "loc": { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 17, + "line": 10, + }, + }, + "locations": [ + { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 17, + "line": 10, + }, + }, + ], + "type": "branch", + }, + "3": { + "line": 21, + "loc": { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 0, + "line": 21, + }, + }, + "locations": [ + { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 0, + "line": 21, + }, + }, + ], + "type": "branch", + }, + }, + "f": { + "0": 1, + "1": 2, + }, + "fnMap": { + "0": { + "decl": { + "end": { + "column": 2, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "line": 1, + "loc": { + "end": { + "column": 2, + "line": 19, + }, + "start": { + "column": 21, + "line": 1, + }, + }, + "name": "hello", + }, + "1": { + "decl": { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 0, + "line": 21, + }, + }, + "line": 21, + "loc": { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 0, + "line": 21, + }, + }, + "name": "noop", + }, + }, + "path": "/src/original.ts", + "s": { + "0": 1, + "1": 1, + "10": 0, + "11": 0, + "12": 0, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "2": 0, + "20": 2, + "3": 0, + "4": 0, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + }, + "statementMap": { + "0": { + "end": { + "column": 41, + "line": 1, + }, + "start": { + "column": 0, + "line": 1, + }, + }, + "1": { + "end": { + "column": 12, + "line": 2, + }, + "start": { + "column": 0, + "line": 2, + }, + }, + "10": { + "end": { + "column": 16, + "line": 11, + }, + "start": { + "column": 0, + "line": 11, + }, + }, + "11": { + "end": { + "column": 11, + "line": 12, + }, + "start": { + "column": 0, + "line": 12, + }, + }, + "12": { + "end": { + "column": 3, + "line": 13, + }, + "start": { + "column": 0, + "line": 13, + }, + }, + "13": { + "end": { + "column": 0, + "line": 14, + }, + "start": { + "column": 0, + "line": 14, + }, + }, + "14": { + "end": { + "column": 26, + "line": 15, + }, + "start": { + "column": 0, + "line": 15, + }, + }, + "15": { + "end": { + "column": 14, + "line": 16, + }, + "start": { + "column": 0, + "line": 16, + }, + }, + "16": { + "end": { + "column": 11, + "line": 17, + }, + "start": { + "column": 0, + "line": 17, + }, + }, + "17": { + "end": { + "column": 3, + "line": 18, + }, + "start": { + "column": 0, + "line": 18, + }, + }, + "18": { + "end": { + "column": 2, + "line": 19, + }, + "start": { + "column": 0, + "line": 19, + }, + }, + "19": { + "end": { + "column": 0, + "line": 20, + }, + "start": { + "column": 0, + "line": 20, + }, + }, + "2": { + "end": { + "column": 16, + "line": 3, + }, + "start": { + "column": 0, + "line": 3, + }, + }, + "20": { + "end": { + "column": 18, + "line": 21, + }, + "start": { + "column": 0, + "line": 21, + }, + }, + "3": { + "end": { + "column": 11, + "line": 4, + }, + "start": { + "column": 0, + "line": 4, + }, + }, + "4": { + "end": { + "column": 3, + "line": 5, + }, + "start": { + "column": 0, + "line": 5, + }, + }, + "5": { + "end": { + "column": 0, + "line": 6, + }, + "start": { + "column": 0, + "line": 6, + }, + }, + "6": { + "end": { + "column": 12, + "line": 7, + }, + "start": { + "column": 0, + "line": 7, + }, + }, + "7": { + "end": { + "column": 9, + "line": 8, + }, + "start": { + "column": 0, + "line": 8, + }, + }, + "8": { + "end": { + "column": 0, + "line": 9, + }, + "start": { + "column": 0, + "line": 9, + }, + }, + "9": { + "end": { + "column": 18, + "line": 10, + }, + "start": { + "column": 0, + "line": 10, + }, + }, + }, + }, "/src/untested-file.ts": { "all": true, "b": { diff --git a/test/coverage-test/src/original.ts b/test/coverage-test/src/original.ts new file mode 100644 index 000000000000..68adfc0d71ef --- /dev/null +++ b/test/coverage-test/src/original.ts @@ -0,0 +1,21 @@ +export const hello = (arg?: unknown) => { + if (arg) { + // Uncovered + noop(); + } + + // Covered + noop(); + + if (arg === 3) { + // Uncovered + noop(); + } + + if (arg === undefined) { + // Covered + noop(); + } +}; + +function noop() {} diff --git a/test/coverage-test/src/transpiled.d.ts b/test/coverage-test/src/transpiled.d.ts new file mode 100644 index 000000000000..29ef6e88f2d4 --- /dev/null +++ b/test/coverage-test/src/transpiled.d.ts @@ -0,0 +1 @@ +export * from './original' diff --git a/test/coverage-test/src/transpiled.js b/test/coverage-test/src/transpiled.js new file mode 100644 index 000000000000..5424a2703651 --- /dev/null +++ b/test/coverage-test/src/transpiled.js @@ -0,0 +1,18 @@ +export var hello = function (arg) { + if (arg) { + // Uncovered + noop(); + } + // Covered + noop(); + if (arg === 3) { + // Uncovered + noop(); + } + if (arg === undefined) { + // Covered + noop(); + } +}; +function noop() { } +//# sourceMappingURL=transpiled.js.map \ No newline at end of file diff --git a/test/coverage-test/src/transpiled.js.map b/test/coverage-test/src/transpiled.js.map new file mode 100644 index 000000000000..325a67f109fa --- /dev/null +++ b/test/coverage-test/src/transpiled.js.map @@ -0,0 +1,13 @@ +{ + "version": 3, + "file": "transpiled.js", + "sourceRoot": "", + "sources": [ + "./original.ts" + ], + "names": [], + "mappings": "AAAA,MAAM,CAAC,IAAM,KAAK,GAAG,UAAC,GAAa;IACjC,IAAI,GAAG,EAAE,CAAC;QACR,YAAY;QACZ,IAAI,EAAE,CAAC;IACT,CAAC;IAED,UAAU;IACV,IAAI,EAAE,CAAC;IAEP,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,YAAY;QACZ,IAAI,EAAE,CAAC;IACT,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,UAAU;QACV,IAAI,EAAE,CAAC;IACT,CAAC;AACH,CAAC,CAAC;AAEF,SAAS,IAAI,KAAI,CAAC", + "sourcesContent": [ + "export const hello = (arg?: unknown) => {\n if (arg) {\n // Uncovered\n noop();\n }\n\n // Covered\n noop();\n\n if (arg === 3) {\n // Uncovered\n noop();\n }\n\n if (arg === undefined) {\n // Covered\n noop();\n }\n};\n\nfunction noop() {}\n" + ] +} diff --git a/test/coverage-test/test/coverage.test.ts b/test/coverage-test/test/coverage.test.ts index 366743ab4e8f..5d1d1b72e894 100644 --- a/test/coverage-test/test/coverage.test.ts +++ b/test/coverage-test/test/coverage.test.ts @@ -76,3 +76,10 @@ test('virtual file imports', () => { test('decorators', () => { new DecoratorsTester().method('cover line') }) + +// Istanbul fails to follow source maps on windows +test.skipIf(globalThis.process?.env.COVERAGE_PROVIDER === 'istanbul')('pre-transpiled code with source maps to original', async () => { + const transpiled = await import('../src/transpiled.js') + + transpiled.hello() +})