@@ -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,22 +48,64 @@ async function testWatch({ fileToUpdate, file }) {
4848 if ( testRuns ?. length >= 2 ) ran2 . resolve ( ) ;
4949 } ) ;
5050
51- await ran1 . promise ;
52- runs . push ( currentRun ) ;
53- currentRun = '' ;
54- const content = fixtureContent [ fileToUpdate ] ;
55- const path = fixturePaths [ fileToUpdate ] ;
56- const interval = setInterval ( ( ) => writeFileSync ( path , content ) , common . platformTimeout ( 1000 ) ) ;
57- await ran2 . promise ;
58- runs . push ( currentRun ) ;
59- clearInterval ( interval ) ;
60- child . kill ( ) ;
61- for ( const run of runs ) {
62- assert . match ( run , / # t e s t s 1 / ) ;
63- assert . match ( run , / # p a s s 1 / ) ;
64- assert . match ( run , / # f a i l 0 / ) ;
65- assert . match ( run , / # c a n c e l l e d 0 / ) ;
66- }
51+ const testUpdate = async ( ) => {
52+ await ran1 . promise ;
53+ const content = fixtureContent [ fileToUpdate ] ;
54+ const path = fixturePaths [ fileToUpdate ] ;
55+ const interval = setInterval ( ( ) => writeFileSync ( path , content ) , common . platformTimeout ( 1000 ) ) ;
56+ await ran2 . promise ;
57+ runs . push ( currentRun ) ;
58+ clearInterval ( interval ) ;
59+ child . kill ( ) ;
60+ for ( const run of runs ) {
61+ assert . match ( run , / # t e s t s 1 / ) ;
62+ assert . match ( run , / # p a s s 1 / ) ;
63+ assert . match ( run , / # f a i l 0 / ) ;
64+ assert . match ( run , / # c a n c e l l e d 0 / ) ;
65+ }
66+ } ;
67+
68+ const testRename = async ( ) => {
69+ await ran1 . promise ;
70+ const fileToRenamePath = tmpdir . resolve ( fileToUpdate ) ;
71+ const newFileNamePath = tmpdir . resolve ( `test-renamed-${ fileToUpdate } ` ) ;
72+ const interval = setInterval ( ( ) => renameSync ( fileToRenamePath , newFileNamePath ) , common . platformTimeout ( 1000 ) ) ;
73+ await ran2 . promise ;
74+ runs . push ( currentRun ) ;
75+ clearInterval ( interval ) ;
76+ child . kill ( ) ;
77+
78+ for ( const run of runs ) {
79+ assert . match ( run , / # t e s t s 1 / ) ;
80+ assert . match ( run , / # p a s s 1 / ) ;
81+ assert . match ( run , / # f a i l 0 / ) ;
82+ assert . match ( run , / # c a n c e l l e d 0 / ) ;
83+ }
84+ } ;
85+
86+ const testDelete = async ( ) => {
87+ await ran1 . promise ;
88+ const fileToDeletePath = tmpdir . resolve ( fileToUpdate ) ;
89+ const interval = setInterval ( ( ) => {
90+ if ( existsSync ( fileToDeletePath ) ) {
91+ unlinkSync ( fileToDeletePath ) ;
92+ } else {
93+ ran2 . resolve ( ) ;
94+ }
95+ } , common . platformTimeout ( 1000 ) ) ;
96+ await ran2 . promise ;
97+ runs . push ( currentRun ) ;
98+ clearInterval ( interval ) ;
99+ child . kill ( ) ;
100+
101+ for ( const run of runs ) {
102+ assert . doesNotMatch ( run , / M O D U L E _ N O T _ F O U N D / ) ;
103+ }
104+ } ;
105+
106+ action === 'update' && await testUpdate ( ) ;
107+ action === 'rename' && await testRename ( ) ;
108+ action === 'delete' && await testDelete ( ) ;
67109}
68110
69111describe ( 'test runner watch mode' , ( ) => {
@@ -82,4 +124,12 @@ describe('test runner watch mode', () => {
82124 it ( 'should support running tests without a file' , async ( ) => {
83125 await testWatch ( { fileToUpdate : 'test.js' } ) ;
84126 } ) ;
127+
128+ it ( 'should support a watched test file rename' , async ( ) => {
129+ await testWatch ( { fileToUpdate : 'test.js' , action : 'rename' } ) ;
130+ } ) ;
131+
132+ it ( 'should not throw when delete a watched test file' , async ( ) => {
133+ await testWatch ( { fileToUpdate : 'test.js' , action : 'delete' } ) ;
134+ } ) ;
85135} ) ;
0 commit comments