source: trip-planner-front/node_modules/istanbul-reports/lib/text/index.js

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 Copyright 2012-2015, Yahoo Inc.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE
4 file for terms.
5 */
6'use strict';
7const { ReportBase } = require('istanbul-lib-report');
8
9const NAME_COL = 4;
10const PCT_COLS = 7;
11const MISSING_COL = 17;
12const TAB_SIZE = 1;
13const DELIM = ' | ';
14
15function padding(num, ch) {
16 let str = '';
17 let i;
18 ch = ch || ' ';
19 for (i = 0; i < num; i += 1) {
20 str += ch;
21 }
22 return str;
23}
24
25function fill(str, width, right, tabs) {
26 tabs = tabs || 0;
27 str = String(str);
28
29 const leadingSpaces = tabs * TAB_SIZE;
30 const remaining = width - leadingSpaces;
31 const leader = padding(leadingSpaces);
32 let fmtStr = '';
33
34 if (remaining > 0) {
35 const strlen = str.length;
36 let fillStr;
37
38 if (remaining >= strlen) {
39 fillStr = padding(remaining - strlen);
40 } else {
41 fillStr = '...';
42 const length = remaining - fillStr.length;
43
44 str = str.substring(strlen - length);
45 right = true;
46 }
47 fmtStr = right ? fillStr + str : str + fillStr;
48 }
49
50 return leader + fmtStr;
51}
52
53function formatName(name, maxCols, level) {
54 return fill(name, maxCols, false, level);
55}
56
57function formatPct(pct, width) {
58 return fill(pct, width || PCT_COLS, true, 0);
59}
60
61function nodeMissing(node) {
62 if (node.isSummary()) {
63 return '';
64 }
65
66 const metrics = node.getCoverageSummary();
67 const isEmpty = metrics.isEmpty();
68 const lines = isEmpty ? 0 : metrics.lines.pct;
69
70 let coveredLines;
71
72 const fileCoverage = node.getFileCoverage();
73 if (lines === 100) {
74 const branches = fileCoverage.getBranchCoverageByLine();
75 coveredLines = Object.entries(branches).map(([key, { coverage }]) => [
76 key,
77 coverage === 100
78 ]);
79 } else {
80 coveredLines = Object.entries(fileCoverage.getLineCoverage());
81 }
82
83 let newRange = true;
84 const ranges = coveredLines
85 .reduce((acum, [line, hit]) => {
86 if (hit) newRange = true;
87 else {
88 line = parseInt(line);
89 if (newRange) {
90 acum.push([line]);
91 newRange = false;
92 } else acum[acum.length - 1][1] = line;
93 }
94
95 return acum;
96 }, [])
97 .map(range => {
98 const { length } = range;
99
100 if (length === 1) return range[0];
101
102 return `${range[0]}-${range[1]}`;
103 });
104
105 return [].concat(...ranges).join(',');
106}
107
108function nodeName(node) {
109 return node.getRelativeName() || 'All files';
110}
111
112function depthFor(node) {
113 let ret = 0;
114 node = node.getParent();
115 while (node) {
116 ret += 1;
117 node = node.getParent();
118 }
119 return ret;
120}
121
122function nullDepthFor() {
123 return 0;
124}
125
126function findWidth(node, context, nodeExtractor, depthFor = nullDepthFor) {
127 let last = 0;
128 function compareWidth(node) {
129 last = Math.max(
130 last,
131 TAB_SIZE * depthFor(node) + nodeExtractor(node).length
132 );
133 }
134 const visitor = {
135 onSummary: compareWidth,
136 onDetail: compareWidth
137 };
138 node.visit(context.getVisitor(visitor));
139 return last;
140}
141
142function makeLine(nameWidth, missingWidth) {
143 const name = padding(nameWidth, '-');
144 const pct = padding(PCT_COLS, '-');
145 const elements = [];
146
147 elements.push(name);
148 elements.push(pct);
149 elements.push(padding(PCT_COLS + 1, '-'));
150 elements.push(pct);
151 elements.push(pct);
152 elements.push(padding(missingWidth, '-'));
153 return elements.join(DELIM.replace(/ /g, '-')) + '-';
154}
155
156function tableHeader(maxNameCols, missingWidth) {
157 const elements = [];
158 elements.push(formatName('File', maxNameCols, 0));
159 elements.push(formatPct('% Stmts'));
160 elements.push(formatPct('% Branch', PCT_COLS + 1));
161 elements.push(formatPct('% Funcs'));
162 elements.push(formatPct('% Lines'));
163 elements.push(formatName('Uncovered Line #s', missingWidth));
164 return elements.join(DELIM) + ' ';
165}
166
167function isFull(metrics) {
168 return (
169 metrics.statements.pct === 100 &&
170 metrics.branches.pct === 100 &&
171 metrics.functions.pct === 100 &&
172 metrics.lines.pct === 100
173 );
174}
175
176function tableRow(
177 node,
178 context,
179 colorizer,
180 maxNameCols,
181 level,
182 skipEmpty,
183 skipFull,
184 missingWidth
185) {
186 const name = nodeName(node);
187 const metrics = node.getCoverageSummary();
188 const isEmpty = metrics.isEmpty();
189 if (skipEmpty && isEmpty) {
190 return '';
191 }
192 if (skipFull && isFull(metrics)) {
193 return '';
194 }
195
196 const mm = {
197 statements: isEmpty ? 0 : metrics.statements.pct,
198 branches: isEmpty ? 0 : metrics.branches.pct,
199 functions: isEmpty ? 0 : metrics.functions.pct,
200 lines: isEmpty ? 0 : metrics.lines.pct
201 };
202 const colorize = isEmpty
203 ? function(str) {
204 return str;
205 }
206 : function(str, key) {
207 return colorizer(str, context.classForPercent(key, mm[key]));
208 };
209 const elements = [];
210
211 elements.push(colorize(formatName(name, maxNameCols, level), 'statements'));
212 elements.push(colorize(formatPct(mm.statements), 'statements'));
213 elements.push(colorize(formatPct(mm.branches, PCT_COLS + 1), 'branches'));
214 elements.push(colorize(formatPct(mm.functions), 'functions'));
215 elements.push(colorize(formatPct(mm.lines), 'lines'));
216 elements.push(
217 colorizer(
218 formatName(nodeMissing(node), missingWidth),
219 mm.lines === 100 ? 'medium' : 'low'
220 )
221 );
222
223 return elements.join(DELIM) + ' ';
224}
225
226class TextReport extends ReportBase {
227 constructor(opts) {
228 super(opts);
229
230 opts = opts || {};
231 const { maxCols } = opts;
232
233 this.file = opts.file || null;
234 this.maxCols = maxCols != null ? maxCols : process.stdout.columns || 80;
235 this.cw = null;
236 this.skipEmpty = opts.skipEmpty;
237 this.skipFull = opts.skipFull;
238 }
239
240 onStart(root, context) {
241 this.cw = context.writer.writeFile(this.file);
242 this.nameWidth = Math.max(
243 NAME_COL,
244 findWidth(root, context, nodeName, depthFor)
245 );
246 this.missingWidth = Math.max(
247 MISSING_COL,
248 findWidth(root, context, nodeMissing)
249 );
250
251 if (this.maxCols > 0) {
252 const pct_cols = DELIM.length + 4 * (PCT_COLS + DELIM.length) + 2;
253
254 const maxRemaining = this.maxCols - (pct_cols + MISSING_COL);
255 if (this.nameWidth > maxRemaining) {
256 this.nameWidth = maxRemaining;
257 this.missingWidth = MISSING_COL;
258 } else if (this.nameWidth < maxRemaining) {
259 const maxRemaining = this.maxCols - (this.nameWidth + pct_cols);
260 if (this.missingWidth > maxRemaining) {
261 this.missingWidth = maxRemaining;
262 }
263 }
264 }
265 const line = makeLine(this.nameWidth, this.missingWidth);
266 this.cw.println(line);
267 this.cw.println(tableHeader(this.nameWidth, this.missingWidth));
268 this.cw.println(line);
269 }
270
271 onSummary(node, context) {
272 const nodeDepth = depthFor(node);
273 const row = tableRow(
274 node,
275 context,
276 this.cw.colorize.bind(this.cw),
277 this.nameWidth,
278 nodeDepth,
279 this.skipEmpty,
280 this.skipFull,
281 this.missingWidth
282 );
283 if (row) {
284 this.cw.println(row);
285 }
286 }
287
288 onDetail(node, context) {
289 return this.onSummary(node, context);
290 }
291
292 onEnd() {
293 this.cw.println(makeLine(this.nameWidth, this.missingWidth));
294 this.cw.close();
295 }
296}
297
298module.exports = TextReport;
Note: See TracBrowser for help on using the repository browser.