@@ -29,16 +29,11 @@ const { tmpdir } = require('os');
29
29
const { join, resolve, relative, matchesGlob } = require ( 'path' ) ;
30
30
const { fileURLToPath } = require ( 'internal/url' ) ;
31
31
const { kMappings, SourceMap } = require ( 'internal/source_map/source_map' ) ;
32
- const { parseCommandLine } = require ( 'internal/test_runner/utils' ) ;
33
32
const kCoverageFileRegex = / ^ c o v e r a g e - ( \d + ) - ( \d { 13 } ) - ( \d + ) \. j s o n $ / ;
34
33
const kIgnoreRegex = / \/ \* n o d e : c o v e r a g e i g n o r e n e x t (?< count > \d + ) ? \* \/ / ;
35
34
const kLineEndingRegex = / \r ? \n $ / u;
36
35
const kLineSplitRegex = / (?< = \r ? \n ) / u;
37
36
const kStatusRegex = / \/ \* n o d e : c o v e r a g e (?< status > e n a b l e | d i s a b l e ) \* \/ / ;
38
- const {
39
- coverageExcludeGlobs,
40
- coverageIncludeGlobs,
41
- } = parseCommandLine ( ) ;
42
37
43
38
class CoverageLine {
44
39
constructor ( line , startOffset , src , length = src ?. length ) {
@@ -55,10 +50,12 @@ class CoverageLine {
55
50
}
56
51
57
52
class TestCoverage {
58
- constructor ( coverageDirectory , originalCoverageDirectory , workingDirectory ) {
53
+ constructor ( coverageDirectory , originalCoverageDirectory , workingDirectory , excludeGlobs , includeGlobs ) {
59
54
this . coverageDirectory = coverageDirectory ;
60
55
this . originalCoverageDirectory = originalCoverageDirectory ;
61
56
this . workingDirectory = workingDirectory ;
57
+ this . excludeGlobs = excludeGlobs ;
58
+ this . includeGlobs = includeGlobs ;
62
59
}
63
60
64
61
#sourceLines = new SafeMap ( ) ;
@@ -313,7 +310,7 @@ class TestCoverage {
313
310
314
311
const coverageFile = join ( this . coverageDirectory , entry . name ) ;
315
312
const coverage = JSONParse ( readFileSync ( coverageFile , 'utf8' ) ) ;
316
- mergeCoverage ( result , this . mapCoverageWithSourceMap ( coverage ) , this . workingDirectory ) ;
313
+ this . mergeCoverage ( result , this . mapCoverageWithSourceMap ( coverage ) ) ;
317
314
}
318
315
319
316
return ArrayFrom ( result . values ( ) ) ;
@@ -336,7 +333,7 @@ class TestCoverage {
336
333
const script = result [ i ] ;
337
334
const { url, functions } = script ;
338
335
339
- if ( shouldSkipFileCoverage ( url , this . workingDirectory ) || sourceMapCache [ url ] == null ) {
336
+ if ( this . shouldSkipFileCoverage ( url ) || sourceMapCache [ url ] == null ) {
340
337
newResult . set ( url , script ) ;
341
338
continue ;
342
339
}
@@ -412,6 +409,54 @@ class TestCoverage {
412
409
return MathMin ( lines [ line ] . startOffset + entry . originalColumn , lines [ line ] . endOffset ) ;
413
410
}
414
411
412
+ mergeCoverage ( merged , coverage ) {
413
+ for ( let i = 0 ; i < coverage . length ; ++ i ) {
414
+ const newScript = coverage [ i ] ;
415
+ const { url } = newScript ;
416
+
417
+ if ( this . shouldSkipFileCoverage ( url ) ) {
418
+ continue ;
419
+ }
420
+
421
+ const oldScript = merged . get ( url ) ;
422
+
423
+ if ( oldScript === undefined ) {
424
+ merged . set ( url , newScript ) ;
425
+ } else {
426
+ mergeCoverageScripts ( oldScript , newScript ) ;
427
+ }
428
+ }
429
+ }
430
+
431
+ shouldSkipFileCoverage ( url ) {
432
+ // This check filters out core modules, which start with 'node:' in
433
+ // coverage reports, as well as any invalid coverages which have been
434
+ // observed on Windows.
435
+ if ( ! StringPrototypeStartsWith ( url , 'file:' ) ) return true ;
436
+
437
+ const absolutePath = fileURLToPath ( url ) ;
438
+ const relativePath = relative ( this . workingDirectory , absolutePath ) ;
439
+
440
+ // This check filters out files that match the exclude globs.
441
+ if ( this . excludeGlobs ?. length > 0 ) {
442
+ for ( let i = 0 ; i < this . excludeGlobs . length ; ++ i ) {
443
+ if ( matchesGlob ( relativePath , this . excludeGlobs [ i ] ) ||
444
+ matchesGlob ( absolutePath , this . excludeGlobs [ i ] ) ) return true ;
445
+ }
446
+ }
447
+
448
+ // This check filters out files that do not match the include globs.
449
+ if ( this . includeGlobs ?. length > 0 ) {
450
+ for ( let i = 0 ; i < this . includeGlobs . length ; ++ i ) {
451
+ if ( matchesGlob ( relativePath , this . includeGlobs [ i ] ) ||
452
+ matchesGlob ( absolutePath , this . includeGlobs [ i ] ) ) return false ;
453
+ }
454
+ return true ;
455
+ }
456
+
457
+ // This check filters out the node_modules/ directory, unless it is explicitly included.
458
+ return StringPrototypeIncludes ( url , '/node_modules/' ) ;
459
+ }
415
460
}
416
461
417
462
function toPercentage ( covered , total ) {
@@ -422,7 +467,7 @@ function sortCoverageFiles(a, b) {
422
467
return StringPrototypeLocaleCompare ( a . path , b . path ) ;
423
468
}
424
469
425
- function setupCoverage ( ) {
470
+ function setupCoverage ( options ) {
426
471
let originalCoverageDirectory = process . env . NODE_V8_COVERAGE ;
427
472
const cwd = process . cwd ( ) ;
428
473
@@ -446,7 +491,13 @@ function setupCoverage() {
446
491
// child processes.
447
492
process . env . NODE_V8_COVERAGE = coverageDirectory ;
448
493
449
- return new TestCoverage ( coverageDirectory , originalCoverageDirectory , cwd ) ;
494
+ return new TestCoverage (
495
+ coverageDirectory ,
496
+ originalCoverageDirectory ,
497
+ cwd ,
498
+ options . coverageExcludeGlobs ,
499
+ options . coverageIncludeGlobs ,
500
+ ) ;
450
501
}
451
502
452
503
function mapRangeToLines ( range , lines ) {
@@ -490,55 +541,6 @@ function mapRangeToLines(range, lines) {
490
541
return { __proto__ : null , lines : mappedLines , ignoredLines } ;
491
542
}
492
543
493
- function shouldSkipFileCoverage ( url , workingDirectory ) {
494
- // This check filters out core modules, which start with 'node:' in
495
- // coverage reports, as well as any invalid coverages which have been
496
- // observed on Windows.
497
- if ( ! StringPrototypeStartsWith ( url , 'file:' ) ) return true ;
498
-
499
- const absolutePath = fileURLToPath ( url ) ;
500
- const relativePath = relative ( workingDirectory , absolutePath ) ;
501
-
502
- // This check filters out files that match the exclude globs.
503
- if ( coverageExcludeGlobs ?. length > 0 ) {
504
- for ( let i = 0 ; i < coverageExcludeGlobs . length ; ++ i ) {
505
- if ( matchesGlob ( relativePath , coverageExcludeGlobs [ i ] ) ||
506
- matchesGlob ( absolutePath , coverageExcludeGlobs [ i ] ) ) return true ;
507
- }
508
- }
509
-
510
- // This check filters out files that do not match the include globs.
511
- if ( coverageIncludeGlobs ?. length > 0 ) {
512
- for ( let i = 0 ; i < coverageIncludeGlobs . length ; ++ i ) {
513
- if ( matchesGlob ( relativePath , coverageIncludeGlobs [ i ] ) ||
514
- matchesGlob ( absolutePath , coverageIncludeGlobs [ i ] ) ) return false ;
515
- }
516
- return true ;
517
- }
518
-
519
- // This check filters out the node_modules/ directory, unless it is explicitly included.
520
- return StringPrototypeIncludes ( url , '/node_modules/' ) ;
521
- }
522
-
523
- function mergeCoverage ( merged , coverage , workingDirectory ) {
524
- for ( let i = 0 ; i < coverage . length ; ++ i ) {
525
- const newScript = coverage [ i ] ;
526
- const { url } = newScript ;
527
-
528
- if ( shouldSkipFileCoverage ( url , workingDirectory ) ) {
529
- continue ;
530
- }
531
-
532
- const oldScript = merged . get ( url ) ;
533
-
534
- if ( oldScript === undefined ) {
535
- merged . set ( url , newScript ) ;
536
- } else {
537
- mergeCoverageScripts ( oldScript , newScript ) ;
538
- }
539
- }
540
- }
541
-
542
544
function mergeCoverageScripts ( oldScript , newScript ) {
543
545
// Merge the functions from the new coverage into the functions from the
544
546
// existing (merged) coverage.
0 commit comments