1 | import libCoverage from "istanbul-lib-coverage";
|
2 | import { istanbulize, SourceType, unwrapScriptCov, unwrapSourceText } from "istanbulize";
|
3 | import { parseSys as parseNodeScriptUrl } from "node-script-url";
|
4 | import sourceMap from "source-map";
|
5 | import urlMod from "url";
|
6 | import { GetText, getText as defaultGetText } from "./get-text";
|
7 | import { mergeCovMaps } from "./istanbul-merge";
|
8 | import { mergeRichProcessCovs } from "./merge";
|
9 | import { addFromGeneratedFileCov } from "./source-map";
|
10 | import { CoverageMapBuilder } from "./source-map/builder";
|
11 | import { MemorySourceStore, NullableSourceText } from "./source-map/source-store";
|
12 | import { RichProcessCov, RichScriptCov } from "./spawn-inspected";
|
13 |
|
14 | export interface RichIstanbulCoverageMap {
|
15 | coverageMap: libCoverage.CoverageMap;
|
16 | sources: Map<string, NullableSourceText>;
|
17 | }
|
18 |
|
19 | export async function processCovsToIstanbul(
|
20 | processCovs: ReadonlyArray<RichProcessCov>,
|
21 | getText: GetText = defaultGetText,
|
22 | unwrapCjs: boolean = true,
|
23 | ): Promise<RichIstanbulCoverageMap> {
|
24 | const merged: RichProcessCov = mergeRichProcessCovs(processCovs);
|
25 | const processCov: RichProcessCov = unwrapCjs ? normalizeProcessCov(merged) : merged;
|
26 | return toIstanbul(processCov, getText);
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | async function toIstanbul(
|
36 | processCov: RichProcessCov,
|
37 | getText: GetText = defaultGetText,
|
38 | ): Promise<RichIstanbulCoverageMap> {
|
39 | const rawCoverageMap: libCoverage.CoverageMapData = toRawIstanbul(processCov);
|
40 |
|
41 | const generatedCovMap: libCoverage.CoverageMapData = Object.create(null);
|
42 | const originalBuilder: CoverageMapBuilder = new CoverageMapBuilder();
|
43 | const sourceStore: MemorySourceStore = new MemorySourceStore();
|
44 |
|
45 | for (const scriptCov of processCov.result) {
|
46 | const rawFileCov: libCoverage.FileCoverage = rawCoverageMap[scriptCov.url];
|
47 | let useOriginal: boolean = false;
|
48 | if (scriptCov.sourceMapUrl !== undefined && parseNodeScriptUrl(scriptCov.url).isFileUrl) {
|
49 | const sourceMapString: string = await getText(new urlMod.URL(scriptCov.sourceMapUrl));
|
50 | const rawSourceMap: sourceMap.RawSourceMap = JSON.parse(sourceMapString);
|
51 | useOriginal = await addFromGeneratedFileCov(
|
52 | originalBuilder,
|
53 | sourceStore,
|
54 | rawFileCov,
|
55 | rawSourceMap,
|
56 | scriptCov.sourceMapUrl,
|
57 | );
|
58 | }
|
59 |
|
60 | if (!useOriginal) {
|
61 | sourceStore.set(scriptCov.url, scriptCov.sourceText);
|
62 | generatedCovMap[scriptCov.url] = rawFileCov;
|
63 | }
|
64 | }
|
65 |
|
66 | const coverageMap: libCoverage.CoverageMapData = mergeCovMaps([generatedCovMap, originalBuilder.build()]);
|
67 |
|
68 | return {
|
69 | coverageMap: libCoverage.createCoverageMap(coverageMap),
|
70 | sources: new Map(sourceStore),
|
71 | };
|
72 | }
|
73 |
|
74 | export function normalizeProcessCov(processCov: RichProcessCov): RichProcessCov {
|
75 | return {...processCov, result: processCov.result.map(normalizeScriptCov)};
|
76 | }
|
77 |
|
78 | export function normalizeScriptCov(scriptCov: RichScriptCov): RichScriptCov {
|
79 | const sourceType: SourceType = scriptCov.sourceType;
|
80 | if (sourceType !== SourceType.Script) {
|
81 | return scriptCov;
|
82 | }
|
83 | const sourceText: string = unwrapSourceText(scriptCov.sourceText);
|
84 | const {functions} = unwrapScriptCov(scriptCov);
|
85 | return {...scriptCov, functions, sourceText};
|
86 | }
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | export function toRawIstanbul(processCov: RichProcessCov): libCoverage.CoverageMapData {
|
94 | const coverageMap: libCoverage.CoverageMapData = Object.create(null);
|
95 |
|
96 | for (const scriptCov of processCov.result) {
|
97 | const generatedFileCov: libCoverage.FileCoverageData = istanbulize({
|
98 | sourceType: scriptCov.sourceType,
|
99 | sourceText: scriptCov.sourceText,
|
100 | scriptCov,
|
101 | });
|
102 | coverageMap[scriptCov.url] = libCoverage.createFileCoverage(generatedFileCov);
|
103 | }
|
104 |
|
105 | return coverageMap;
|
106 | }
|