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,
@@ -138,11 +143,14 @@ function filterExecArgv(arg, i, arr) {
138
143
! ArrayPrototypeSome ( kFilterArgValues , ( p ) => arg === p || ( i > 0 && arr [ i - 1 ] === p ) || StringPrototypeStartsWith ( arg , `${ p } =` ) ) ;
139
144
}
140
145
141
- function getRunArgs ( { path, inspectPort } ) {
146
+ function getRunArgs ( { path, inspectPort, testNamePatterns } ) {
142
147
const argv = ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ;
143
148
if ( isUsingInspector ( ) ) {
144
149
ArrayPrototypePush ( argv , `--inspect-port=${ getInspectPort ( inspectPort ) } ` ) ;
145
150
}
151
+ if ( testNamePatterns ) {
152
+ ArrayPrototypeForEach ( testNamePatterns , ( pattern ) => ArrayPrototypePush ( argv , `--test-name-pattern=${ pattern } ` ) ) ;
153
+ }
146
154
ArrayPrototypePush ( argv , path ) ;
147
155
148
156
return argv ;
@@ -256,9 +264,9 @@ class FileTest extends Test {
256
264
const runningProcesses = new SafeMap ( ) ;
257
265
const runningSubtests = new SafeMap ( ) ;
258
266
259
- function runTestFile ( path , root , inspectPort , filesWatcher ) {
267
+ function runTestFile ( path , root , inspectPort , filesWatcher , testNamePatterns ) {
260
268
const subtest = root . createSubtest ( FileTest , path , async ( t ) => {
261
- const args = getRunArgs ( { path, inspectPort } ) ;
269
+ const args = getRunArgs ( { path, inspectPort, testNamePatterns } ) ;
262
270
const stdio = [ 'pipe' , 'pipe' , 'pipe' ] ;
263
271
const env = { ...process . env , NODE_TEST_CONTEXT : 'child' } ;
264
272
if ( filesWatcher ) {
@@ -340,7 +348,7 @@ function runTestFile(path, root, inspectPort, filesWatcher) {
340
348
return promise ;
341
349
}
342
350
343
- function watchFiles ( testFiles , root , inspectPort ) {
351
+ function watchFiles ( testFiles , root , inspectPort , testNamePatterns ) {
344
352
const filesWatcher = new FilesWatcher ( { throttle : 500 , mode : 'filter' } ) ;
345
353
filesWatcher . on ( 'changed' , ( { owners } ) => {
346
354
filesWatcher . unfilterFilesOwnedBy ( owners ) ;
@@ -354,7 +362,7 @@ function watchFiles(testFiles, root, inspectPort) {
354
362
await once ( runningProcess , 'exit' ) ;
355
363
}
356
364
await runningSubtests . get ( file ) ;
357
- runningSubtests . set ( file , runTestFile ( file , root , inspectPort , filesWatcher ) ) ;
365
+ runningSubtests . set ( file , runTestFile ( file , root , inspectPort , filesWatcher , testNamePatterns ) ) ;
358
366
} , undefined , ( error ) => {
359
367
triggerUncaughtException ( error , true /* fromPromise */ ) ;
360
368
} ) ) ;
@@ -366,6 +374,7 @@ function run(options) {
366
374
if ( options === null || typeof options !== 'object' ) {
367
375
options = kEmptyObject ;
368
376
}
377
+ let { testNamePatterns } = options ;
369
378
const { concurrency, timeout, signal, files, inspectPort, watch, setup } = options ;
370
379
371
380
if ( files != null ) {
@@ -377,20 +386,36 @@ function run(options) {
377
386
if ( setup != null ) {
378
387
validateFunction ( setup , 'options.setup' ) ;
379
388
}
389
+ if ( testNamePatterns != null ) {
390
+ if ( ! ArrayIsArray ( testNamePatterns ) ) {
391
+ testNamePatterns = [ testNamePatterns ] ;
392
+ }
393
+ validateArray ( testNamePatterns , 'options.testNamePatterns' ) ;
394
+ testNamePatterns = ArrayPrototypeMap ( testNamePatterns , ( value , i ) => {
395
+ if ( isRegExp ( value ) ) {
396
+ return value ;
397
+ }
398
+ const name = `options.testNamePatterns[${ i } ]` ;
399
+ if ( typeof value === 'string' ) {
400
+ return convertStringToRegExp ( value , name ) ;
401
+ }
402
+ throw new ERR_INVALID_ARG_TYPE ( name , [ 'string' , 'RegExp' ] , value ) ;
403
+ } ) ;
404
+ }
380
405
381
406
const root = createTestTree ( { concurrency, timeout, signal } ) ;
382
407
const testFiles = files ?? createTestFileList ( ) ;
383
408
384
409
let postRun = ( ) => root . postRun ( ) ;
385
410
let filesWatcher ;
386
411
if ( watch ) {
387
- filesWatcher = watchFiles ( testFiles , root , inspectPort ) ;
412
+ filesWatcher = watchFiles ( testFiles , root , inspectPort , testNamePatterns ) ;
388
413
postRun = undefined ;
389
414
}
390
415
const runFiles = ( ) => {
391
416
root . harness . bootstrapComplete = true ;
392
417
return SafePromiseAllSettledReturnVoid ( testFiles , ( path ) => {
393
- const subtest = runTestFile ( path , root , inspectPort , filesWatcher ) ;
418
+ const subtest = runTestFile ( path , root , inspectPort , filesWatcher , testNamePatterns ) ;
394
419
runningSubtests . set ( path , subtest ) ;
395
420
return subtest ;
396
421
} ) ;
0 commit comments