@@ -39,10 +39,18 @@ const console = require('internal/console/global');
39
39
const {
40
40
codes : {
41
41
ERR_INVALID_ARG_TYPE ,
42
+ ERR_INVALID_ARG_VALUE ,
42
43
ERR_TEST_FAILURE ,
44
+ ERR_OUT_OF_RANGE ,
43
45
} ,
44
46
} = require ( 'internal/errors' ) ;
45
- const { validateArray, validateBoolean, validateFunction } = require ( 'internal/validators' ) ;
47
+ const {
48
+ validateArray,
49
+ validateBoolean,
50
+ validateFunction,
51
+ validateObject,
52
+ validateInteger,
53
+ } = require ( 'internal/validators' ) ;
46
54
const { getInspectPort, isUsingInspector, isInspectorMessage } = require ( 'internal/util/inspector' ) ;
47
55
const { isRegExp } = require ( 'internal/util/types' ) ;
48
56
const { kEmptyObject } = require ( 'internal/util' ) ;
@@ -459,7 +467,7 @@ function run(options) {
459
467
if ( options === null || typeof options !== 'object' ) {
460
468
options = kEmptyObject ;
461
469
}
462
- let { testNamePatterns } = options ;
470
+ let { testNamePatterns, shard } = options ;
463
471
const { concurrency, timeout, signal, files, inspectPort, watch, setup } = options ;
464
472
465
473
if ( files != null ) {
@@ -468,6 +476,22 @@ function run(options) {
468
476
if ( watch != null ) {
469
477
validateBoolean ( watch , 'options.watch' ) ;
470
478
}
479
+ if ( shard != null ) {
480
+ validateObject ( shard , 'options.shard' ) ;
481
+ // Avoid re-evaluating the shard object in case it's a getter
482
+ shard = { __proto__ : null , index : shard . index , total : shard . total } ;
483
+
484
+ validateInteger ( shard . total , 'options.shard.total' , 1 ) ;
485
+ validateInteger ( shard . index , 'options.shard.index' ) ;
486
+
487
+ if ( shard . index <= 0 || shard . total < shard . index ) {
488
+ throw new ERR_OUT_OF_RANGE ( 'options.shard.index' , `>= 1 && <= ${ shard . total } ("options.shard.total")` , shard . index ) ;
489
+ }
490
+
491
+ if ( watch ) {
492
+ throw new ERR_INVALID_ARG_VALUE ( 'options.shard' , watch , 'shards not supported with watch mode' ) ;
493
+ }
494
+ }
471
495
if ( setup != null ) {
472
496
validateFunction ( setup , 'options.setup' ) ;
473
497
}
@@ -489,7 +513,11 @@ function run(options) {
489
513
}
490
514
491
515
const root = createTestTree ( { concurrency, timeout, signal } ) ;
492
- const testFiles = files ?? createTestFileList ( ) ;
516
+ let testFiles = files ?? createTestFileList ( ) ;
517
+
518
+ if ( shard ) {
519
+ testFiles = ArrayPrototypeFilter ( testFiles , ( _ , index ) => index % shard . total === shard . index - 1 ) ;
520
+ }
493
521
494
522
let postRun = ( ) => root . postRun ( ) ;
495
523
let filesWatcher ;
0 commit comments