@@ -8,6 +8,7 @@ import { spawn } from 'node:child_process';
88import { writeFileSync , readFileSync , mkdirSync } from 'node:fs' ;
99import { inspect } from 'node:util' ;
1010import { pathToFileURL } from 'node:url' ;
11+ import { once } from 'node:events' ;
1112import { createInterface } from 'node:readline' ;
1213
1314if ( common . isIBMi )
@@ -574,4 +575,84 @@ console.log(values.random);
574575 `Completed running ${ inspect ( file ) } ` ,
575576 ] ) ;
576577 } ) ;
578+
579+ it ( 'should pass IPC messages from a spawning parent to the child and back' , async ( ) => {
580+ const file = createTmpFile ( `console.log('running');
581+ process.on('message', (message) => {
582+ if (message === 'exit') {
583+ process.exit(0);
584+ } else {
585+ console.log('Received:', message);
586+ process.send(message);
587+ }
588+ })` ) ;
589+
590+ const child = spawn (
591+ execPath ,
592+ [
593+ '--watch' ,
594+ '--no-warnings' ,
595+ file ,
596+ ] ,
597+ {
598+ encoding : 'utf8' ,
599+ stdio : [ 'pipe' , 'pipe' , 'pipe' , 'ipc' ] ,
600+ } ,
601+ ) ;
602+
603+ let stderr = '' ;
604+ let stdout = '' ;
605+
606+ child . stdout . on ( 'data' , ( data ) => stdout += data ) ;
607+ child . stderr . on ( 'data' , ( data ) => stderr += data ) ;
608+ async function waitForEcho ( msg ) {
609+ const receivedPromise = new Promise ( ( resolve ) => {
610+ const fn = ( message ) => {
611+ if ( message === msg ) {
612+ child . off ( 'message' , fn ) ;
613+ resolve ( ) ;
614+ }
615+ } ;
616+ child . on ( 'message' , fn ) ;
617+ } ) ;
618+ child . send ( msg ) ;
619+ await receivedPromise ;
620+ }
621+
622+ async function waitForText ( text ) {
623+ const seenPromise = new Promise ( ( resolve ) => {
624+ const fn = ( data ) => {
625+ if ( data . toString ( ) . includes ( text ) ) {
626+ resolve ( ) ;
627+ child . stdout . off ( 'data' , fn ) ;
628+ }
629+ } ;
630+ child . stdout . on ( 'data' , fn ) ;
631+ } ) ;
632+ await seenPromise ;
633+ }
634+
635+ await waitForText ( 'running' ) ;
636+ await waitForEcho ( 'first message' ) ;
637+ const stopRestarts = restart ( file ) ;
638+ await waitForText ( 'running' ) ;
639+ stopRestarts ( ) ;
640+ await waitForEcho ( 'second message' ) ;
641+ const exitedPromise = once ( child , 'exit' ) ;
642+ child . send ( 'exit' ) ;
643+ await waitForText ( 'Completed' ) ;
644+ child . disconnect ( ) ;
645+ child . kill ( ) ;
646+ await exitedPromise ;
647+ assert . strictEqual ( stderr , '' ) ;
648+ const lines = stdout . split ( / \r ? \n / ) . filter ( Boolean ) ;
649+ assert . deepStrictEqual ( lines , [
650+ 'running' ,
651+ 'Received: first message' ,
652+ `Restarting ${ inspect ( file ) } ` ,
653+ 'running' ,
654+ 'Received: second message' ,
655+ `Completed running ${ inspect ( file ) } ` ,
656+ ] ) ;
657+ } ) ;
577658} ) ;
0 commit comments