monocart-coverage-reports 2.9.2 → 2.10.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 +5 -2
- package/README.zh-Hans.md +5 -2
- package/lib/assets.js +98 -0
- package/lib/converter/converter.js +21 -6
- package/lib/converter/find-original-range.js +19 -10
- package/lib/converter/flatten-source-maps.js +186 -166
- package/lib/converter/ignore.js +86 -24
- package/lib/converter/info-function.js +7 -4
- package/lib/generate.js +88 -475
- package/lib/index.d.ts +22 -1
- package/lib/istanbul/istanbul.js +11 -8
- package/lib/packages/monocart-coverage-assets.js +4 -0
- package/lib/packages/monocart-coverage-vendor.js +22 -20
- package/lib/platform/share.js +16 -0
- package/lib/reports/codacy.js +43 -0
- package/lib/reports/codecov.js +28 -0
- package/lib/reports/console-details.js +174 -0
- package/lib/reports/console-summary.js +83 -0
- package/lib/reports/markdown-details.js +121 -0
- package/lib/reports/markdown-summary.js +45 -0
- package/lib/reports/raw.js +33 -0
- package/lib/reports/v8-json.js +22 -0
- package/lib/reports/v8.js +51 -0
- package/lib/utils/markdown.js +132 -132
- package/lib/utils/util.js +10 -126
- package/lib/v8/v8.js +14 -73
- package/package.json +116 -112
- package/lib/packages/monocart-coverage-app.js +0 -1
package/lib/generate.js
CHANGED
|
@@ -1,38 +1,78 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const CG = require('console-grid');
|
|
4
|
-
const EC = require('eight-colors');
|
|
5
3
|
const { pathToFileURL, fileURLToPath } = require('url');
|
|
6
4
|
|
|
5
|
+
const EC = require('eight-colors');
|
|
6
|
+
const { minimatch } = require('./packages/monocart-coverage-vendor.js');
|
|
7
|
+
|
|
7
8
|
const Util = require('./utils/util.js');
|
|
9
|
+
const { convertV8List } = require('./converter/converter.js');
|
|
10
|
+
const { resolveSourceMap } = require('./converter/collect-source-maps.js');
|
|
11
|
+
|
|
12
|
+
// ========================================================================================================
|
|
13
|
+
// built-in reports
|
|
14
|
+
|
|
15
|
+
// istanbul
|
|
8
16
|
const {
|
|
9
17
|
initIstanbulData, mergeIstanbulCoverage, saveIstanbulReports
|
|
10
18
|
} = require('./istanbul/istanbul.js');
|
|
11
19
|
|
|
20
|
+
// v8
|
|
12
21
|
const { mergeV8Coverage, saveV8Report } = require('./v8/v8.js');
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
const {
|
|
23
|
+
// both
|
|
24
|
+
const { codecovReport } = require('./reports/codecov.js');
|
|
25
|
+
const { codacyReport } = require('./reports/codacy.js');
|
|
16
26
|
|
|
17
|
-
const {
|
|
18
|
-
const {
|
|
19
|
-
const generateMarkdownGrid = require('./utils/markdown.js');
|
|
27
|
+
const { consoleDetailsReport } = require('./reports/console-details.js');
|
|
28
|
+
const { consoleSummaryReport } = require('./reports/console-summary.js');
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
const { markdownDetailsReport } = require('./reports/markdown-details.js');
|
|
31
|
+
const { markdownSummaryReport } = require('./reports/markdown-summary.js');
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
const generateV8ListReports = async (v8list, coverageData, fileSources, options) => {
|
|
25
|
-
let istanbulReportPath;
|
|
26
|
-
// v8 to istanbul reports
|
|
27
|
-
if (options.reportGroup.istanbul) {
|
|
28
|
-
const istanbulCoverageResults = await saveIstanbulReports(coverageData, fileSources, options);
|
|
29
|
-
istanbulReportPath = istanbulCoverageResults.reportPath;
|
|
30
|
-
}
|
|
33
|
+
const { rawReport } = require('./reports/raw.js');
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
const allBuiltInReports = {
|
|
36
|
+
// v8
|
|
37
|
+
'v8': 'v8',
|
|
38
|
+
'v8-json': 'v8',
|
|
39
|
+
|
|
40
|
+
// istanbul
|
|
41
|
+
'clover': 'istanbul',
|
|
42
|
+
'cobertura': 'istanbul',
|
|
43
|
+
'html': 'istanbul',
|
|
44
|
+
'html-spa': 'istanbul',
|
|
45
|
+
'json': 'istanbul',
|
|
46
|
+
'json-summary': 'istanbul',
|
|
47
|
+
'lcov': 'istanbul',
|
|
48
|
+
'lcovonly': 'istanbul',
|
|
49
|
+
'none': 'istanbul',
|
|
50
|
+
'teamcity': 'istanbul',
|
|
51
|
+
'text': 'istanbul',
|
|
52
|
+
'text-lcov': 'istanbul',
|
|
53
|
+
'text-summary': 'istanbul',
|
|
54
|
+
|
|
55
|
+
// both
|
|
56
|
+
'codecov': 'both',
|
|
57
|
+
'codacy': 'both',
|
|
58
|
+
'console-details': 'both',
|
|
59
|
+
'console-summary': 'both',
|
|
60
|
+
'markdown-details': 'both',
|
|
61
|
+
'markdown-summary': 'both',
|
|
62
|
+
'raw': 'both'
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const bothBuiltInReports = {
|
|
66
|
+
'codecov': codecovReport,
|
|
67
|
+
'codacy': codacyReport,
|
|
68
|
+
|
|
69
|
+
'console-details': consoleDetailsReport,
|
|
70
|
+
'console-summary': consoleSummaryReport,
|
|
71
|
+
|
|
72
|
+
'markdown-details': markdownDetailsReport,
|
|
73
|
+
'markdown-summary': markdownSummaryReport,
|
|
74
|
+
|
|
75
|
+
'raw': rawReport
|
|
36
76
|
};
|
|
37
77
|
|
|
38
78
|
// ========================================================================================================
|
|
@@ -69,469 +109,54 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
69
109
|
reportMap.lcovonly = {};
|
|
70
110
|
}
|
|
71
111
|
|
|
72
|
-
const allBuildInReports = {
|
|
73
|
-
// v8
|
|
74
|
-
'v8': 'v8',
|
|
75
|
-
'v8-json': 'v8',
|
|
76
|
-
|
|
77
|
-
// istanbul
|
|
78
|
-
'clover': 'istanbul',
|
|
79
|
-
'cobertura': 'istanbul',
|
|
80
|
-
'html': 'istanbul',
|
|
81
|
-
'html-spa': 'istanbul',
|
|
82
|
-
'json': 'istanbul',
|
|
83
|
-
'json-summary': 'istanbul',
|
|
84
|
-
'lcov': 'istanbul',
|
|
85
|
-
'lcovonly': 'istanbul',
|
|
86
|
-
'none': 'istanbul',
|
|
87
|
-
'teamcity': 'istanbul',
|
|
88
|
-
'text': 'istanbul',
|
|
89
|
-
'text-lcov': 'istanbul',
|
|
90
|
-
'text-summary': 'istanbul',
|
|
91
|
-
|
|
92
|
-
// both
|
|
93
|
-
'codecov': 'both',
|
|
94
|
-
'codacy': 'both',
|
|
95
|
-
'console-details': 'both',
|
|
96
|
-
'console-summary': 'both',
|
|
97
|
-
'markdown-details': 'both',
|
|
98
|
-
'markdown-summary': 'both',
|
|
99
|
-
'raw': 'both'
|
|
100
|
-
};
|
|
101
|
-
|
|
102
112
|
// group v8 and istanbul
|
|
103
|
-
const
|
|
113
|
+
const groupMap = new Map();
|
|
104
114
|
Object.keys(reportMap).forEach((k) => {
|
|
105
115
|
const options = reportMap[k];
|
|
106
116
|
|
|
107
|
-
let type =
|
|
117
|
+
let type = allBuiltInReports[k];
|
|
108
118
|
if (!type) {
|
|
109
119
|
// for custom reporter
|
|
110
120
|
type = options.type || 'v8';
|
|
111
121
|
}
|
|
112
122
|
|
|
113
|
-
let group =
|
|
123
|
+
let group = groupMap.get(type);
|
|
114
124
|
if (!group) {
|
|
115
|
-
group =
|
|
116
|
-
|
|
125
|
+
group = new Map();
|
|
126
|
+
groupMap.set(type, group);
|
|
117
127
|
}
|
|
118
128
|
|
|
119
|
-
group
|
|
129
|
+
group.set(k, options);
|
|
120
130
|
|
|
121
131
|
});
|
|
122
132
|
|
|
123
133
|
// requires a default istanbul report if data is istanbul
|
|
124
|
-
if (dataType === 'istanbul' && !
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
if (dataType === 'istanbul' && !groupMap.has('istanbul')) {
|
|
135
|
+
const istanbulGroup = new Map();
|
|
136
|
+
istanbulGroup.set('html', {});
|
|
137
|
+
groupMap.set('istanbul', istanbulGroup);
|
|
128
138
|
}
|
|
129
139
|
|
|
130
|
-
return
|
|
140
|
+
return groupMap;
|
|
131
141
|
};
|
|
132
142
|
|
|
133
143
|
// ========================================================================================================
|
|
134
144
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const getRowData = (rowName, summary, metrics, color) => {
|
|
143
|
-
const summaryRow = {};
|
|
144
|
-
let lowest = {
|
|
145
|
-
pct: 100,
|
|
146
|
-
status: 'high'
|
|
147
|
-
};
|
|
148
|
-
metrics.map((k) => {
|
|
149
|
-
const s = summary[k];
|
|
150
|
-
if (!s) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const percent = s.pct;
|
|
154
|
-
if (typeof percent !== 'number') {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status, color);
|
|
158
|
-
if (percent < lowest.pct) {
|
|
159
|
-
lowest = s;
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
summaryRow.nameStatus = lowest.status;
|
|
163
|
-
summaryRow.name = rowName;
|
|
164
|
-
return summaryRow;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
const getDetailsRows = (files, metrics, cdOptions, color) => {
|
|
168
|
-
|
|
169
|
-
const skipPercent = cdOptions.skipPercent;
|
|
170
|
-
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
171
|
-
files = files.filter((file) => {
|
|
172
|
-
const { summary } = file;
|
|
173
|
-
for (const k of metrics) {
|
|
174
|
-
const percent = summary[k].pct;
|
|
175
|
-
if (typeof percent === 'number' && percent < skipPercent) {
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return false;
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const flatRows = [];
|
|
184
|
-
files.forEach((file) => {
|
|
185
|
-
|
|
186
|
-
// do NOT add debug file
|
|
187
|
-
if (file.debug) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const { sourcePath, summary } = file;
|
|
192
|
-
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
193
|
-
fileRow.uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
194
|
-
flatRows.push(fileRow);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
return getGroupedRows(flatRows);
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
const handleCodecovReport = async (reportData, reportOptions, options) => {
|
|
201
|
-
const codecovOptions = {
|
|
202
|
-
outputFile: 'codecov.json',
|
|
203
|
-
... reportOptions
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const jsonPath = path.resolve(options.outputDir, codecovOptions.outputFile);
|
|
207
|
-
|
|
208
|
-
// https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
209
|
-
const coverage = {};
|
|
210
|
-
reportData.files.forEach((item) => {
|
|
211
|
-
const { sourcePath, data } = item;
|
|
212
|
-
coverage[sourcePath] = data.lines;
|
|
213
|
-
});
|
|
214
|
-
const codecovData = {
|
|
215
|
-
coverage
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
await Util.writeFile(jsonPath, JSON.stringify(codecovData));
|
|
219
|
-
return Util.relativePath(jsonPath);
|
|
220
|
-
};
|
|
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
|
-
|
|
258
|
-
const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
259
|
-
const cdOptions = {
|
|
260
|
-
maxCols: 50,
|
|
261
|
-
skipPercent: 0,
|
|
262
|
-
metrics: [],
|
|
263
|
-
... reportOptions
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
const {
|
|
267
|
-
type, name, summary, files
|
|
268
|
-
} = reportData;
|
|
269
|
-
|
|
270
|
-
if (name) {
|
|
271
|
-
Util.logInfo(EC.cyan(name));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const color = 'ansicode';
|
|
275
|
-
|
|
276
|
-
const metrics = Util.getMetrics(cdOptions.metrics, type);
|
|
277
|
-
const rows = getDetailsRows(files, metrics, cdOptions, color);
|
|
278
|
-
const summaryRow = getRowData('Summary', summary, metrics, color);
|
|
279
|
-
if (summaryRow.nameStatus) {
|
|
280
|
-
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
281
|
-
}
|
|
282
|
-
// no rows if skipped all by skipPercent
|
|
283
|
-
if (rows.length) {
|
|
284
|
-
rows.push({
|
|
285
|
-
innerBorder: true
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
rows.push(summaryRow);
|
|
289
|
-
|
|
290
|
-
const columns = [{
|
|
291
|
-
id: 'name',
|
|
292
|
-
name: 'Name'
|
|
293
|
-
}, ... metrics.map((m) => {
|
|
294
|
-
return {
|
|
295
|
-
id: m,
|
|
296
|
-
name: Util.capitalizeFirstLetter(m),
|
|
297
|
-
align: 'right'
|
|
298
|
-
};
|
|
299
|
-
}), {
|
|
300
|
-
id: 'uncoveredLines',
|
|
301
|
-
name: 'Uncovered Lines'
|
|
302
|
-
}];
|
|
303
|
-
|
|
304
|
-
return CG({
|
|
305
|
-
options: {
|
|
306
|
-
silent: cdOptions.silent,
|
|
307
|
-
nullPlaceholder: '',
|
|
308
|
-
defaultMaxWidth: cdOptions.maxCols
|
|
309
|
-
},
|
|
310
|
-
columns,
|
|
311
|
-
rows
|
|
312
|
-
});
|
|
313
|
-
};
|
|
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
|
-
|
|
350
|
-
const handleConsoleSummaryReport = (reportData, reportOptions, options) => {
|
|
351
|
-
|
|
352
|
-
const csOptions = {
|
|
353
|
-
metrics: [],
|
|
354
|
-
... reportOptions
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
const {
|
|
358
|
-
summary, name, type
|
|
359
|
-
} = reportData;
|
|
360
|
-
|
|
361
|
-
if (name) {
|
|
362
|
-
Util.logInfo(EC.cyan(name));
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const metrics = Util.getMetrics(csOptions.metrics, type);
|
|
366
|
-
|
|
367
|
-
const rows = metrics.map((k) => {
|
|
368
|
-
return {
|
|
369
|
-
... summary[k],
|
|
370
|
-
name: Util.capitalizeFirstLetter(k)
|
|
371
|
-
};
|
|
372
|
-
});
|
|
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
|
-
|
|
444
|
-
const columns = [{
|
|
445
|
-
id: 'name',
|
|
446
|
-
name: 'Name'
|
|
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'
|
|
456
|
-
}];
|
|
457
|
-
|
|
458
|
-
const markdownGrid = generateMarkdownGrid({
|
|
459
|
-
options: {
|
|
460
|
-
name: reportData.name
|
|
461
|
-
},
|
|
462
|
-
columns,
|
|
463
|
-
rows
|
|
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);
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
const handleRawReport = (reportData, reportOptions, options) => {
|
|
507
|
-
const rawOptions = {
|
|
508
|
-
outputDir: 'raw',
|
|
509
|
-
... reportOptions
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
const cacheDir = options.cacheDir;
|
|
513
|
-
const rawDir = path.resolve(options.outputDir, rawOptions.outputDir);
|
|
514
|
-
// console.log(rawDir, cacheDir);
|
|
515
|
-
if (fs.existsSync(rawDir)) {
|
|
516
|
-
Util.logError(`Failed to save raw report because the dir already exists: ${Util.relativePath(rawDir)}`);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const rawParent = path.dirname(rawDir);
|
|
521
|
-
if (!fs.existsSync(rawParent)) {
|
|
522
|
-
fs.mkdirSync(rawParent, {
|
|
523
|
-
recursive: true
|
|
524
|
-
});
|
|
145
|
+
// maybe v8 or to istanbul reports
|
|
146
|
+
const generateV8ListReports = async (v8list, coverageData, fileSources, options) => {
|
|
147
|
+
let istanbulReportPath;
|
|
148
|
+
// v8 to istanbul reports
|
|
149
|
+
if (options.reportGroup.has('istanbul')) {
|
|
150
|
+
const istanbulCoverageResults = await saveIstanbulReports(coverageData, fileSources, options);
|
|
151
|
+
istanbulReportPath = istanbulCoverageResults.reportPath;
|
|
525
152
|
}
|
|
526
153
|
|
|
527
|
-
//
|
|
528
|
-
|
|
529
|
-
|
|
154
|
+
// v8 reports and v8 coverage results
|
|
155
|
+
// could be no v8 or v8-json, but requires v8 coverage results
|
|
156
|
+
const v8CoverageResults = await saveV8Report(v8list, options, istanbulReportPath);
|
|
157
|
+
return v8CoverageResults;
|
|
530
158
|
};
|
|
531
159
|
|
|
532
|
-
|
|
533
|
-
// ========================================================================================================
|
|
534
|
-
|
|
535
160
|
const getCoverageResults = async (dataList, sourceCache, options) => {
|
|
536
161
|
// get first and check v8list or istanbul data
|
|
537
162
|
const firstData = dataList[0];
|
|
@@ -575,25 +200,13 @@ const generateCoverageReports = async (dataList, sourceCache, options) => {
|
|
|
575
200
|
// [ 'type', 'reportPath', 'name', 'watermarks', 'summary', 'files' ]
|
|
576
201
|
// console.log(Object.keys(coverageResults));
|
|
577
202
|
|
|
578
|
-
|
|
579
|
-
'
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
'console-summary': handleConsoleSummaryReport,
|
|
583
|
-
'markdown-details': handleMarkdownDetailsReport,
|
|
584
|
-
'markdown-summary': handleMarkdownSummaryReport,
|
|
585
|
-
'raw': handleRawReport
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
const bothGroup = options.reportGroup.both;
|
|
589
|
-
if (bothGroup) {
|
|
590
|
-
const bothReports = Object.keys(bothGroup);
|
|
591
|
-
for (const reportName of bothReports) {
|
|
592
|
-
const reportOptions = bothGroup[reportName];
|
|
593
|
-
const buildInHandler = buildInBothReports[reportName];
|
|
203
|
+
if (options.reportGroup.has('both')) {
|
|
204
|
+
const bothGroup = options.reportGroup.get('both');
|
|
205
|
+
for (const [reportName, reportOptions] of bothGroup) {
|
|
206
|
+
const builtInHandler = bothBuiltInReports[reportName];
|
|
594
207
|
const t1 = Date.now();
|
|
595
|
-
if (
|
|
596
|
-
await
|
|
208
|
+
if (builtInHandler) {
|
|
209
|
+
await builtInHandler(coverageResults, reportOptions, options);
|
|
597
210
|
} else {
|
|
598
211
|
await Util.runCustomReporter(reportName, coverageResults, reportOptions, options);
|
|
599
212
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -129,6 +129,9 @@ declare namespace MCR {
|
|
|
129
129
|
maxCols?: number;
|
|
130
130
|
skipPercent?: number;
|
|
131
131
|
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
132
|
+
filter?: string | {
|
|
133
|
+
[pattern: string]: boolean;
|
|
134
|
+
} | ((file: CoverageFile) => boolean);
|
|
132
135
|
}] |
|
|
133
136
|
['markdown-summary'] | ['markdown-summary', {
|
|
134
137
|
color: 'unicode' | 'html' | 'tex' | string;
|
|
@@ -141,8 +144,12 @@ declare namespace MCR {
|
|
|
141
144
|
['markdown-details'] | ['markdown-details', {
|
|
142
145
|
baseUrl?: string;
|
|
143
146
|
color: 'unicode' | 'html' | 'tex' | string;
|
|
147
|
+
maxCols?: number;
|
|
144
148
|
skipPercent?: number;
|
|
145
149
|
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
150
|
+
filter?: string | {
|
|
151
|
+
[pattern: string]: boolean;
|
|
152
|
+
} | ((file: CoverageFile) => boolean);
|
|
146
153
|
/**
|
|
147
154
|
* defaults to `coverage-details.md`
|
|
148
155
|
*/
|
|
@@ -190,14 +197,23 @@ declare namespace MCR {
|
|
|
190
197
|
start: number;
|
|
191
198
|
end: number;
|
|
192
199
|
count: number;
|
|
200
|
+
/** ignored by special comment which starts with `v8 ignore` */
|
|
193
201
|
ignored?: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* branch only, for example:
|
|
204
|
+
* there is only `if` branch but no `else` branch, then `none` will be true, it shows `else path uncovered`
|
|
205
|
+
*/
|
|
194
206
|
none?: boolean;
|
|
207
|
+
/** function only, function name */
|
|
208
|
+
name?: boolean;
|
|
195
209
|
}
|
|
196
210
|
|
|
197
211
|
export interface IgnoredRange {
|
|
198
212
|
start: number;
|
|
199
213
|
end: number;
|
|
214
|
+
/** ignore type: `next` or `range` */
|
|
200
215
|
type: string;
|
|
216
|
+
/** n lines for `next` type */
|
|
201
217
|
n?: number;
|
|
202
218
|
}
|
|
203
219
|
|
|
@@ -246,6 +262,7 @@ declare namespace MCR {
|
|
|
246
262
|
export type CoverageResults = {
|
|
247
263
|
type: "v8" | "istanbul";
|
|
248
264
|
reportPath: string;
|
|
265
|
+
version: string;
|
|
249
266
|
name: string;
|
|
250
267
|
watermarks: Watermarks;
|
|
251
268
|
summary: CoverageSummary;
|
|
@@ -315,7 +332,11 @@ declare namespace MCR {
|
|
|
315
332
|
*
|
|
316
333
|
* {object} Replace key with value.
|
|
317
334
|
* */
|
|
318
|
-
sourcePath?: ((filePath: string, info:
|
|
335
|
+
sourcePath?: ((filePath: string, info: {
|
|
336
|
+
/** the related dist file of current source file */
|
|
337
|
+
distFile?: string;
|
|
338
|
+
[key: string]: any;
|
|
339
|
+
}) => string) | {
|
|
319
340
|
[key: string]: string;
|
|
320
341
|
};
|
|
321
342
|
|