monocart-coverage-reports 2.8.7 → 2.9.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 +15 -9
- package/README.zh-Hans.md +13 -7
- package/lib/cli.js +2 -4
- package/lib/converter/ast.js +3 -3
- package/lib/converter/converter.js +16 -4
- package/lib/converter/find-original-range.js +2 -2
- package/lib/default/options.js +3 -0
- package/lib/generate.js +173 -95
- package/lib/index.d.ts +49 -2
- package/lib/index.js +5 -0
- package/lib/istanbul/istanbul-summary.js +4 -1
- package/lib/packages/monocart-coverage-app.js +1 -1
- package/lib/packages/monocart-coverage-vendor.js +23 -37
- 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 +171 -12
- package/lib/v8/v8.js +3 -1
- package/package.json +111 -104
- package/lib/packages/monocart-coverage-cli.js +0 -43
package/README.md
CHANGED
|
@@ -139,22 +139,27 @@ For more information, see [Command Line](#command-line)
|
|
|
139
139
|
|
|
140
140
|
> Other build-in reports (both V8 and Istanbul data):
|
|
141
141
|
|
|
142
|
-
- `codecov`
|
|
143
|
-
- coverage data for [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format), see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports)
|
|
142
|
+
- `codecov` Save coverage data to a json file with [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format) format (defaults to `codecov.json`), see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports).
|
|
144
143
|
|
|
145
|
-
- `codacy`
|
|
146
|
-
- coverage data for [Codacy](https://api.codacy.com/swagger#tocscoveragereport) API
|
|
144
|
+
- `codacy` Save coverage data to a json file with [Codacy API](https://api.codacy.com/swagger#tocscoveragereport) format (defaults to `codacy.json`).
|
|
147
145
|
|
|
148
|
-
- `console-summary` shows coverage summary in the console
|
|
146
|
+
- `console-summary` shows coverage summary in the console.
|
|
149
147
|
|
|
150
148
|

|
|
151
149
|
|
|
152
|
-
- `console-details` Show
|
|
150
|
+
- `console-details` Show coverage details in the console. Like `text`, but for V8. For Github actions, we can enforce color with env: `FORCE_COLOR: true`.
|
|
153
151
|
|
|
154
152
|

|
|
155
153
|
|
|
156
|
-
- `
|
|
157
|
-
|
|
154
|
+
- `markdown-summary` Save coverage summary to a markdown file (defaults to `coverage-summary.md`). For Github actions, we can show the markdown content to [a job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary)
|
|
155
|
+
```sh
|
|
156
|
+
cat path-to/coverage-summary.md >> $GITHUB_STEP_SUMMARY
|
|
157
|
+
```
|
|
158
|
+

|
|
159
|
+
|
|
160
|
+
- `markdown-details` Save coverage details to a markdown file (defaults to `coverage-details.md`).
|
|
161
|
+
|
|
162
|
+
- `raw` only keep all original data, which can be used for other reports input with `inputDir`. see [Merge Coverage Reports](#merge-coverage-reports)
|
|
158
163
|
|
|
159
164
|
- Custom Reporter
|
|
160
165
|
```js
|
|
@@ -1016,8 +1021,9 @@ const coverageOptions = {
|
|
|
1016
1021
|
- Github actions:
|
|
1017
1022
|
```yml
|
|
1018
1023
|
- name: Codecov
|
|
1019
|
-
uses: codecov/codecov-action@
|
|
1024
|
+
uses: codecov/codecov-action@v4
|
|
1020
1025
|
with:
|
|
1026
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
1021
1027
|
files: ./coverage-reports/codecov.json
|
|
1022
1028
|
```
|
|
1023
1029
|
|
package/README.zh-Hans.md
CHANGED
|
@@ -139,11 +139,9 @@ mcr node my-app.js -r v8,console-details
|
|
|
139
139
|
|
|
140
140
|
> 其他内置报告 (V8和Istanbul格式数据都支持):
|
|
141
141
|
|
|
142
|
-
- `codecov`
|
|
143
|
-
- 专属支持[Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format)的报告, see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports)
|
|
142
|
+
- `codecov` 保存覆盖率数据到 [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format) 专属的json文件 (默认是`codecov.json`), 见[例子](https://app.codecov.io/github/cenfun/monocart-coverage-reports)
|
|
144
143
|
|
|
145
|
-
- `codacy`
|
|
146
|
-
- 专属支持[Codacy](https://api.codacy.com/swagger#tocscoveragereport) API的报告
|
|
144
|
+
- `codacy` 保存覆盖率数据到 [Codacy](https://api.codacy.com/swagger#tocscoveragereport) 专属的json文件 (默认是`codacy.json`)
|
|
147
145
|
|
|
148
146
|
- `console-summary` 在控制台显示覆盖率概要
|
|
149
147
|
|
|
@@ -153,8 +151,15 @@ mcr node my-app.js -r v8,console-details
|
|
|
153
151
|
|
|
154
152
|

|
|
155
153
|
|
|
156
|
-
- `
|
|
157
|
-
|
|
154
|
+
- `markdown-summary` 保存概要信息到markdown文件 (默认是`coverage-summary.md`)。 如果是Github actions, 可以把markdown的内容添加到[a job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary)
|
|
155
|
+
```sh
|
|
156
|
+
cat path-to/coverage-summary.md >> $GITHUB_STEP_SUMMARY
|
|
157
|
+
```
|
|
158
|
+

|
|
159
|
+
|
|
160
|
+
- `markdown-details` 保存覆盖率详情到markdown文件 (默认是 `coverage-details.md`)
|
|
161
|
+
|
|
162
|
+
- `raw` 只是保存原始覆盖率数据, 用于使用`inputDir`参数来导入多个原始数据进行合并报告。参见 [合并覆盖率报告](#merge-coverage-reports)
|
|
158
163
|
|
|
159
164
|
- 自定义报告
|
|
160
165
|
```js
|
|
@@ -1020,8 +1025,9 @@ const coverageOptions = {
|
|
|
1020
1025
|
- Github actions example:
|
|
1021
1026
|
```yml
|
|
1022
1027
|
- name: Codecov
|
|
1023
|
-
uses: codecov/codecov-action@
|
|
1028
|
+
uses: codecov/codecov-action@v4
|
|
1024
1029
|
with:
|
|
1030
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
1025
1031
|
files: ./coverage-reports/codecov.json
|
|
1026
1032
|
```
|
|
1027
1033
|
|
package/lib/cli.js
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const EC = require('eight-colors');
|
|
5
5
|
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
} = require('./packages/monocart-coverage-cli.js');
|
|
6
|
+
const { program } = require('commander');
|
|
7
|
+
const { foregroundChild } = require('foreground-child');
|
|
10
8
|
|
|
11
9
|
const MCR = require('./index.js');
|
|
12
10
|
const Util = require('./utils/util.js');
|
package/lib/converter/ast.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
} = require('../packages/monocart-coverage-vendor.js');
|
|
1
|
+
const acorn = require('acorn');
|
|
2
|
+
const acornLoose = require('acorn-loose');
|
|
3
|
+
const { parseCss } = require('../packages/monocart-coverage-vendor.js');
|
|
4
4
|
const Util = require('../utils/util.js');
|
|
5
5
|
|
|
6
6
|
const { collectAstInfo } = require('./ast-visitor.js');
|
|
@@ -17,7 +17,9 @@ const {
|
|
|
17
17
|
sortRanges, dedupeCountRanges, mergeRangesWith
|
|
18
18
|
} = require('../utils/dedupe.js');
|
|
19
19
|
const { getSourceType, initSourceMapSourcesPath } = require('../utils/source-path.js');
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
const { decode } = require('@jridgewell/sourcemap-codec');
|
|
22
|
+
const { minimatch } = require('minimatch');
|
|
21
23
|
|
|
22
24
|
const InfoBranch = require('./info-branch.js');
|
|
23
25
|
const InfoFunction = require('./info-function.js');
|
|
@@ -115,24 +117,30 @@ const handleLinesCoverage = (bytes, locator, ignoredRanges) => {
|
|
|
115
117
|
// init lines
|
|
116
118
|
let blankCount = 0;
|
|
117
119
|
let commentCount = 0;
|
|
120
|
+
const dataExtras = {};
|
|
118
121
|
// line 1 based
|
|
119
122
|
const lineMap = new Map();
|
|
120
123
|
locator.lines.forEach((lineItem) => {
|
|
124
|
+
// line 1-base
|
|
125
|
+
const line = lineItem.line + 1;
|
|
126
|
+
|
|
121
127
|
// exclude blank and comment
|
|
122
128
|
if (lineItem.blank) {
|
|
123
129
|
blankCount += 1;
|
|
130
|
+
dataExtras[line] = 'b';
|
|
124
131
|
return;
|
|
125
132
|
}
|
|
126
133
|
if (lineItem.comment) {
|
|
127
134
|
commentCount += 1;
|
|
135
|
+
dataExtras[line] = 'c';
|
|
128
136
|
return;
|
|
129
137
|
}
|
|
130
138
|
const ignored = Util.findInRanges(lineItem.start, lineItem.end, ignoredRanges);
|
|
131
139
|
if (ignored) {
|
|
140
|
+
dataExtras[line] = 'i';
|
|
132
141
|
return;
|
|
133
142
|
}
|
|
134
|
-
|
|
135
|
-
const line = lineItem.line + 1;
|
|
143
|
+
|
|
136
144
|
lineItem.coveredCount = 1;
|
|
137
145
|
lineItem.uncoveredEntire = null;
|
|
138
146
|
lineItem.uncoveredPieces = [];
|
|
@@ -164,6 +172,7 @@ const handleLinesCoverage = (bytes, locator, ignoredRanges) => {
|
|
|
164
172
|
|
|
165
173
|
return {
|
|
166
174
|
dataLines,
|
|
175
|
+
dataExtras,
|
|
167
176
|
summaryLines
|
|
168
177
|
};
|
|
169
178
|
};
|
|
@@ -262,9 +271,12 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
262
271
|
// ==========================================
|
|
263
272
|
// lines
|
|
264
273
|
// after bytes with ignored, before calculateV8Lines
|
|
265
|
-
const {
|
|
274
|
+
const {
|
|
275
|
+
dataLines, dataExtras, summaryLines
|
|
276
|
+
} = handleLinesCoverage(data.bytes, locator, ignoredRanges);
|
|
266
277
|
|
|
267
278
|
data.lines = dataLines;
|
|
279
|
+
data.extras = dataExtras;
|
|
268
280
|
|
|
269
281
|
// console.log('statements', state.sourcePath, statements.length);
|
|
270
282
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const diffSequence = require('diff-sequences').default;
|
|
2
2
|
const Util = require('../utils/util.js');
|
|
3
3
|
const EC = Util.EC;
|
|
4
4
|
|
|
@@ -79,7 +79,7 @@ const alignText = (gt, ot, info) => {
|
|
|
79
79
|
// console.log(ol);
|
|
80
80
|
|
|
81
81
|
const commonItems = [];
|
|
82
|
-
|
|
82
|
+
diffSequence(gl.length, ol.length, (gi, oi) => {
|
|
83
83
|
return gl[gi].value === ol[oi].value;
|
|
84
84
|
}, (len, gi, oi) => {
|
|
85
85
|
commonItems.push([gi, oi, len]);
|
package/lib/default/options.js
CHANGED
|
@@ -27,6 +27,9 @@ module.exports = {
|
|
|
27
27
|
// {string} base dir for normalizing the relative source path, defaults to cwd
|
|
28
28
|
baseDir: null,
|
|
29
29
|
|
|
30
|
+
// {string} coverage data dir, alternative to method `addFromDir()`, defaults to null
|
|
31
|
+
dataDir: null,
|
|
32
|
+
|
|
30
33
|
// (V8 only) {function} A filter function to execute for each element in the V8 list.
|
|
31
34
|
// entryFilter: (entry) => {
|
|
32
35
|
// if (entry.url.indexOf('googleapis.com') !== -1) {
|
package/lib/generate.js
CHANGED
|
@@ -14,8 +14,9 @@ const { mergeV8Coverage, saveV8Report } = require('./v8/v8.js');
|
|
|
14
14
|
const { convertV8List } = require('./converter/converter.js');
|
|
15
15
|
const { resolveSourceMap } = require('./converter/collect-source-maps.js');
|
|
16
16
|
|
|
17
|
-
const { minimatch } = require('
|
|
17
|
+
const { minimatch } = require('minimatch');
|
|
18
18
|
const { getGroupedRows } = require('./utils/snapshot.js');
|
|
19
|
+
const generateMarkdownGrid = require('./utils/markdown.js');
|
|
19
20
|
|
|
20
21
|
// ========================================================================================================
|
|
21
22
|
|
|
@@ -93,6 +94,8 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
93
94
|
'codacy': 'both',
|
|
94
95
|
'console-details': 'both',
|
|
95
96
|
'console-summary': 'both',
|
|
97
|
+
'markdown-details': 'both',
|
|
98
|
+
'markdown-summary': 'both',
|
|
96
99
|
'raw': 'both'
|
|
97
100
|
};
|
|
98
101
|
|
|
@@ -129,13 +132,6 @@ const getReportGroup = (reports, lcov, dataType) => {
|
|
|
129
132
|
|
|
130
133
|
// ========================================================================================================
|
|
131
134
|
|
|
132
|
-
const pFormatter = (v, row, column) => {
|
|
133
|
-
if (typeof v === 'number') {
|
|
134
|
-
return Util.getColorStrByStatus(Util.PSF(v, 100, 2), row.status);
|
|
135
|
-
}
|
|
136
|
-
return v;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
135
|
const nFormatter = (v) => {
|
|
140
136
|
if (typeof v === 'number') {
|
|
141
137
|
return Util.NF(v);
|
|
@@ -143,7 +139,7 @@ const nFormatter = (v) => {
|
|
|
143
139
|
return v;
|
|
144
140
|
};
|
|
145
141
|
|
|
146
|
-
const getRowData = (rowName, summary, metrics) => {
|
|
142
|
+
const getRowData = (rowName, summary, metrics, color) => {
|
|
147
143
|
const summaryRow = {};
|
|
148
144
|
let lowest = {
|
|
149
145
|
pct: 100,
|
|
@@ -158,7 +154,7 @@ const getRowData = (rowName, summary, metrics) => {
|
|
|
158
154
|
if (typeof percent !== 'number') {
|
|
159
155
|
return;
|
|
160
156
|
}
|
|
161
|
-
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status);
|
|
157
|
+
summaryRow[k] = Util.getColorStrByStatus(Util.PSF(percent, 100, 2), s.status, color);
|
|
162
158
|
if (percent < lowest.pct) {
|
|
163
159
|
lowest = s;
|
|
164
160
|
}
|
|
@@ -168,65 +164,7 @@ const getRowData = (rowName, summary, metrics) => {
|
|
|
168
164
|
return summaryRow;
|
|
169
165
|
};
|
|
170
166
|
|
|
171
|
-
const
|
|
172
|
-
const lines = [];
|
|
173
|
-
|
|
174
|
-
const dataLines = file.data.lines;
|
|
175
|
-
|
|
176
|
-
let startLine;
|
|
177
|
-
let endLine;
|
|
178
|
-
|
|
179
|
-
const addLines = () => {
|
|
180
|
-
if (!startLine) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
if (endLine) {
|
|
184
|
-
// range
|
|
185
|
-
const link = startLine.color === 'yellow' && endLine.color === 'yellow' ? EC.yellow('-') : EC.red('-');
|
|
186
|
-
lines.push(EC[startLine.color](startLine.line) + link + EC[endLine.color](endLine.line));
|
|
187
|
-
startLine = null;
|
|
188
|
-
endLine = null;
|
|
189
|
-
} else {
|
|
190
|
-
// only start
|
|
191
|
-
lines.push(EC[startLine.color](startLine.line));
|
|
192
|
-
startLine = null;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const setLines = (line, color) => {
|
|
197
|
-
if (startLine) {
|
|
198
|
-
endLine = {
|
|
199
|
-
line,
|
|
200
|
-
color
|
|
201
|
-
};
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
startLine = {
|
|
205
|
-
line,
|
|
206
|
-
color
|
|
207
|
-
};
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
Object.keys(dataLines).forEach((line) => {
|
|
211
|
-
const count = dataLines[line];
|
|
212
|
-
if (count === 0) {
|
|
213
|
-
setLines(line, 'red');
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
// 0 < count < 1
|
|
217
|
-
if (typeof count === 'string') {
|
|
218
|
-
setLines(line, 'yellow');
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
// count >= 1
|
|
222
|
-
addLines();
|
|
223
|
-
});
|
|
224
|
-
addLines();
|
|
225
|
-
|
|
226
|
-
return lines.join(',');
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
const getDetailsRows = (files, metrics, cdOptions) => {
|
|
167
|
+
const getDetailsRows = (files, metrics, cdOptions, color) => {
|
|
230
168
|
|
|
231
169
|
const skipPercent = cdOptions.skipPercent;
|
|
232
170
|
if (typeof skipPercent === 'number' && skipPercent > 0) {
|
|
@@ -251,8 +189,8 @@ const getDetailsRows = (files, metrics, cdOptions) => {
|
|
|
251
189
|
}
|
|
252
190
|
|
|
253
191
|
const { sourcePath, summary } = file;
|
|
254
|
-
const fileRow = getRowData(sourcePath, summary, metrics);
|
|
255
|
-
fileRow.uncoveredLines = getUncoveredLines(file);
|
|
192
|
+
const fileRow = getRowData(sourcePath, summary, metrics, color);
|
|
193
|
+
fileRow.uncoveredLines = Util.getUncoveredLines(file.data.lines, color);
|
|
256
194
|
flatRows.push(fileRow);
|
|
257
195
|
});
|
|
258
196
|
|
|
@@ -333,11 +271,13 @@ const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
|
333
271
|
Util.logInfo(EC.cyan(name));
|
|
334
272
|
}
|
|
335
273
|
|
|
274
|
+
const color = 'ansicode';
|
|
275
|
+
|
|
336
276
|
const metrics = Util.getMetrics(cdOptions.metrics, type);
|
|
337
|
-
const rows = getDetailsRows(files, metrics, cdOptions);
|
|
338
|
-
const summaryRow = getRowData('Summary', summary, metrics);
|
|
277
|
+
const rows = getDetailsRows(files, metrics, cdOptions, color);
|
|
278
|
+
const summaryRow = getRowData('Summary', summary, metrics, color);
|
|
339
279
|
if (summaryRow.nameStatus) {
|
|
340
|
-
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus);
|
|
280
|
+
summaryRow.name = Util.getColorStrByStatus(summaryRow.name, summaryRow.nameStatus, color);
|
|
341
281
|
}
|
|
342
282
|
// no rows if skipped all by skipPercent
|
|
343
283
|
if (rows.length) {
|
|
@@ -372,6 +312,41 @@ const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
|
372
312
|
});
|
|
373
313
|
};
|
|
374
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
|
+
|
|
375
350
|
const handleConsoleSummaryReport = (reportData, reportOptions, options) => {
|
|
376
351
|
|
|
377
352
|
const csOptions = {
|
|
@@ -396,35 +371,136 @@ const handleConsoleSummaryReport = (reportData, reportOptions, options) => {
|
|
|
396
371
|
};
|
|
397
372
|
});
|
|
398
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
|
+
|
|
399
444
|
const columns = [{
|
|
400
445
|
id: 'name',
|
|
401
446
|
name: 'Name'
|
|
402
|
-
}, {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
formatter: nFormatter
|
|
412
|
-
}, {
|
|
413
|
-
id: 'uncovered',
|
|
414
|
-
name: 'Uncovered',
|
|
415
|
-
align: 'right',
|
|
416
|
-
formatter: nFormatter
|
|
417
|
-
}, {
|
|
418
|
-
id: 'total',
|
|
419
|
-
name: 'Total',
|
|
420
|
-
align: 'right',
|
|
421
|
-
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'
|
|
422
456
|
}];
|
|
423
457
|
|
|
424
|
-
|
|
458
|
+
const markdownGrid = generateMarkdownGrid({
|
|
459
|
+
options: {
|
|
460
|
+
name: reportData.name
|
|
461
|
+
},
|
|
425
462
|
columns,
|
|
426
463
|
rows
|
|
427
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);
|
|
428
504
|
};
|
|
429
505
|
|
|
430
506
|
const handleRawReport = (reportData, reportOptions, options) => {
|
|
@@ -504,6 +580,8 @@ const generateCoverageReports = async (dataList, sourceCache, options) => {
|
|
|
504
580
|
'codacy': handleCodacyReport,
|
|
505
581
|
'console-details': handleConsoleDetailsReport,
|
|
506
582
|
'console-summary': handleConsoleSummaryReport,
|
|
583
|
+
'markdown-details': handleMarkdownDetailsReport,
|
|
584
|
+
'markdown-summary': handleMarkdownSummaryReport,
|
|
507
585
|
'raw': handleRawReport
|
|
508
586
|
};
|
|
509
587
|
|
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,9 +111,15 @@ declare namespace MCR {
|
|
|
105
111
|
file?: string;
|
|
106
112
|
}] |
|
|
107
113
|
['codecov'] | ["codecov", {
|
|
114
|
+
/**
|
|
115
|
+
* defaults to `codecov.json`
|
|
116
|
+
*/
|
|
108
117
|
outputFile?: string;
|
|
109
118
|
}] |
|
|
110
119
|
['codacy'] | ["codacy", {
|
|
120
|
+
/**
|
|
121
|
+
* defaults to `codacy.json`
|
|
122
|
+
*/
|
|
111
123
|
outputFile?: string;
|
|
112
124
|
}] |
|
|
113
125
|
['console-summary'] | ['console-summary', {
|
|
@@ -118,6 +130,24 @@ declare namespace MCR {
|
|
|
118
130
|
skipPercent?: number;
|
|
119
131
|
metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">;
|
|
120
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
|
+
}] |
|
|
121
151
|
['raw'] | ['raw', {
|
|
122
152
|
outputDir?: string;
|
|
123
153
|
}] |
|
|
@@ -193,10 +223,23 @@ declare namespace MCR {
|
|
|
193
223
|
branches?: CoverageRange[];
|
|
194
224
|
functions?: CoverageRange[];
|
|
195
225
|
ignores?: IgnoredRange[];
|
|
196
|
-
|
|
197
|
-
|
|
226
|
+
lines?: {
|
|
227
|
+
/**
|
|
228
|
+
* key: line number;
|
|
229
|
+
* number: hits (0 means uncovered);
|
|
230
|
+
* string: partial covered
|
|
231
|
+
*/
|
|
198
232
|
[key: string]: number | string;
|
|
199
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
|
+
}
|
|
200
243
|
}
|
|
201
244
|
}
|
|
202
245
|
|
|
@@ -237,6 +280,9 @@ declare namespace MCR {
|
|
|
237
280
|
/** {string} base dir for normalizing the relative source path, defaults to cwd */
|
|
238
281
|
baseDir?: string;
|
|
239
282
|
|
|
283
|
+
/** {string} coverage data dir, alternative to method `addFromDir()`, defaults to null */
|
|
284
|
+
dataDir?: string;
|
|
285
|
+
|
|
240
286
|
/** (V8 only)
|
|
241
287
|
*
|
|
242
288
|
* {string} `minimatch` pattern for entry url;
|
|
@@ -416,6 +462,7 @@ declare namespace MCR {
|
|
|
416
462
|
functions: string;
|
|
417
463
|
lines: string;
|
|
418
464
|
uncoveredLines: string;
|
|
465
|
+
extras: string;
|
|
419
466
|
}
|
|
420
467
|
}
|
|
421
468
|
}
|
package/lib/index.js
CHANGED