1 | 'use strict';
|
2 | Object.defineProperty(exports, '__esModule', { value: true });
|
3 | exports.getColorByPercent = exports.setCoveredSizes = exports.addCoverageRanges = void 0;
|
4 | const url_1 = require('url');
|
5 | const helpers_1 = require('./helpers');
|
6 | const app_error_1 = require('./app-error');
|
7 | function convertRangesToLinesRanges(coverage) {
|
8 | const { ranges, text } = coverage;
|
9 | const eol = helpers_1.detectEOL(text);
|
10 | const eolLength = eol.length;
|
11 | const lines = text.split(eol);
|
12 | let offset = 0;
|
13 | const lineRanges = lines.map((line) => {
|
14 | const lineLength = line.length;
|
15 | if (lineLength === 0) {
|
16 | return [];
|
17 | }
|
18 | const lineStart = offset;
|
19 | const lineEnd = offset + lineLength;
|
20 | const lineRanges = ranges.reduce((result, { start, end }) => {
|
21 | const startIndex = start - lineStart;
|
22 | const endIndex = end - lineStart - 1;
|
23 | const lineEndIndex = lineLength - 1;
|
24 | if (start <= lineStart && lineEnd <= end) {
|
25 | result.push({ start: 0, end: lineEndIndex });
|
26 | } else if (lineStart <= start && end <= lineEnd) {
|
27 | result.push({ start: startIndex, end: endIndex });
|
28 | } else if (lineStart <= start && start <= lineEnd) {
|
29 | result.push({ start: startIndex, end: lineEndIndex });
|
30 | } else if (lineStart <= end && end <= lineEnd) {
|
31 | result.push({ start: 0, end: endIndex });
|
32 | }
|
33 | return result;
|
34 | }, []);
|
35 | offset = lineEnd + eolLength;
|
36 | return lineRanges;
|
37 | });
|
38 | return lineRanges;
|
39 | }
|
40 | const PATH_SEPARATOR_REGEX = /[/\\]/;
|
41 | function getPathParts(path) {
|
42 | return path.split(PATH_SEPARATOR_REGEX).filter(Boolean);
|
43 | }
|
44 | function addCoverageRanges(bundles, coverageFilename) {
|
45 | if (!coverageFilename) {
|
46 | return bundles;
|
47 | }
|
48 | try {
|
49 | const coverages = JSON.parse(helpers_1.getFileContent(coverageFilename));
|
50 | const bundlesPaths = bundles.reduce((result, { code }, index) => {
|
51 | if (!Buffer.isBuffer(code)) {
|
52 | result.push([getPathParts(code).reverse(), index]);
|
53 | }
|
54 | return result;
|
55 | }, []);
|
56 | coverages
|
57 | .map(({ url }) => getPathParts(new url_1.URL(url).pathname).reverse())
|
58 | .forEach((partsA, coverageIndex) => {
|
59 | if (!partsA.length) return;
|
60 | let matchingBundles = [...bundlesPaths];
|
61 | for (let i = 0; i < partsA.length; i++) {
|
62 | matchingBundles = matchingBundles.filter(
|
63 | ([partsB]) => i < partsB.length && partsB[i] === partsA[i]
|
64 | );
|
65 | if (matchingBundles.length <= 1) {
|
66 | break;
|
67 | }
|
68 | }
|
69 | if (matchingBundles.length === 1) {
|
70 | const [[, bundleIndex]] = matchingBundles;
|
71 | bundles[bundleIndex].coverageRanges = convertRangesToLinesRanges(
|
72 | coverages[coverageIndex]
|
73 | );
|
74 | }
|
75 | });
|
76 | } catch (error) {
|
77 | throw new app_error_1.AppError({ code: 'CannotOpenCoverageFile' }, error);
|
78 | }
|
79 | if (bundles.every(({ coverageRanges }) => coverageRanges === undefined)) {
|
80 | throw new app_error_1.AppError({ code: 'NoCoverageMatches' });
|
81 | }
|
82 | return bundles;
|
83 | }
|
84 | exports.addCoverageRanges = addCoverageRanges;
|
85 | function findCoveredMappingRanges(mappingRanges, coveredRanges) {
|
86 | let i = 0;
|
87 | let j = 0;
|
88 | const result = [];
|
89 | while (i < mappingRanges.length && j < coveredRanges.length) {
|
90 | const mappingRange = mappingRanges[i];
|
91 | const coveredRange = coveredRanges[j];
|
92 | if (mappingRange.start <= coveredRange.end && coveredRange.start <= mappingRange.end) {
|
93 | const end = Math.min(coveredRange.end, mappingRange.end);
|
94 | const start = Math.max(mappingRange.start, coveredRange.start);
|
95 | result.push({
|
96 | start,
|
97 | end,
|
98 | source: mappingRange.source,
|
99 | });
|
100 | if (
|
101 | mappingRanges[i + 1] !== undefined &&
|
102 | mappingRanges[i + 1].start <= coveredRange.end &&
|
103 | mappingRanges[i + 1].end >= coveredRange.start
|
104 | ) {
|
105 | i++;
|
106 | } else {
|
107 | j++;
|
108 | }
|
109 | } else if (mappingRange.end < coveredRange.start) {
|
110 | i++;
|
111 | }
|
112 | if (coveredRange.end < mappingRange.start) {
|
113 | j++;
|
114 | }
|
115 | }
|
116 | return result;
|
117 | }
|
118 | function setCoveredSizes(line, files, mappingRanges, coveredRanges) {
|
119 | findCoveredMappingRanges(mappingRanges, coveredRanges).forEach(({ start, end, source }) => {
|
120 | const rangeByteLength = Buffer.byteLength(line.substring(start, end + 1));
|
121 | let coveredSize = files[source].coveredSize || 0;
|
122 | coveredSize += rangeByteLength;
|
123 | files[source].coveredSize = coveredSize;
|
124 | });
|
125 | return files;
|
126 | }
|
127 | exports.setCoveredSizes = setCoveredSizes;
|
128 | const percentColors = [
|
129 | { percent: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
|
130 | { percent: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
|
131 | { percent: 1.0, color: { r: 0x00, g: 0xff, b: 0 } },
|
132 | ];
|
133 | function getColorByPercent(percent) {
|
134 | let i = 1;
|
135 | for (; i < percentColors.length - 1; i++) {
|
136 | if (percent < percentColors[i].percent) {
|
137 | break;
|
138 | }
|
139 | }
|
140 | const lowerColor = percentColors[i - 1];
|
141 | const upperColor = percentColors[i];
|
142 | const rangeWithinColors = upperColor.percent - lowerColor.percent;
|
143 | const rangePercent = (percent - lowerColor.percent) / rangeWithinColors;
|
144 | const percentLower = 1 - rangePercent;
|
145 | const percentUpper = rangePercent;
|
146 | const r = Math.floor(lowerColor.color.r * percentLower + upperColor.color.r * percentUpper);
|
147 | const g = Math.floor(lowerColor.color.g * percentLower + upperColor.color.g * percentUpper);
|
148 | const b = Math.floor(lowerColor.color.b * percentLower + upperColor.color.b * percentUpper);
|
149 | return `rgb(${r}, ${g}, ${b})`;
|
150 | }
|
151 | exports.getColorByPercent = getColorByPercent;
|
152 |
|