@@ -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,22 +48,64 @@ 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 / ) ;
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 ( ) ;
67
109
}
68
110
69
111
describe ( 'test runner watch mode' , ( ) => {
@@ -82,4 +124,12 @@ describe('test runner watch mode', () => {
82
124
it ( 'should support running tests without a file' , async ( ) => {
83
125
await testWatch ( { fileToUpdate : 'test.js' } ) ;
84
126
} ) ;
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
+ } ) ;
85
135
} ) ;
0 commit comments