monocart-coverage-reports 2.9.3 → 2.10.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 +6 -1
- package/README.zh-Hans.md +4 -1
- package/lib/assets.js +98 -0
- package/lib/converter/converter.js +36 -12
- package/lib/converter/find-original-range.js +29 -13
- 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 +91 -476
- 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 +16 -16
- package/lib/platform/share.js +22 -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/custom.js +34 -0
- package/lib/reports/markdown-details.js +120 -0
- package/lib/reports/markdown-summary.js +44 -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 +95 -155
- package/lib/v8/v8.js +16 -74
- package/package.json +116 -112
- package/lib/packages/monocart-coverage-app.js +0 -1
package/lib/platform/share.js
CHANGED
|
@@ -26,6 +26,22 @@ const Util = {
|
|
|
26
26
|
return s.padStart(l, '0');
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
+
isNum: function(num) {
|
|
30
|
+
if (typeof num !== 'number' || isNaN(num)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const isInvalid = function(n) {
|
|
34
|
+
if (n === Number.MAX_VALUE || n === Number.MIN_VALUE || n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
if (isInvalid(num)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
},
|
|
44
|
+
|
|
29
45
|
toNum: function(num, toInt) {
|
|
30
46
|
if (typeof (num) !== 'number') {
|
|
31
47
|
num = parseFloat(num);
|
|
@@ -322,6 +338,12 @@ const Util = {
|
|
|
322
338
|
return lines;
|
|
323
339
|
},
|
|
324
340
|
|
|
341
|
+
initLineCoverage: (lineItem) => {
|
|
342
|
+
lineItem.coveredCount = 1;
|
|
343
|
+
lineItem.uncoveredEntire = null;
|
|
344
|
+
lineItem.uncoveredPieces = [];
|
|
345
|
+
},
|
|
346
|
+
|
|
325
347
|
updateLinesCoverage: (lines, count, lineMap) => {
|
|
326
348
|
lines.forEach((it) => {
|
|
327
349
|
const lineItem = lineMap.get(it.line);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const codacyReport = async (reportData, reportOptions, options) => {
|
|
5
|
+
const codacyOptions = {
|
|
6
|
+
outputFile: 'codacy.json',
|
|
7
|
+
... reportOptions
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const jsonPath = path.resolve(options.outputDir, codacyOptions.outputFile);
|
|
11
|
+
|
|
12
|
+
// https://api.codacy.com/swagger#tocscoveragereport
|
|
13
|
+
const fileReports = [];
|
|
14
|
+
reportData.files.forEach((item) => {
|
|
15
|
+
const { sourcePath, data } = item;
|
|
16
|
+
|
|
17
|
+
const coverage = {};
|
|
18
|
+
for (const [key, value] of Object.entries(data.lines)) {
|
|
19
|
+
if (typeof value === 'number') {
|
|
20
|
+
coverage[key] = value;
|
|
21
|
+
} else {
|
|
22
|
+
// partial coverage not supported?
|
|
23
|
+
coverage[key] = 0;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fileReports.push({
|
|
28
|
+
filename: sourcePath,
|
|
29
|
+
coverage
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
const codacyData = {
|
|
33
|
+
fileReports
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
await Util.writeFile(jsonPath, JSON.stringify(codacyData));
|
|
37
|
+
return Util.relativePath(jsonPath);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
codacyReport
|
|
43
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const codecovReport = async (reportData, reportOptions, options) => {
|
|
5
|
+
const codecovOptions = {
|
|
6
|
+
outputFile: 'codecov.json',
|
|
7
|
+
... reportOptions
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const jsonPath = path.resolve(options.outputDir, codecovOptions.outputFile);
|
|
11
|
+
|
|
12
|
+
// https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
13
|
+
const coverage = {};
|
|
14
|
+
reportData.files.forEach((item) => {
|
|
15
|
+
const { sourcePath, data } = item;
|
|
16
|
+
coverage[sourcePath] = data.lines;
|
|
17
|
+
});
|
|
18
|
+
const codecovData = {
|
|
19
|
+
coverage
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
await Util.writeFile(jsonPath, JSON.stringify(codecovData));
|
|
23
|
+
return Util.relativePath(jsonPath);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
codecovReport
|
|
28
|
+
};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const CG = require('console-grid');
|
|
2
|
+
const EC = require('eight-colors');
|
|
3
|
+
const { minimatch } = require('../packages/monocart-coverage-vendor.js');
|
|
4
|
+
const { getGroupedRows } = require('../utils/snapshot.js');
|
|
5
|
+
const Util = require('../utils/util.js');
|
|
6
|
+
|
|
7
|
+
const getRowData = (rowName, summary, metrics, color) => {
|
|
8
|
+
const summaryRow = {};
|
|
9
|
+
let lowest = {
|
|
10
|
+
pct: 100,
|
|
11
|
+
status: 'high'
|
|
12
|
+
};
|
|
13
|
+
metrics.map((k) => {
|
|
14
|
+
const s = summary[k];
|
|
15
|
+
if (!s) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const percent = s.pct;
|
|
19
|
+
if (typeof percent !== 'number') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status, color);
|
|
23
|
+
if (percent < lowest.pct) {
|
|
24
|
+
lowest = s;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
summaryRow.nameStatus = lowest.status;
|
|
28
|
+
summaryRow.name = rowName;
|
|
29
|
+
return summaryRow;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getDetailsRows = (files, metrics, cdOptions, color) => {
|
|
33
|
+
|
|
34
|
+
const skipPercent = cdOptions.skipPercent;
|
|
35
|
+
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
36
|
+
files = files.filter((file) => {
|
|
37
|
+
const { summary } = file;
|
|
38
|
+
for (const k of metrics) {
|
|
39
|
+
const percent = summary[k].pct;
|
|
40
|
+
if (typeof percent === 'number' && percent < skipPercent) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const flatRows = [];
|
|
49
|
+
files.forEach((file) => {
|
|
50
|
+
|
|
51
|
+
// do NOT add debug file
|
|
52
|
+
if (file.debug) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { sourcePath, summary } = file;
|
|
57
|
+
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
58
|
+
fileRow.uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
59
|
+
flatRows.push(fileRow);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return getGroupedRows(flatRows);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getFileFilter = (input) => {
|
|
66
|
+
// for function handler
|
|
67
|
+
if (typeof input === 'function') {
|
|
68
|
+
return input;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// for single minimatch pattern
|
|
72
|
+
if (input && typeof input === 'string') {
|
|
73
|
+
// string to multiple patterns "{...}"
|
|
74
|
+
// mcr npx mocha --entryFilter {'**/node_modules/**':false,'**/src/*.js':true}
|
|
75
|
+
// mcr npx mocha --entryFilter "{'**/node_modules/**': false, '**/src/*.js': true}"
|
|
76
|
+
const obj = Util.strToObj(input);
|
|
77
|
+
if (obj) {
|
|
78
|
+
input = obj;
|
|
79
|
+
} else {
|
|
80
|
+
return (file) => {
|
|
81
|
+
return minimatch(file.sourcePath, input);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// for patterns
|
|
87
|
+
if (input && typeof input === 'object') {
|
|
88
|
+
const patterns = Object.keys(input);
|
|
89
|
+
return (file) => {
|
|
90
|
+
const sourcePath = file.sourcePath;
|
|
91
|
+
for (const pattern of patterns) {
|
|
92
|
+
if (minimatch(sourcePath, pattern)) {
|
|
93
|
+
return input[pattern];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// false if not matched
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const getFilteredFiles = (filter, files) => {
|
|
103
|
+
const fileFilter = getFileFilter(filter);
|
|
104
|
+
if (fileFilter) {
|
|
105
|
+
return files.filter(fileFilter);
|
|
106
|
+
}
|
|
107
|
+
return files;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const consoleDetailsReport = (reportData, reportOptions, options) => {
|
|
111
|
+
const cdOptions = {
|
|
112
|
+
maxCols: 50,
|
|
113
|
+
skipPercent: 0,
|
|
114
|
+
metrics: [],
|
|
115
|
+
filter: null,
|
|
116
|
+
... reportOptions
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const {
|
|
120
|
+
type, name, summary
|
|
121
|
+
} = reportData;
|
|
122
|
+
|
|
123
|
+
if (name) {
|
|
124
|
+
Util.logInfo(EC.cyan(name));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const color = 'ansicode';
|
|
128
|
+
let files = reportData.files;
|
|
129
|
+
files = getFilteredFiles(cdOptions.filter, files);
|
|
130
|
+
|
|
131
|
+
const metrics = Util.getMetrics(cdOptions.metrics, type);
|
|
132
|
+
const rows = getDetailsRows(files, metrics, cdOptions, color);
|
|
133
|
+
const summaryRow = getRowData('Summary', summary, metrics, color);
|
|
134
|
+
if (summaryRow.nameStatus) {
|
|
135
|
+
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
136
|
+
}
|
|
137
|
+
// no rows if skipped all by skipPercent
|
|
138
|
+
if (rows.length) {
|
|
139
|
+
rows.push({
|
|
140
|
+
innerBorder: true
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
rows.push(summaryRow);
|
|
144
|
+
|
|
145
|
+
const columns = [{
|
|
146
|
+
id: 'name',
|
|
147
|
+
name: 'Name'
|
|
148
|
+
}, ... metrics.map((m) => {
|
|
149
|
+
return {
|
|
150
|
+
id: m,
|
|
151
|
+
name: Util.capitalizeFirstLetter(m),
|
|
152
|
+
align: 'right'
|
|
153
|
+
};
|
|
154
|
+
}), {
|
|
155
|
+
id: 'uncoveredLines',
|
|
156
|
+
name: 'Uncovered Lines'
|
|
157
|
+
}];
|
|
158
|
+
|
|
159
|
+
return CG({
|
|
160
|
+
options: {
|
|
161
|
+
silent: cdOptions.silent,
|
|
162
|
+
nullPlaceholder: '',
|
|
163
|
+
defaultMaxWidth: cdOptions.maxCols
|
|
164
|
+
},
|
|
165
|
+
columns,
|
|
166
|
+
rows
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
getRowData,
|
|
172
|
+
getFilteredFiles,
|
|
173
|
+
consoleDetailsReport
|
|
174
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const CG = require('console-grid');
|
|
2
|
+
const EC = require('eight-colors');
|
|
3
|
+
const Util = require('../utils/util.js');
|
|
4
|
+
|
|
5
|
+
const nFormatter = (v) => {
|
|
6
|
+
if (typeof v === 'number') {
|
|
7
|
+
return Util.NF(v);
|
|
8
|
+
}
|
|
9
|
+
return v;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const getSummaryColumns = (color) => {
|
|
14
|
+
|
|
15
|
+
const columns = [{
|
|
16
|
+
id: 'name',
|
|
17
|
+
name: 'Name'
|
|
18
|
+
}, {
|
|
19
|
+
id: 'pct',
|
|
20
|
+
name: 'Coverage %',
|
|
21
|
+
align: 'right',
|
|
22
|
+
formatter: (v, row, column) => {
|
|
23
|
+
if (typeof v === 'number') {
|
|
24
|
+
return Util.getColorStrByStatus(Util.PSF(v, 100, 2), row.status, color);
|
|
25
|
+
}
|
|
26
|
+
return v;
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
id: 'covered',
|
|
30
|
+
name: 'Covered',
|
|
31
|
+
align: 'right',
|
|
32
|
+
formatter: nFormatter
|
|
33
|
+
}, {
|
|
34
|
+
id: 'uncovered',
|
|
35
|
+
name: 'Uncovered',
|
|
36
|
+
align: 'right',
|
|
37
|
+
formatter: nFormatter
|
|
38
|
+
}, {
|
|
39
|
+
id: 'total',
|
|
40
|
+
name: 'Total',
|
|
41
|
+
align: 'right',
|
|
42
|
+
formatter: nFormatter
|
|
43
|
+
}];
|
|
44
|
+
|
|
45
|
+
return columns;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const consoleSummaryReport = (reportData, reportOptions, options) => {
|
|
49
|
+
|
|
50
|
+
const csOptions = {
|
|
51
|
+
metrics: [],
|
|
52
|
+
... reportOptions
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const {
|
|
56
|
+
summary, name, type
|
|
57
|
+
} = reportData;
|
|
58
|
+
|
|
59
|
+
if (name) {
|
|
60
|
+
Util.logInfo(EC.cyan(name));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const metrics = Util.getMetrics(csOptions.metrics, type);
|
|
64
|
+
|
|
65
|
+
const rows = metrics.map((k) => {
|
|
66
|
+
return {
|
|
67
|
+
... summary[k],
|
|
68
|
+
name: Util.capitalizeFirstLetter(k)
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const columns = getSummaryColumns('ansicode');
|
|
73
|
+
|
|
74
|
+
CG({
|
|
75
|
+
columns,
|
|
76
|
+
rows
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
getSummaryColumns,
|
|
82
|
+
consoleSummaryReport
|
|
83
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const { pathToFileURL } = require('url');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const customReport = async (reportName, reportData, reportOptions, globalOptions) => {
|
|
5
|
+
let CustomReporter;
|
|
6
|
+
let err;
|
|
7
|
+
try {
|
|
8
|
+
CustomReporter = await import(reportName);
|
|
9
|
+
} catch (e) {
|
|
10
|
+
err = e;
|
|
11
|
+
try {
|
|
12
|
+
CustomReporter = await import(pathToFileURL(reportName));
|
|
13
|
+
} catch (ee) {
|
|
14
|
+
err = ee;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!CustomReporter) {
|
|
19
|
+
Util.logError(err.message);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
CustomReporter = CustomReporter.default || CustomReporter;
|
|
24
|
+
|
|
25
|
+
const reporter = new CustomReporter(reportOptions, globalOptions);
|
|
26
|
+
|
|
27
|
+
const results = await reporter.generate(reportData);
|
|
28
|
+
|
|
29
|
+
return results;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
customReport
|
|
34
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const { getRowData, getFilteredFiles } = require('./console-details.js');
|
|
5
|
+
|
|
6
|
+
const cutWithMaxCols = (str, maxCols, before) => {
|
|
7
|
+
if (str && maxCols && str.length > maxCols) {
|
|
8
|
+
if (before) {
|
|
9
|
+
return `... ${str.slice(str.length - (maxCols - 4))}`;
|
|
10
|
+
}
|
|
11
|
+
return `${str.slice(0, maxCols - 4)} ...`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return str;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const markdownDetailsReport = async (reportData, reportOptions, options) => {
|
|
18
|
+
const mdOptions = {
|
|
19
|
+
baseUrl: '',
|
|
20
|
+
// unicode, html, or empty for no color
|
|
21
|
+
color: 'unicode',
|
|
22
|
+
maxCols: 50,
|
|
23
|
+
skipPercent: 0,
|
|
24
|
+
metrics: [],
|
|
25
|
+
filter: null,
|
|
26
|
+
outputFile: 'coverage-details.md',
|
|
27
|
+
... reportOptions
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const baseUrl = mdOptions.baseUrl;
|
|
31
|
+
const color = Util.normalizeColorType(mdOptions.color);
|
|
32
|
+
const maxCols = Util.normalizeMaxCols(mdOptions.maxCols, 15);
|
|
33
|
+
|
|
34
|
+
const mdPath = path.resolve(options.outputDir, mdOptions.outputFile);
|
|
35
|
+
|
|
36
|
+
const metrics = Util.getMetrics(mdOptions.metrics, reportData.type);
|
|
37
|
+
|
|
38
|
+
let files = reportData.files;
|
|
39
|
+
const skipPercent = mdOptions.skipPercent;
|
|
40
|
+
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
41
|
+
files = files.filter((file) => {
|
|
42
|
+
const { summary } = file;
|
|
43
|
+
for (const k of metrics) {
|
|
44
|
+
const percent = summary[k].pct;
|
|
45
|
+
if (typeof percent === 'number' && percent < skipPercent) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
files = getFilteredFiles(mdOptions.filter, files);
|
|
54
|
+
|
|
55
|
+
const rows = [];
|
|
56
|
+
files.forEach((file) => {
|
|
57
|
+
|
|
58
|
+
// do NOT add debug file
|
|
59
|
+
if (file.debug) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { sourcePath, summary } = file;
|
|
64
|
+
|
|
65
|
+
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
66
|
+
|
|
67
|
+
let rowName = cutWithMaxCols(fileRow.name, maxCols, true);
|
|
68
|
+
|
|
69
|
+
if (fileRow.nameStatus) {
|
|
70
|
+
const nameColor = baseUrl && color === 'tex' ? '' : color;
|
|
71
|
+
rowName = Util.getColorStrByStatus(rowName, fileRow.nameStatus, nameColor);
|
|
72
|
+
}
|
|
73
|
+
if (baseUrl) {
|
|
74
|
+
rowName = `[${rowName}](${baseUrl + sourcePath})`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fileRow.name = rowName;
|
|
78
|
+
|
|
79
|
+
const uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
80
|
+
fileRow.uncoveredLines = cutWithMaxCols(uncoveredLines, maxCols);
|
|
81
|
+
|
|
82
|
+
rows.push(fileRow);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const summaryRow = getRowData('Summary', reportData.summary, metrics, color);
|
|
86
|
+
if (summaryRow.nameStatus) {
|
|
87
|
+
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
88
|
+
}
|
|
89
|
+
rows.push(summaryRow);
|
|
90
|
+
|
|
91
|
+
const columns = [{
|
|
92
|
+
id: 'name',
|
|
93
|
+
name: 'Name'
|
|
94
|
+
}, ... metrics.map((m) => {
|
|
95
|
+
return {
|
|
96
|
+
id: m,
|
|
97
|
+
name: Util.capitalizeFirstLetter(m),
|
|
98
|
+
align: 'right'
|
|
99
|
+
};
|
|
100
|
+
}), {
|
|
101
|
+
id: 'uncoveredLines',
|
|
102
|
+
name: 'Uncovered Lines'
|
|
103
|
+
}];
|
|
104
|
+
|
|
105
|
+
const markdownGrid = Util.markdownGrid({
|
|
106
|
+
options: {
|
|
107
|
+
name: reportData.name
|
|
108
|
+
},
|
|
109
|
+
columns,
|
|
110
|
+
rows
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await Util.writeFile(mdPath, markdownGrid);
|
|
114
|
+
return Util.relativePath(mdPath);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
markdownDetailsReport
|
|
120
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const { getSummaryColumns } = require('./console-summary.js');
|
|
5
|
+
|
|
6
|
+
const markdownSummaryReport = async (reportData, reportOptions, options) => {
|
|
7
|
+
const msOptions = {
|
|
8
|
+
// unicode, html, or empty for no color
|
|
9
|
+
color: 'unicode',
|
|
10
|
+
metrics: [],
|
|
11
|
+
outputFile: 'coverage-summary.md',
|
|
12
|
+
... reportOptions
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const color = Util.normalizeColorType(msOptions.color);
|
|
16
|
+
|
|
17
|
+
const mdPath = path.resolve(options.outputDir, msOptions.outputFile);
|
|
18
|
+
|
|
19
|
+
const metrics = Util.getMetrics(msOptions.metrics, reportData.type);
|
|
20
|
+
|
|
21
|
+
const rows = metrics.map((k) => {
|
|
22
|
+
return {
|
|
23
|
+
... reportData.summary[k],
|
|
24
|
+
name: Util.capitalizeFirstLetter(k)
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const columns = getSummaryColumns(color);
|
|
29
|
+
|
|
30
|
+
const markdownGrid = Util.markdownGrid({
|
|
31
|
+
options: {
|
|
32
|
+
name: reportData.name
|
|
33
|
+
},
|
|
34
|
+
columns,
|
|
35
|
+
rows
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await Util.writeFile(mdPath, markdownGrid);
|
|
39
|
+
return Util.relativePath(mdPath);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
markdownSummaryReport
|
|
44
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const Util = require('../utils/util.js');
|
|
4
|
+
|
|
5
|
+
const rawReport = (reportData, reportOptions, options) => {
|
|
6
|
+
const rawOptions = {
|
|
7
|
+
outputDir: 'raw',
|
|
8
|
+
... reportOptions
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const cacheDir = options.cacheDir;
|
|
12
|
+
const rawDir = path.resolve(options.outputDir, rawOptions.outputDir);
|
|
13
|
+
// console.log(rawDir, cacheDir);
|
|
14
|
+
if (fs.existsSync(rawDir)) {
|
|
15
|
+
Util.logError(`Failed to save raw report because the dir already exists: ${Util.relativePath(rawDir)}`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const rawParent = path.dirname(rawDir);
|
|
20
|
+
if (!fs.existsSync(rawParent)) {
|
|
21
|
+
fs.mkdirSync(rawParent, {
|
|
22
|
+
recursive: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// just rename the cache folder name
|
|
27
|
+
fs.renameSync(cacheDir, rawDir);
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
rawReport
|
|
33
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
|
|
4
|
+
const v8JsonReport = async (reportData, reportOptions, options) => {
|
|
5
|
+
const v8JsonOptions = {
|
|
6
|
+
outputFile: 'coverage-report.json',
|
|
7
|
+
... reportOptions
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// console.log(mergedOptions);
|
|
11
|
+
const jsonPath = path.resolve(options.outputDir, v8JsonOptions.outputFile);
|
|
12
|
+
const reportPath = Util.relativePath(jsonPath);
|
|
13
|
+
|
|
14
|
+
reportData.reportPath = reportPath;
|
|
15
|
+
|
|
16
|
+
await Util.writeFile(jsonPath, JSON.stringify(reportData));
|
|
17
|
+
return reportPath;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
v8JsonReport
|
|
22
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Assets = require('../assets.js');
|
|
3
|
+
|
|
4
|
+
const v8Report = async (reportData, reportOptions, options) => {
|
|
5
|
+
|
|
6
|
+
// V8 only options, merged with root options
|
|
7
|
+
const v8HtmlOptions = {
|
|
8
|
+
outputFile: options.outputFile,
|
|
9
|
+
inline: options.inline,
|
|
10
|
+
assetsPath: options.assetsPath,
|
|
11
|
+
metrics: options.metrics,
|
|
12
|
+
... reportOptions
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// add metrics to data for UI
|
|
16
|
+
reportData.metrics = v8HtmlOptions.metrics;
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
outputFile, inline, assetsPath
|
|
20
|
+
} = v8HtmlOptions;
|
|
21
|
+
|
|
22
|
+
// resolve full report path
|
|
23
|
+
const reportPath = path.resolve(options.outputDir, outputFile);
|
|
24
|
+
const outputDir = path.dirname(reportPath);
|
|
25
|
+
const htmlFile = path.basename(reportPath);
|
|
26
|
+
|
|
27
|
+
const jsFiles = ['monocart-coverage-app'];
|
|
28
|
+
// console.log(jsFiles);
|
|
29
|
+
|
|
30
|
+
const htmlOptions = {
|
|
31
|
+
reportData,
|
|
32
|
+
jsFiles,
|
|
33
|
+
inline,
|
|
34
|
+
assetsPath,
|
|
35
|
+
outputDir,
|
|
36
|
+
htmlFile,
|
|
37
|
+
|
|
38
|
+
saveReportPath: 'reportPath',
|
|
39
|
+
|
|
40
|
+
reportDataFile: 'coverage-data.js'
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// compress json data for html
|
|
44
|
+
const htmlPath = await Assets.saveHtmlReport(htmlOptions);
|
|
45
|
+
|
|
46
|
+
return htmlPath;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
v8Report
|
|
51
|
+
};
|