monocart-coverage-reports 2.4.4 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -74
- package/lib/default/options.js +3 -0
- package/lib/generate.js +13 -33
- package/lib/index.d.ts +8 -0
- package/lib/index.js +9 -7
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/platform/share.js +18 -59
- package/lib/utils/util.js +13 -0
- package/lib/v8/v8.js +214 -6
- package/package.json +2 -2
package/lib/platform/share.js
CHANGED
|
@@ -4,65 +4,6 @@ const Util = {
|
|
|
4
4
|
tagPattern: /(\s*)@([^@\s]+)(\s*)/g,
|
|
5
5
|
lineBreakPattern: /\r\n|[\r\n\u2028\u2029]/gu,
|
|
6
6
|
|
|
7
|
-
attachments: {
|
|
8
|
-
audit: {
|
|
9
|
-
name: 'audit',
|
|
10
|
-
contentType: 'text/html',
|
|
11
|
-
reportFile: 'audit-report.json'
|
|
12
|
-
},
|
|
13
|
-
coverage: {
|
|
14
|
-
name: 'coverage',
|
|
15
|
-
contentType: 'text/html',
|
|
16
|
-
reportFile: 'coverage-report.json'
|
|
17
|
-
},
|
|
18
|
-
network: {
|
|
19
|
-
name: 'network',
|
|
20
|
-
contentType: 'text/html',
|
|
21
|
-
reportFile: 'network-report.json'
|
|
22
|
-
},
|
|
23
|
-
// artifact will be removed finally
|
|
24
|
-
artifact: {
|
|
25
|
-
name: 'artifact',
|
|
26
|
-
contentType: 'application/json'
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
pageTimings: [{
|
|
31
|
-
key: 'onContentLoad',
|
|
32
|
-
name: 'Content Loaded',
|
|
33
|
-
color: '#1a1aa6'
|
|
34
|
-
}, {
|
|
35
|
-
key: 'onLoad',
|
|
36
|
-
name: 'Page Loaded',
|
|
37
|
-
color: '#c80000'
|
|
38
|
-
}],
|
|
39
|
-
|
|
40
|
-
timings: [{
|
|
41
|
-
key: 'blocked',
|
|
42
|
-
name: 'Blocking',
|
|
43
|
-
color: '#858585'
|
|
44
|
-
}, {
|
|
45
|
-
key: 'dns',
|
|
46
|
-
name: 'DNS Lookup',
|
|
47
|
-
color: '#009688'
|
|
48
|
-
}, {
|
|
49
|
-
key: 'connect',
|
|
50
|
-
name: 'Connecting',
|
|
51
|
-
color: '#b52dcd'
|
|
52
|
-
}, {
|
|
53
|
-
key: 'send',
|
|
54
|
-
name: 'Sending',
|
|
55
|
-
color: '#74979a'
|
|
56
|
-
}, {
|
|
57
|
-
key: 'wait',
|
|
58
|
-
name: 'Waiting',
|
|
59
|
-
color: '#00a846'
|
|
60
|
-
}, {
|
|
61
|
-
key: 'receive',
|
|
62
|
-
name: 'Receiving',
|
|
63
|
-
color: '#0299de'
|
|
64
|
-
}],
|
|
65
|
-
|
|
66
7
|
hasOwn: function(obj, key) {
|
|
67
8
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
68
9
|
},
|
|
@@ -190,6 +131,20 @@ const Util = {
|
|
|
190
131
|
|
|
191
132
|
// =============================================================================
|
|
192
133
|
|
|
134
|
+
getMetrics: (type, metrics) => {
|
|
135
|
+
const istanbulMetrics = ['statements', 'branches', 'functions', 'lines'];
|
|
136
|
+
const v8Metrics = ['bytes'].concat(istanbulMetrics);
|
|
137
|
+
const allMetrics = type === 'v8' ? v8Metrics : istanbulMetrics;
|
|
138
|
+
let list = allMetrics;
|
|
139
|
+
if (Util.isList(metrics)) {
|
|
140
|
+
const newList = list.filter((k) => metrics.includes(k));
|
|
141
|
+
if (newList.length) {
|
|
142
|
+
list = newList;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return list;
|
|
146
|
+
},
|
|
147
|
+
|
|
193
148
|
generatePercentChart: function(percent) {
|
|
194
149
|
return `<div style="--mcr-percent:${percent}%;" class="mcr-percent-chart"></div>`;
|
|
195
150
|
},
|
|
@@ -409,6 +364,10 @@ const Util = {
|
|
|
409
364
|
return `${Util.dFixed(px)},${Util.dFixed(py)}`;
|
|
410
365
|
},
|
|
411
366
|
|
|
367
|
+
capitalizeFirstLetter: (string) => {
|
|
368
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
369
|
+
},
|
|
370
|
+
|
|
412
371
|
// =============================================================================
|
|
413
372
|
// formatter
|
|
414
373
|
|
package/lib/utils/util.js
CHANGED
|
@@ -409,6 +409,19 @@ const Util = {
|
|
|
409
409
|
return template;
|
|
410
410
|
},
|
|
411
411
|
|
|
412
|
+
getColorStrByStatus: (str, status) => {
|
|
413
|
+
if (status === 'low') {
|
|
414
|
+
return EC.red(str);
|
|
415
|
+
}
|
|
416
|
+
if (status === 'medium') {
|
|
417
|
+
return EC.yellow(str);
|
|
418
|
+
}
|
|
419
|
+
if (status === 'high') {
|
|
420
|
+
return EC.green(str);
|
|
421
|
+
}
|
|
422
|
+
return str;
|
|
423
|
+
},
|
|
424
|
+
|
|
412
425
|
// ==========================================================================================
|
|
413
426
|
|
|
414
427
|
loggingLevels: {
|
package/lib/v8/v8.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const CG = require('console-grid');
|
|
3
|
+
const EC = require('eight-colors');
|
|
2
4
|
const Util = require('../utils/util.js');
|
|
3
5
|
const { getV8Summary } = require('./v8-summary.js');
|
|
4
6
|
const { dedupeFlatRanges } = require('../utils/dedupe.js');
|
|
@@ -233,7 +235,212 @@ const mergeV8Coverage = async (dataList, sourceCache, options) => {
|
|
|
233
235
|
|
|
234
236
|
// ============================================================
|
|
235
237
|
|
|
236
|
-
const
|
|
238
|
+
const mergeSingleSubGroups = (item) => {
|
|
239
|
+
|
|
240
|
+
if (!item.subs) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (item.subs.length === 1) {
|
|
244
|
+
const sub = item.subs[0];
|
|
245
|
+
if (!sub.subs) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
item.name = [item.name, sub.name].filter((it) => it).join('/');
|
|
249
|
+
item.subs = sub.subs;
|
|
250
|
+
mergeSingleSubGroups(item);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
item.subs.forEach((sub) => {
|
|
255
|
+
mergeSingleSubGroups(sub);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const getRowData = (rowName, summary, metrics) => {
|
|
261
|
+
const summaryRow = {};
|
|
262
|
+
let lowest = {
|
|
263
|
+
pct: 100,
|
|
264
|
+
status: 'high'
|
|
265
|
+
};
|
|
266
|
+
metrics.map((k) => {
|
|
267
|
+
const s = summary[k];
|
|
268
|
+
const percent = s.pct;
|
|
269
|
+
if (typeof percent !== 'number') {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status);
|
|
273
|
+
if (percent < lowest.pct) {
|
|
274
|
+
lowest = s;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
summaryRow.name = Util.getColorStrByStatus(rowName, lowest.status);
|
|
278
|
+
return summaryRow;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const getUncoveredLines = (file) => {
|
|
282
|
+
const lines = [];
|
|
283
|
+
|
|
284
|
+
const dataLines = file.data.lines;
|
|
285
|
+
|
|
286
|
+
let startLine;
|
|
287
|
+
let endLine;
|
|
288
|
+
|
|
289
|
+
const addLines = () => {
|
|
290
|
+
if (!startLine) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (endLine) {
|
|
294
|
+
// range
|
|
295
|
+
const link = startLine.color === 'yellow' && endLine.color === 'yellow' ? EC.yellow('-') : EC.red('-');
|
|
296
|
+
lines.push(EC[startLine.color](startLine.line) + link + EC[endLine.color](endLine.line));
|
|
297
|
+
startLine = null;
|
|
298
|
+
endLine = null;
|
|
299
|
+
} else {
|
|
300
|
+
// only start
|
|
301
|
+
lines.push(EC[startLine.color](startLine.line));
|
|
302
|
+
startLine = null;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const setLines = (line, color) => {
|
|
307
|
+
if (startLine) {
|
|
308
|
+
endLine = {
|
|
309
|
+
line,
|
|
310
|
+
color
|
|
311
|
+
};
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
startLine = {
|
|
315
|
+
line,
|
|
316
|
+
color
|
|
317
|
+
};
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
Object.keys(dataLines).forEach((line) => {
|
|
321
|
+
const count = dataLines[line];
|
|
322
|
+
if (count === 0) {
|
|
323
|
+
setLines(line, 'red');
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
// 0 < count < 1
|
|
327
|
+
if (typeof count === 'string') {
|
|
328
|
+
setLines(line, 'yellow');
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
// count >= 1
|
|
332
|
+
addLines();
|
|
333
|
+
});
|
|
334
|
+
addLines();
|
|
335
|
+
|
|
336
|
+
return lines.join(',');
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const getGroupedRows = (files, metrics, cdOptions) => {
|
|
340
|
+
|
|
341
|
+
const skipPercent = cdOptions.skipPercent;
|
|
342
|
+
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
343
|
+
files = files.filter((file) => {
|
|
344
|
+
const { summary } = file;
|
|
345
|
+
for (const k of metrics) {
|
|
346
|
+
const percent = summary[k].pct;
|
|
347
|
+
if (typeof percent === 'number' && percent < skipPercent) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
let groups = [];
|
|
356
|
+
|
|
357
|
+
files.forEach((file) => {
|
|
358
|
+
const { sourcePath, summary } = file;
|
|
359
|
+
const pathList = sourcePath.split('/');
|
|
360
|
+
const lastName = pathList.pop();
|
|
361
|
+
let subs = groups;
|
|
362
|
+
pathList.forEach((key) => {
|
|
363
|
+
const item = subs.find((it) => it.name === key && it.subs);
|
|
364
|
+
if (item) {
|
|
365
|
+
subs = item.subs;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const sub = {
|
|
369
|
+
name: key,
|
|
370
|
+
subs: []
|
|
371
|
+
};
|
|
372
|
+
subs.push(sub);
|
|
373
|
+
subs = sub.subs;
|
|
374
|
+
});
|
|
375
|
+
const fileRow = getRowData(lastName, summary, metrics);
|
|
376
|
+
fileRow.uncoveredLines = getUncoveredLines(file);
|
|
377
|
+
subs.push(fileRow);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
const group = {
|
|
381
|
+
subs: groups
|
|
382
|
+
};
|
|
383
|
+
mergeSingleSubGroups(group);
|
|
384
|
+
|
|
385
|
+
if (group.name) {
|
|
386
|
+
groups = [group];
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return groups;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
393
|
+
const cdOptions = {
|
|
394
|
+
maxCols: 50,
|
|
395
|
+
skipPercent: 0,
|
|
396
|
+
metrics: [],
|
|
397
|
+
... reportOptions
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const {
|
|
401
|
+
name, summary, files
|
|
402
|
+
} = reportData;
|
|
403
|
+
|
|
404
|
+
if (name) {
|
|
405
|
+
EC.logCyan(name);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const metrics = Util.getMetrics('v8', cdOptions.metrics);
|
|
409
|
+
const rows = getGroupedRows(files, metrics, cdOptions);
|
|
410
|
+
const summaryRow = getRowData('Summary', summary, metrics);
|
|
411
|
+
// no rows if skipped all by skipPercent
|
|
412
|
+
if (rows.length) {
|
|
413
|
+
rows.push({
|
|
414
|
+
innerBorder: true
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
rows.push(summaryRow);
|
|
418
|
+
|
|
419
|
+
const columns = [{
|
|
420
|
+
id: 'name',
|
|
421
|
+
name: 'Name'
|
|
422
|
+
}, ... metrics.map((m) => {
|
|
423
|
+
return {
|
|
424
|
+
id: m,
|
|
425
|
+
name: Util.capitalizeFirstLetter(m),
|
|
426
|
+
align: 'right'
|
|
427
|
+
};
|
|
428
|
+
}), {
|
|
429
|
+
id: 'uncoveredLines',
|
|
430
|
+
name: 'Uncovered Lines'
|
|
431
|
+
}];
|
|
432
|
+
|
|
433
|
+
CG({
|
|
434
|
+
options: {
|
|
435
|
+
nullPlaceholder: '',
|
|
436
|
+
defaultMaxWidth: cdOptions.maxCols
|
|
437
|
+
},
|
|
438
|
+
columns,
|
|
439
|
+
rows
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const handleCodecovReport = async (reportData, reportOptions, options) => {
|
|
237
444
|
const codecovOptions = {
|
|
238
445
|
outputFile: 'codecov.json',
|
|
239
446
|
... reportOptions
|
|
@@ -255,7 +462,7 @@ const saveCodecovReport = async (reportData, reportOptions, options) => {
|
|
|
255
462
|
return Util.relativePath(jsonPath);
|
|
256
463
|
};
|
|
257
464
|
|
|
258
|
-
const
|
|
465
|
+
const handleV8JsonReport = async (reportData, reportOptions, options) => {
|
|
259
466
|
const v8JsonOptions = {
|
|
260
467
|
outputFile: 'coverage-report.json',
|
|
261
468
|
... reportOptions
|
|
@@ -268,7 +475,7 @@ const saveV8JsonReport = async (reportData, reportOptions, options) => {
|
|
|
268
475
|
};
|
|
269
476
|
|
|
270
477
|
|
|
271
|
-
const
|
|
478
|
+
const handleV8HtmlReport = async (reportData, reportOptions, options) => {
|
|
272
479
|
|
|
273
480
|
// V8 only options, merged with root options
|
|
274
481
|
const v8HtmlOptions = {
|
|
@@ -340,9 +547,10 @@ const saveV8Report = async (v8list, options) => {
|
|
|
340
547
|
|
|
341
548
|
// v8 reports
|
|
342
549
|
const buildInV8Reports = {
|
|
343
|
-
'v8':
|
|
344
|
-
'v8-json':
|
|
345
|
-
'codecov':
|
|
550
|
+
'v8': handleV8HtmlReport,
|
|
551
|
+
'v8-json': handleV8JsonReport,
|
|
552
|
+
'codecov': handleCodecovReport,
|
|
553
|
+
'console-details': handleConsoleDetailsReport
|
|
346
554
|
};
|
|
347
555
|
|
|
348
556
|
const outputs = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-coverage-reports",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "Monocart coverage reports",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"url": "git+https://github.com/cenfun/monocart-coverage-reports.git"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"console-grid": "~2.1
|
|
57
|
+
"console-grid": "~2.2.1",
|
|
58
58
|
"eight-colors": "~1.2.1",
|
|
59
59
|
"istanbul-lib-coverage": "~3.2.2",
|
|
60
60
|
"istanbul-lib-report": "~3.0.1",
|