1
1
'use strict' ;
2
2
const {
3
3
ArrayFrom,
4
+ ArrayIsArray,
4
5
ArrayPrototypeFilter,
5
6
ArrayPrototypeForEach,
6
7
ArrayPrototypeIncludes,
7
8
ArrayPrototypeIndexOf,
9
+ ArrayPrototypeMap,
8
10
ArrayPrototypePush,
9
11
ArrayPrototypeSlice,
10
12
ArrayPrototypeSome,
@@ -33,11 +35,13 @@ const { FilesWatcher } = require('internal/watch_mode/files_watcher');
33
35
const console = require ( 'internal/console/global' ) ;
34
36
const {
35
37
codes : {
38
+ ERR_INVALID_ARG_TYPE ,
36
39
ERR_TEST_FAILURE ,
37
40
} ,
38
41
} = require ( 'internal/errors' ) ;
39
42
const { validateArray, validateBoolean, validateFunction } = require ( 'internal/validators' ) ;
40
43
const { getInspectPort, isUsingInspector, isInspectorMessage } = require ( 'internal/util/inspector' ) ;
44
+ const { isRegExp } = require ( 'internal/util/types' ) ;
41
45
const { kEmptyObject } = require ( 'internal/util' ) ;
42
46
const { createTestTree } = require ( 'internal/test_runner/harness' ) ;
43
47
const {
@@ -53,6 +57,7 @@ const { YAMLToJs } = require('internal/test_runner/yaml_to_js');
53
57
const { TokenKind } = require ( 'internal/test_runner/tap_lexer' ) ;
54
58
55
59
const {
60
+ convertStringToRegExp,
56
61
countCompletedTest,
57
62
doesPathMatchFilter,
58
63
isSupportedFileType,
@@ -137,11 +142,14 @@ function filterExecArgv(arg, i, arr) {
137
142
! ArrayPrototypeSome ( kFilterArgValues , ( p ) => arg === p || ( i > 0 && arr [ i - 1 ] === p ) || StringPrototypeStartsWith ( arg , `${ p } =` ) ) ;
138
143
}
139
144
140
- function getRunArgs ( { path, inspectPort } ) {
145
+ function getRunArgs ( { path, inspectPort, testNamePatterns } ) {
141
146
const argv = ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ;
142
147
if ( isUsingInspector ( ) ) {
143
148
ArrayPrototypePush ( argv , `--inspect-port=${ getInspectPort ( inspectPort ) } ` ) ;
144
149
}
150
+ if ( testNamePatterns ) {
151
+ ArrayPrototypeForEach ( testNamePatterns , ( pattern ) => ArrayPrototypePush ( argv , `--test-name-pattern=${ pattern } ` ) ) ;
152
+ }
145
153
ArrayPrototypePush ( argv , path ) ;
146
154
147
155
return argv ;
@@ -255,9 +263,9 @@ class FileTest extends Test {
255
263
const runningProcesses = new SafeMap ( ) ;
256
264
const runningSubtests = new SafeMap ( ) ;
257
265
258
- function runTestFile ( path , root , inspectPort , filesWatcher ) {
266
+ function runTestFile ( path , root , inspectPort , filesWatcher , testNamePatterns ) {
259
267
const subtest = root . createSubtest ( FileTest , path , async ( t ) => {
260
- const args = getRunArgs ( { path, inspectPort } ) ;
268
+ const args = getRunArgs ( { path, inspectPort, testNamePatterns } ) ;
261
269
const stdio = [ 'pipe' , 'pipe' , 'pipe' ] ;
262
270
const env = { ...process . env , NODE_TEST_CONTEXT : 'child' } ;
263
271
if ( filesWatcher ) {
@@ -339,7 +347,7 @@ function runTestFile(path, root, inspectPort, filesWatcher) {
339
347
return promise ;
340
348
}
341
349
342
- function watchFiles ( testFiles , root , inspectPort ) {
350
+ function watchFiles ( testFiles , root , inspectPort , testNamePatterns ) {
343
351
const filesWatcher = new FilesWatcher ( { throttle : 500 , mode : 'filter' } ) ;
344
352
filesWatcher . on ( 'changed' , ( { owners } ) => {
345
353
filesWatcher . unfilterFilesOwnedBy ( owners ) ;
@@ -353,7 +361,7 @@ function watchFiles(testFiles, root, inspectPort) {
353
361
await once ( runningProcess , 'exit' ) ;
354
362
}
355
363
await runningSubtests . get ( file ) ;
356
- runningSubtests . set ( file , runTestFile ( file , root , inspectPort , filesWatcher ) ) ;
364
+ runningSubtests . set ( file , runTestFile ( file , root , inspectPort , filesWatcher , testNamePatterns ) ) ;
357
365
} , undefined , ( error ) => {
358
366
triggerUncaughtException ( error , true /* fromPromise */ ) ;
359
367
} ) ) ;
@@ -365,6 +373,7 @@ function run(options) {
365
373
if ( options === null || typeof options !== 'object' ) {
366
374
options = kEmptyObject ;
367
375
}
376
+ let { testNamePatterns } = options ;
368
377
const { concurrency, timeout, signal, files, inspectPort, watch, setup } = options ;
369
378
370
379
if ( files != null ) {
@@ -376,20 +385,36 @@ function run(options) {
376
385
if ( setup != null ) {
377
386
validateFunction ( setup , 'options.setup' ) ;
378
387
}
388
+ if ( testNamePatterns != null ) {
389
+ if ( ! ArrayIsArray ( testNamePatterns ) ) {
390
+ testNamePatterns = [ testNamePatterns ] ;
391
+ }
392
+ validateArray ( testNamePatterns , 'options.testNamePatterns' ) ;
393
+ testNamePatterns = ArrayPrototypeMap ( testNamePatterns , ( value , i ) => {
394
+ if ( isRegExp ( value ) ) {
395
+ return value ;
396
+ }
397
+ const name = `options.testNamePatterns[${ i } ]` ;
398
+ if ( typeof value === 'string' ) {
399
+ return convertStringToRegExp ( value , name ) ;
400
+ }
401
+ throw new ERR_INVALID_ARG_TYPE ( name , [ 'string' , 'RegExp' ] , value ) ;
402
+ } ) ;
403
+ }
379
404
380
405
const root = createTestTree ( { concurrency, timeout, signal } ) ;
381
406
const testFiles = files ?? createTestFileList ( ) ;
382
407
383
408
let postRun = ( ) => root . postRun ( ) ;
384
409
let filesWatcher ;
385
410
if ( watch ) {
386
- filesWatcher = watchFiles ( testFiles , root , inspectPort ) ;
411
+ filesWatcher = watchFiles ( testFiles , root , inspectPort , testNamePatterns ) ;
387
412
postRun = undefined ;
388
413
}
389
414
const runFiles = ( ) => {
390
415
root . harness . bootstrapComplete = true ;
391
416
return SafePromiseAllSettledReturnVoid ( testFiles , ( path ) => {
392
- const subtest = runTestFile ( path , root , inspectPort , filesWatcher ) ;
417
+ const subtest = runTestFile ( path , root , inspectPort , filesWatcher , testNamePatterns ) ;
393
418
runningSubtests . set ( path , subtest ) ;
394
419
return subtest ;
395
420
} ) ;
0 commit comments