monocart-coverage-reports 2.8.6 → 2.9.0
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 +29 -6
- package/README.zh-Hans.md +27 -4
- package/lib/converter/converter.js +14 -5
- package/lib/default/options.js +3 -0
- package/lib/generate.js +255 -134
- package/lib/index.d.ts +52 -2
- package/lib/index.js +18 -5
- package/lib/istanbul/istanbul-summary.js +4 -1
- package/lib/packages/monocart-coverage-app.js +1 -1
- package/lib/platform/share.js +1 -7
- package/lib/utils/markdown.js +132 -0
- package/lib/utils/snapshot.js +13 -53
- package/lib/utils/util.js +178 -10
- package/package.json +104 -104
package/lib/generate.js
CHANGED
|
@@ -16,6 +16,7 @@ const { resolveSourceMap } = require('./converter/collect-source-maps.js');
|
|
|
16
16
|
|
|
17
17
|
const { minimatch } = require('./packages/monocart-coverage-vendor.js');
|
|
18
18
|
const { getGroupedRows } = require('./utils/snapshot.js');
|
|
19
|
+
const generateMarkdownGrid = require('./utils/markdown.js');
|
|
19
20
|
|
|
20
21
|
// ========================================================================================================
|
|
21
22
|
|
|
@@ -90,8 +91,11 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
90
91
|
|
|
91
92
|
// both
|
|
92
93
|
'codecov': 'both',
|
|
94
|
+
'codacy': 'both',
|
|
93
95
|
'console-details': 'both',
|
|
94
96
|
'console-summary': 'both',
|
|
97
|
+
'markdown-details': 'both',
|
|
98
|
+
'markdown-summary': 'both',
|
|
95
99
|
'raw': 'both'
|
|
96
100
|
};
|
|
97
101
|
|
|
@@ -128,13 +132,6 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
128
132
|
|
|
129
133
|
// ========================================================================================================
|
|
130
134
|
|
|
131
|
-
const pFormatter = (v, row, column) => {
|
|
132
|
-
if (typeof v === 'number') {
|
|
133
|
-
return Util.getColorStrByStatus(Util.PSF(v, 100, 2), row.status);
|
|
134
|
-
}
|
|
135
|
-
return v;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
135
|
const nFormatter = (v) => {
|
|
139
136
|
if (typeof v === 'number') {
|
|
140
137
|
return Util.NF(v);
|
|
@@ -142,7 +139,7 @@ const nFormatter = (v) => {
|
|
|
142
139
|
return v;
|
|
143
140
|
};
|
|
144
141
|
|
|
145
|
-
const getRowData = (rowName, summary, metrics) => {
|
|
142
|
+
const getRowData = (rowName, summary, metrics, color) => {
|
|
146
143
|
const summaryRow = {};
|
|
147
144
|
let lowest = {
|
|
148
145
|
pct: 100,
|
|
@@ -157,7 +154,7 @@ const getRowData = (rowName, summary, metrics) => {
|
|
|
157
154
|
if (typeof percent !== 'number') {
|
|
158
155
|
return;
|
|
159
156
|
}
|
|
160
|
-
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status);
|
|
157
|
+
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status, color);
|
|
161
158
|
if (percent < lowest.pct) {
|
|
162
159
|
lowest = s;
|
|
163
160
|
}
|
|
@@ -167,65 +164,7 @@ const getRowData = (rowName, summary, metrics) => {
|
|
|
167
164
|
return summaryRow;
|
|
168
165
|
};
|
|
169
166
|
|
|
170
|
-
const
|
|
171
|
-
const lines = [];
|
|
172
|
-
|
|
173
|
-
const dataLines = file.data.lines;
|
|
174
|
-
|
|
175
|
-
let startLine;
|
|
176
|
-
let endLine;
|
|
177
|
-
|
|
178
|
-
const addLines = () => {
|
|
179
|
-
if (!startLine) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (endLine) {
|
|
183
|
-
// range
|
|
184
|
-
const link = startLine.color === 'yellow' && endLine.color === 'yellow' ? EC.yellow('-') : EC.red('-');
|
|
185
|
-
lines.push(EC[startLine.color](startLine.line) + link + EC[endLine.color](endLine.line));
|
|
186
|
-
startLine = null;
|
|
187
|
-
endLine = null;
|
|
188
|
-
} else {
|
|
189
|
-
// only start
|
|
190
|
-
lines.push(EC[startLine.color](startLine.line));
|
|
191
|
-
startLine = null;
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const setLines = (line, color) => {
|
|
196
|
-
if (startLine) {
|
|
197
|
-
endLine = {
|
|
198
|
-
line,
|
|
199
|
-
color
|
|
200
|
-
};
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
startLine = {
|
|
204
|
-
line,
|
|
205
|
-
color
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
Object.keys(dataLines).forEach((line) => {
|
|
210
|
-
const count = dataLines[line];
|
|
211
|
-
if (count === 0) {
|
|
212
|
-
setLines(line, 'red');
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
// 0 < count < 1
|
|
216
|
-
if (typeof count === 'string') {
|
|
217
|
-
setLines(line, 'yellow');
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
// count >= 1
|
|
221
|
-
addLines();
|
|
222
|
-
});
|
|
223
|
-
addLines();
|
|
224
|
-
|
|
225
|
-
return lines.join(',');
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const getDetailsRows = (files, metrics, cdOptions) => {
|
|
167
|
+
const getDetailsRows = (files, metrics, cdOptions, color) => {
|
|
229
168
|
|
|
230
169
|
const skipPercent = cdOptions.skipPercent;
|
|
231
170
|
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
@@ -250,8 +189,8 @@ const getDetailsRows = (files, metrics, cdOptions) => {
|
|
|
250
189
|
}
|
|
251
190
|
|
|
252
191
|
const { sourcePath, summary } = file;
|
|
253
|
-
const fileRow = getRowData(sourcePath, summary, metrics);
|
|
254
|
-
fileRow.uncoveredLines = getUncoveredLines(file);
|
|
192
|
+
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
193
|
+
fileRow.uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
255
194
|
flatRows.push(fileRow);
|
|
256
195
|
});
|
|
257
196
|
|
|
@@ -280,6 +219,42 @@ const handleCodecovReport = async (reportData, reportOptions, options) => {
|
|
|
280
219
|
return Util.relativePath(jsonPath);
|
|
281
220
|
};
|
|
282
221
|
|
|
222
|
+
const handleCodacyReport = async (reportData, reportOptions, options) => {
|
|
223
|
+
const codacyOptions = {
|
|
224
|
+
outputFile: 'codacy.json',
|
|
225
|
+
... reportOptions
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const jsonPath = path.resolve(options.outputDir, codacyOptions.outputFile);
|
|
229
|
+
|
|
230
|
+
// https://api.codacy.com/swagger#tocscoveragereport
|
|
231
|
+
const fileReports = [];
|
|
232
|
+
reportData.files.forEach((item) => {
|
|
233
|
+
const { sourcePath, data } = item;
|
|
234
|
+
|
|
235
|
+
const coverage = {};
|
|
236
|
+
for (const [key, value] of Object.entries(data.lines)) {
|
|
237
|
+
if (typeof value === 'number') {
|
|
238
|
+
coverage[key] = value;
|
|
239
|
+
} else {
|
|
240
|
+
// partial coverage not supported?
|
|
241
|
+
coverage[key] = 0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
fileReports.push({
|
|
246
|
+
filename: sourcePath,
|
|
247
|
+
coverage
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
const codacyData = {
|
|
251
|
+
fileReports
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
await Util.writeFile(jsonPath, JSON.stringify(codacyData));
|
|
255
|
+
return Util.relativePath(jsonPath);
|
|
256
|
+
};
|
|
257
|
+
|
|
283
258
|
const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
284
259
|
const cdOptions = {
|
|
285
260
|
maxCols: 50,
|
|
@@ -296,11 +271,13 @@ const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
|
296
271
|
Util.logInfo(EC.cyan(name));
|
|
297
272
|
}
|
|
298
273
|
|
|
274
|
+
const color = 'ansicode';
|
|
275
|
+
|
|
299
276
|
const metrics = Util.getMetrics(cdOptions.metrics, type);
|
|
300
|
-
const rows = getDetailsRows(files, metrics, cdOptions);
|
|
301
|
-
const summaryRow = getRowData('Summary', summary, metrics);
|
|
277
|
+
const rows = getDetailsRows(files, metrics, cdOptions, color);
|
|
278
|
+
const summaryRow = getRowData('Summary', summary, metrics, color);
|
|
302
279
|
if (summaryRow.nameStatus) {
|
|
303
|
-
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus);
|
|
280
|
+
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
304
281
|
}
|
|
305
282
|
// no rows if skipped all by skipPercent
|
|
306
283
|
if (rows.length) {
|
|
@@ -335,6 +312,41 @@ const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
|
335
312
|
});
|
|
336
313
|
};
|
|
337
314
|
|
|
315
|
+
const getSummaryColumns = (color) => {
|
|
316
|
+
|
|
317
|
+
const columns = [{
|
|
318
|
+
id: 'name',
|
|
319
|
+
name: 'Name'
|
|
320
|
+
}, {
|
|
321
|
+
id: 'pct',
|
|
322
|
+
name: 'Coverage %',
|
|
323
|
+
align: 'right',
|
|
324
|
+
formatter: (v, row, column) => {
|
|
325
|
+
if (typeof v === 'number') {
|
|
326
|
+
return Util.getColorStrByStatus(Util.PSF(v, 100, 2), row.status, color);
|
|
327
|
+
}
|
|
328
|
+
return v;
|
|
329
|
+
}
|
|
330
|
+
}, {
|
|
331
|
+
id: 'covered',
|
|
332
|
+
name: 'Covered',
|
|
333
|
+
align: 'right',
|
|
334
|
+
formatter: nFormatter
|
|
335
|
+
}, {
|
|
336
|
+
id: 'uncovered',
|
|
337
|
+
name: 'Uncovered',
|
|
338
|
+
align: 'right',
|
|
339
|
+
formatter: nFormatter
|
|
340
|
+
}, {
|
|
341
|
+
id: 'total',
|
|
342
|
+
name: 'Total',
|
|
343
|
+
align: 'right',
|
|
344
|
+
formatter: nFormatter
|
|
345
|
+
}];
|
|
346
|
+
|
|
347
|
+
return columns;
|
|
348
|
+
};
|
|
349
|
+
|
|
338
350
|
const handleConsoleSummaryReport = (reportData, reportOptions, options) => {
|
|
339
351
|
|
|
340
352
|
const csOptions = {
|
|
@@ -359,35 +371,136 @@ const handleConsoleSummaryReport = (reportData, reportOptions, options) => {
|
|
|
359
371
|
};
|
|
360
372
|
});
|
|
361
373
|
|
|
374
|
+
const columns = getSummaryColumns('ansicode');
|
|
375
|
+
|
|
376
|
+
CG({
|
|
377
|
+
columns,
|
|
378
|
+
rows
|
|
379
|
+
});
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const handleMarkdownDetailsReport = async (reportData, reportOptions, options) => {
|
|
383
|
+
const mdOptions = {
|
|
384
|
+
baseUrl: '',
|
|
385
|
+
// unicode, html, or empty for no color
|
|
386
|
+
color: 'unicode',
|
|
387
|
+
skipPercent: 0,
|
|
388
|
+
metrics: [],
|
|
389
|
+
outputFile: 'coverage-details.md',
|
|
390
|
+
... reportOptions
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
const color = Util.normalizeColorType(mdOptions.color);
|
|
394
|
+
const baseUrl = mdOptions.baseUrl;
|
|
395
|
+
|
|
396
|
+
const mdPath = path.resolve(options.outputDir, mdOptions.outputFile);
|
|
397
|
+
|
|
398
|
+
const metrics = Util.getMetrics(mdOptions.metrics, reportData.type);
|
|
399
|
+
|
|
400
|
+
let files = reportData.files;
|
|
401
|
+
const skipPercent = mdOptions.skipPercent;
|
|
402
|
+
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
403
|
+
files = files.filter((file) => {
|
|
404
|
+
const { summary } = file;
|
|
405
|
+
for (const k of metrics) {
|
|
406
|
+
const percent = summary[k].pct;
|
|
407
|
+
if (typeof percent === 'number' && percent < skipPercent) {
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return false;
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const rows = [];
|
|
416
|
+
files.forEach((file) => {
|
|
417
|
+
|
|
418
|
+
// do NOT add debug file
|
|
419
|
+
if (file.debug) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const { sourcePath, summary } = file;
|
|
424
|
+
|
|
425
|
+
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
426
|
+
if (fileRow.nameStatus) {
|
|
427
|
+
const nameColor = baseUrl && color === 'tex' ? '' : color;
|
|
428
|
+
fileRow.name = Util.getColorStrByStatus(fileRow.name, fileRow.nameStatus, nameColor);
|
|
429
|
+
}
|
|
430
|
+
if (baseUrl) {
|
|
431
|
+
fileRow.name = `[${fileRow.name}](${baseUrl + sourcePath})`;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
fileRow.uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
435
|
+
rows.push(fileRow);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const summaryRow = getRowData('Summary', reportData.summary, metrics, color);
|
|
439
|
+
if (summaryRow.nameStatus) {
|
|
440
|
+
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
441
|
+
}
|
|
442
|
+
rows.push(summaryRow);
|
|
443
|
+
|
|
362
444
|
const columns = [{
|
|
363
445
|
id: 'name',
|
|
364
446
|
name: 'Name'
|
|
365
|
-
}, {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
formatter: nFormatter
|
|
375
|
-
}, {
|
|
376
|
-
id: 'uncovered',
|
|
377
|
-
name: 'Uncovered',
|
|
378
|
-
align: 'right',
|
|
379
|
-
formatter: nFormatter
|
|
380
|
-
}, {
|
|
381
|
-
id: 'total',
|
|
382
|
-
name: 'Total',
|
|
383
|
-
align: 'right',
|
|
384
|
-
formatter: nFormatter
|
|
447
|
+
}, ... metrics.map((m) => {
|
|
448
|
+
return {
|
|
449
|
+
id: m,
|
|
450
|
+
name: Util.capitalizeFirstLetter(m),
|
|
451
|
+
align: 'right'
|
|
452
|
+
};
|
|
453
|
+
}), {
|
|
454
|
+
id: 'uncoveredLines',
|
|
455
|
+
name: 'Uncovered Lines'
|
|
385
456
|
}];
|
|
386
457
|
|
|
387
|
-
|
|
458
|
+
const markdownGrid = generateMarkdownGrid({
|
|
459
|
+
options: {
|
|
460
|
+
name: reportData.name
|
|
461
|
+
},
|
|
388
462
|
columns,
|
|
389
463
|
rows
|
|
390
464
|
});
|
|
465
|
+
|
|
466
|
+
await Util.writeFile(mdPath, markdownGrid);
|
|
467
|
+
return Util.relativePath(mdPath);
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
const handleMarkdownSummaryReport = async (reportData, reportOptions, options) => {
|
|
471
|
+
const msOptions = {
|
|
472
|
+
// unicode, html, or empty for no color
|
|
473
|
+
color: 'unicode',
|
|
474
|
+
metrics: [],
|
|
475
|
+
outputFile: 'coverage-summary.md',
|
|
476
|
+
... reportOptions
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
const color = Util.normalizeColorType(msOptions.color);
|
|
480
|
+
|
|
481
|
+
const mdPath = path.resolve(options.outputDir, msOptions.outputFile);
|
|
482
|
+
|
|
483
|
+
const metrics = Util.getMetrics(msOptions.metrics, reportData.type);
|
|
484
|
+
|
|
485
|
+
const rows = metrics.map((k) => {
|
|
486
|
+
return {
|
|
487
|
+
... reportData.summary[k],
|
|
488
|
+
name: Util.capitalizeFirstLetter(k)
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
const columns = getSummaryColumns(color);
|
|
493
|
+
|
|
494
|
+
const markdownGrid = generateMarkdownGrid({
|
|
495
|
+
options: {
|
|
496
|
+
name: reportData.name
|
|
497
|
+
},
|
|
498
|
+
columns,
|
|
499
|
+
rows
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
await Util.writeFile(mdPath, markdownGrid);
|
|
503
|
+
return Util.relativePath(mdPath);
|
|
391
504
|
};
|
|
392
505
|
|
|
393
506
|
const handleRawReport = (reportData, reportOptions, options) => {
|
|
@@ -464,8 +577,11 @@ const generateCoverageReports = async (dataList, sourceCache, options) => {
|
|
|
464
577
|
|
|
465
578
|
const buildInBothReports = {
|
|
466
579
|
'codecov': handleCodecovReport,
|
|
580
|
+
'codacy': handleCodacyReport,
|
|
467
581
|
'console-details': handleConsoleDetailsReport,
|
|
468
582
|
'console-summary': handleConsoleSummaryReport,
|
|
583
|
+
'markdown-details': handleMarkdownDetailsReport,
|
|
584
|
+
'markdown-summary': handleMarkdownSummaryReport,
|
|
469
585
|
'raw': handleRawReport
|
|
470
586
|
};
|
|
471
587
|
|
|
@@ -854,9 +970,16 @@ const resolveEntrySourceMap = (entry, sourceMapCache) => {
|
|
|
854
970
|
}
|
|
855
971
|
};
|
|
856
972
|
|
|
857
|
-
const readCoverageData = (
|
|
973
|
+
const readCoverageData = async (dir, filename, entryFilter, sourceCache) => {
|
|
858
974
|
|
|
859
|
-
const
|
|
975
|
+
const content = await Util.readFile(path.resolve(dir, filename));
|
|
976
|
+
if (!content) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
const json = JSON.parse(content);
|
|
980
|
+
if (!json) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
860
983
|
|
|
861
984
|
// raw v8 json
|
|
862
985
|
let coverageData = json.result;
|
|
@@ -886,6 +1009,26 @@ const readCoverageData = (item, entryFilter, sourceCache) => {
|
|
|
886
1009
|
return coverageData;
|
|
887
1010
|
};
|
|
888
1011
|
|
|
1012
|
+
const readSourceList = async (dir, sourceList) => {
|
|
1013
|
+
const sourceCache = {};
|
|
1014
|
+
|
|
1015
|
+
for (const filename of sourceList) {
|
|
1016
|
+
const content = await Util.readFile(path.resolve(dir, filename));
|
|
1017
|
+
if (!content) {
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
const json = JSON.parse(content);
|
|
1021
|
+
if (!json) {
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
if (json.url) {
|
|
1025
|
+
sourceCache[json.url] = json;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
return sourceCache;
|
|
1030
|
+
};
|
|
1031
|
+
|
|
889
1032
|
const readFromDir = async (mcr, dir) => {
|
|
890
1033
|
|
|
891
1034
|
if (!dir || !fs.existsSync(dir)) {
|
|
@@ -894,56 +1037,34 @@ const readFromDir = async (mcr, dir) => {
|
|
|
894
1037
|
}
|
|
895
1038
|
|
|
896
1039
|
const files = fs.readdirSync(dir);
|
|
897
|
-
|
|
1040
|
+
|
|
1041
|
+
const coverageList = [];
|
|
1042
|
+
const sourceList = [];
|
|
1043
|
+
|
|
898
1044
|
files.forEach((filename) => {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
list.push({
|
|
908
|
-
type: 'source',
|
|
909
|
-
filename
|
|
910
|
-
});
|
|
1045
|
+
// read all json files
|
|
1046
|
+
if (filename.endsWith('.json')) {
|
|
1047
|
+
// could be source files generated by register hooks
|
|
1048
|
+
if (filename.startsWith('source-')) {
|
|
1049
|
+
sourceList.push(filename);
|
|
1050
|
+
} else {
|
|
1051
|
+
coverageList.push(filename);
|
|
1052
|
+
}
|
|
911
1053
|
}
|
|
912
1054
|
});
|
|
913
1055
|
|
|
914
|
-
if (!
|
|
1056
|
+
if (!coverageList.length) {
|
|
915
1057
|
Util.logInfo(`No coverage files in the dir: ${dir}`);
|
|
916
1058
|
return;
|
|
917
1059
|
}
|
|
918
1060
|
|
|
919
|
-
const
|
|
920
|
-
const sourceCache = {};
|
|
921
|
-
const coverageFiles = [];
|
|
922
|
-
|
|
923
|
-
contentList.forEach((content, i) => {
|
|
924
|
-
if (!content) {
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
const json = JSON.parse(content);
|
|
928
|
-
if (!json) {
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
const item = list[i];
|
|
932
|
-
if (item.type === 'source') {
|
|
933
|
-
if (json.url) {
|
|
934
|
-
sourceCache[json.url] = json;
|
|
935
|
-
}
|
|
936
|
-
} else {
|
|
937
|
-
item.json = json;
|
|
938
|
-
coverageFiles.push(item);
|
|
939
|
-
}
|
|
940
|
-
});
|
|
1061
|
+
const sourceCache = await readSourceList(dir, sourceList);
|
|
941
1062
|
|
|
942
1063
|
const entryFilter = mcr.getEntryFilter();
|
|
943
1064
|
|
|
944
1065
|
const results = [];
|
|
945
|
-
for (const
|
|
946
|
-
const coverageData = readCoverageData(
|
|
1066
|
+
for (const filename of coverageList) {
|
|
1067
|
+
const coverageData = await readCoverageData(dir, filename, entryFilter, sourceCache);
|
|
947
1068
|
if (coverageData) {
|
|
948
1069
|
const res = await mcr.add(coverageData);
|
|
949
1070
|
results.push(res);
|
package/lib/index.d.ts
CHANGED
|
@@ -44,12 +44,18 @@ declare namespace MCR {
|
|
|
44
44
|
|
|
45
45
|
export type ReportDescription =
|
|
46
46
|
['v8'] | ["v8", {
|
|
47
|
+
/**
|
|
48
|
+
* defaults to `index.html`
|
|
49
|
+
*/
|
|
47
50
|
outputFile?: string;
|
|
48
51
|
inline?: boolean;
|
|
49
52
|
assetsPath?: string;
|
|
50
53
|
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
51
54
|
}] |
|
|
52
55
|
['v8-json'] | ["v8-json", {
|
|
56
|
+
/**
|
|
57
|
+
* defaults to `coverage-report.json`
|
|
58
|
+
*/
|
|
53
59
|
outputFile?: string;
|
|
54
60
|
}] |
|
|
55
61
|
['clover'] | ['clover', {
|
|
@@ -105,6 +111,15 @@ declare namespace MCR {
|
|
|
105
111
|
file?: string;
|
|
106
112
|
}] |
|
|
107
113
|
['codecov'] | ["codecov", {
|
|
114
|
+
/**
|
|
115
|
+
* defaults to `codecov.json`
|
|
116
|
+
*/
|
|
117
|
+
outputFile?: string;
|
|
118
|
+
}] |
|
|
119
|
+
['codacy'] | ["codacy", {
|
|
120
|
+
/**
|
|
121
|
+
* defaults to `codacy.json`
|
|
122
|
+
*/
|
|
108
123
|
outputFile?: string;
|
|
109
124
|
}] |
|
|
110
125
|
['console-summary'] | ['console-summary', {
|
|
@@ -115,6 +130,24 @@ declare namespace MCR {
|
|
|
115
130
|
skipPercent?: number;
|
|
116
131
|
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
117
132
|
}] |
|
|
133
|
+
['markdown-summary'] | ['markdown-summary', {
|
|
134
|
+
color: 'unicode' | 'html' | 'tex' | string;
|
|
135
|
+
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
136
|
+
/**
|
|
137
|
+
* defaults to `coverage-summary.md`
|
|
138
|
+
*/
|
|
139
|
+
outputFile?: string;
|
|
140
|
+
}] |
|
|
141
|
+
['markdown-details'] | ['markdown-details', {
|
|
142
|
+
baseUrl?: string;
|
|
143
|
+
color: 'unicode' | 'html' | 'tex' | string;
|
|
144
|
+
skipPercent?: number;
|
|
145
|
+
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
146
|
+
/**
|
|
147
|
+
* defaults to `coverage-details.md`
|
|
148
|
+
*/
|
|
149
|
+
outputFile?: string;
|
|
150
|
+
}] |
|
|
118
151
|
['raw'] | ['raw', {
|
|
119
152
|
outputDir?: string;
|
|
120
153
|
}] |
|
|
@@ -190,10 +223,23 @@ declare namespace MCR {
|
|
|
190
223
|
branches?: CoverageRange[];
|
|
191
224
|
functions?: CoverageRange[];
|
|
192
225
|
ignores?: IgnoredRange[];
|
|
193
|
-
|
|
194
|
-
|
|
226
|
+
lines?: {
|
|
227
|
+
/**
|
|
228
|
+
* key: line number;
|
|
229
|
+
* number: hits (0 means uncovered);
|
|
230
|
+
* string: partial covered
|
|
231
|
+
*/
|
|
195
232
|
[key: string]: number | string;
|
|
196
233
|
};
|
|
234
|
+
extras?: {
|
|
235
|
+
/**
|
|
236
|
+
* key: line number;
|
|
237
|
+
* b: blank;
|
|
238
|
+
* c: comment;
|
|
239
|
+
* i: ignored;
|
|
240
|
+
*/
|
|
241
|
+
[key: string]: "b" | "c" | "i";
|
|
242
|
+
}
|
|
197
243
|
}
|
|
198
244
|
}
|
|
199
245
|
|
|
@@ -234,6 +280,9 @@ declare namespace MCR {
|
|
|
234
280
|
/** {string} base dir for normalizing the relative source path, defaults to cwd */
|
|
235
281
|
baseDir?: string;
|
|
236
282
|
|
|
283
|
+
/** {string} coverage data dir, alternative to method `addFromDir()`, defaults to null */
|
|
284
|
+
dataDir?: string;
|
|
285
|
+
|
|
237
286
|
/** (V8 only)
|
|
238
287
|
*
|
|
239
288
|
* {string} `minimatch` pattern for entry url;
|
|
@@ -413,6 +462,7 @@ declare namespace MCR {
|
|
|
413
462
|
functions: string;
|
|
414
463
|
lines: string;
|
|
415
464
|
uncoveredLines: string;
|
|
465
|
+
extras: string;
|
|
416
466
|
}
|
|
417
467
|
}
|
|
418
468
|
}
|
package/lib/index.js
CHANGED
|
@@ -136,11 +136,19 @@ class CoverageReport {
|
|
|
136
136
|
|
|
137
137
|
this.initOptions();
|
|
138
138
|
|
|
139
|
+
const dataDir = this.options.dataDir;
|
|
140
|
+
if (dataDir) {
|
|
141
|
+
await this.addFromDir(dataDir);
|
|
142
|
+
}
|
|
143
|
+
|
|
139
144
|
const inputData = await getInputData(this);
|
|
140
145
|
if (!inputData) {
|
|
141
146
|
return;
|
|
142
147
|
}
|
|
143
148
|
|
|
149
|
+
// GC, no OOM
|
|
150
|
+
this.fileCache.clear();
|
|
151
|
+
|
|
144
152
|
const { dataList, sourceCache } = inputData;
|
|
145
153
|
|
|
146
154
|
// empty output dir except cache dir before generate reports
|
|
@@ -161,16 +169,21 @@ class CoverageReport {
|
|
|
161
169
|
|
|
162
170
|
const coverageResults = await generateCoverageReports(dataList, sourceCache, this.options);
|
|
163
171
|
|
|
164
|
-
if (this.logging !== 'debug') {
|
|
165
|
-
Util.rmSync(this.options.cacheDir);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
172
|
const onEnd = this.options.onEnd;
|
|
169
173
|
if (typeof onEnd === 'function') {
|
|
170
174
|
await onEnd.call(this, coverageResults);
|
|
171
175
|
}
|
|
172
176
|
|
|
173
|
-
|
|
177
|
+
// remove cache dir after finished
|
|
178
|
+
if (!Util.isDebug()) {
|
|
179
|
+
Util.rmSync(this.options.cacheDir);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let reportPath = '';
|
|
183
|
+
if (coverageResults.reportPath) {
|
|
184
|
+
reportPath = EC.cyan(coverageResults.reportPath);
|
|
185
|
+
}
|
|
186
|
+
Util.logTime(`generated coverage reports: ${reportPath}`, time_start);
|
|
174
187
|
|
|
175
188
|
return coverageResults;
|
|
176
189
|
}
|
|
@@ -32,12 +32,15 @@ class IstanbulSummary extends ReportBase {
|
|
|
32
32
|
|
|
33
33
|
const fileCoverage = node.getFileCoverage();
|
|
34
34
|
const lines = fileCoverage.getLineCoverage();
|
|
35
|
+
// no extras for istanbul
|
|
36
|
+
const extras = {};
|
|
35
37
|
|
|
36
38
|
this.files.push({
|
|
37
39
|
sourcePath,
|
|
38
40
|
summary: fileSummary,
|
|
39
41
|
data: {
|
|
40
|
-
lines
|
|
42
|
+
lines,
|
|
43
|
+
extras
|
|
41
44
|
}
|
|
42
45
|
});
|
|
43
46
|
}
|