@@ -13,6 +13,12 @@ import { once } from 'node:events';
13
13
if ( common . isIBMi )
14
14
common . skip ( 'IBMi does not support `fs.watch()`' ) ;
15
15
16
+ function deferred ( ) {
17
+ let res ;
18
+ const promise = new Promise ( ( resolve ) => res = resolve ) ;
19
+ return { resolve : res , promise } ;
20
+ }
21
+
16
22
function restart ( file ) {
17
23
// To avoid flakiness, we save the file repeatedly until test is done
18
24
writeFileSync ( file , readFileSync ( file ) ) ;
@@ -59,8 +65,8 @@ async function spawnWithRestarts({
59
65
}
60
66
61
67
let tmpFiles = 0 ;
62
- function createTmpFile ( content = 'console.log("running");' ) {
63
- const file = path . join ( tmpdir . path , `${ tmpFiles ++ } .js ` ) ;
68
+ function createTmpFile ( content = 'console.log("running");' , ext = '.js' ) {
69
+ const file = path . join ( tmpdir . path , `${ tmpFiles ++ } ${ ext } ` ) ;
64
70
writeFileSync ( file , content ) ;
65
71
return file ;
66
72
}
@@ -74,6 +80,25 @@ function assertRestartedCorrectly({ stdout, messages: { inner, completed, restar
74
80
assert . deepStrictEqual ( lines . slice ( - end . length ) , end ) ;
75
81
}
76
82
83
+ async function failWriteSucceed ( { file, watchedFile } ) {
84
+ let stdout = '' ;
85
+ const notFound = deferred ( ) ;
86
+ const completed = deferred ( ) ;
87
+ const child = spawn ( execPath , [ '--watch' , '--no-warnings' , file ] , { encoding : 'utf8' } ) ;
88
+
89
+ child . stdout . on ( 'data' , ( data ) => {
90
+ stdout += data ;
91
+ if ( data . toString ( ) . startsWith ( 'Failed running' ) ) notFound . resolve ( ) ;
92
+ if ( data . toString ( ) . startsWith ( 'Completed running' ) ) completed . resolve ( ) ;
93
+ } ) ;
94
+
95
+ await notFound . promise ;
96
+ writeFileSync ( watchedFile , 'console.log("test has ran");' ) ;
97
+ await completed . promise ;
98
+ child . kill ( ) ;
99
+ assert . match ( stdout , / t e s t h a s r a n / ) ;
100
+ }
101
+
77
102
tmpdir . refresh ( ) ;
78
103
79
104
// Warning: this suite can run safely with concurrency: true
@@ -104,14 +129,6 @@ describe('watch mode', { concurrency: true, timeout: 60_0000 }, () => {
104
129
} ) ;
105
130
} ) ;
106
131
107
- it ( 'should not watch when running an non-existing file' , async ( ) => {
108
- const file = fixtures . path ( 'watch-mode/non-existing.js' ) ;
109
- const { stderr, stdout } = await spawnWithRestarts ( { file, restarts : 0 } ) ;
110
-
111
- assert . match ( stderr , / c o d e : ' M O D U L E _ N O T _ F O U N D ' / ) ;
112
- assert . strictEqual ( stdout , `Failed running ${ inspect ( file ) } \n` ) ;
113
- } ) ;
114
-
115
132
it ( 'should watch when running an non-existing file - when specified under --watch-path' , {
116
133
skip : ! common . isOSX && ! common . isWindows
117
134
} , async ( ) => {
@@ -220,4 +237,30 @@ describe('watch mode', { concurrency: true, timeout: 60_0000 }, () => {
220
237
messages : { restarted : `Restarting ${ inspect ( file ) } ` , completed : `Completed running ${ inspect ( file ) } ` } ,
221
238
} ) ;
222
239
} ) ;
240
+
241
+ it ( 'should not watch when running an missing file' , async ( ) => {
242
+ const nonExistingfile = path . join ( tmpdir . path , `${ tmpFiles ++ } .js` ) ;
243
+ await failWriteSucceed ( { file : nonExistingfile , watchedFile : nonExistingfile } ) ;
244
+ } ) ;
245
+
246
+ it ( 'should not watch when running an missing mjs file' , async ( ) => {
247
+ const nonExistingfile = path . join ( tmpdir . path , `${ tmpFiles ++ } .mjs` ) ;
248
+ await failWriteSucceed ( { file : nonExistingfile , watchedFile : nonExistingfile } ) ;
249
+ } ) ;
250
+
251
+ it ( 'should watch changes to previously missing dependency' , async ( ) => {
252
+ const dependency = path . join ( tmpdir . path , `${ tmpFiles ++ } .js` ) ;
253
+ const relativeDependencyPath = `./${ path . basename ( dependency ) } ` ;
254
+ const dependant = createTmpFile ( `console.log(require('${ relativeDependencyPath } '))` ) ;
255
+
256
+ await failWriteSucceed ( { file : dependant , watchedFile : dependency } ) ;
257
+ } ) ;
258
+
259
+ it ( 'should watch changes to previously missing ESM dependency' , async ( ) => {
260
+ const dependency = path . join ( tmpdir . path , `${ tmpFiles ++ } .mjs` ) ;
261
+ const relativeDependencyPath = `./${ path . basename ( dependency ) } ` ;
262
+ const dependant = createTmpFile ( `import '${ relativeDependencyPath } '` , '.mjs' ) ;
263
+
264
+ await failWriteSucceed ( { file : dependant , watchedFile : dependency } ) ;
265
+ } ) ;
223
266
} ) ;
0 commit comments