@@ -3,7 +3,7 @@ import * as common from '../common/index.mjs';
33import  {  describe ,  it  }  from  'node:test' ; 
44import  assert  from  'node:assert' ; 
55import  {  spawn  }  from  'node:child_process' ; 
6- import  {  writeFileSync  }  from  'node:fs' ; 
6+ import  {  writeFileSync ,   renameSync ,   unlinkSync ,   existsSync  }  from  'node:fs' ; 
77import  util  from  'internal/util' ; 
88import  tmpdir  from  '../common/tmpdir.js' ; 
99
@@ -30,7 +30,7 @@ const fixturePaths = Object.keys(fixtureContent)
3030Object . entries ( fixtureContent ) 
3131  . forEach ( ( [ file ,  content ] )  =>  writeFileSync ( fixturePaths [ file ] ,  content ) ) ; 
3232
33- async  function  testWatch ( {  fileToUpdate,  file } )  { 
33+ async  function  testWatch ( {  fileToUpdate,  file,  action  =   'update'  } )  { 
3434  const  ran1  =  util . createDeferredPromise ( ) ; 
3535  const  ran2  =  util . createDeferredPromise ( ) ; 
3636  const  child  =  spawn ( process . execPath , 
@@ -48,6 +48,7 @@ async function testWatch({ fileToUpdate, file }) {
4848    if  ( testRuns ?. length  >=  2 )  ran2 . resolve ( ) ; 
4949  } ) ; 
5050
51+   if  ( action  ===  'update' )  { 
5152  await  ran1 . promise ; 
5253  runs . push ( currentRun ) ; 
5354  currentRun  =  '' ; 
@@ -58,11 +59,51 @@ async function testWatch({ fileToUpdate, file }) {
5859  runs . push ( currentRun ) ; 
5960  clearInterval ( interval ) ; 
6061  child . kill ( ) ; 
62+     for  ( const  run  of  runs )  { 
63+       assert . match ( run ,  / #   t e s t s   1 / ) ; 
64+       assert . match ( run ,  / #   p a s s   1 / ) ; 
65+       assert . match ( run ,  / #   f a i l   0 / ) ; 
66+       assert . match ( run ,  / #   c a n c e l l e d   0 / ) ; 
67+     } 
68+   }  else  if  ( action  ===  'rename' )  { 
69+     await  ran1 . promise ; 
70+     runs . push ( currentRun ) ; 
71+     currentRun  =  '' ; 
72+     const  fileToRenamePath  =  tmpdir . resolve ( fileToUpdate ) ; 
73+     const  newFileNamePath  =  tmpdir . resolve ( `test-renamed-${ fileToUpdate }  ` ) ; 
74+     const  interval  =  setInterval ( ( )  =>  renameSync ( fileToRenamePath ,  newFileNamePath ) ,  common . platformTimeout ( 1000 ) ) ; 
75+     await  ran2 . promise ; 
76+     runs . push ( currentRun ) ; 
77+     clearInterval ( interval ) ; 
78+     child . kill ( ) ; 
79+ 
6180  for  ( const  run  of  runs )  { 
6281    assert . match ( run ,  / #   t e s t s   1 / ) ; 
6382    assert . match ( run ,  / #   p a s s   1 / ) ; 
6483    assert . match ( run ,  / #   f a i l   0 / ) ; 
6584    assert . match ( run ,  / #   c a n c e l l e d   0 / ) ; 
85+     } 
86+   }  else  if  ( action  ===  'delete' )  { 
87+     await  ran1 . promise ; 
88+     runs . push ( currentRun ) ; 
89+     currentRun  =  '' ; 
90+     const  fileToDeletePath  =  tmpdir . resolve ( fileToUpdate ) ; 
91+     const  interval  =  setInterval ( ( )  =>  { 
92+       if ( existsSync ( fileToDeletePath ) )  { 
93+         unlinkSync ( fileToDeletePath ) 
94+       }  else  { 
95+         ran2 . resolve ( ) ; 
96+       } 
97+     } ,  common . platformTimeout ( 1000 ) ) ; 
98+     await  ran2 . promise ; 
99+ 
100+     runs . push ( currentRun ) ; 
101+     clearInterval ( interval ) ; 
102+     child . kill ( ) ; 
103+ 
104+     for  ( const  run  of  runs )  { 
105+       assert . doesNotMatch ( run ,  / M O D U L E _ N O T _ F O U N D / ) 
106+     } 
66107  } 
67108} 
68109
@@ -82,4 +123,12 @@ describe('test runner watch mode', () => {
82123  it ( 'should support running tests without a file' ,  async  ( )  =>  { 
83124    await  testWatch ( {  fileToUpdate : 'test.js'  } ) ; 
84125  } ) ; 
126+ 
127+   it ( 'should support a watched test file rename' ,  async  ( )  =>  { 
128+     await  testWatch ( {  fileToUpdate : 'test.js' ,  action : 'rename'  } ) ; 
129+   } ) ; 
130+ 
131+   it ( 'should not throw when delete a watched test file' ,  async  ( )  =>  { 
132+     await  testWatch ( {  fileToUpdate : 'test.js' ,  action : 'delete'  } ) ; 
133+   } ) ; 
85134} ) ; 
0 commit comments