11'use strict' ;
22const {
33 ArrayFrom,
4- ArrayPrototypeConcat,
54 ArrayPrototypeFilter,
65 ArrayPrototypeIncludes,
76 ArrayPrototypeJoin,
7+ ArrayPrototypePop,
8+ ArrayPrototypePush,
89 ArrayPrototypeSlice,
910 ArrayPrototypeSort,
1011 ObjectAssign,
1112 PromisePrototypeThen,
13+ RegExpPrototypeSymbolSplit,
1214 SafePromiseAll,
1315 SafeSet,
16+ StringPrototypeEndsWith,
1417} = primordials ;
1518
19+ const { Buffer } = require ( 'buffer' ) ;
1620const { spawn } = require ( 'child_process' ) ;
1721const { readdirSync, statSync } = require ( 'fs' ) ;
1822const console = require ( 'internal/console/global' ) ;
@@ -22,6 +26,7 @@ const {
2226 } ,
2327} = require ( 'internal/errors' ) ;
2428const { validateArray } = require ( 'internal/validators' ) ;
29+ const { getInspectPort, isUsingInspector, isInspectorMessage } = require ( 'internal/util/inspector' ) ;
2530const { kEmptyObject } = require ( 'internal/util' ) ;
2631const { createTestTree } = require ( 'internal/test_runner/harness' ) ;
2732const { kSubtestsFailed, Test } = require ( 'internal/test_runner/test' ) ;
@@ -100,25 +105,59 @@ function filterExecArgv(arg) {
100105 return ! ArrayPrototypeIncludes ( kFilterArgs , arg ) ;
101106}
102107
103- function runTestFile ( path , root ) {
108+ function getRunArgs ( { path, inspectPort } ) {
109+ const argv = ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ;
110+ if ( isUsingInspector ( ) ) {
111+ ArrayPrototypePush ( argv , `--inspect-port=${ getInspectPort ( inspectPort ) } ` ) ;
112+ }
113+ ArrayPrototypePush ( argv , path ) ;
114+ return argv ;
115+ }
116+
117+ function makeStderrCallback ( callback ) {
118+ if ( ! isUsingInspector ( ) ) {
119+ return callback ;
120+ }
121+ let buffer = Buffer . alloc ( 0 ) ;
122+ return ( data ) => {
123+ callback ( data ) ;
124+ const newData = Buffer . concat ( [ buffer , data ] ) ;
125+ const str = newData . toString ( 'utf8' ) ;
126+ let lines = str ;
127+ if ( StringPrototypeEndsWith ( lines , '\n' ) ) {
128+ buffer = Buffer . alloc ( 0 ) ;
129+ } else {
130+ lines = RegExpPrototypeSymbolSplit ( / \r ? \n / , str ) ;
131+ buffer = Buffer . from ( ArrayPrototypePop ( lines ) , 'utf8' ) ;
132+ lines = ArrayPrototypeJoin ( lines , '\n' ) ;
133+ }
134+ if ( isInspectorMessage ( lines ) ) {
135+ process . stderr . write ( lines ) ;
136+ }
137+ } ;
138+ }
139+
140+ function runTestFile ( path , root , inspectPort ) {
104141 const subtest = root . createSubtest ( Test , path , async ( t ) => {
105- const args = ArrayPrototypeConcat (
106- ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ,
107- path ) ;
142+ const args = getRunArgs ( { path, inspectPort } ) ;
108143
109144 const child = spawn ( process . execPath , args , { signal : t . signal , encoding : 'utf8' } ) ;
110145 // TODO(cjihrig): Implement a TAP parser to read the child's stdout
111146 // instead of just displaying it all if the child fails.
112147 let err ;
148+ let stderr = '' ;
113149
114150 child . on ( 'error' , ( error ) => {
115151 err = error ;
116152 } ) ;
117153
118- const { 0 : { 0 : code , 1 : signal } , 1 : stdout , 2 : stderr } = await SafePromiseAll ( [
154+ child . stderr . on ( 'data' , makeStderrCallback ( ( data ) => {
155+ stderr += data ;
156+ } ) ) ;
157+
158+ const { 0 : { 0 : code , 1 : signal } , 1 : stdout } = await SafePromiseAll ( [
119159 once ( child , 'exit' , { signal : t . signal } ) ,
120160 child . stdout . toArray ( { signal : t . signal } ) ,
121- child . stderr . toArray ( { signal : t . signal } ) ,
122161 ] ) ;
123162
124163 if ( code !== 0 || signal !== null ) {
@@ -128,7 +167,7 @@ function runTestFile(path, root) {
128167 exitCode : code ,
129168 signal : signal ,
130169 stdout : ArrayPrototypeJoin ( stdout , '' ) ,
131- stderr : ArrayPrototypeJoin ( stderr , '' ) ,
170+ stderr,
132171 // The stack will not be useful since the failures came from tests
133172 // in a child process.
134173 stack : undefined ,
@@ -145,7 +184,7 @@ function run(options) {
145184 if ( options === null || typeof options !== 'object' ) {
146185 options = kEmptyObject ;
147186 }
148- const { concurrency, timeout, signal, files } = options ;
187+ const { concurrency, timeout, signal, files, inspectPort } = options ;
149188
150189 if ( files != null ) {
151190 validateArray ( files , 'options.files' ) ;
@@ -154,7 +193,7 @@ function run(options) {
154193 const root = createTestTree ( { concurrency, timeout, signal } ) ;
155194 const testFiles = files ?? createTestFileList ( ) ;
156195
157- PromisePrototypeThen ( SafePromiseAll ( testFiles , ( path ) => runTestFile ( path , root ) ) ,
196+ PromisePrototypeThen ( SafePromiseAll ( testFiles , ( path ) => runTestFile ( path , root , inspectPort ) ) ,
158197 ( ) => root . postRun ( ) ) ;
159198
160199 return root . reporter ;
0 commit comments