monocart-coverage-reports 2.5.9 → 2.6.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/LICENSE +21 -21
- package/README.md +791 -778
- package/lib/cli.js +250 -215
- package/lib/converter/ast-visitor.js +675 -666
- package/lib/converter/ast.js +353 -353
- package/lib/converter/collect-source-maps.js +201 -201
- package/lib/converter/converter.js +1487 -1429
- package/lib/converter/find-original-range.js +737 -737
- package/lib/converter/ignore.js +163 -163
- package/lib/converter/info-branch.js +93 -93
- package/lib/converter/info-function.js +63 -63
- package/lib/converter/info-statement.js +43 -43
- package/lib/default/options.js +84 -84
- package/lib/default/template.html +47 -47
- package/lib/generate.js +720 -532
- package/lib/index.d.ts +360 -324
- package/lib/index.js +187 -180
- package/lib/index.mjs +5 -3
- package/lib/istanbul/istanbul-summary.js +70 -63
- package/lib/istanbul/istanbul.js +146 -146
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/platform/concurrency.js +74 -74
- package/lib/platform/share.js +484 -484
- package/lib/utils/dedupe.js +118 -118
- package/lib/utils/request.js +62 -62
- package/lib/utils/snapshot.js +381 -0
- package/lib/utils/source-path.js +179 -179
- package/lib/utils/util.js +526 -526
- package/lib/v8/v8-summary.js +138 -138
- package/lib/v8/v8.js +400 -630
- package/package.json +81 -80
package/lib/v8/v8.js
CHANGED
|
@@ -1,630 +1,400 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
// empty coverage
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
data.
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
mergeMap[id]
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
item.
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
let subs = groups;
|
|
402
|
-
pathList.forEach((key) => {
|
|
403
|
-
const item = subs.find((it) => it.name === key && it.subs);
|
|
404
|
-
if (item) {
|
|
405
|
-
subs = item.subs;
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
const sub = {
|
|
409
|
-
name: key,
|
|
410
|
-
subs: []
|
|
411
|
-
};
|
|
412
|
-
subs.push(sub);
|
|
413
|
-
subs = sub.subs;
|
|
414
|
-
});
|
|
415
|
-
const fileRow = getRowData(lastName, summary, metrics);
|
|
416
|
-
fileRow.uncoveredLines = getUncoveredLines(file);
|
|
417
|
-
subs.push(fileRow);
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
const group = {
|
|
421
|
-
subs: groups
|
|
422
|
-
};
|
|
423
|
-
mergeSingleSubGroups(group);
|
|
424
|
-
|
|
425
|
-
if (group.name) {
|
|
426
|
-
groups = [group];
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return groups;
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const handleConsoleDetailsReport = (reportData, reportOptions, options) => {
|
|
433
|
-
const cdOptions = {
|
|
434
|
-
maxCols: 50,
|
|
435
|
-
skipPercent: 0,
|
|
436
|
-
metrics: [],
|
|
437
|
-
... reportOptions
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
const {
|
|
441
|
-
name, summary, files
|
|
442
|
-
} = reportData;
|
|
443
|
-
|
|
444
|
-
if (name) {
|
|
445
|
-
EC.logCyan(name);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const metrics = Util.getMetrics('v8', cdOptions.metrics);
|
|
449
|
-
const rows = getGroupedRows(files, metrics, cdOptions);
|
|
450
|
-
const summaryRow = getRowData('Summary', summary, metrics);
|
|
451
|
-
// no rows if skipped all by skipPercent
|
|
452
|
-
if (rows.length) {
|
|
453
|
-
rows.push({
|
|
454
|
-
innerBorder: true
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
rows.push(summaryRow);
|
|
458
|
-
|
|
459
|
-
const columns = [{
|
|
460
|
-
id: 'name',
|
|
461
|
-
name: 'Name'
|
|
462
|
-
}, ... metrics.map((m) => {
|
|
463
|
-
return {
|
|
464
|
-
id: m,
|
|
465
|
-
name: Util.capitalizeFirstLetter(m),
|
|
466
|
-
align: 'right'
|
|
467
|
-
};
|
|
468
|
-
}), {
|
|
469
|
-
id: 'uncoveredLines',
|
|
470
|
-
name: 'Uncovered Lines'
|
|
471
|
-
}];
|
|
472
|
-
|
|
473
|
-
CG({
|
|
474
|
-
options: {
|
|
475
|
-
nullPlaceholder: '',
|
|
476
|
-
defaultMaxWidth: cdOptions.maxCols
|
|
477
|
-
},
|
|
478
|
-
columns,
|
|
479
|
-
rows
|
|
480
|
-
});
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
const handleCodecovReport = async (reportData, reportOptions, options) => {
|
|
484
|
-
const codecovOptions = {
|
|
485
|
-
outputFile: 'codecov.json',
|
|
486
|
-
... reportOptions
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
const jsonPath = path.resolve(options.outputDir, codecovOptions.outputFile);
|
|
490
|
-
|
|
491
|
-
// https://docs.codecov.com/docs/codecov-custom-coverage-format
|
|
492
|
-
const coverage = {};
|
|
493
|
-
reportData.files.forEach((item) => {
|
|
494
|
-
const { sourcePath, data } = item;
|
|
495
|
-
coverage[sourcePath] = data.lines;
|
|
496
|
-
});
|
|
497
|
-
const codecovData = {
|
|
498
|
-
coverage
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
await Util.writeFile(jsonPath, JSON.stringify(codecovData));
|
|
502
|
-
return Util.relativePath(jsonPath);
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
const handleV8JsonReport = async (reportData, reportOptions, options) => {
|
|
506
|
-
const v8JsonOptions = {
|
|
507
|
-
outputFile: 'coverage-report.json',
|
|
508
|
-
... reportOptions
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
// console.log(mergedOptions);
|
|
512
|
-
const jsonPath = path.resolve(options.outputDir, v8JsonOptions.outputFile);
|
|
513
|
-
await Util.writeFile(jsonPath, JSON.stringify(reportData));
|
|
514
|
-
return Util.relativePath(jsonPath);
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const handleV8HtmlReport = async (reportData, reportOptions, options) => {
|
|
519
|
-
|
|
520
|
-
// V8 only options, merged with root options
|
|
521
|
-
const v8HtmlOptions = {
|
|
522
|
-
outputFile: options.outputFile,
|
|
523
|
-
inline: options.inline,
|
|
524
|
-
assetsPath: options.assetsPath,
|
|
525
|
-
metrics: options.metrics,
|
|
526
|
-
... reportOptions
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
// add metrics to data for UI
|
|
530
|
-
reportData.metrics = v8HtmlOptions.metrics;
|
|
531
|
-
|
|
532
|
-
const {
|
|
533
|
-
outputFile, inline, assetsPath
|
|
534
|
-
} = v8HtmlOptions;
|
|
535
|
-
|
|
536
|
-
// resolve full report path
|
|
537
|
-
const reportPath = path.resolve(options.outputDir, outputFile);
|
|
538
|
-
const outputDir = path.dirname(reportPath);
|
|
539
|
-
const htmlFile = path.basename(reportPath);
|
|
540
|
-
|
|
541
|
-
// deps
|
|
542
|
-
const jsFiles = ['monocart-code-viewer', 'monocart-formatter', 'turbogrid'].map((it) => {
|
|
543
|
-
return Util.resolveNodeModule(`${it}/dist/${it}.js`);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
// package v8 ui
|
|
547
|
-
jsFiles.push(Util.resolvePackage('monocart-coverage-v8.js'));
|
|
548
|
-
|
|
549
|
-
// console.log(jsFiles);
|
|
550
|
-
|
|
551
|
-
const htmlOptions = {
|
|
552
|
-
reportData,
|
|
553
|
-
jsFiles,
|
|
554
|
-
inline,
|
|
555
|
-
assetsPath,
|
|
556
|
-
outputDir,
|
|
557
|
-
htmlFile,
|
|
558
|
-
|
|
559
|
-
reportDataFile: 'coverage-data.js'
|
|
560
|
-
};
|
|
561
|
-
|
|
562
|
-
const htmlPath = await Util.saveHtmlReport(htmlOptions);
|
|
563
|
-
|
|
564
|
-
return htmlPath;
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
const saveV8Report = async (v8list, options) => {
|
|
568
|
-
|
|
569
|
-
const defaultWatermarks = {
|
|
570
|
-
bytes: [50, 80],
|
|
571
|
-
statements: [50, 80],
|
|
572
|
-
branches: [50, 80],
|
|
573
|
-
functions: [50, 80],
|
|
574
|
-
lines: [50, 80]
|
|
575
|
-
};
|
|
576
|
-
const watermarks = Util.resolveWatermarks(defaultWatermarks, options.watermarks);
|
|
577
|
-
|
|
578
|
-
const summary = getV8Summary(v8list, watermarks);
|
|
579
|
-
|
|
580
|
-
const reportData = {
|
|
581
|
-
name: options.name,
|
|
582
|
-
version,
|
|
583
|
-
watermarks,
|
|
584
|
-
summary,
|
|
585
|
-
files: v8list
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
// v8 reports
|
|
589
|
-
const buildInV8Reports = {
|
|
590
|
-
'v8': handleV8HtmlReport,
|
|
591
|
-
'v8-json': handleV8JsonReport,
|
|
592
|
-
'codecov': handleCodecovReport,
|
|
593
|
-
'console-details': handleConsoleDetailsReport
|
|
594
|
-
};
|
|
595
|
-
|
|
596
|
-
const outputs = {};
|
|
597
|
-
const v8Group = options.reportGroup.v8;
|
|
598
|
-
const v8Reports = Object.keys(v8Group);
|
|
599
|
-
for (const reportName of v8Reports) {
|
|
600
|
-
const reportOptions = v8Group[reportName];
|
|
601
|
-
const buildInHandler = buildInV8Reports[reportName];
|
|
602
|
-
if (buildInHandler) {
|
|
603
|
-
outputs[reportName] = await buildInHandler(reportData, reportOptions, options);
|
|
604
|
-
} else {
|
|
605
|
-
outputs[reportName] = await Util.runCustomReporter(reportName, reportData, reportOptions, options);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
// outputPath, should be html or json
|
|
610
|
-
const reportPath = Util.resolveReportPath(options, () => {
|
|
611
|
-
return outputs.v8 || outputs['v8-json'] || Object.values(outputs).filter((it) => it && typeof it === 'string').shift();
|
|
612
|
-
});
|
|
613
|
-
|
|
614
|
-
const coverageResults = {
|
|
615
|
-
type: 'v8',
|
|
616
|
-
reportPath,
|
|
617
|
-
name: options.name,
|
|
618
|
-
watermarks,
|
|
619
|
-
summary,
|
|
620
|
-
files: v8list
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
return coverageResults;
|
|
624
|
-
};
|
|
625
|
-
|
|
626
|
-
module.exports = {
|
|
627
|
-
initV8ListAndSourcemap,
|
|
628
|
-
mergeV8Coverage,
|
|
629
|
-
saveV8Report
|
|
630
|
-
};
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const Util = require('../utils/util.js');
|
|
3
|
+
const { getV8Summary } = require('./v8-summary.js');
|
|
4
|
+
const { dedupeFlatRanges } = require('../utils/dedupe.js');
|
|
5
|
+
const { getSourcePath, getSourcePathHandler } = require('../utils/source-path.js');
|
|
6
|
+
const { mergeScriptCovs, minimatch } = require('../packages/monocart-coverage-vendor.js');
|
|
7
|
+
const { collectSourceMaps } = require('../converter/collect-source-maps.js');
|
|
8
|
+
const version = require('../../package.json').version;
|
|
9
|
+
|
|
10
|
+
const getWrapperSource = (offset, source) => {
|
|
11
|
+
// NO \n because it break line number in mappings
|
|
12
|
+
let startStr = '';
|
|
13
|
+
if (offset >= 4) {
|
|
14
|
+
// fill comments
|
|
15
|
+
const spaces = ''.padEnd(offset - 4, '*');
|
|
16
|
+
startStr = `/*${spaces}*/`;
|
|
17
|
+
} else {
|
|
18
|
+
// fill spaces (should no chance)
|
|
19
|
+
startStr += ''.padEnd(offset, ' ');
|
|
20
|
+
}
|
|
21
|
+
return startStr + source;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getEntryFilter = (options) => {
|
|
25
|
+
const input = options.entryFilter;
|
|
26
|
+
|
|
27
|
+
// for function handler
|
|
28
|
+
if (typeof input === 'function') {
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// for single minimatch pattern
|
|
33
|
+
if (input && typeof input === 'string') {
|
|
34
|
+
return (entry) => {
|
|
35
|
+
return minimatch(entry.url, input);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// for patterns
|
|
40
|
+
if (input && typeof input === 'object') {
|
|
41
|
+
const patterns = Object.keys(input);
|
|
42
|
+
return (entry) => {
|
|
43
|
+
const url = entry.url;
|
|
44
|
+
for (const pattern of patterns) {
|
|
45
|
+
if (minimatch(url, pattern)) {
|
|
46
|
+
return input[pattern];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// false if not matched
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// default
|
|
54
|
+
return () => true;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const initV8ListAndSourcemap = async (v8list, options) => {
|
|
58
|
+
|
|
59
|
+
// entry filter
|
|
60
|
+
const entryFilter = getEntryFilter(options);
|
|
61
|
+
|
|
62
|
+
// filter no source or text
|
|
63
|
+
// init type and css source from text
|
|
64
|
+
// keep functions
|
|
65
|
+
v8list = v8list.filter((item) => {
|
|
66
|
+
|
|
67
|
+
// filter entry
|
|
68
|
+
if (!entryFilter(item)) {
|
|
69
|
+
// console.log('-', item.url);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// console.log(item.url);
|
|
73
|
+
|
|
74
|
+
if (typeof item.source === 'string' && item.functions) {
|
|
75
|
+
item.type = 'js';
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (typeof item.text === 'string' && item.ranges) {
|
|
79
|
+
item.type = 'css';
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
// allow empty coverage
|
|
83
|
+
if (item.empty) {
|
|
84
|
+
if (!['js', 'css'].includes(item.type)) {
|
|
85
|
+
item.type = 'js';
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// 404 css, text will be empty
|
|
90
|
+
// Util.logError(`Invalid source: ${item.url}`);
|
|
91
|
+
// console.log(item);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// do not change original v8list, to work for multiple APIs
|
|
96
|
+
|
|
97
|
+
const sourcePathHandler = getSourcePathHandler(options);
|
|
98
|
+
|
|
99
|
+
// init id, sourcePath
|
|
100
|
+
v8list = v8list.map((item, i) => {
|
|
101
|
+
|
|
102
|
+
// it could be a empty file
|
|
103
|
+
let source = `${item.source || item.text || ''}`;
|
|
104
|
+
|
|
105
|
+
// fix source with script offset
|
|
106
|
+
let scriptOffset;
|
|
107
|
+
const offset = Util.toNum(item.scriptOffset, true);
|
|
108
|
+
if (offset > 0) {
|
|
109
|
+
scriptOffset = offset;
|
|
110
|
+
source = getWrapperSource(offset, source);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const data = {
|
|
114
|
+
url: item.url,
|
|
115
|
+
type: item.type,
|
|
116
|
+
source,
|
|
117
|
+
// script offset >= 0, for vm script
|
|
118
|
+
scriptOffset,
|
|
119
|
+
// Manually Resolve the Sourcemap
|
|
120
|
+
sourceMap: item.sourceMap,
|
|
121
|
+
// fake source with `lineLengths`
|
|
122
|
+
fake: item.fake,
|
|
123
|
+
// empty coverage
|
|
124
|
+
empty: item.empty,
|
|
125
|
+
// match source if using empty coverage
|
|
126
|
+
distFile: item.distFile
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// coverage
|
|
130
|
+
if (data.type === 'js') {
|
|
131
|
+
data.functions = item.functions;
|
|
132
|
+
} else {
|
|
133
|
+
data.ranges = item.ranges;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// resolve source path
|
|
137
|
+
let sourcePath = getSourcePath(data.url, i + 1, data.type);
|
|
138
|
+
if (sourcePathHandler) {
|
|
139
|
+
const newSourcePath = sourcePathHandler(sourcePath, data.url);
|
|
140
|
+
if (typeof newSourcePath === 'string' && newSourcePath) {
|
|
141
|
+
sourcePath = newSourcePath;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
data.sourcePath = sourcePath;
|
|
145
|
+
|
|
146
|
+
// calculate source id
|
|
147
|
+
data.id = Util.calculateSha1(sourcePath + data.source);
|
|
148
|
+
|
|
149
|
+
return data;
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// collect sourcemap first
|
|
153
|
+
const time_start = Date.now();
|
|
154
|
+
const smList = await collectSourceMaps(v8list, options);
|
|
155
|
+
if (smList.length) {
|
|
156
|
+
// debug level time
|
|
157
|
+
Util.logTime(`loaded sourcemaps: ${smList.length}`, time_start);
|
|
158
|
+
// console.log(smList);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return v8list;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// ========================================================================================================
|
|
165
|
+
|
|
166
|
+
// force to async
|
|
167
|
+
const mergeCssRanges = (itemList) => {
|
|
168
|
+
return new Promise((resolve) => {
|
|
169
|
+
|
|
170
|
+
let concatRanges = [];
|
|
171
|
+
itemList.forEach((item) => {
|
|
172
|
+
concatRanges = concatRanges.concat(item.ranges);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// ranges: [ {start, end} ]
|
|
176
|
+
const ranges = dedupeFlatRanges(concatRanges);
|
|
177
|
+
|
|
178
|
+
resolve(ranges || []);
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const mergeJsFunctions = (itemList) => {
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
|
|
185
|
+
const res = mergeScriptCovs(itemList);
|
|
186
|
+
const functions = res && res.functions;
|
|
187
|
+
|
|
188
|
+
resolve(functions || []);
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const mergeV8Coverage = async (dataList, sourceCache, options) => {
|
|
193
|
+
|
|
194
|
+
let allList = [];
|
|
195
|
+
dataList.forEach((d) => {
|
|
196
|
+
allList = allList.concat(d.data);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// remove empty items
|
|
200
|
+
const coverageList = allList.filter((it) => !it.empty);
|
|
201
|
+
|
|
202
|
+
// connect all functions and ranges
|
|
203
|
+
const itemMap = {};
|
|
204
|
+
const mergeMap = {};
|
|
205
|
+
coverageList.forEach((item) => {
|
|
206
|
+
const { id } = item;
|
|
207
|
+
const prev = itemMap[id];
|
|
208
|
+
if (prev) {
|
|
209
|
+
if (mergeMap[id]) {
|
|
210
|
+
mergeMap[id].push(item);
|
|
211
|
+
} else {
|
|
212
|
+
mergeMap[id] = [prev, item];
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
itemMap[id] = item;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// merge functions and ranges
|
|
220
|
+
const mergeIds = Object.keys(mergeMap);
|
|
221
|
+
for (const id of mergeIds) {
|
|
222
|
+
const itemList = mergeMap[id];
|
|
223
|
+
const item = itemMap[id];
|
|
224
|
+
if (item.type === 'js') {
|
|
225
|
+
item.functions = await mergeJsFunctions(itemList);
|
|
226
|
+
} else {
|
|
227
|
+
item.ranges = await mergeCssRanges(itemList);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// first time filter for empty, (not for sources)
|
|
232
|
+
// empty and not in item map
|
|
233
|
+
const emptyList = allList.filter((it) => it.empty).filter((it) => !itemMap[it.id]);
|
|
234
|
+
|
|
235
|
+
// empty list + merged list
|
|
236
|
+
const mergedList = emptyList.concat(Object.values(itemMap));
|
|
237
|
+
|
|
238
|
+
// try to load coverage and source by id
|
|
239
|
+
for (const item of mergedList) {
|
|
240
|
+
const {
|
|
241
|
+
id, type, empty
|
|
242
|
+
} = item;
|
|
243
|
+
const json = sourceCache.get(id);
|
|
244
|
+
if (json) {
|
|
245
|
+
item.source = json.source;
|
|
246
|
+
item.sourceMap = json.sourceMap;
|
|
247
|
+
} else {
|
|
248
|
+
Util.logError(`Not found source data: ${Util.relativePath(item.sourcePath)}`);
|
|
249
|
+
item.source = '';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// add empty coverage after merged
|
|
253
|
+
if (empty) {
|
|
254
|
+
if (type === 'js') {
|
|
255
|
+
item.functions = [{
|
|
256
|
+
functionName: '',
|
|
257
|
+
ranges: [{
|
|
258
|
+
startOffset: 0,
|
|
259
|
+
endOffset: item.source.length,
|
|
260
|
+
count: 0
|
|
261
|
+
}]
|
|
262
|
+
}];
|
|
263
|
+
} else {
|
|
264
|
+
// empty css
|
|
265
|
+
item.ranges = [];
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return mergedList;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// ============================================================
|
|
275
|
+
|
|
276
|
+
const handleV8JsonReport = async (reportData, reportOptions, options) => {
|
|
277
|
+
const v8JsonOptions = {
|
|
278
|
+
outputFile: 'coverage-report.json',
|
|
279
|
+
... reportOptions
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// console.log(mergedOptions);
|
|
283
|
+
const jsonPath = path.resolve(options.outputDir, v8JsonOptions.outputFile);
|
|
284
|
+
await Util.writeFile(jsonPath, JSON.stringify(reportData));
|
|
285
|
+
return Util.relativePath(jsonPath);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
const handleV8HtmlReport = async (reportData, reportOptions, options) => {
|
|
290
|
+
|
|
291
|
+
// V8 only options, merged with root options
|
|
292
|
+
const v8HtmlOptions = {
|
|
293
|
+
outputFile: options.outputFile,
|
|
294
|
+
inline: options.inline,
|
|
295
|
+
assetsPath: options.assetsPath,
|
|
296
|
+
metrics: options.metrics,
|
|
297
|
+
... reportOptions
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// add metrics to data for UI
|
|
301
|
+
reportData.metrics = v8HtmlOptions.metrics;
|
|
302
|
+
|
|
303
|
+
const {
|
|
304
|
+
outputFile, inline, assetsPath
|
|
305
|
+
} = v8HtmlOptions;
|
|
306
|
+
|
|
307
|
+
// resolve full report path
|
|
308
|
+
const reportPath = path.resolve(options.outputDir, outputFile);
|
|
309
|
+
const outputDir = path.dirname(reportPath);
|
|
310
|
+
const htmlFile = path.basename(reportPath);
|
|
311
|
+
|
|
312
|
+
// deps
|
|
313
|
+
const jsFiles = ['monocart-code-viewer', 'monocart-formatter', 'turbogrid'].map((it) => {
|
|
314
|
+
return Util.resolveNodeModule(`${it}/dist/${it}.js`);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// package v8 ui
|
|
318
|
+
jsFiles.push(Util.resolvePackage('monocart-coverage-v8.js'));
|
|
319
|
+
|
|
320
|
+
// console.log(jsFiles);
|
|
321
|
+
|
|
322
|
+
const htmlOptions = {
|
|
323
|
+
reportData,
|
|
324
|
+
jsFiles,
|
|
325
|
+
inline,
|
|
326
|
+
assetsPath,
|
|
327
|
+
outputDir,
|
|
328
|
+
htmlFile,
|
|
329
|
+
|
|
330
|
+
reportDataFile: 'coverage-data.js'
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const htmlPath = await Util.saveHtmlReport(htmlOptions);
|
|
334
|
+
|
|
335
|
+
return htmlPath;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const saveV8Report = async (v8list, options) => {
|
|
339
|
+
|
|
340
|
+
const defaultWatermarks = {
|
|
341
|
+
bytes: [50, 80],
|
|
342
|
+
statements: [50, 80],
|
|
343
|
+
branches: [50, 80],
|
|
344
|
+
functions: [50, 80],
|
|
345
|
+
lines: [50, 80]
|
|
346
|
+
};
|
|
347
|
+
const watermarks = Util.resolveWatermarks(defaultWatermarks, options.watermarks);
|
|
348
|
+
|
|
349
|
+
const summary = getV8Summary(v8list, watermarks);
|
|
350
|
+
|
|
351
|
+
const reportData = {
|
|
352
|
+
name: options.name,
|
|
353
|
+
version,
|
|
354
|
+
watermarks,
|
|
355
|
+
summary,
|
|
356
|
+
files: v8list
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// v8 reports
|
|
360
|
+
const buildInV8Reports = {
|
|
361
|
+
'v8': handleV8HtmlReport,
|
|
362
|
+
'v8-json': handleV8JsonReport
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
const outputs = {};
|
|
366
|
+
const v8Group = options.reportGroup.v8;
|
|
367
|
+
const v8Reports = Object.keys(v8Group);
|
|
368
|
+
for (const reportName of v8Reports) {
|
|
369
|
+
const reportOptions = v8Group[reportName];
|
|
370
|
+
const buildInHandler = buildInV8Reports[reportName];
|
|
371
|
+
if (buildInHandler) {
|
|
372
|
+
outputs[reportName] = await buildInHandler(reportData, reportOptions, options);
|
|
373
|
+
} else {
|
|
374
|
+
outputs[reportName] = await Util.runCustomReporter(reportName, reportData, reportOptions, options);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// outputPath, should be html or json
|
|
379
|
+
const reportPath = Util.resolveReportPath(options, () => {
|
|
380
|
+
return outputs.v8 || outputs['v8-json'] || Object.values(outputs).filter((it) => it && typeof it === 'string').shift();
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const coverageResults = {
|
|
384
|
+
type: 'v8',
|
|
385
|
+
reportPath,
|
|
386
|
+
name: options.name,
|
|
387
|
+
watermarks,
|
|
388
|
+
summary,
|
|
389
|
+
files: v8list
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
return coverageResults;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
module.exports = {
|
|
396
|
+
initV8ListAndSourcemap,
|
|
397
|
+
mergeV8Coverage,
|
|
398
|
+
saveV8Report,
|
|
399
|
+
getEntryFilter
|
|
400
|
+
};
|