monocart-coverage-reports 1.0.9 → 2.0.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 +116 -29
- package/lib/converter/ast.js +297 -0
- package/lib/converter/branches.js +405 -0
- package/lib/converter/converter.js +720 -237
- package/lib/converter/find-original-range.js +106 -60
- package/lib/converter/info-branch.js +21 -22
- package/lib/converter/info-function.js +6 -18
- package/lib/converter/info-line.js +3 -0
- package/lib/default/options.js +5 -1
- package/lib/generate.js +4 -0
- package/lib/index.d.ts +12 -9
- package/lib/index.js +7 -2
- package/lib/istanbul/istanbul.js +1 -1
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/packages/monocart-coverage-vendor.js +21 -14
- package/lib/platform/share.js +104 -3
- package/lib/{converter → utils}/source-path.js +2 -2
- package/lib/utils/util.js +27 -0
- package/lib/v8/v8-summary.js +19 -24
- package/lib/v8/v8.js +66 -28
- package/package.json +24 -29
- package/lib/converter/position-mapping.js +0 -183
- /package/lib/{converter → utils}/dedupe.js +0 -0
|
@@ -4,11 +4,12 @@ const Util = require('../utils/util.js');
|
|
|
4
4
|
const decodeMappings = require('../utils/decode-mappings.js');
|
|
5
5
|
|
|
6
6
|
// position mapping for conversion between offset and line/column
|
|
7
|
-
const
|
|
7
|
+
const { Locator } = require('monocart-formatter/node');
|
|
8
8
|
const findOriginalRange = require('./find-original-range.js');
|
|
9
|
+
const { getJsAstInfo, getCssAstInfo } = require('./ast.js');
|
|
9
10
|
|
|
10
|
-
const { dedupeCountRanges } = require('
|
|
11
|
-
const { getSourceType, initSourceMapSourcePath } = require('
|
|
11
|
+
const { dedupeCountRanges } = require('../utils/dedupe.js');
|
|
12
|
+
const { getSourceType, initSourceMapSourcePath } = require('../utils/source-path.js');
|
|
12
13
|
|
|
13
14
|
const InfoLine = require('./info-line.js');
|
|
14
15
|
const InfoBranch = require('./info-branch.js');
|
|
@@ -16,6 +17,98 @@ const InfoFunction = require('./info-function.js');
|
|
|
16
17
|
|
|
17
18
|
// ========================================================================================================
|
|
18
19
|
|
|
20
|
+
const calculateV8Functions = (functions) => {
|
|
21
|
+
|
|
22
|
+
const v8Functions = {
|
|
23
|
+
total: 0,
|
|
24
|
+
covered: 0
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
functions.forEach((fn) => {
|
|
28
|
+
v8Functions.total += 1;
|
|
29
|
+
if (fn.count > 0) {
|
|
30
|
+
v8Functions.covered += 1;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return v8Functions;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const calculateV8Branches = (branches) => {
|
|
38
|
+
const v8Branches = {
|
|
39
|
+
total: 0,
|
|
40
|
+
covered: 0
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
branches.forEach((branch) => {
|
|
44
|
+
branch.locations.forEach((location) => {
|
|
45
|
+
v8Branches.total += 1;
|
|
46
|
+
if (location.count > 0) {
|
|
47
|
+
v8Branches.covered += 1;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return v8Branches;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const calculateV8Lines = (lines, blankCount, commentCount) => {
|
|
56
|
+
const v8Lines = {
|
|
57
|
+
total: 0,
|
|
58
|
+
covered: 0,
|
|
59
|
+
blank: blankCount,
|
|
60
|
+
comment: commentCount
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
lines.forEach((ln) => {
|
|
64
|
+
v8Lines.total += 1;
|
|
65
|
+
// full line covered
|
|
66
|
+
if (ln.covered) {
|
|
67
|
+
v8Lines.covered += 1;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return v8Lines;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const createEmptyCoverageInfo = () => {
|
|
75
|
+
|
|
76
|
+
// data for v8 UI
|
|
77
|
+
const data = {
|
|
78
|
+
bytes: [],
|
|
79
|
+
functions: [],
|
|
80
|
+
branches: []
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const branches = [];
|
|
84
|
+
|
|
85
|
+
const functions = [];
|
|
86
|
+
|
|
87
|
+
const lines = [];
|
|
88
|
+
// line 1 based
|
|
89
|
+
const lineMap = new Map();
|
|
90
|
+
|
|
91
|
+
const blankCount = 0;
|
|
92
|
+
const commentCount = 0;
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
// v8
|
|
97
|
+
data,
|
|
98
|
+
|
|
99
|
+
// istanbul
|
|
100
|
+
branches,
|
|
101
|
+
|
|
102
|
+
functions,
|
|
103
|
+
|
|
104
|
+
lines,
|
|
105
|
+
lineMap,
|
|
106
|
+
blankCount,
|
|
107
|
+
commentCount
|
|
108
|
+
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
19
112
|
// istanbul coverage format
|
|
20
113
|
/**
|
|
21
114
|
* * `path` - the file path for which coverage is being tracked
|
|
@@ -26,243 +119,387 @@ const InfoFunction = require('./info-function.js');
|
|
|
26
119
|
* * `f` - hit count for functions
|
|
27
120
|
* * `b` - hit count for branches
|
|
28
121
|
*/
|
|
29
|
-
const
|
|
122
|
+
const collectFileCoverage = (item, coverageInfo, state) => {
|
|
123
|
+
|
|
124
|
+
const { sourcePath } = item;
|
|
30
125
|
|
|
31
126
|
const {
|
|
32
|
-
|
|
33
|
-
|
|
127
|
+
// v8
|
|
128
|
+
data,
|
|
129
|
+
|
|
130
|
+
// istanbul
|
|
131
|
+
branches,
|
|
34
132
|
|
|
35
|
-
|
|
36
|
-
inputData.ranges = dedupeCountRanges(ranges);
|
|
133
|
+
functions,
|
|
37
134
|
|
|
38
|
-
|
|
39
|
-
|
|
135
|
+
lines,
|
|
136
|
+
blankCount,
|
|
137
|
+
commentCount
|
|
138
|
+
|
|
139
|
+
} = coverageInfo;
|
|
140
|
+
|
|
141
|
+
// ==========================================
|
|
142
|
+
// v8
|
|
143
|
+
data.bytes = dedupeCountRanges(data.bytes);
|
|
144
|
+
item.data = data;
|
|
145
|
+
item.summary = {
|
|
146
|
+
functions: calculateV8Functions(functions),
|
|
147
|
+
branches: calculateV8Branches(branches),
|
|
148
|
+
lines: calculateV8Lines(lines, blankCount, commentCount)
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// ==========================================
|
|
152
|
+
// istanbul
|
|
153
|
+
const istanbulCoverage = {
|
|
40
154
|
path: sourcePath,
|
|
41
155
|
|
|
42
156
|
statementMap: {},
|
|
43
|
-
s: {},
|
|
44
|
-
|
|
45
157
|
fnMap: {},
|
|
46
|
-
f: {},
|
|
47
|
-
|
|
48
158
|
branchMap: {},
|
|
159
|
+
|
|
160
|
+
s: {},
|
|
161
|
+
f: {},
|
|
49
162
|
b: {}
|
|
50
163
|
};
|
|
51
164
|
|
|
52
165
|
lines.forEach((line, index) => {
|
|
53
|
-
|
|
54
|
-
|
|
166
|
+
istanbulCoverage.statementMap[`${index}`] = line.generate();
|
|
167
|
+
istanbulCoverage.s[`${index}`] = line.count;
|
|
55
168
|
});
|
|
56
169
|
|
|
57
170
|
functions.forEach((fn, index) => {
|
|
58
|
-
|
|
59
|
-
|
|
171
|
+
istanbulCoverage.fnMap[`${index}`] = fn.generate();
|
|
172
|
+
istanbulCoverage.f[`${index}`] = fn.count;
|
|
60
173
|
});
|
|
61
174
|
|
|
62
175
|
branches.forEach((branch, index) => {
|
|
63
|
-
|
|
64
|
-
|
|
176
|
+
istanbulCoverage.branchMap[`${index}`] = branch.generate();
|
|
177
|
+
istanbulCoverage.b[`${index}`] = branch.generateCounts();
|
|
65
178
|
});
|
|
66
179
|
|
|
67
|
-
|
|
180
|
+
// append to dist file state
|
|
181
|
+
state.coverageData[sourcePath] = istanbulCoverage;
|
|
182
|
+
|
|
68
183
|
};
|
|
69
184
|
|
|
70
185
|
// ========================================================================================================
|
|
71
186
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
187
|
+
// https://github.com/demurgos/v8-coverage
|
|
188
|
+
/**
|
|
189
|
+
* @ranges is always non-empty. The first range is called the "root range".
|
|
190
|
+
* @isBlockCoverage indicates if the function has block coverage information
|
|
191
|
+
* @false means that there is a single range and its count is the number of times the function was called.
|
|
192
|
+
* @true means that the ranges form a tree of blocks representing how many times each statement or expression inside was executed.
|
|
193
|
+
* It detects skipped or repeated statements. The root range counts the number of function calls.
|
|
194
|
+
*
|
|
195
|
+
* @functionName can be an empty string. This is common for the FunctionCov representing the whole module.
|
|
196
|
+
*/
|
|
197
|
+
// if you have a line of code that says `var x= 10; console.log(x);` that's one line and 2 statements.
|
|
78
198
|
|
|
79
|
-
const
|
|
80
|
-
// nothing between
|
|
81
|
-
if (sLoc.column >= eLoc.column) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
199
|
+
const addJsLineCoverage = (state, range) => {
|
|
84
200
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
201
|
+
const { locator, coverageInfo } = state;
|
|
202
|
+
|
|
203
|
+
const { data, lineMap } = coverageInfo;
|
|
204
|
+
|
|
205
|
+
const {
|
|
206
|
+
startOffset, endOffset, count
|
|
207
|
+
} = range;
|
|
208
|
+
|
|
209
|
+
// add bytes range
|
|
210
|
+
data.bytes.push({
|
|
211
|
+
// index,
|
|
212
|
+
start: startOffset,
|
|
213
|
+
end: endOffset,
|
|
214
|
+
count
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const sLoc = locator.offsetToLocation(startOffset);
|
|
218
|
+
const eLoc = locator.offsetToLocation(endOffset);
|
|
219
|
+
|
|
220
|
+
// update lines coverage
|
|
221
|
+
const lines = Util.getRangeLines(sLoc, eLoc);
|
|
222
|
+
|
|
223
|
+
lines.forEach((it) => {
|
|
224
|
+
const line = lineMap.get(it.line);
|
|
225
|
+
if (!line) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// from outside into inside, uncovered is certain
|
|
230
|
+
// default is covered
|
|
231
|
+
if (it.entire) {
|
|
232
|
+
line.covered = count > 0;
|
|
233
|
+
line.count = count;
|
|
234
|
+
} else {
|
|
235
|
+
if (count > 0) {
|
|
236
|
+
line.count = count;
|
|
237
|
+
} else {
|
|
238
|
+
// not covered if any count = 0
|
|
239
|
+
line.covered = false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// if (!line.history) {
|
|
244
|
+
// line.history = [];
|
|
245
|
+
// }
|
|
246
|
+
// line.history.push(`${it.entire}-${count}`);
|
|
247
|
+
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// if (state.sourcePath.endsWith('component.js')) {
|
|
251
|
+
// console.log('===========================================', state.sourcePath);
|
|
252
|
+
// console.log(coverageInfo.lines);
|
|
253
|
+
// }
|
|
90
254
|
|
|
91
255
|
};
|
|
92
256
|
|
|
93
|
-
const
|
|
257
|
+
const addCssLineCoverage = (state, range) => {
|
|
94
258
|
|
|
95
|
-
|
|
96
|
-
if (sLoc.line === eLoc.line) {
|
|
97
|
-
setSingleLineCount(lineMap, sLoc, eLoc, count);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
259
|
+
const { coverageInfo, locator } = state;
|
|
100
260
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
261
|
+
const { lineMap, data } = coverageInfo;
|
|
262
|
+
|
|
263
|
+
const {
|
|
264
|
+
start, end, count
|
|
265
|
+
} = range;
|
|
266
|
+
|
|
267
|
+
if (count > 0) {
|
|
268
|
+
const sLoc = locator.offsetToLocation(start);
|
|
269
|
+
const eLoc = locator.offsetToLocation(end);
|
|
106
270
|
|
|
107
|
-
|
|
108
|
-
|
|
271
|
+
// covered css lines
|
|
272
|
+
const lines = Util.getRangeLines(sLoc, eLoc);
|
|
273
|
+
lines.forEach((it) => {
|
|
274
|
+
if (!it.entire) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const line = lineMap.get(it.line);
|
|
278
|
+
if (line) {
|
|
279
|
+
// default is uncovered
|
|
280
|
+
// count always 1, covered is certain
|
|
281
|
+
line.covered = true;
|
|
282
|
+
}
|
|
283
|
+
});
|
|
109
284
|
}
|
|
110
285
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
286
|
+
// add bytes range
|
|
287
|
+
data.bytes.push(range);
|
|
288
|
+
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// ========================================================================================================
|
|
116
292
|
|
|
293
|
+
const updateOffsetToLocation = (locator, loc) => {
|
|
294
|
+
const sLoc = locator.offsetToLocation(loc.start);
|
|
295
|
+
loc.start = {
|
|
296
|
+
line: sLoc.line,
|
|
297
|
+
column: sLoc.column
|
|
298
|
+
};
|
|
299
|
+
const eLoc = locator.offsetToLocation(loc.end);
|
|
300
|
+
loc.end = {
|
|
301
|
+
line: eLoc.line,
|
|
302
|
+
column: eLoc.column
|
|
303
|
+
};
|
|
117
304
|
};
|
|
118
305
|
|
|
119
|
-
const
|
|
306
|
+
const handleFunctionsCoverage = (state) => {
|
|
120
307
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const ranges = [];
|
|
308
|
+
// functions only for js
|
|
309
|
+
if (!state.js) {
|
|
310
|
+
// use css rules data for functions
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
127
313
|
|
|
128
|
-
|
|
129
|
-
|
|
314
|
+
const {
|
|
315
|
+
locator, coverageInfo, astInfo
|
|
316
|
+
} = state;
|
|
130
317
|
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
318
|
+
const v8Functions = coverageInfo.data.functions;
|
|
319
|
+
const istanbulFunctions = coverageInfo.functions;
|
|
320
|
+
|
|
321
|
+
astInfo.functions.forEach((it) => {
|
|
322
|
+
const {
|
|
323
|
+
start, end, functionName, count
|
|
324
|
+
} = it;
|
|
325
|
+
|
|
326
|
+
v8Functions.push({
|
|
327
|
+
start,
|
|
328
|
+
end,
|
|
329
|
+
count
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const loc = {
|
|
333
|
+
start,
|
|
334
|
+
end
|
|
335
|
+
};
|
|
336
|
+
updateOffsetToLocation(locator, loc);
|
|
337
|
+
const functionInfo = new InfoFunction(loc, count, functionName);
|
|
338
|
+
istanbulFunctions.push(functionInfo);
|
|
142
339
|
});
|
|
143
340
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
341
|
+
// if (state.sourcePath.endsWith('store.js')) {
|
|
342
|
+
// console.log('==========================================================');
|
|
343
|
+
// console.log(astInfo.functions);
|
|
344
|
+
// console.log(functions);
|
|
345
|
+
// }
|
|
346
|
+
|
|
147
347
|
};
|
|
148
348
|
|
|
349
|
+
const handleBranchesCoverage = (state) => {
|
|
149
350
|
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
* @false means that there is a single range and its count is the number of times the function was called.
|
|
155
|
-
* @true means that the ranges form a tree of blocks representing how many times each statement or expression inside was executed.
|
|
156
|
-
* It detects skipped or repeated statements. The root range counts the number of function calls.
|
|
157
|
-
*
|
|
158
|
-
* @functionName can be an empty string. This is common for the FunctionCov representing the whole module.
|
|
159
|
-
*/
|
|
160
|
-
const addJsCoverage = (coverage, block, range, index, positionMapping) => {
|
|
351
|
+
// functions only for js
|
|
352
|
+
if (!state.js) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
161
355
|
|
|
162
356
|
const {
|
|
163
|
-
|
|
164
|
-
} =
|
|
357
|
+
locator, coverageInfo, astInfo
|
|
358
|
+
} = state;
|
|
165
359
|
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
} = range;
|
|
360
|
+
const v8Branches = coverageInfo.data.branches;
|
|
361
|
+
const isTanbulBranches = coverageInfo.branches;
|
|
362
|
+
astInfo.branches.forEach((it) => {
|
|
170
363
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
364
|
+
const branchType = it.type;
|
|
365
|
+
const branchLoc = {
|
|
366
|
+
... it.loc
|
|
367
|
+
};
|
|
368
|
+
updateOffsetToLocation(locator, branchLoc);
|
|
176
369
|
|
|
177
|
-
|
|
178
|
-
|
|
370
|
+
// locations
|
|
371
|
+
// [ { start:{line,column}, end:{line,column}, count }, ...]
|
|
372
|
+
const locations = it.locations.map((oLoc) => {
|
|
373
|
+
const newLoc = {
|
|
374
|
+
... oLoc
|
|
375
|
+
};
|
|
376
|
+
if (newLoc.none) {
|
|
179
377
|
|
|
180
|
-
|
|
181
|
-
|
|
378
|
+
// the branch count is not very accurate
|
|
379
|
+
v8Branches.push({
|
|
380
|
+
start: it.loc.start,
|
|
381
|
+
end: it.loc.end,
|
|
382
|
+
count: oLoc.count,
|
|
383
|
+
none: true
|
|
384
|
+
});
|
|
182
385
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// The root range counts the number of function calls
|
|
186
|
-
functions.push(new InfoFunction(sLoc, eLoc, count, functionName));
|
|
187
|
-
}
|
|
386
|
+
return newLoc;
|
|
387
|
+
}
|
|
188
388
|
|
|
189
|
-
|
|
190
|
-
|
|
389
|
+
// the branch count is not very accurate
|
|
390
|
+
v8Branches.push({
|
|
391
|
+
start: oLoc.start,
|
|
392
|
+
end: oLoc.end,
|
|
393
|
+
count: oLoc.count
|
|
394
|
+
});
|
|
191
395
|
|
|
192
|
-
|
|
193
|
-
|
|
396
|
+
updateOffsetToLocation(locator, newLoc);
|
|
397
|
+
return newLoc;
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
const branchInfo = new InfoBranch(branchLoc, locations, branchType);
|
|
401
|
+
isTanbulBranches.push(branchInfo);
|
|
402
|
+
});
|
|
194
403
|
|
|
195
|
-
// possible have branches in the function but no information for it
|
|
196
404
|
|
|
197
|
-
}
|
|
198
405
|
};
|
|
199
406
|
|
|
200
|
-
const
|
|
201
|
-
|
|
407
|
+
const handleLinesCoverage = (state) => {
|
|
408
|
+
|
|
409
|
+
const {
|
|
410
|
+
js, locator, coverageInfo
|
|
411
|
+
} = state;
|
|
202
412
|
|
|
203
|
-
const
|
|
413
|
+
const lines = coverageInfo.lines;
|
|
414
|
+
const lineMap = coverageInfo.lineMap;
|
|
204
415
|
|
|
205
|
-
|
|
206
|
-
|
|
416
|
+
// init lines
|
|
417
|
+
let blankCount = 0;
|
|
418
|
+
let commentCount = 0;
|
|
207
419
|
|
|
208
|
-
//
|
|
209
|
-
|
|
420
|
+
// js: 1 (functions include all uncovered)
|
|
421
|
+
// css: 0 (ranges include all covered)
|
|
422
|
+
const baseLineCount = js ? 1 : 0;
|
|
210
423
|
|
|
424
|
+
locator.lines.forEach((it) => {
|
|
425
|
+
// exclude blank and comment
|
|
426
|
+
if (it.blank) {
|
|
427
|
+
blankCount += 1;
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (it.comment) {
|
|
431
|
+
commentCount += 1;
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
// line 1-base
|
|
435
|
+
const line = it.line + 1;
|
|
436
|
+
const lineInfo = new InfoLine(line, it.length, baseLineCount);
|
|
437
|
+
lineMap.set(line, lineInfo);
|
|
438
|
+
lines.push(lineInfo);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
coverageInfo.blankCount = blankCount;
|
|
442
|
+
coverageInfo.commentCount = commentCount;
|
|
211
443
|
};
|
|
212
444
|
|
|
213
|
-
|
|
445
|
+
const handleRangesCoverage = (state) => {
|
|
214
446
|
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
if (
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
addJsCoverage(coverage, block, range, index, positionMapping);
|
|
447
|
+
const { js, coverageList } = state;
|
|
448
|
+
|
|
449
|
+
if (js) {
|
|
450
|
+
coverageList.forEach((block) => {
|
|
451
|
+
block.ranges.forEach((range) => {
|
|
452
|
+
addJsLineCoverage(state, range);
|
|
222
453
|
});
|
|
223
454
|
});
|
|
224
|
-
|
|
455
|
+
|
|
456
|
+
} else {
|
|
457
|
+
coverageList.forEach((range) => {
|
|
458
|
+
addCssLineCoverage(state, range);
|
|
459
|
+
});
|
|
225
460
|
}
|
|
226
461
|
|
|
227
|
-
const coverage = initFileCoverage(positionMapping, 0);
|
|
228
|
-
item.ranges.forEach((range) => {
|
|
229
|
-
addCssCoverage(coverage, range, positionMapping);
|
|
230
|
-
});
|
|
231
|
-
return coverage;
|
|
232
462
|
};
|
|
233
463
|
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
state
|
|
238
|
-
|
|
239
|
-
|
|
464
|
+
const generateCoverageForDist = (item, state) => {
|
|
465
|
+
|
|
466
|
+
// handle coverage
|
|
467
|
+
handleFunctionsCoverage(state);
|
|
468
|
+
handleBranchesCoverage(state);
|
|
469
|
+
handleLinesCoverage(state);
|
|
470
|
+
handleRangesCoverage(state);
|
|
471
|
+
|
|
472
|
+
collectFileCoverage(item, state.coverageInfo, state);
|
|
473
|
+
|
|
240
474
|
};
|
|
241
475
|
|
|
242
476
|
// ========================================================================================================
|
|
243
477
|
|
|
244
|
-
const decodeSourceMappings = async (
|
|
478
|
+
const decodeSourceMappings = async (item, state, originalDecodedMap) => {
|
|
479
|
+
|
|
480
|
+
const generatedLocator = state.locator;
|
|
481
|
+
|
|
482
|
+
const { sources, mappings } = state.sourceMap;
|
|
245
483
|
|
|
246
|
-
const decodedList = await decodeMappings(
|
|
484
|
+
const decodedList = await decodeMappings(mappings);
|
|
247
485
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
originalIndexMap.set(i, []);
|
|
486
|
+
sources.forEach((source, i) => {
|
|
487
|
+
originalDecodedMap.set(i, []);
|
|
251
488
|
});
|
|
252
489
|
|
|
253
490
|
const allDecodedMappings = [];
|
|
254
491
|
let generatedIndex = 0;
|
|
255
492
|
decodedList.forEach((segments, generatedLine) => {
|
|
256
|
-
let
|
|
493
|
+
let info = null;
|
|
257
494
|
segments.forEach((segment) => {
|
|
258
495
|
const [generatedColumn, sourceIndex, originalLine, originalColumn] = segment;
|
|
259
|
-
const generatedOffset =
|
|
496
|
+
const generatedOffset = generatedLocator.locationToOffset({
|
|
260
497
|
// 1-base
|
|
261
498
|
line: generatedLine + 1,
|
|
262
499
|
column: generatedColumn
|
|
263
500
|
});
|
|
264
501
|
|
|
265
|
-
|
|
502
|
+
info = {
|
|
266
503
|
generatedOffset,
|
|
267
504
|
generatedLine,
|
|
268
505
|
generatedColumn,
|
|
@@ -273,22 +510,22 @@ const decodeSourceMappings = async (sourceMap, generatedPositionMapping) => {
|
|
|
273
510
|
originalColumn
|
|
274
511
|
};
|
|
275
512
|
|
|
276
|
-
allDecodedMappings.push(
|
|
513
|
+
allDecodedMappings.push(info);
|
|
277
514
|
generatedIndex += 1;
|
|
278
515
|
|
|
279
516
|
if (typeof sourceIndex === 'undefined') {
|
|
280
517
|
return;
|
|
281
518
|
}
|
|
282
519
|
|
|
283
|
-
|
|
520
|
+
originalDecodedMap.get(sourceIndex).push(info);
|
|
284
521
|
|
|
285
522
|
});
|
|
286
523
|
|
|
287
524
|
// line last one
|
|
288
|
-
if (
|
|
289
|
-
const line =
|
|
525
|
+
if (info) {
|
|
526
|
+
const line = generatedLocator.getLine(info.generatedLine + 1);
|
|
290
527
|
// last column
|
|
291
|
-
|
|
528
|
+
info.generatedEndOffset = info.generatedOffset + (line.length - info.generatedColumn);
|
|
292
529
|
}
|
|
293
530
|
|
|
294
531
|
});
|
|
@@ -298,16 +535,12 @@ const decodeSourceMappings = async (sourceMap, generatedPositionMapping) => {
|
|
|
298
535
|
// return a.generatedOffset - b.generatedOffset;
|
|
299
536
|
// });
|
|
300
537
|
|
|
301
|
-
return
|
|
302
|
-
allDecodedMappings,
|
|
303
|
-
originalIndexMap
|
|
304
|
-
};
|
|
305
|
-
|
|
538
|
+
return allDecodedMappings;
|
|
306
539
|
};
|
|
307
540
|
|
|
308
|
-
const getOriginalDecodedMappings = (
|
|
541
|
+
const getOriginalDecodedMappings = (originalDecodedMap, sourceIndex, locator) => {
|
|
309
542
|
// all mappings for the original file sorted
|
|
310
|
-
const decodedMappings =
|
|
543
|
+
const decodedMappings = originalDecodedMap.get(sourceIndex);
|
|
311
544
|
|
|
312
545
|
if (!decodeMappings) {
|
|
313
546
|
return [];
|
|
@@ -324,7 +557,7 @@ const getOriginalDecodedMappings = (originalIndexMap, sourceIndex, positionMappi
|
|
|
324
557
|
// add offset and index
|
|
325
558
|
decodedMappings.forEach((item, i) => {
|
|
326
559
|
item.originalIndex = i;
|
|
327
|
-
item.originalOffset =
|
|
560
|
+
item.originalOffset = locator.locationToOffset({
|
|
328
561
|
line: item.originalLine + 1,
|
|
329
562
|
column: item.originalColumn
|
|
330
563
|
});
|
|
@@ -333,19 +566,20 @@ const getOriginalDecodedMappings = (originalIndexMap, sourceIndex, positionMappi
|
|
|
333
566
|
return decodedMappings;
|
|
334
567
|
};
|
|
335
568
|
|
|
336
|
-
const initOriginalList = (
|
|
569
|
+
const initOriginalList = (item, state, originalDecodedMap, options) => {
|
|
337
570
|
|
|
338
571
|
// source filter
|
|
339
|
-
const { sources, sourcesContent } = sourceMap;
|
|
340
|
-
|
|
341
572
|
let sourceFilter = options.sourceFilter;
|
|
342
573
|
if (typeof sourceFilter !== 'function') {
|
|
343
574
|
sourceFilter = () => true;
|
|
344
575
|
}
|
|
345
576
|
|
|
577
|
+
const fileSources = state.fileSources;
|
|
578
|
+
|
|
346
579
|
// create original content mappings
|
|
347
|
-
const
|
|
580
|
+
const originalMap = new Map();
|
|
348
581
|
|
|
582
|
+
const { sources, sourcesContent } = state.sourceMap;
|
|
349
583
|
sources.forEach((sourcePath, sourceIndex) => {
|
|
350
584
|
|
|
351
585
|
// filter
|
|
@@ -363,83 +597,49 @@ const initOriginalList = (sourceMap, originalIndexMap, fileSources, options) =>
|
|
|
363
597
|
// keep original formatted content
|
|
364
598
|
fileSources[sourcePath] = sourceContent;
|
|
365
599
|
|
|
366
|
-
const
|
|
600
|
+
const locator = new Locator(sourceContent);
|
|
367
601
|
|
|
368
|
-
const decodedMappings = getOriginalDecodedMappings(
|
|
602
|
+
const decodedMappings = getOriginalDecodedMappings(originalDecodedMap, sourceIndex, locator);
|
|
369
603
|
|
|
370
|
-
|
|
604
|
+
// unpacked file always is js
|
|
371
605
|
|
|
372
606
|
const type = getSourceType(sourcePath);
|
|
373
607
|
|
|
374
608
|
const originalState = {
|
|
375
|
-
|
|
609
|
+
original: true,
|
|
610
|
+
// only js sourceMap for now
|
|
611
|
+
js: true,
|
|
376
612
|
type,
|
|
377
613
|
sourcePath,
|
|
378
|
-
|
|
614
|
+
source: sourceContent,
|
|
615
|
+
locator,
|
|
379
616
|
decodedMappings,
|
|
380
|
-
|
|
617
|
+
coverageInfo: createEmptyCoverageInfo(),
|
|
618
|
+
astInfo: {
|
|
619
|
+
functions: [],
|
|
620
|
+
branches: []
|
|
621
|
+
}
|
|
381
622
|
};
|
|
382
623
|
|
|
383
|
-
|
|
624
|
+
originalMap.set(sourceIndex, originalState);
|
|
384
625
|
});
|
|
385
626
|
|
|
386
|
-
return
|
|
627
|
+
return originalMap;
|
|
387
628
|
};
|
|
388
629
|
|
|
389
|
-
const
|
|
390
|
-
const sourceMap = item.sourceMap;
|
|
391
|
-
const generatedPositionMapping = state.positionMapping;
|
|
392
|
-
const distFile = sourceMap.file || path.basename(item.sourcePath);
|
|
393
|
-
|
|
394
|
-
// keep original urls
|
|
395
|
-
const fileUrls = {};
|
|
396
|
-
const sourcePathHandler = options.sourcePath;
|
|
397
|
-
initSourceMapSourcePath(sourceMap, fileUrls, sourcePathHandler);
|
|
398
|
-
|
|
399
|
-
// decode mappings for each original file
|
|
400
|
-
const time_start_decode = Date.now();
|
|
401
|
-
const { allDecodedMappings, originalIndexMap } = await decodeSourceMappings(sourceMap, generatedPositionMapping);
|
|
402
|
-
// only debug level
|
|
403
|
-
Util.logTime(`decode source mappings ${distFile}`, time_start_decode);
|
|
404
|
-
|
|
405
|
-
// filter original list and init list
|
|
406
|
-
const fileSources = state.fileSources;
|
|
407
|
-
const originalMap = initOriginalList(sourceMap, originalIndexMap, fileSources, options);
|
|
408
|
-
|
|
409
|
-
originalIndexMap.clear();
|
|
630
|
+
const collectOriginalList = (item, state, originalMap) => {
|
|
410
631
|
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
positionMapping: generatedPositionMapping
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// const time_start_mapping = Date.now();
|
|
417
|
-
item.functions.forEach((block) => {
|
|
418
|
-
block.ranges.forEach((range, index) => {
|
|
419
|
-
|
|
420
|
-
const result = findOriginalRange(range, generatedState, originalMap);
|
|
421
|
-
if (!result) {
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const { originalRange, originalState } = result;
|
|
426
|
-
const { coverage, positionMapping } = originalState;
|
|
427
|
-
addJsCoverage(coverage, block, originalRange, index, positionMapping);
|
|
428
|
-
|
|
429
|
-
});
|
|
430
|
-
});
|
|
632
|
+
const { fileUrls, sourceMap } = state;
|
|
633
|
+
const distFile = sourceMap.file || path.basename(item.sourcePath);
|
|
431
634
|
|
|
432
635
|
// collect original files
|
|
433
636
|
const sourceList = [];
|
|
434
637
|
originalMap.forEach((originalState) => {
|
|
638
|
+
|
|
435
639
|
const {
|
|
436
|
-
|
|
640
|
+
js, type, sourcePath, source, coverageInfo
|
|
437
641
|
} = originalState;
|
|
438
642
|
|
|
439
|
-
// generate coverage
|
|
440
|
-
state.coverageData[sourcePath] = getFileCoverage(sourcePath, coverage);
|
|
441
|
-
const ranges = coverage.ranges;
|
|
442
|
-
|
|
443
643
|
// add file item
|
|
444
644
|
const url = fileUrls[sourcePath] || sourcePath;
|
|
445
645
|
const id = Util.calculateSha1(url + source);
|
|
@@ -447,17 +647,257 @@ const unpackSourceMap = async (item, state, options) => {
|
|
|
447
647
|
const sourceItem = {
|
|
448
648
|
url,
|
|
449
649
|
id,
|
|
650
|
+
js,
|
|
450
651
|
type,
|
|
451
652
|
sourcePath,
|
|
452
653
|
distFile,
|
|
453
|
-
ranges,
|
|
454
654
|
source
|
|
455
655
|
};
|
|
456
656
|
|
|
657
|
+
// generate coverage, coverageInfo for current file, state for dist file
|
|
658
|
+
collectFileCoverage(sourceItem, coverageInfo, state);
|
|
659
|
+
|
|
457
660
|
sourceList.push(sourceItem);
|
|
458
661
|
});
|
|
459
662
|
|
|
460
|
-
|
|
663
|
+
return sourceList;
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
// =======================================================================================
|
|
667
|
+
|
|
668
|
+
const handleOriginalFunctionsCoverage = (state, originalMap) => {
|
|
669
|
+
|
|
670
|
+
// functions only for js
|
|
671
|
+
if (!state.js) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// console.log(state.astInfo.functions);
|
|
676
|
+
|
|
677
|
+
// function count
|
|
678
|
+
state.astInfo.functions.forEach((it) => {
|
|
679
|
+
const {
|
|
680
|
+
start, end, wrap
|
|
681
|
+
} = it;
|
|
682
|
+
|
|
683
|
+
// remove webpack wrap functions for functions count, not for ranges here
|
|
684
|
+
if (wrap) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// rename to startOffset and endOffset
|
|
689
|
+
const range = {
|
|
690
|
+
startOffset: start,
|
|
691
|
+
endOffset: end
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
const result = findOriginalRange(range, state, originalMap);
|
|
695
|
+
if (result.error) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
const { originalRange, originalState } = result;
|
|
699
|
+
|
|
700
|
+
// add back to original ast
|
|
701
|
+
originalState.astInfo.functions.push({
|
|
702
|
+
... it,
|
|
703
|
+
generatedStart: start,
|
|
704
|
+
generatedEnd: end,
|
|
705
|
+
start: originalRange.startOffset,
|
|
706
|
+
end: originalRange.endOffset
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// if (originalState.sourcePath.endsWith('store.js')) {
|
|
710
|
+
// console.log('==========================================================');
|
|
711
|
+
// console.log(it, result.startMapping, result.endMapping);
|
|
712
|
+
// }
|
|
713
|
+
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
const handleOriginalBranchesCoverage = (state, originalMap) => {
|
|
719
|
+
|
|
720
|
+
// branches only for js
|
|
721
|
+
if (!state.js) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// console.log(state.astInfo.branches);
|
|
726
|
+
|
|
727
|
+
// function count
|
|
728
|
+
state.astInfo.branches.forEach((it) => {
|
|
729
|
+
|
|
730
|
+
const {
|
|
731
|
+
type, loc, locations
|
|
732
|
+
} = it;
|
|
733
|
+
|
|
734
|
+
// rename to startOffset and endOffset
|
|
735
|
+
const bRange = {
|
|
736
|
+
startOffset: loc.start,
|
|
737
|
+
endOffset: loc.end
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
// start
|
|
741
|
+
const result = findOriginalRange(bRange, state, originalMap);
|
|
742
|
+
if (result.error) {
|
|
743
|
+
// not in the original files
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const { originalRange, originalState } = result;
|
|
747
|
+
|
|
748
|
+
const newBranchLoc = {
|
|
749
|
+
start: originalRange.startOffset,
|
|
750
|
+
end: originalRange.endOffset
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
let hasError;
|
|
754
|
+
const newLocations = locations.map((oLoc) => {
|
|
755
|
+
|
|
756
|
+
const newLoc = {
|
|
757
|
+
... oLoc
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
if (newLoc.none) {
|
|
761
|
+
return newLoc;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
const { start, end } = newLoc;
|
|
765
|
+
|
|
766
|
+
const lRange = {
|
|
767
|
+
startOffset: start,
|
|
768
|
+
endOffset: end
|
|
769
|
+
};
|
|
770
|
+
const res = findOriginalRange(lRange, state, originalMap);
|
|
771
|
+
if (res.error) {
|
|
772
|
+
// It should not happen unless it is minify files, the SourceMap has some order problems
|
|
773
|
+
|
|
774
|
+
hasError = true;
|
|
775
|
+
|
|
776
|
+
// console.log('====================================', state.sourcePath, loc);
|
|
777
|
+
// console.log(res.errors);
|
|
778
|
+
// Util.logError(`Not found original branch. start: ${start}, end: ${end}`);
|
|
779
|
+
|
|
780
|
+
return newLoc;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
const oRage = res.originalRange;
|
|
784
|
+
newLoc.start = oRage.startOffset;
|
|
785
|
+
newLoc.end = oRage.endOffset;
|
|
786
|
+
|
|
787
|
+
return newLoc;
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
if (hasError) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// add back to original ast
|
|
795
|
+
originalState.astInfo.branches.push({
|
|
796
|
+
type,
|
|
797
|
+
loc: newBranchLoc,
|
|
798
|
+
locations: newLocations
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
const handleOriginalRangesCoverage = (state, originalMap) => {
|
|
806
|
+
|
|
807
|
+
const { js, coverageList } = state;
|
|
808
|
+
|
|
809
|
+
// const time_start_mapping = Date.now();
|
|
810
|
+
if (js) {
|
|
811
|
+
// v8 coverage
|
|
812
|
+
coverageList.forEach((block) => {
|
|
813
|
+
block.ranges.forEach((range, index) => {
|
|
814
|
+
|
|
815
|
+
// remove wrap functions for original files
|
|
816
|
+
if (range.wrap) {
|
|
817
|
+
// console.log(range);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
const result = findOriginalRange(range, state, originalMap);
|
|
822
|
+
if (result.error) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
const { originalRange, originalState } = result;
|
|
827
|
+
addJsLineCoverage(originalState, originalRange);
|
|
828
|
+
|
|
829
|
+
// if (originalRange.startOffset === 110 && originalRange.endOffset === 271) {
|
|
830
|
+
// console.log('===============================', originalState.sourcePath);
|
|
831
|
+
// console.log(result.startMapping, result.endMapping);
|
|
832
|
+
// }
|
|
833
|
+
|
|
834
|
+
});
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
} else {
|
|
838
|
+
// support css later
|
|
839
|
+
// current css no sourceMap, so never come in
|
|
840
|
+
// coverageList.forEach((range) => {
|
|
841
|
+
|
|
842
|
+
// });
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
const unpackSourceMap = async (item, state, options) => {
|
|
848
|
+
|
|
849
|
+
const { sourcePath } = item;
|
|
850
|
+
const sourceMap = state.sourceMap;
|
|
851
|
+
|
|
852
|
+
// keep original urls
|
|
853
|
+
const fileUrls = {};
|
|
854
|
+
const sourcePathHandler = options.sourcePath;
|
|
855
|
+
initSourceMapSourcePath(sourceMap, fileUrls, sourcePathHandler);
|
|
856
|
+
state.fileUrls = fileUrls;
|
|
857
|
+
|
|
858
|
+
// ===============================================
|
|
859
|
+
// decode mappings for each original file
|
|
860
|
+
const time_start_decode = Date.now();
|
|
861
|
+
const originalDecodedMap = new Map();
|
|
862
|
+
// for find-original-range
|
|
863
|
+
state.decodedMappings = await decodeSourceMappings(item, state, originalDecodedMap);
|
|
864
|
+
// only debug level
|
|
865
|
+
Util.logTime(`decode source mappings: ${sourcePath}`, time_start_decode);
|
|
866
|
+
|
|
867
|
+
// filter original list and init list
|
|
868
|
+
const originalMap = initOriginalList(item, state, originalDecodedMap, options);
|
|
869
|
+
|
|
870
|
+
originalDecodedMap.clear();
|
|
871
|
+
|
|
872
|
+
// ===============================================
|
|
873
|
+
|
|
874
|
+
// handle functions before handle original state functions
|
|
875
|
+
handleOriginalFunctionsCoverage(state, originalMap);
|
|
876
|
+
handleOriginalBranchesCoverage(state, originalMap);
|
|
877
|
+
|
|
878
|
+
// handle lines info before handle ranges to update line count
|
|
879
|
+
originalMap.forEach((originalState) => {
|
|
880
|
+
handleFunctionsCoverage(originalState);
|
|
881
|
+
handleBranchesCoverage(originalState);
|
|
882
|
+
handleLinesCoverage(originalState);
|
|
883
|
+
|
|
884
|
+
// console.log(originalState.sourcePath, '================================');
|
|
885
|
+
// console.log(originalState.astInfo.functions);
|
|
886
|
+
// console.log(originalState.source.length);
|
|
887
|
+
// console.log(originalState.coverageInfo.functions);
|
|
888
|
+
|
|
889
|
+
// if (originalState.sourcePath.endsWith('demo.js')) {
|
|
890
|
+
// console.log('=================================', originalState.sourcePath);
|
|
891
|
+
// console.log(originalState.coverageInfo.lineMap);
|
|
892
|
+
// }
|
|
893
|
+
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
// handle ranges after lines ready
|
|
897
|
+
handleOriginalRangesCoverage(state, originalMap);
|
|
898
|
+
|
|
899
|
+
// collect coverage for original list
|
|
900
|
+
state.sourceList = collectOriginalList(item, state, originalMap);
|
|
461
901
|
|
|
462
902
|
};
|
|
463
903
|
|
|
@@ -465,10 +905,10 @@ const unpackSourceMap = async (item, state, options) => {
|
|
|
465
905
|
|
|
466
906
|
const unpackDistFile = async (item, state, options) => {
|
|
467
907
|
|
|
468
|
-
if (
|
|
908
|
+
if (state.sourceMap) {
|
|
469
909
|
if (Util.loggingType === 'debug') {
|
|
470
910
|
// js self
|
|
471
|
-
|
|
911
|
+
generateCoverageForDist(item, state);
|
|
472
912
|
} else {
|
|
473
913
|
item.dedupe = true;
|
|
474
914
|
}
|
|
@@ -476,19 +916,13 @@ const unpackDistFile = async (item, state, options) => {
|
|
|
476
916
|
// unpack source map
|
|
477
917
|
await unpackSourceMap(item, state, options);
|
|
478
918
|
|
|
479
|
-
// remove sourceMap
|
|
480
|
-
delete item.sourceMap;
|
|
481
|
-
|
|
482
919
|
} else {
|
|
483
920
|
|
|
484
921
|
// css/js self
|
|
485
|
-
|
|
922
|
+
generateCoverageForDist(item, state);
|
|
486
923
|
|
|
487
924
|
}
|
|
488
925
|
|
|
489
|
-
// clean after all
|
|
490
|
-
delete item.functions;
|
|
491
|
-
|
|
492
926
|
};
|
|
493
927
|
|
|
494
928
|
// ========================================================================================================
|
|
@@ -508,7 +942,6 @@ const dedupeV8List = (v8list) => {
|
|
|
508
942
|
}
|
|
509
943
|
};
|
|
510
944
|
|
|
511
|
-
|
|
512
945
|
const convertV8List = async (v8list, options) => {
|
|
513
946
|
|
|
514
947
|
// global file sources and coverage data
|
|
@@ -519,18 +952,68 @@ const convertV8List = async (v8list, options) => {
|
|
|
519
952
|
for (const item of v8list) {
|
|
520
953
|
// console.log([item.id]);
|
|
521
954
|
|
|
522
|
-
const {
|
|
955
|
+
const {
|
|
956
|
+
type, source, sourcePath
|
|
957
|
+
} = item;
|
|
523
958
|
|
|
524
|
-
|
|
959
|
+
// for source file, type could be ts or vue as extname, but js = true
|
|
960
|
+
const js = type === 'js';
|
|
961
|
+
item.js = js;
|
|
525
962
|
|
|
526
963
|
// append file source
|
|
527
964
|
fileSources[sourcePath] = source;
|
|
528
965
|
|
|
966
|
+
// source mapping
|
|
967
|
+
const locator = new Locator(source);
|
|
968
|
+
|
|
969
|
+
// ============================
|
|
970
|
+
// move sourceMap
|
|
971
|
+
const sourceMap = item.sourceMap;
|
|
972
|
+
if (sourceMap) {
|
|
973
|
+
delete item.sourceMap;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// ============================
|
|
977
|
+
const coverageInfo = createEmptyCoverageInfo();
|
|
978
|
+
|
|
979
|
+
// ============================
|
|
980
|
+
// move functions and ranges to coverageList
|
|
981
|
+
let coverageList;
|
|
982
|
+
let astInfo;
|
|
983
|
+
if (js) {
|
|
984
|
+
coverageList = item.functions;
|
|
985
|
+
// remove original functions
|
|
986
|
+
if (Util.loggingType !== 'debug') {
|
|
987
|
+
delete item.functions;
|
|
988
|
+
}
|
|
989
|
+
astInfo = getJsAstInfo(item, coverageList);
|
|
990
|
+
} else {
|
|
991
|
+
astInfo = getCssAstInfo(item, locator);
|
|
992
|
+
// convent css covered ranges to rules ranges and include uncovered ranges
|
|
993
|
+
coverageList = astInfo.coverageList;
|
|
994
|
+
// console.log(coverageList);
|
|
995
|
+
|
|
996
|
+
// remove original ranges
|
|
997
|
+
if (Util.loggingType !== 'debug') {
|
|
998
|
+
delete item.ranges;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// ============================
|
|
1003
|
+
|
|
529
1004
|
// current file and it's sources from sourceMap
|
|
530
1005
|
const state = {
|
|
1006
|
+
js,
|
|
1007
|
+
type,
|
|
1008
|
+
sourcePath,
|
|
1009
|
+
sourceMap,
|
|
1010
|
+
coverageList,
|
|
1011
|
+
locator,
|
|
1012
|
+
coverageInfo,
|
|
1013
|
+
astInfo,
|
|
1014
|
+
// for istanbul data
|
|
531
1015
|
fileSources: {},
|
|
532
|
-
coverageData: {}
|
|
533
|
-
positionMapping
|
|
1016
|
+
coverageData: {}
|
|
534
1017
|
};
|
|
535
1018
|
|
|
536
1019
|
await unpackDistFile(item, state, options);
|