@@ -3,7 +3,7 @@ import * as common from '../common/index.mjs';
3
3
import { describe , it } from 'node:test' ;
4
4
import assert from 'node:assert' ;
5
5
import { spawn } from 'node:child_process' ;
6
- import { writeFileSync } from 'node:fs' ;
6
+ import { writeFileSync , renameSync , unlinkSync , existsSync } from 'node:fs' ;
7
7
import util from 'internal/util' ;
8
8
import tmpdir from '../common/tmpdir.js' ;
9
9
@@ -30,7 +30,7 @@ const fixturePaths = Object.keys(fixtureContent)
30
30
Object . entries ( fixtureContent )
31
31
. forEach ( ( [ file , content ] ) => writeFileSync ( fixturePaths [ file ] , content ) ) ;
32
32
33
- async function testWatch ( { fileToUpdate, file } ) {
33
+ async function testWatch ( { fileToUpdate, file, action = 'update' } ) {
34
34
const ran1 = util . createDeferredPromise ( ) ;
35
35
const ran2 = util . createDeferredPromise ( ) ;
36
36
const child = spawn ( process . execPath ,
@@ -48,21 +48,62 @@ async function testWatch({ fileToUpdate, file }) {
48
48
if ( testRuns ?. length >= 2 ) ran2 . resolve ( ) ;
49
49
} ) ;
50
50
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 / ) ;
51
+ if ( action === 'update' ) {
52
+ await ran1 . promise ;
53
+ runs . push ( currentRun ) ;
54
+ currentRun = '' ;
55
+ const content = fixtureContent [ fileToUpdate ] ;
56
+ const path = fixturePaths [ fileToUpdate ] ;
57
+ const interval = setInterval ( ( ) => writeFileSync ( path , content ) , common . platformTimeout ( 1000 ) ) ;
58
+ await ran2 . promise ;
59
+ runs . push ( currentRun ) ;
60
+ clearInterval ( interval ) ;
61
+ 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
+
80
+ for ( const run of runs ) {
81
+ assert . match ( run , / # t e s t s 1 / ) ;
82
+ assert . match ( run , / # p a s s 1 / ) ;
83
+ assert . match ( run , / # f a i l 0 / ) ;
84
+ 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
+ }
66
107
}
67
108
}
68
109
@@ -82,4 +123,12 @@ describe('test runner watch mode', () => {
82
123
it ( 'should support running tests without a file' , async ( ) => {
83
124
await testWatch ( { fileToUpdate : 'test.js' } ) ;
84
125
} ) ;
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
+ } ) ;
85
134
} ) ;
0 commit comments