1- // https://github.com/nodejs/node/blob/59527de13d39327eb3dfa8dedc92241eb40066d5 /lib/internal/test_runner/runner.js
1+ // https://github.com/nodejs/node/blob/a165193c5c8e4bcfbd12b2c3f6e55a81a251c258 /lib/internal/test_runner/runner.js
22'use strict'
33const {
44 ArrayFrom,
5- ArrayPrototypeConcat,
65 ArrayPrototypeFilter,
76 ArrayPrototypeIncludes,
87 ArrayPrototypeJoin,
8+ ArrayPrototypePop,
9+ ArrayPrototypePush,
910 ArrayPrototypeSlice,
1011 ArrayPrototypeSort,
1112 ObjectAssign,
1213 PromisePrototypeThen,
14+ RegExpPrototypeSymbolSplit,
1315 SafePromiseAll,
14- SafeSet
16+ SafeSet,
17+ StringPrototypeEndsWith
1518} = require ( '#internal/per_context/primordials' )
1619
20+ const { Buffer } = require ( 'buffer' )
1721const { spawn } = require ( 'child_process' )
1822const { readdirSync, statSync } = require ( 'fs' )
1923const {
@@ -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' )
@@ -101,25 +106,59 @@ function filterExecArgv (arg) {
101106 return ! ArrayPrototypeIncludes ( kFilterArgs , arg )
102107}
103108
104- function runTestFile ( path , root ) {
109+ function getRunArgs ( { path, inspectPort } ) {
110+ const argv = ArrayPrototypeFilter ( process . execArgv , filterExecArgv )
111+ if ( isUsingInspector ( ) ) {
112+ ArrayPrototypePush ( argv , `--inspect-port=${ getInspectPort ( inspectPort ) } ` )
113+ }
114+ ArrayPrototypePush ( argv , path )
115+ return argv
116+ }
117+
118+ function makeStderrCallback ( callback ) {
119+ if ( ! isUsingInspector ( ) ) {
120+ return callback
121+ }
122+ let buffer = Buffer . alloc ( 0 )
123+ return ( data ) => {
124+ callback ( data )
125+ const newData = Buffer . concat ( [ buffer , data ] )
126+ const str = newData . toString ( 'utf8' )
127+ let lines = str
128+ if ( StringPrototypeEndsWith ( lines , '\n' ) ) {
129+ buffer = Buffer . alloc ( 0 )
130+ } else {
131+ lines = RegExpPrototypeSymbolSplit ( / \r ? \n / , str )
132+ buffer = Buffer . from ( ArrayPrototypePop ( lines ) , 'utf8' )
133+ lines = ArrayPrototypeJoin ( lines , '\n' )
134+ }
135+ if ( isInspectorMessage ( lines ) ) {
136+ process . stderr . write ( lines )
137+ }
138+ }
139+ }
140+
141+ function runTestFile ( path , root , inspectPort ) {
105142 const subtest = root . createSubtest ( Test , path , async ( t ) => {
106- const args = ArrayPrototypeConcat (
107- ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ,
108- path )
143+ const args = getRunArgs ( { path, inspectPort } )
109144
110145 const child = spawn ( process . execPath , args , { signal : t . signal , encoding : 'utf8' } )
111146 // TODO(cjihrig): Implement a TAP parser to read the child's stdout
112147 // instead of just displaying it all if the child fails.
113148 let err
149+ let stderr = ''
114150
115151 child . on ( 'error' , ( error ) => {
116152 err = error
117153 } )
118154
119- const { 0 : { 0 : code , 1 : signal } , 1 : stdout , 2 : stderr } = await SafePromiseAll ( [
155+ child . stderr . on ( 'data' , makeStderrCallback ( ( data ) => {
156+ stderr += data
157+ } ) )
158+
159+ const { 0 : { 0 : code , 1 : signal } , 1 : stdout } = await SafePromiseAll ( [
120160 once ( child , 'exit' , { signal : t . signal } ) ,
121- child . stdout . toArray ( { signal : t . signal } ) ,
122- child . stderr . toArray ( { signal : t . signal } )
161+ child . stdout . toArray ( { signal : t . signal } )
123162 ] )
124163
125164 if ( code !== 0 || signal !== null ) {
@@ -129,7 +168,7 @@ function runTestFile (path, root) {
129168 exitCode : code ,
130169 signal,
131170 stdout : ArrayPrototypeJoin ( stdout , '' ) ,
132- stderr : ArrayPrototypeJoin ( stderr , '' ) ,
171+ stderr,
133172 // The stack will not be useful since the failures came from tests
134173 // in a child process.
135174 stack : undefined
@@ -146,7 +185,7 @@ function run (options) {
146185 if ( options === null || typeof options !== 'object' ) {
147186 options = kEmptyObject
148187 }
149- const { concurrency, timeout, signal, files } = options
188+ const { concurrency, timeout, signal, files, inspectPort } = options
150189
151190 if ( files != null ) {
152191 validateArray ( files , 'options.files' )
@@ -155,7 +194,7 @@ function run (options) {
155194 const root = createTestTree ( { concurrency, timeout, signal } )
156195 const testFiles = files ?? createTestFileList ( )
157196
158- PromisePrototypeThen ( SafePromiseAll ( testFiles , ( path ) => runTestFile ( path , root ) ) ,
197+ PromisePrototypeThen ( SafePromiseAll ( testFiles , ( path ) => runTestFile ( path , root , inspectPort ) ) ,
159198 ( ) => root . postRun ( ) )
160199
161200 return root . reporter
0 commit comments