diff --git a/packages/coverage-c8/src/provider.ts b/packages/coverage-c8/src/provider.ts index dc8621acaa7d..71ab00461f82 100644 --- a/packages/coverage-c8/src/provider.ts +++ b/packages/coverage-c8/src/provider.ts @@ -48,39 +48,61 @@ export class C8CoverageProvider implements CoverageProvider { takeCoverage() const report = createReport(this.ctx.config.coverage) + interface MapAndSource { map: RawSourceMap; source: string | undefined } + type SourceMapMeta = { url: string; filepath: string } & MapAndSource + // add source maps - const sourceMapMeta: Record = {} - await Promise.all(Array + const sourceMapMeta: Record = {} + + const entries = Array .from(this.ctx.vitenode.fetchCache.entries()) .filter(i => !i[0].includes('/node_modules/')) - .map(async ([file, { result }]) => { - const map = result.map - if (!map) - return + .map(([file, { result }]) => { + if (!result.map) + return null const filepath = file.split('?')[0] - const url = _url.pathToFileURL(filepath).href - - let code: string | undefined - try { - code = (await fs.readFile(filepath)).toString() - } - catch { } - - // Vite does not report full path in sourcemap sources - // so use an actual file path - const sources = [url] - - sourceMapMeta[url] = { + return { + filepath, + url: _url.pathToFileURL(filepath).href, + map: result.map, source: result.code, - map: { - sourcesContent: code ? [code] : undefined, - ...map, - sources, - }, } - })) + }) + .filter((entry) => { + if (!entry) + return false + + // Mappings and sourcesContent are needed for C8 to work + return ( + entry.map.mappings.length > 0 + && entry.map.sourcesContent + && entry.map.sourcesContent.length > 0 + && entry.map.sourcesContent[0].length > 0 + ) + }) as SourceMapMeta[] + + await Promise.all(entries.map(async ({ url, source, map, filepath }) => { + let code: string | undefined + try { + code = (await fs.readFile(filepath)).toString() + } + catch { } + + // Vite does not report full path in sourcemap sources + // so use an actual file path + const sources = [url] + + sourceMapMeta[url] = { + source, + map: { + sourcesContent: code ? [code] : undefined, + ...map, + sources, + }, + } + })) // This is a magic number. It corresponds to the amount of code // that we add in packages/vite-node/src/client.ts:114 (vm.runInThisContext) diff --git a/test/coverage-test/coverage-report-tests/__snapshots__/c8.report.test.ts.snap b/test/coverage-test/coverage-report-tests/__snapshots__/c8.report.test.ts.snap index 07f8eb6edfcf..d3f6fe9e7335 100644 --- a/test/coverage-test/coverage-report-tests/__snapshots__/c8.report.test.ts.snap +++ b/test/coverage-test/coverage-report-tests/__snapshots__/c8.report.test.ts.snap @@ -809,19 +809,63 @@ exports[`c8 json report 1`] = ` }, "/src/Defined.vue": { "all": false, - "b": {}, - "branchMap": {}, + "b": { + "0": [ + 0, + ], + }, + "branchMap": { + "0": { + "line": 6, + "loc": { + "end": { + "column": 36, + "line": 8, + }, + "start": { + "column": 33, + "line": 6, + }, + }, + "locations": [ + { + "end": { + "column": 36, + "line": 8, + }, + "start": { + "column": 33, + "line": 6, + }, + }, + ], + "type": "branch", + }, + }, "f": {}, "fnMap": {}, "path": "/src/Defined.vue", "s": { "0": 1, "1": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, "2": 1, "3": 1, "4": 1, "5": 1, - "6": 1, + "6": 0, + "7": 0, + "8": 1, + "9": 1, }, "statementMap": { "0": { @@ -844,9 +888,109 @@ exports[`c8 json report 1`] = ` "line": 2, }, }, + "10": { + "end": { + "column": 10, + "line": 11, + }, + "start": { + "column": 0, + "line": 11, + }, + }, + "11": { + "end": { + "column": 15, + "line": 12, + }, + "start": { + "column": 0, + "line": 12, + }, + }, + "12": { + "end": { + "column": 11, + "line": 13, + }, + "start": { + "column": 0, + "line": 13, + }, + }, + "13": { + "end": { + "column": 0, + "line": 14, + }, + "start": { + "column": 0, + "line": 14, + }, + }, + "14": { + "end": { + "column": 90, + "line": 15, + }, + "start": { + "column": 0, + "line": 15, + }, + }, + "15": { + "end": { + "column": 25, + "line": 16, + }, + "start": { + "column": 0, + "line": 16, + }, + }, + "16": { + "end": { + "column": 6, + "line": 17, + }, + "start": { + "column": 0, + "line": 17, + }, + }, + "17": { + "end": { + "column": 25, + "line": 18, + }, + "start": { + "column": 0, + "line": 18, + }, + }, + "18": { + "end": { + "column": 1, + "line": 19, + }, + "start": { + "column": 0, + "line": 19, + }, + }, + "19": { + "end": { + "column": 8, + "line": 20, + }, + "start": { + "column": 0, + "line": 20, + }, + }, "2": { "end": { - "column": 9, + "column": 0, "line": 3, }, "start": { @@ -856,7 +1000,7 @@ exports[`c8 json report 1`] = ` }, "3": { "end": { - "column": 0, + "column": 31, "line": 4, }, "start": { @@ -866,7 +1010,7 @@ exports[`c8 json report 1`] = ` }, "4": { "end": { - "column": 10, + "column": 12, "line": 5, }, "start": { @@ -876,7 +1020,7 @@ exports[`c8 json report 1`] = ` }, "5": { "end": { - "column": 15, + "column": 34, "line": 6, }, "start": { @@ -886,7 +1030,7 @@ exports[`c8 json report 1`] = ` }, "6": { "end": { - "column": 11, + "column": 4, "line": 7, }, "start": { @@ -894,6 +1038,36 @@ exports[`c8 json report 1`] = ` "line": 7, }, }, + "7": { + "end": { + "column": 36, + "line": 8, + }, + "start": { + "column": 0, + "line": 8, + }, + }, + "8": { + "end": { + "column": 9, + "line": 9, + }, + "start": { + "column": 0, + "line": 9, + }, + }, + "9": { + "end": { + "column": 0, + "line": 10, + }, + "start": { + "column": 0, + "line": 10, + }, + }, }, }, "/src/Hello.vue": { 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 1a268c4af53e..4894bfa52465 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 @@ -256,14 +256,58 @@ exports[`istanbul json report 1`] = ` }, }, "/src/Defined.vue": { - "b": {}, - "branchMap": {}, + "b": { + "0": [ + 1, + 0, + ], + }, + "branchMap": { + "0": { + "loc": { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 0, + "line": 5, + }, + }, + "locations": [ + { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 0, + "line": 5, + }, + }, + { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 2, + "line": 8, + }, + }, + ], + "type": "if", + }, + }, "f": {}, "fnMap": {}, "path": "/src/Defined.vue", "s": { "0": 1, "1": 1, + "2": 1, + "3": 0, + "4": 1, }, "statementMap": { "0": { @@ -277,15 +321,45 @@ exports[`istanbul json report 1`] = ` }, }, "1": { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 0, + "line": 5, + }, + }, + "2": { "end": { "column": null, "line": 6, }, "start": { - "column": 5, + "column": 2, "line": 6, }, }, + "3": { + "end": { + "column": null, + "line": 8, + }, + "start": { + "column": 2, + "line": 8, + }, + }, + "4": { + "end": { + "column": null, + "line": 12, + }, + "start": { + "column": 5, + "line": 12, + }, + }, }, }, "/src/Hello.vue": { diff --git a/test/coverage-test/src/Defined.vue b/test/coverage-test/src/Defined.vue index 4774d9d23160..0f116e00bebd 100644 --- a/test/coverage-test/src/Defined.vue +++ b/test/coverage-test/src/Defined.vue @@ -1,7 +1,20 @@ + + +