escover 6.2.2 → 6.2.4
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/ChangeLog +10 -0
- package/lib/cli/cli.js +2 -2
- package/lib/formatters/responsive.js +124 -118
- package/package.json +1 -1
package/ChangeLog
CHANGED
package/lib/cli/cli.js
CHANGED
|
@@ -56,7 +56,7 @@ export const cli = ({argv, exit, readCoverage}) => {
|
|
|
56
56
|
const cmd = argv.slice(2);
|
|
57
57
|
|
|
58
58
|
if (cmd.length)
|
|
59
|
-
execute(`"${cmd.join('" "')}"
|
|
59
|
+
execute(`"${cmd.join('" "')}"`);
|
|
60
60
|
|
|
61
61
|
const coverage = readCoverage();
|
|
62
62
|
|
|
@@ -76,7 +76,7 @@ export const cli = ({argv, exit, readCoverage}) => {
|
|
|
76
76
|
|
|
77
77
|
export const isSuccess = (error) => !error || error?.status === Number(process.env.ESCOVER_SUCCESS_EXIT_CODE);
|
|
78
78
|
|
|
79
|
-
function execute(cmd, exit) {
|
|
79
|
+
function execute(cmd, exit = noop) {
|
|
80
80
|
const [error] = tryCatch(execSync, cmd, {
|
|
81
81
|
stdio: [0, 1, 2],
|
|
82
82
|
env: {
|
|
@@ -13,34 +13,44 @@ const makeRed = chalk.hex('#f44336');
|
|
|
13
13
|
|
|
14
14
|
export default (coverageFile, {skipFull = false} = {}) => {
|
|
15
15
|
const files = parseCoverageFile(coverageFile, skipFull);
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
if (skipFull && !files.length)
|
|
18
18
|
return '💪 coverage 100% Good Job!\n';
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
const totalWidth = process.stdout.columns || 80;
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
let showPercent = false;
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
if (totalWidth >= 70)
|
|
25
25
|
showPercent = true;
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
const tableData = buildGroupedTable(files, showPercent);
|
|
28
|
+
|
|
29
|
+
const options = createTableOptions({
|
|
30
|
+
totalWidth,
|
|
31
|
+
showPercent,
|
|
32
|
+
tableData,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return table(tableData, options);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function createTableOptions({totalWidth, showPercent, tableData}) {
|
|
27
39
|
let percentColWidth = 0;
|
|
28
|
-
|
|
40
|
+
|
|
29
41
|
if (showPercent)
|
|
30
42
|
percentColWidth = 8;
|
|
31
|
-
|
|
43
|
+
|
|
32
44
|
const fileColWidth = Math.floor(totalWidth * 0.45);
|
|
33
45
|
const linesColWidth = totalWidth - fileColWidth - percentColWidth - 6;
|
|
34
|
-
|
|
35
|
-
const tableData = buildGroupedTable(files, showPercent);
|
|
36
|
-
|
|
46
|
+
|
|
37
47
|
const columns = [{
|
|
38
48
|
paddingLeft: 1,
|
|
39
49
|
paddingRight: 1,
|
|
40
50
|
width: fileColWidth,
|
|
41
51
|
wrapWord: false,
|
|
42
52
|
}];
|
|
43
|
-
|
|
53
|
+
|
|
44
54
|
if (showPercent)
|
|
45
55
|
columns.push({
|
|
46
56
|
alignment: 'center',
|
|
@@ -48,26 +58,26 @@ export default (coverageFile, {skipFull = false} = {}) => {
|
|
|
48
58
|
paddingRight: 0,
|
|
49
59
|
width: percentColWidth,
|
|
50
60
|
});
|
|
51
|
-
|
|
61
|
+
|
|
52
62
|
columns.push({
|
|
53
63
|
paddingLeft: 1,
|
|
54
64
|
paddingRight: 0,
|
|
55
65
|
width: linesColWidth,
|
|
56
66
|
});
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
|
|
68
|
+
return {
|
|
59
69
|
drawHorizontalLine: (raw) => {
|
|
60
70
|
if (!raw)
|
|
61
71
|
return true;
|
|
62
|
-
|
|
72
|
+
|
|
63
73
|
if (raw === 1)
|
|
64
74
|
return true;
|
|
65
|
-
|
|
75
|
+
|
|
66
76
|
return raw === tableData.length;
|
|
67
77
|
},
|
|
68
|
-
|
|
78
|
+
|
|
69
79
|
columns,
|
|
70
|
-
|
|
80
|
+
|
|
71
81
|
border: {
|
|
72
82
|
...getBorderCharacters('void'),
|
|
73
83
|
topBody: '-',
|
|
@@ -79,46 +89,72 @@ export default (coverageFile, {skipFull = false} = {}) => {
|
|
|
79
89
|
bodyJoin: '|',
|
|
80
90
|
},
|
|
81
91
|
};
|
|
82
|
-
|
|
83
|
-
return table(tableData, options);
|
|
84
92
|
};
|
|
85
93
|
|
|
86
|
-
function groupByFolder(files) {
|
|
94
|
+
export function groupByFolder(files) {
|
|
87
95
|
const groups = new Map();
|
|
88
|
-
|
|
96
|
+
|
|
89
97
|
for (const f of files) {
|
|
90
98
|
const parts = f.filename.split('/');
|
|
91
|
-
|
|
99
|
+
|
|
92
100
|
let folder = '';
|
|
93
|
-
|
|
101
|
+
|
|
94
102
|
if (parts.length > 1)
|
|
95
|
-
folder = parts
|
|
96
|
-
|
|
97
|
-
.join('/');
|
|
98
|
-
|
|
103
|
+
folder = parts.slice(0, -1).join('/');
|
|
104
|
+
|
|
99
105
|
const fileName = parts.at(-1);
|
|
100
|
-
|
|
106
|
+
|
|
101
107
|
let group = groups.get(folder);
|
|
102
|
-
|
|
108
|
+
|
|
103
109
|
if (!group) {
|
|
104
110
|
group = {
|
|
105
111
|
files: [],
|
|
106
112
|
};
|
|
107
113
|
groups.set(folder, group);
|
|
108
114
|
}
|
|
109
|
-
|
|
115
|
+
|
|
110
116
|
group.files.push({
|
|
111
117
|
...f,
|
|
112
118
|
shortName: fileName,
|
|
113
119
|
});
|
|
114
120
|
}
|
|
115
|
-
|
|
121
|
+
|
|
116
122
|
return groups;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
|
-
function
|
|
125
|
+
export function parseCoverageFile(coverageFile, skipFull) {
|
|
126
|
+
const files = [];
|
|
127
|
+
|
|
128
|
+
for (const {name, lines} of coverageFile) {
|
|
129
|
+
const uncovered = parseUncoveredLines(lines);
|
|
130
|
+
|
|
131
|
+
const linesCount = keys(lines).length;
|
|
132
|
+
const uncoveredCount = uncovered.length;
|
|
133
|
+
|
|
134
|
+
const percentLines = getLinesPercent(linesCount, uncoveredCount);
|
|
135
|
+
|
|
136
|
+
let covered = true;
|
|
137
|
+
|
|
138
|
+
if (uncoveredCount > 0)
|
|
139
|
+
covered = false;
|
|
140
|
+
|
|
141
|
+
if (skipFull && covered)
|
|
142
|
+
continue;
|
|
143
|
+
|
|
144
|
+
files.push({
|
|
145
|
+
filename: name.replace(`${CWD}/`, ''),
|
|
146
|
+
covered,
|
|
147
|
+
lines: uncovered,
|
|
148
|
+
percentLines,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return files;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function buildGroupedTable(files, showPercent) {
|
|
120
156
|
const tableData = [];
|
|
121
|
-
|
|
157
|
+
|
|
122
158
|
if (showPercent)
|
|
123
159
|
tableData.push([
|
|
124
160
|
'File',
|
|
@@ -130,153 +166,123 @@ function buildGroupedTable(files, showPercent) {
|
|
|
130
166
|
'File',
|
|
131
167
|
'Uncovered Lines #s',
|
|
132
168
|
]);
|
|
133
|
-
|
|
169
|
+
|
|
134
170
|
const groups = groupByFolder(files);
|
|
135
|
-
|
|
171
|
+
const hideFolders = groups.size === 1;
|
|
172
|
+
|
|
136
173
|
for (const [folder, group] of groups) {
|
|
137
174
|
let sum = 0;
|
|
138
|
-
|
|
175
|
+
|
|
139
176
|
for (const f of group.files)
|
|
140
177
|
sum += f.percentLines;
|
|
141
|
-
|
|
178
|
+
|
|
142
179
|
let coverage = 100;
|
|
143
|
-
|
|
180
|
+
|
|
144
181
|
if (group.files.length > 0)
|
|
145
182
|
coverage = Math.round(sum / group.files.length);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
folderLabel
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
folderColor = makeGreen;
|
|
158
|
-
|
|
159
|
-
const folderName = folderColor(trimmedFolder);
|
|
160
|
-
|
|
161
|
-
const headerRow = [folderName];
|
|
162
|
-
|
|
163
|
-
if (showPercent) {
|
|
164
|
-
let color = makeRed;
|
|
165
|
-
|
|
183
|
+
|
|
184
|
+
if (!hideFolders) {
|
|
185
|
+
let folderLabel = folder;
|
|
186
|
+
|
|
187
|
+
if (!folderLabel)
|
|
188
|
+
folderLabel = '.';
|
|
189
|
+
|
|
190
|
+
const trimmedFolder = trim(folderLabel, 25);
|
|
191
|
+
|
|
192
|
+
let folderColor = makeRed;
|
|
193
|
+
|
|
166
194
|
if (coverage === 100)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
headerRow
|
|
195
|
+
folderColor = makeGreen;
|
|
196
|
+
|
|
197
|
+
const headerRow = [folderColor(trimmedFolder)];
|
|
198
|
+
|
|
199
|
+
if (showPercent) {
|
|
200
|
+
let color = makeRed;
|
|
201
|
+
|
|
202
|
+
if (coverage === 100)
|
|
203
|
+
color = makeGreen;
|
|
204
|
+
|
|
205
|
+
headerRow.push(color(`${coverage}%`));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
headerRow.push('');
|
|
209
|
+
tableData.push(headerRow);
|
|
170
210
|
}
|
|
171
|
-
|
|
172
|
-
headerRow.push('');
|
|
173
|
-
tableData.push(headerRow);
|
|
174
|
-
|
|
211
|
+
|
|
175
212
|
for (const f of group.files) {
|
|
176
213
|
const fileCell = ' ' + trim(f.shortName, 30);
|
|
177
|
-
|
|
214
|
+
|
|
178
215
|
let fileColor = makeRed;
|
|
179
|
-
|
|
216
|
+
|
|
180
217
|
if (f.covered)
|
|
181
218
|
fileColor = makeGreen;
|
|
182
|
-
|
|
219
|
+
|
|
183
220
|
const row = [fileColor(fileCell)];
|
|
184
|
-
|
|
221
|
+
|
|
185
222
|
if (showPercent) {
|
|
186
223
|
let percentColor = makeRed;
|
|
187
|
-
|
|
224
|
+
|
|
188
225
|
if (f.percentLines === 100)
|
|
189
226
|
percentColor = makeGreen;
|
|
190
|
-
|
|
227
|
+
|
|
191
228
|
row.push(percentColor(`${f.percentLines}%`));
|
|
192
229
|
}
|
|
193
|
-
|
|
230
|
+
|
|
194
231
|
let uncovered = '';
|
|
195
|
-
|
|
232
|
+
|
|
196
233
|
if (!f.covered)
|
|
197
234
|
uncovered = makeRed(formatLines(f.lines));
|
|
198
|
-
|
|
235
|
+
|
|
199
236
|
row.push(uncovered);
|
|
200
|
-
|
|
201
237
|
tableData.push(row);
|
|
202
238
|
}
|
|
203
239
|
}
|
|
204
|
-
|
|
205
|
-
return tableData;
|
|
206
|
-
}
|
|
207
240
|
|
|
208
|
-
|
|
209
|
-
const files = [];
|
|
210
|
-
|
|
211
|
-
for (const {name, lines} of coverageFile) {
|
|
212
|
-
const uncovered = parseUncoveredLines(lines);
|
|
213
|
-
|
|
214
|
-
const linesCount = keys(lines).length;
|
|
215
|
-
const uncoveredCount = uncovered.length;
|
|
216
|
-
|
|
217
|
-
const percentLines = getLinesPercent(linesCount, uncoveredCount);
|
|
218
|
-
|
|
219
|
-
let covered = true;
|
|
220
|
-
|
|
221
|
-
if (uncoveredCount > 0)
|
|
222
|
-
covered = false;
|
|
223
|
-
|
|
224
|
-
if (skipFull && covered)
|
|
225
|
-
continue;
|
|
226
|
-
|
|
227
|
-
files.push({
|
|
228
|
-
filename: name.replace(`${CWD}/`, ''),
|
|
229
|
-
covered,
|
|
230
|
-
lines: uncovered,
|
|
231
|
-
percentLines,
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return files;
|
|
241
|
+
return tableData;
|
|
236
242
|
}
|
|
237
243
|
|
|
238
244
|
function trim(str, max) {
|
|
239
245
|
if (str.length <= max)
|
|
240
246
|
return str;
|
|
241
|
-
|
|
247
|
+
|
|
242
248
|
return '...' + str.slice(-(max - 3));
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
export function formatLines(array) {
|
|
246
252
|
if (array.length <= 10) {
|
|
247
253
|
const joined = array.join(', ');
|
|
248
|
-
|
|
254
|
+
|
|
249
255
|
if (joined.length <= 30)
|
|
250
256
|
return joined;
|
|
251
257
|
}
|
|
252
|
-
|
|
258
|
+
|
|
253
259
|
const [first] = array;
|
|
254
260
|
const last = array.at(-1);
|
|
255
|
-
|
|
261
|
+
|
|
256
262
|
const base = first + '..' + last;
|
|
257
|
-
|
|
263
|
+
|
|
258
264
|
if (base.length <= 30)
|
|
259
265
|
return base;
|
|
260
|
-
|
|
266
|
+
|
|
261
267
|
return last;
|
|
262
268
|
}
|
|
263
269
|
|
|
264
270
|
function parseUncoveredLines(lines) {
|
|
265
271
|
const out = [];
|
|
266
|
-
|
|
272
|
+
|
|
267
273
|
for (const [line, covered] of entries(lines)) {
|
|
268
274
|
if (!covered)
|
|
269
275
|
out.push(line);
|
|
270
276
|
}
|
|
271
|
-
|
|
277
|
+
|
|
272
278
|
return out;
|
|
273
279
|
}
|
|
274
280
|
|
|
275
281
|
export function getLinesPercent(linesCount, uncoveredLinesCount) {
|
|
276
282
|
if (!linesCount)
|
|
277
283
|
return 100;
|
|
278
|
-
|
|
279
|
-
const ratio = 100 / linesCount * uncoveredLinesCount;
|
|
280
|
-
|
|
284
|
+
|
|
285
|
+
const ratio = (100 / linesCount) * uncoveredLinesCount;
|
|
286
|
+
|
|
281
287
|
return 100 - Math.round(ratio);
|
|
282
288
|
}
|