@@ -6,6 +6,9 @@ import { dot, spec, tap } from 'node:test/reporters';
6
6
import assert from 'node:assert' ;
7
7
8
8
const testFixtures = fixtures . path ( 'test-runner' ) ;
9
+ const skipIfNoInspector = {
10
+ skip : ! process . features . inspector ? 'inspector disabled' : false
11
+ } ;
9
12
10
13
describe ( 'require(\'node:test\').run' , { concurrency : true } , ( ) => {
11
14
it ( 'should run with no tests' , async ( ) => {
@@ -488,6 +491,92 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
488
491
} ) ;
489
492
} ) ;
490
493
494
+ describe ( 'coverage' , ( ) => {
495
+ describe ( 'validation' , ( ) => {
496
+
497
+ it ( 'should only allow boolean in options.coverage' , async ( ) => {
498
+ [ Symbol ( ) , { } , ( ) => { } , 0 , 1 , 0n , 1n , '' , '1' , Promise . resolve ( true ) , [ ] ]
499
+ . forEach ( ( coverage ) => assert . throws ( ( ) => run ( { coverage } ) , {
500
+ code : 'ERR_INVALID_ARG_TYPE'
501
+ } ) ) ;
502
+ } ) ;
503
+
504
+ it ( 'should only allow coverageExcludeGlobs and coverageIncludeGlobs when coverage is true' , async ( ) => {
505
+ assert . throws (
506
+ ( ) => run ( { coverage : false , coverageIncludeGlobs : [ ] } ) ,
507
+ { code : 'ERR_INVALID_ARG_VALUE' } ,
508
+ ) ;
509
+ assert . throws (
510
+ ( ) => run ( { coverage : false , coverageExcludeGlobs : [ ] } ) ,
511
+ { code : 'ERR_INVALID_ARG_VALUE' } ,
512
+ ) ;
513
+ } ) ;
514
+
515
+ it ( 'should only allow string|string[] in options.coverageExcludeGlobs' , async ( ) => {
516
+ [ Symbol ( ) , { } , ( ) => { } , 0 , 1 , 0n , 1n , Promise . resolve ( [ ] ) , true , false ]
517
+ . forEach ( ( coverageExcludeGlobs ) => {
518
+ assert . throws ( ( ) => run ( { coverage : true , coverageExcludeGlobs } ) , {
519
+ code : 'ERR_INVALID_ARG_TYPE'
520
+ } ) ;
521
+ assert . throws ( ( ) => run ( { coverage : true , coverageExcludeGlobs : [ coverageExcludeGlobs ] } ) , {
522
+ code : 'ERR_INVALID_ARG_TYPE'
523
+ } ) ;
524
+ } ) ;
525
+ run ( { files : [ ] , signal : AbortSignal . abort ( ) , coverage : true , coverageExcludeGlobs : [ '' ] } ) ;
526
+ run ( { files : [ ] , signal : AbortSignal . abort ( ) , coverage : true , coverageExcludeGlobs : '' } ) ;
527
+ } ) ;
528
+
529
+ it ( 'should only allow string|string[] in options.coverageIncludeGlobs' , async ( ) => {
530
+ [ Symbol ( ) , { } , ( ) => { } , 0 , 1 , 0n , 1n , Promise . resolve ( [ ] ) , true , false ]
531
+ . forEach ( ( coverageIncludeGlobs ) => {
532
+ assert . throws ( ( ) => run ( { coverage : true , coverageIncludeGlobs } ) , {
533
+ code : 'ERR_INVALID_ARG_TYPE'
534
+ } ) ;
535
+ assert . throws ( ( ) => run ( { coverage : true , coverageIncludeGlobs : [ coverageIncludeGlobs ] } ) , {
536
+ code : 'ERR_INVALID_ARG_TYPE'
537
+ } ) ;
538
+ } ) ;
539
+
540
+ run ( { files : [ ] , signal : AbortSignal . abort ( ) , coverage : true , coverageIncludeGlobs : [ '' ] } ) ;
541
+ run ( { files : [ ] , signal : AbortSignal . abort ( ) , coverage : true , coverageIncludeGlobs : '' } ) ;
542
+ } ) ;
543
+ } ) ;
544
+
545
+ const files = [ fixtures . path ( 'test-runner' , 'coverage.js' ) ] ;
546
+ it ( 'should run with coverage' , skipIfNoInspector , async ( ) => {
547
+ const stream = run ( { files, coverage : true } ) ;
548
+ stream . on ( 'test:fail' , common . mustNotCall ( ) ) ;
549
+ stream . on ( 'test:pass' , common . mustCall ( 1 ) ) ;
550
+ stream . on ( 'test:coverage' , common . mustCall ( ) ) ;
551
+ // eslint-disable-next-line no-unused-vars
552
+ for await ( const _ of stream ) ;
553
+ } ) ;
554
+
555
+ it ( 'should run with coverage and exclude by glob' , skipIfNoInspector , async ( ) => {
556
+ const stream = run ( { files, coverage : true , coverageExcludeGlobs : [ 'test/*/test-runner/invalid-tap.js' ] } ) ;
557
+ stream . on ( 'test:fail' , common . mustNotCall ( ) ) ;
558
+ stream . on ( 'test:pass' , common . mustCall ( 1 ) ) ;
559
+ stream . on ( 'test:coverage' , common . mustCall ( ( { summary : { files } } ) => {
560
+ const filesPaths = files . map ( ( { path } ) => path ) ;
561
+ assert . strictEqual ( filesPaths . some ( ( path ) => path . includes ( 'test-runner/invalid-tap.js' ) ) , false ) ;
562
+ } ) ) ;
563
+ // eslint-disable-next-line no-unused-vars
564
+ for await ( const _ of stream ) ;
565
+ } ) ;
566
+
567
+ it ( 'should run with coverage and include by glob' , skipIfNoInspector , async ( ) => {
568
+ const stream = run ( { files, coverage : true , coverageIncludeGlobs : [ 'test/*/test-runner/invalid-tap.js' ] } ) ;
569
+ stream . on ( 'test:fail' , common . mustNotCall ( ) ) ;
570
+ stream . on ( 'test:pass' , common . mustCall ( 1 ) ) ;
571
+ stream . on ( 'test:coverage' , common . mustCall ( ( { summary : { files } } ) => {
572
+ const filesPaths = files . map ( ( { path } ) => path ) ;
573
+ assert . strictEqual ( filesPaths . some ( ( path ) => path . includes ( 'test-runner/invalid-tap.js' ) ) , true ) ;
574
+ } ) ) ;
575
+ // eslint-disable-next-line no-unused-vars
576
+ for await ( const _ of stream ) ;
577
+ } ) ;
578
+ } ) ;
579
+
491
580
it ( 'should run with no files' , async ( ) => {
492
581
const stream = run ( {
493
582
files : undefined
0 commit comments