monocart-coverage-reports 2.3.3 → 2.4.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 +50 -20
- package/lib/converter/ast-visitor.js +646 -0
- package/lib/converter/ast.js +116 -137
- package/lib/converter/collect-source-maps.js +1 -1
- package/lib/converter/converter.js +337 -226
- package/lib/converter/find-original-range.js +471 -411
- package/lib/converter/ignore.js +33 -22
- package/lib/converter/info-branch.js +13 -2
- package/lib/converter/info-function.js +29 -6
- package/lib/converter/info-statement.js +43 -0
- package/lib/default/options.js +1 -1
- package/lib/generate.js +2 -2
- package/lib/index.d.ts +24 -13
- package/lib/istanbul/istanbul.js +1 -1
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/packages/monocart-coverage-vendor.js +38 -37
- package/lib/platform/share.js +39 -4
- package/lib/utils/util.js +8 -2
- package/lib/v8/v8-summary.js +5 -1
- package/lib/v8/v8.js +4 -1
- package/package.json +3 -3
- package/lib/converter/branches.js +0 -429
- package/lib/converter/find-in-ranges.js +0 -39
- package/lib/converter/info-line.js +0 -23
|
@@ -17,19 +17,37 @@ const {
|
|
|
17
17
|
const { getSourceType, initSourceMapSourcePath } = require('../utils/source-path.js');
|
|
18
18
|
const { decode } = require('../packages/monocart-coverage-vendor.js');
|
|
19
19
|
|
|
20
|
-
const InfoLine = require('./info-line.js');
|
|
21
20
|
const InfoBranch = require('./info-branch.js');
|
|
22
21
|
const InfoFunction = require('./info-function.js');
|
|
23
|
-
const
|
|
22
|
+
const InfoStatement = require('./info-statement.js');
|
|
23
|
+
|
|
24
|
+
// ========================================================================================================
|
|
25
|
+
|
|
26
|
+
// debug info
|
|
27
|
+
const logMappingErrors = (type, result) => {
|
|
28
|
+
|
|
29
|
+
// const {
|
|
30
|
+
// errors, start, end, sourcePath
|
|
31
|
+
// } = result;
|
|
32
|
+
// // if (!sourcePath.endsWith('monocart-v8.js') || type !== 'byte') {
|
|
33
|
+
// // return;
|
|
34
|
+
// // }
|
|
35
|
+
// const list = [
|
|
36
|
+
// Util.EC.red('[Mapping]'),
|
|
37
|
+
// Util.EC.magenta(type),
|
|
38
|
+
// errors.join(' -> '),
|
|
39
|
+
// Util.EC.blue(`${start} ~ ${end}`),
|
|
40
|
+
// sourcePath
|
|
41
|
+
// ];
|
|
42
|
+
// console.log(list.join(' '));
|
|
43
|
+
|
|
44
|
+
};
|
|
24
45
|
|
|
25
46
|
// ========================================================================================================
|
|
26
47
|
|
|
27
48
|
const handleIgnoredRanges = (list, ignoredRanges) => {
|
|
28
49
|
list.forEach((item) => {
|
|
29
|
-
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const range = findInRanges(item.start, item.end, ignoredRanges);
|
|
50
|
+
const range = Util.findInRanges(item.start, item.end, ignoredRanges, 'start', 'end');
|
|
33
51
|
if (range) {
|
|
34
52
|
// console.log(item, range);
|
|
35
53
|
item.ignored = true;
|
|
@@ -37,15 +55,18 @@ const handleIgnoredRanges = (list, ignoredRanges) => {
|
|
|
37
55
|
});
|
|
38
56
|
};
|
|
39
57
|
|
|
40
|
-
// ========================================================================================================
|
|
41
58
|
|
|
42
|
-
const
|
|
59
|
+
const applyBytesToLines = (bytes, locator, lineMap) => {
|
|
43
60
|
bytes.forEach((range) => {
|
|
44
|
-
|
|
45
61
|
const {
|
|
46
62
|
start, end, count, ignored
|
|
47
63
|
} = range;
|
|
48
64
|
|
|
65
|
+
// no need handle ignored and uncovered byte
|
|
66
|
+
if (count === 0 && ignored) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
49
70
|
const sLoc = locator.offsetToLocation(start);
|
|
50
71
|
const eLoc = locator.offsetToLocation(end);
|
|
51
72
|
|
|
@@ -53,155 +74,150 @@ const updateLinesCount = (bytes, locator, lineMap) => {
|
|
|
53
74
|
const lines = Util.getRangeLines(sLoc, eLoc);
|
|
54
75
|
|
|
55
76
|
lines.forEach((it) => {
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
77
|
+
const lineItem = lineMap.get(it.line);
|
|
78
|
+
if (!lineItem) {
|
|
79
|
+
// not found line, could be comment or blank line
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (lineItem.ignored) {
|
|
58
83
|
return;
|
|
59
84
|
}
|
|
60
85
|
|
|
61
|
-
|
|
62
|
-
// default is covered
|
|
63
|
-
if (it.entire) {
|
|
64
|
-
line.covered = count > 0;
|
|
65
|
-
line.count = count;
|
|
86
|
+
it.count = count;
|
|
66
87
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
// default is covered, so only focus on
|
|
89
|
+
// 1, biggest covered count
|
|
90
|
+
// 2, uncovered entire and pieces
|
|
91
|
+
if (count > 0) {
|
|
92
|
+
lineItem.coveredCount = Math.max(lineItem.coveredCount, count);
|
|
93
|
+
} else {
|
|
94
|
+
if (it.entire) {
|
|
95
|
+
lineItem.uncoveredEntire = it;
|
|
96
|
+
} else {
|
|
97
|
+
lineItem.uncoveredPieces.push(it);
|
|
71
98
|
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
72
101
|
|
|
73
|
-
|
|
102
|
+
});
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
line.count = count;
|
|
78
|
-
} else {
|
|
79
|
-
// not covered if any count = 0
|
|
80
|
-
line.covered = false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
104
|
+
// no ignore items
|
|
105
|
+
lineMap.forEach((lineItem, line) => {
|
|
83
106
|
|
|
84
|
-
|
|
107
|
+
const {
|
|
108
|
+
uncoveredEntire, uncoveredPieces, coveredCount
|
|
109
|
+
} = lineItem;
|
|
85
110
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
// default count to 1, both js and css
|
|
112
|
+
let count = 1;
|
|
113
|
+
// full covered true/false for entire line
|
|
114
|
+
let covered = true;
|
|
90
115
|
|
|
91
|
-
|
|
116
|
+
if (uncoveredEntire) {
|
|
117
|
+
count = 0;
|
|
118
|
+
covered = false;
|
|
119
|
+
} else {
|
|
120
|
+
count = coveredCount;
|
|
121
|
+
const uncoveredLen = uncoveredPieces.length;
|
|
122
|
+
if (uncoveredLen > 0) {
|
|
123
|
+
covered = false;
|
|
124
|
+
// uncovered
|
|
125
|
+
count = `1/${uncoveredLen + 1}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
92
128
|
|
|
93
|
-
|
|
129
|
+
lineItem.covered = covered;
|
|
130
|
+
lineItem.count = count;
|
|
94
131
|
|
|
95
|
-
|
|
96
|
-
// console.log('===========================================', state.sourcePath);
|
|
97
|
-
// }
|
|
132
|
+
});
|
|
98
133
|
|
|
99
134
|
};
|
|
100
135
|
|
|
101
|
-
const handleLinesCoverage = (bytes, locator) => {
|
|
102
|
-
|
|
103
|
-
const lines = [];
|
|
104
|
-
// line 1 based
|
|
105
|
-
const lineMap = new Map();
|
|
136
|
+
const handleLinesCoverage = (bytes, locator, ignoredRanges) => {
|
|
106
137
|
|
|
107
138
|
// init lines
|
|
108
139
|
let blankCount = 0;
|
|
109
140
|
let commentCount = 0;
|
|
110
|
-
|
|
111
|
-
|
|
141
|
+
// line 1 based
|
|
142
|
+
const lineMap = new Map();
|
|
143
|
+
locator.lines.forEach((lineItem) => {
|
|
112
144
|
// exclude blank and comment
|
|
113
|
-
if (
|
|
145
|
+
if (lineItem.blank) {
|
|
114
146
|
blankCount += 1;
|
|
115
147
|
return;
|
|
116
148
|
}
|
|
117
|
-
if (
|
|
149
|
+
if (lineItem.comment) {
|
|
118
150
|
commentCount += 1;
|
|
119
151
|
return;
|
|
120
152
|
}
|
|
153
|
+
const ignored = Util.findInRanges(lineItem.start, lineItem.end, ignoredRanges);
|
|
154
|
+
if (ignored) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
121
157
|
// line 1-base
|
|
122
|
-
const line =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
158
|
+
const line = lineItem.line + 1;
|
|
159
|
+
lineItem.coveredCount = 1;
|
|
160
|
+
lineItem.uncoveredEntire = null;
|
|
161
|
+
lineItem.uncoveredPieces = [];
|
|
162
|
+
lineMap.set(line, lineItem);
|
|
127
163
|
});
|
|
128
164
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
lines,
|
|
133
|
-
blankCount,
|
|
134
|
-
commentCount
|
|
135
|
-
};
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// ========================================================================================================
|
|
139
|
-
|
|
140
|
-
const calculateV8Functions = (functions) => {
|
|
165
|
+
applyBytesToLines(bytes, locator, lineMap);
|
|
141
166
|
|
|
142
|
-
const
|
|
167
|
+
const summaryLines = {
|
|
143
168
|
total: 0,
|
|
144
|
-
covered: 0
|
|
169
|
+
covered: 0,
|
|
170
|
+
blank: blankCount,
|
|
171
|
+
comment: commentCount
|
|
145
172
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
173
|
+
// data lines for codecov
|
|
174
|
+
// https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
175
|
+
const dataLines = {};
|
|
176
|
+
|
|
177
|
+
// no ignore items
|
|
178
|
+
lineMap.forEach((lineItem, line) => {
|
|
179
|
+
const { count, covered } = lineItem;
|
|
180
|
+
// data lines
|
|
181
|
+
dataLines[line] = count;
|
|
182
|
+
|
|
183
|
+
summaryLines.total += 1;
|
|
184
|
+
if (covered) {
|
|
185
|
+
summaryLines.covered += 1;
|
|
155
186
|
}
|
|
156
187
|
});
|
|
157
188
|
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const calculateV8Branches = (branches) => {
|
|
162
|
-
const v8Branches = {
|
|
163
|
-
total: 0,
|
|
164
|
-
covered: 0
|
|
189
|
+
return {
|
|
190
|
+
dataLines,
|
|
191
|
+
summaryLines
|
|
165
192
|
};
|
|
193
|
+
};
|
|
166
194
|
|
|
167
|
-
|
|
168
|
-
if (branch.ignored) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
v8Branches.total += 1;
|
|
172
|
-
if (branch.count > 0) {
|
|
173
|
-
v8Branches.covered += 1;
|
|
174
|
-
}
|
|
175
|
-
});
|
|
195
|
+
// ========================================================================================================
|
|
176
196
|
|
|
177
|
-
|
|
178
|
-
};
|
|
197
|
+
const calculateV8Summary = (list) => {
|
|
179
198
|
|
|
180
|
-
const
|
|
181
|
-
const v8Lines = {
|
|
199
|
+
const summary = {
|
|
182
200
|
total: 0,
|
|
183
|
-
covered: 0
|
|
184
|
-
blank: blankCount,
|
|
185
|
-
comment: commentCount
|
|
201
|
+
covered: 0
|
|
186
202
|
};
|
|
187
203
|
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
// console.log(ln);
|
|
204
|
+
list.forEach((item) => {
|
|
205
|
+
if (item.ignored) {
|
|
191
206
|
return;
|
|
192
207
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
208
|
+
|
|
209
|
+
summary.total += 1;
|
|
210
|
+
if (item.count > 0) {
|
|
211
|
+
summary.covered += 1;
|
|
197
212
|
}
|
|
198
213
|
});
|
|
199
214
|
|
|
200
|
-
return
|
|
215
|
+
return summary;
|
|
201
216
|
};
|
|
202
217
|
|
|
203
218
|
// ========================================================================================================
|
|
204
219
|
// istanbul coverage format
|
|
220
|
+
// https://github.com/istanbuljs/istanbuljs/blob/master/docs/raw-output.md
|
|
205
221
|
/**
|
|
206
222
|
* * `path` - the file path for which coverage is being tracked
|
|
207
223
|
* * `statementMap` - map of statement locations keyed by statement index
|
|
@@ -217,6 +233,7 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
217
233
|
bytes,
|
|
218
234
|
functions,
|
|
219
235
|
branches,
|
|
236
|
+
statements,
|
|
220
237
|
|
|
221
238
|
sourcePath,
|
|
222
239
|
locator
|
|
@@ -227,7 +244,8 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
227
244
|
const data = {
|
|
228
245
|
bytes: dedupeCountRanges(bytes),
|
|
229
246
|
functions: [],
|
|
230
|
-
branches: []
|
|
247
|
+
branches: [],
|
|
248
|
+
statements: []
|
|
231
249
|
};
|
|
232
250
|
|
|
233
251
|
// ==========================================
|
|
@@ -235,13 +253,15 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
235
253
|
const ignoredRanges = getIgnoredRanges(locator, options);
|
|
236
254
|
if (ignoredRanges) {
|
|
237
255
|
|
|
256
|
+
data.ignores = ignoredRanges;
|
|
257
|
+
|
|
238
258
|
// data bytes is start/end/count object
|
|
239
259
|
handleIgnoredRanges(data.bytes, ignoredRanges);
|
|
240
260
|
|
|
241
|
-
// functions
|
|
261
|
+
// functions start/end/count instance
|
|
242
262
|
handleIgnoredRanges(functions, ignoredRanges);
|
|
243
263
|
|
|
244
|
-
// branches
|
|
264
|
+
// branches start/end/count instance
|
|
245
265
|
handleIgnoredRanges(branches, ignoredRanges);
|
|
246
266
|
|
|
247
267
|
// branch locations start/end/count object
|
|
@@ -256,10 +276,24 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
256
276
|
}
|
|
257
277
|
});
|
|
258
278
|
|
|
279
|
+
// statements start/end/count instance
|
|
280
|
+
handleIgnoredRanges(statements, ignoredRanges);
|
|
281
|
+
|
|
259
282
|
// console.log(ignoredRanges);
|
|
260
283
|
|
|
261
284
|
}
|
|
262
285
|
|
|
286
|
+
// ==========================================
|
|
287
|
+
// lines
|
|
288
|
+
// after bytes with ignored, before calculateV8Lines
|
|
289
|
+
const { dataLines, summaryLines } = handleLinesCoverage(data.bytes, locator, ignoredRanges);
|
|
290
|
+
|
|
291
|
+
data.lines = dataLines;
|
|
292
|
+
|
|
293
|
+
// console.log('statements', state.sourcePath, statements.length);
|
|
294
|
+
|
|
295
|
+
// ==========================================
|
|
296
|
+
|
|
263
297
|
data.functions = functions.map((info) => {
|
|
264
298
|
return info.getRange();
|
|
265
299
|
});
|
|
@@ -271,21 +305,24 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
271
305
|
}).flat();
|
|
272
306
|
sortRanges(data.branches);
|
|
273
307
|
|
|
308
|
+
data.statements = statements.map((info) => {
|
|
309
|
+
return info.getRange();
|
|
310
|
+
});
|
|
311
|
+
sortRanges(data.statements);
|
|
312
|
+
|
|
274
313
|
// ==========================================
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
314
|
+
|
|
315
|
+
const summary = {
|
|
316
|
+
functions: calculateV8Summary(data.functions),
|
|
317
|
+
branches: calculateV8Summary(data.branches),
|
|
318
|
+
statements: calculateV8Summary(data.statements),
|
|
319
|
+
lines: summaryLines
|
|
320
|
+
};
|
|
280
321
|
|
|
281
322
|
// ==========================================
|
|
282
323
|
// v8 data and summary
|
|
283
324
|
v8Data.data = data;
|
|
284
|
-
v8Data.summary =
|
|
285
|
-
functions: calculateV8Functions(data.functions),
|
|
286
|
-
branches: calculateV8Branches(data.branches),
|
|
287
|
-
lines: calculateV8Lines(lines, blankCount, commentCount)
|
|
288
|
-
};
|
|
325
|
+
v8Data.summary = summary;
|
|
289
326
|
|
|
290
327
|
// ==========================================
|
|
291
328
|
// istanbul
|
|
@@ -301,25 +338,13 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
301
338
|
b: {}
|
|
302
339
|
};
|
|
303
340
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
lines.filter((it) => !it.ignored).forEach((line, index) => {
|
|
308
|
-
istanbulData.statementMap[`${index}`] = line.generate();
|
|
309
|
-
istanbulData.s[`${index}`] = line.count;
|
|
310
|
-
|
|
311
|
-
let count = 0;
|
|
312
|
-
if (line.covered) {
|
|
313
|
-
count = line.count;
|
|
314
|
-
} else if (!line.covered && line.count > 0) {
|
|
315
|
-
count = '1/2';
|
|
316
|
-
}
|
|
317
|
-
// 1-base
|
|
318
|
-
data.lines[`${line.line}`] = count;
|
|
341
|
+
statements.filter((it) => !it.ignored).forEach((statement, index) => {
|
|
342
|
+
istanbulData.statementMap[`${index}`] = statement.generate(locator);
|
|
343
|
+
istanbulData.s[`${index}`] = statement.count;
|
|
319
344
|
});
|
|
320
345
|
|
|
321
346
|
functions.filter((it) => !it.ignored).forEach((fn, index) => {
|
|
322
|
-
istanbulData.fnMap[`${index}`] = fn.generate(locator);
|
|
347
|
+
istanbulData.fnMap[`${index}`] = fn.generate(locator, index);
|
|
323
348
|
istanbulData.f[`${index}`] = fn.count;
|
|
324
349
|
});
|
|
325
350
|
|
|
@@ -329,7 +354,6 @@ const collectFileCoverage = (v8Data, state, options) => {
|
|
|
329
354
|
istanbulData.b[`${index}`] = counts;
|
|
330
355
|
});
|
|
331
356
|
|
|
332
|
-
// istanbul data
|
|
333
357
|
return istanbulData;
|
|
334
358
|
|
|
335
359
|
};
|
|
@@ -341,11 +365,17 @@ const addJsBytesCoverage = (state, range) => {
|
|
|
341
365
|
startOffset, endOffset, count
|
|
342
366
|
} = range;
|
|
343
367
|
// add bytes range
|
|
344
|
-
|
|
368
|
+
const byte = {
|
|
345
369
|
start: startOffset,
|
|
346
370
|
end: endOffset,
|
|
347
371
|
count
|
|
348
|
-
}
|
|
372
|
+
};
|
|
373
|
+
// for debug
|
|
374
|
+
if (Util.isDebug() && state.original) {
|
|
375
|
+
byte.generatedStart = range.generatedStart;
|
|
376
|
+
byte.generatedEnd = range.generatedEnd;
|
|
377
|
+
}
|
|
378
|
+
state.bytes.push(byte);
|
|
349
379
|
};
|
|
350
380
|
|
|
351
381
|
const addCssBytesCoverage = (state, range) => {
|
|
@@ -371,11 +401,14 @@ const handleFunctionsCoverage = (state) => {
|
|
|
371
401
|
|
|
372
402
|
const { functions, astInfo } = state;
|
|
373
403
|
astInfo.functions.forEach((it) => {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
404
|
+
|
|
405
|
+
const { start, end } = it;
|
|
406
|
+
if (start >= end) {
|
|
407
|
+
// console.log('invalid function', start, end);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
functions.push(new InfoFunction(it, state.original));
|
|
379
412
|
});
|
|
380
413
|
|
|
381
414
|
};
|
|
@@ -389,11 +422,35 @@ const handleBranchesCoverage = (state) => {
|
|
|
389
422
|
|
|
390
423
|
const { branches, astInfo } = state;
|
|
391
424
|
astInfo.branches.forEach((it) => {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
425
|
+
|
|
426
|
+
const { start, end } = it;
|
|
427
|
+
if (start >= end) {
|
|
428
|
+
// console.log('invalid branch', state.sourcePath, it);
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
branches.push(new InfoBranch(it, state.original));
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
const handleStatementsCoverage = (state) => {
|
|
438
|
+
|
|
439
|
+
// statement only for js
|
|
440
|
+
if (!state.js) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const { statements, astInfo } = state;
|
|
445
|
+
astInfo.statements.forEach((it) => {
|
|
446
|
+
|
|
447
|
+
const { start, end } = it;
|
|
448
|
+
if (start >= end) {
|
|
449
|
+
// console.log('invalid statement', start, end);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
statements.push(new InfoStatement(it, state.original));
|
|
397
454
|
});
|
|
398
455
|
|
|
399
456
|
};
|
|
@@ -427,10 +484,22 @@ const handleOriginalFunctionsCoverage = (state, originalStateMap) => {
|
|
|
427
484
|
|
|
428
485
|
// console.log(state.astInfo.functions);
|
|
429
486
|
|
|
487
|
+
const updateFunctionBodyRange = (start, end, bodyStart, bodyEnd, originalFunction) => {
|
|
488
|
+
if (bodyStart !== start || bodyEnd !== end) {
|
|
489
|
+
const result = findOriginalRange(bodyStart, bodyEnd, state, originalStateMap);
|
|
490
|
+
if (result.error) {
|
|
491
|
+
logMappingErrors('function body', result);
|
|
492
|
+
} else {
|
|
493
|
+
originalFunction.bodyStart = result.start;
|
|
494
|
+
originalFunction.bodyEnd = result.end;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
430
499
|
// function count
|
|
431
500
|
state.astInfo.functions.forEach((it) => {
|
|
432
501
|
const {
|
|
433
|
-
start, end, wrap
|
|
502
|
+
start, end, bodyStart, bodyEnd, wrap
|
|
434
503
|
} = it;
|
|
435
504
|
|
|
436
505
|
// remove webpack wrap functions for functions count, not for ranges here
|
|
@@ -438,31 +507,27 @@ const handleOriginalFunctionsCoverage = (state, originalStateMap) => {
|
|
|
438
507
|
return;
|
|
439
508
|
}
|
|
440
509
|
|
|
441
|
-
|
|
442
|
-
const range = {
|
|
443
|
-
startOffset: start,
|
|
444
|
-
endOffset: end
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
const result = findOriginalRange(range, state, originalStateMap);
|
|
510
|
+
const result = findOriginalRange(start, end, state, originalStateMap);
|
|
448
511
|
if (result.error) {
|
|
512
|
+
logMappingErrors('function', result);
|
|
449
513
|
return;
|
|
450
514
|
}
|
|
451
|
-
const { originalRange, originalState } = result;
|
|
452
515
|
|
|
453
|
-
|
|
454
|
-
originalState.astInfo.functions.push({
|
|
516
|
+
const originalFunction = {
|
|
455
517
|
... it,
|
|
456
518
|
generatedStart: start,
|
|
457
519
|
generatedEnd: end,
|
|
458
|
-
start:
|
|
459
|
-
end:
|
|
460
|
-
|
|
520
|
+
start: result.start,
|
|
521
|
+
end: result.end,
|
|
522
|
+
bodyStart: result.start,
|
|
523
|
+
bodyEnd: result.end
|
|
524
|
+
};
|
|
461
525
|
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
//
|
|
526
|
+
// body start and end
|
|
527
|
+
updateFunctionBodyRange(start, end, bodyStart, bodyEnd, originalFunction);
|
|
528
|
+
|
|
529
|
+
// add back to original ast
|
|
530
|
+
result.originalState.astInfo.functions.push(originalFunction);
|
|
466
531
|
|
|
467
532
|
});
|
|
468
533
|
|
|
@@ -478,26 +543,20 @@ const handleOriginalBranchesCoverage = (state, originalStateMap) => {
|
|
|
478
543
|
// console.log(state.astInfo.branches);
|
|
479
544
|
|
|
480
545
|
// function count
|
|
481
|
-
state.astInfo.branches.forEach((
|
|
546
|
+
state.astInfo.branches.forEach((group) => {
|
|
482
547
|
|
|
483
|
-
const { type, locations } =
|
|
484
|
-
|
|
485
|
-
// rename to startOffset and endOffset
|
|
486
|
-
const bRange = {
|
|
487
|
-
startOffset: it.start,
|
|
488
|
-
endOffset: it.end
|
|
489
|
-
};
|
|
548
|
+
const { type, locations } = group;
|
|
490
549
|
|
|
491
550
|
// start
|
|
492
|
-
const result = findOriginalRange(
|
|
551
|
+
const result = findOriginalRange(group.start, group.end, state, originalStateMap);
|
|
493
552
|
if (result.error) {
|
|
494
|
-
|
|
553
|
+
logMappingErrors('branch group', result);
|
|
495
554
|
return;
|
|
496
555
|
}
|
|
497
|
-
const { originalRange, originalState } = result;
|
|
498
556
|
|
|
499
|
-
|
|
500
|
-
const
|
|
557
|
+
// new group start and end
|
|
558
|
+
const groupStart = result.start;
|
|
559
|
+
const groupEnd = result.end;
|
|
501
560
|
|
|
502
561
|
let hasError;
|
|
503
562
|
const newLocations = locations.map((oLoc) => {
|
|
@@ -512,29 +571,19 @@ const handleOriginalBranchesCoverage = (state, originalStateMap) => {
|
|
|
512
571
|
return newLoc;
|
|
513
572
|
}
|
|
514
573
|
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
const lRange = {
|
|
518
|
-
startOffset: start,
|
|
519
|
-
endOffset: end
|
|
520
|
-
};
|
|
521
|
-
const res = findOriginalRange(lRange, state, originalStateMap);
|
|
522
|
-
if (res.error) {
|
|
574
|
+
const locResult = findOriginalRange(newLoc.start, newLoc.end, state, originalStateMap);
|
|
575
|
+
if (locResult.error) {
|
|
523
576
|
// It should not happen unless it is minify files, the SourceMap has some order problems
|
|
524
|
-
|
|
577
|
+
logMappingErrors('branch', locResult);
|
|
525
578
|
hasError = true;
|
|
526
|
-
|
|
527
|
-
// console.log('====================================', state.sourcePath, loc);
|
|
528
|
-
// console.log(res.errors);
|
|
529
|
-
// Util.logError(`Not found original branch. start: ${start}, end: ${end}`);
|
|
530
|
-
|
|
531
579
|
return newLoc;
|
|
532
580
|
}
|
|
533
581
|
|
|
534
582
|
// mapping to new range
|
|
535
|
-
|
|
536
|
-
newLoc.
|
|
537
|
-
newLoc.
|
|
583
|
+
newLoc.start = locResult.start;
|
|
584
|
+
newLoc.end = locResult.end;
|
|
585
|
+
newLoc.generatedStart = newLoc.start;
|
|
586
|
+
newLoc.generatedEnd = newLoc.end;
|
|
538
587
|
|
|
539
588
|
return newLoc;
|
|
540
589
|
});
|
|
@@ -545,7 +594,7 @@ const handleOriginalBranchesCoverage = (state, originalStateMap) => {
|
|
|
545
594
|
}
|
|
546
595
|
|
|
547
596
|
// add back to original ast
|
|
548
|
-
originalState.astInfo.branches.push({
|
|
597
|
+
result.originalState.astInfo.branches.push({
|
|
549
598
|
type,
|
|
550
599
|
start: groupStart,
|
|
551
600
|
end: groupEnd,
|
|
@@ -556,6 +605,50 @@ const handleOriginalBranchesCoverage = (state, originalStateMap) => {
|
|
|
556
605
|
|
|
557
606
|
};
|
|
558
607
|
|
|
608
|
+
const handleOriginalStatementsCoverage = (state, originalStateMap) => {
|
|
609
|
+
|
|
610
|
+
// statements only for js
|
|
611
|
+
if (!state.js) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// statement count
|
|
616
|
+
state.astInfo.statements.forEach((it) => {
|
|
617
|
+
const { start, end } = it;
|
|
618
|
+
|
|
619
|
+
const result = findOriginalRange(start, end, state, originalStateMap);
|
|
620
|
+
if (result.error) {
|
|
621
|
+
logMappingErrors('statement', result);
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// add back to original ast
|
|
626
|
+
result.originalState.astInfo.statements.push({
|
|
627
|
+
... it,
|
|
628
|
+
generatedStart: start,
|
|
629
|
+
generatedEnd: end,
|
|
630
|
+
start: result.start,
|
|
631
|
+
end: result.end
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
originalStateMap.forEach((originalState) => {
|
|
637
|
+
const statements = originalState.astInfo.statements;
|
|
638
|
+
if (Util.isList(statements)) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
// fake source nothing matched
|
|
642
|
+
statements.push({
|
|
643
|
+
start: 0,
|
|
644
|
+
end: originalState.source.length,
|
|
645
|
+
count: 1
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
};
|
|
651
|
+
|
|
559
652
|
const handleOriginalBytesCoverage = (state, originalStateMap) => {
|
|
560
653
|
|
|
561
654
|
const { js, coverageList } = state;
|
|
@@ -572,18 +665,23 @@ const handleOriginalBytesCoverage = (state, originalStateMap) => {
|
|
|
572
665
|
return;
|
|
573
666
|
}
|
|
574
667
|
|
|
575
|
-
const
|
|
668
|
+
const {
|
|
669
|
+
startOffset, endOffset, count
|
|
670
|
+
} = range;
|
|
671
|
+
|
|
672
|
+
const result = findOriginalRange(startOffset, endOffset, state, originalStateMap);
|
|
576
673
|
if (result.error) {
|
|
674
|
+
logMappingErrors('byte', result);
|
|
577
675
|
return;
|
|
578
676
|
}
|
|
579
677
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
678
|
+
addJsBytesCoverage(result.originalState, {
|
|
679
|
+
generatedStart: startOffset,
|
|
680
|
+
generatedEnd: endOffset,
|
|
681
|
+
startOffset: result.start,
|
|
682
|
+
endOffset: result.end,
|
|
683
|
+
count
|
|
684
|
+
});
|
|
587
685
|
|
|
588
686
|
});
|
|
589
687
|
});
|
|
@@ -613,7 +711,15 @@ const handleOriginalBytesCoverage = (state, originalStateMap) => {
|
|
|
613
711
|
const endMapping = decodedMappings[len - 1];
|
|
614
712
|
// console.log(startMapping, endMapping);
|
|
615
713
|
const startOffset = startMapping.generatedOffset;
|
|
616
|
-
|
|
714
|
+
|
|
715
|
+
if (!endMapping.generatedEndOffset) {
|
|
716
|
+
// line last one
|
|
717
|
+
const line = state.locator.getLine(endMapping.generatedLine + 1);
|
|
718
|
+
// last column
|
|
719
|
+
const toEndLength = line.length - endMapping.generatedColumn;
|
|
720
|
+
endMapping.generatedEndOffset = endMapping.generatedOffset + toEndLength;
|
|
721
|
+
}
|
|
722
|
+
const endOffset = endMapping.generatedEndOffset;
|
|
617
723
|
|
|
618
724
|
// console.log('===========================================================', originalState.sourcePath);
|
|
619
725
|
// console.log(originalState.source.length, endMapping);
|
|
@@ -654,11 +760,22 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
|
|
|
654
760
|
});
|
|
655
761
|
|
|
656
762
|
const allDecodedMappings = [];
|
|
657
|
-
let generatedIndex = 0;
|
|
658
763
|
decodedList.forEach((segments, generatedLine) => {
|
|
659
764
|
let info = null;
|
|
660
765
|
segments.forEach((segment) => {
|
|
766
|
+
|
|
767
|
+
// const COLUMN = 0;
|
|
768
|
+
// const SOURCES_INDEX = 1;
|
|
769
|
+
// const SOURCE_LINE = 2;
|
|
770
|
+
// const SOURCE_COLUMN = 3;
|
|
771
|
+
// const NAMES_INDEX = 4;
|
|
661
772
|
const [generatedColumn, sourceIndex, originalLine, originalColumn] = segment;
|
|
773
|
+
// the segment length could be 1, 4 or 5
|
|
774
|
+
|
|
775
|
+
if (typeof sourceIndex === 'undefined') {
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
|
|
662
779
|
const generatedOffset = generatedLocator.locationToOffset({
|
|
663
780
|
// 1-base
|
|
664
781
|
line: generatedLine + 1,
|
|
@@ -669,7 +786,6 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
|
|
|
669
786
|
generatedOffset,
|
|
670
787
|
generatedLine,
|
|
671
788
|
generatedColumn,
|
|
672
|
-
generatedIndex,
|
|
673
789
|
|
|
674
790
|
sourceIndex,
|
|
675
791
|
originalLine,
|
|
@@ -677,23 +793,11 @@ const decodeSourceMappings = (state, originalDecodedMap) => {
|
|
|
677
793
|
};
|
|
678
794
|
|
|
679
795
|
allDecodedMappings.push(info);
|
|
680
|
-
generatedIndex += 1;
|
|
681
|
-
|
|
682
|
-
if (typeof sourceIndex === 'undefined') {
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
796
|
|
|
686
797
|
originalDecodedMap.get(sourceIndex).push(info);
|
|
687
798
|
|
|
688
799
|
});
|
|
689
800
|
|
|
690
|
-
// line last one
|
|
691
|
-
if (info) {
|
|
692
|
-
const line = generatedLocator.getLine(info.generatedLine + 1);
|
|
693
|
-
// last column
|
|
694
|
-
info.generatedEndOffset = info.generatedOffset + (line.length - info.generatedColumn);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
801
|
});
|
|
698
802
|
|
|
699
803
|
// defaults to sort by generated offset, not need sort
|
|
@@ -782,9 +886,11 @@ const initOriginalList = (state, originalDecodedMap, options) => {
|
|
|
782
886
|
bytes: [],
|
|
783
887
|
functions: [],
|
|
784
888
|
branches: [],
|
|
889
|
+
statements: [],
|
|
785
890
|
astInfo: {
|
|
786
891
|
functions: [],
|
|
787
|
-
branches: []
|
|
892
|
+
branches: [],
|
|
893
|
+
statements: []
|
|
788
894
|
},
|
|
789
895
|
// coverage data
|
|
790
896
|
v8Data: {}
|
|
@@ -837,6 +943,7 @@ const generateCoverageForDist = (state) => {
|
|
|
837
943
|
|
|
838
944
|
handleFunctionsCoverage(state);
|
|
839
945
|
handleBranchesCoverage(state);
|
|
946
|
+
handleStatementsCoverage(state);
|
|
840
947
|
handleBytesCoverage(state);
|
|
841
948
|
|
|
842
949
|
};
|
|
@@ -868,12 +975,14 @@ const unpackSourceMap = (state, options) => {
|
|
|
868
975
|
// handle functions before handle original state functions
|
|
869
976
|
handleOriginalFunctionsCoverage(state, originalStateMap);
|
|
870
977
|
handleOriginalBranchesCoverage(state, originalStateMap);
|
|
978
|
+
handleOriginalStatementsCoverage(state, originalStateMap);
|
|
871
979
|
|
|
872
980
|
// handle lines info before handle ranges to update line count
|
|
873
981
|
originalStateMap.forEach((originalState) => {
|
|
874
982
|
|
|
875
983
|
handleFunctionsCoverage(originalState);
|
|
876
984
|
handleBranchesCoverage(originalState);
|
|
985
|
+
handleStatementsCoverage(originalState);
|
|
877
986
|
|
|
878
987
|
// if (originalState.sourcePath.endsWith('demo.js')) {
|
|
879
988
|
// console.log('=================================', originalState.sourcePath);
|
|
@@ -881,7 +990,7 @@ const unpackSourceMap = (state, options) => {
|
|
|
881
990
|
|
|
882
991
|
});
|
|
883
992
|
|
|
884
|
-
// handle ranges
|
|
993
|
+
// handle bytes ranges
|
|
885
994
|
handleOriginalBytesCoverage(state, originalStateMap);
|
|
886
995
|
|
|
887
996
|
// collect coverage for original list
|
|
@@ -892,7 +1001,7 @@ const unpackSourceMap = (state, options) => {
|
|
|
892
1001
|
const unpackDistFile = (item, state, options) => {
|
|
893
1002
|
|
|
894
1003
|
if (state.sourceMap) {
|
|
895
|
-
if (Util.
|
|
1004
|
+
if (Util.isDebug()) {
|
|
896
1005
|
// js self
|
|
897
1006
|
item.debug = true;
|
|
898
1007
|
generateCoverageForDist(state);
|
|
@@ -1197,7 +1306,7 @@ const convertV8List = (v8list, options) => {
|
|
|
1197
1306
|
if (js) {
|
|
1198
1307
|
coverageList = filterCoverageList(item);
|
|
1199
1308
|
// remove original functions
|
|
1200
|
-
if (Util.
|
|
1309
|
+
if (!Util.isDebug()) {
|
|
1201
1310
|
delete item.functions;
|
|
1202
1311
|
}
|
|
1203
1312
|
astInfo = getJsAstInfo(item, coverageList);
|
|
@@ -1205,11 +1314,12 @@ const convertV8List = (v8list, options) => {
|
|
|
1205
1314
|
// convent css covered ranges to rules ranges and include uncovered ranges
|
|
1206
1315
|
astInfo = getCssAstInfo(item, coverageList);
|
|
1207
1316
|
// remove original ranges
|
|
1208
|
-
if (Util.
|
|
1317
|
+
if (!Util.isDebug()) {
|
|
1209
1318
|
delete item.ranges;
|
|
1210
1319
|
}
|
|
1211
1320
|
}
|
|
1212
1321
|
|
|
1322
|
+
// console.log(sourcePath, astInfo.statements.length);
|
|
1213
1323
|
// ============================
|
|
1214
1324
|
|
|
1215
1325
|
// current file and it's sources from sourceMap
|
|
@@ -1226,6 +1336,7 @@ const convertV8List = (v8list, options) => {
|
|
|
1226
1336
|
bytes: [],
|
|
1227
1337
|
functions: [],
|
|
1228
1338
|
branches: [],
|
|
1339
|
+
statements: [],
|
|
1229
1340
|
astInfo,
|
|
1230
1341
|
// for sub source files
|
|
1231
1342
|
coverageList,
|