From 019625e1306bc699108c4e0a2eb106eb23d29990 Mon Sep 17 00:00:00 2001 From: jakecastelli <959672929@qq.com> Date: Thu, 23 May 2024 16:28:50 +0930 Subject: [PATCH] test_runner: handle file rename and deletion under watch mode Fixes: https://github.com/nodejs/node/issues/53113 --- lib/internal/test_runner/runner.js | 17 ++++++++++++++++- lib/internal/watch_mode/files_watcher.js | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 9e01eb2fbb66ed..24767005d357a6 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -418,7 +418,22 @@ function watchFiles(testFiles, opts) { const filesWatcher = { __proto__: null, watcher, runningProcesses, runningSubtests }; opts.root.harness.watching = true; - watcher.on('changed', ({ owners }) => { + watcher.on('changed', ({ owners, eventType }) => { + if (eventType === 'rename') { + const updatedTestFiles = createTestFileList(); + + const { 0: newFileName } = updatedTestFiles.filter((x) => !testFiles.includes(x)); + const { 0: previousFileName } = testFiles.filter((x) => !updatedTestFiles.includes(x)); + + // When file renamed + if (newFileName && previousFileName) { + owners = new SafeSet().add(newFileName); + watcher.filterFile(resolve(newFileName), owners); + } + + testFiles = updatedTestFiles; + } + watcher.unfilterFilesOwnedBy(owners); PromisePrototypeThen(SafePromiseAllReturnVoid(testFiles, async (file) => { if (!owners.has(file)) { diff --git a/lib/internal/watch_mode/files_watcher.js b/lib/internal/watch_mode/files_watcher.js index fda52e88b8d8ad..b961a0c4ba223b 100644 --- a/lib/internal/watch_mode/files_watcher.js +++ b/lib/internal/watch_mode/files_watcher.js @@ -80,7 +80,7 @@ class FilesWatcher extends EventEmitter { watcher.handle.close(); } - #onChange(trigger) { + #onChange(trigger, eventType) { if (this.#mode === 'filter' && !this.#filteredFiles.has(trigger)) { return; } @@ -93,7 +93,7 @@ class FilesWatcher extends EventEmitter { clearTimeout(this.#debounceTimer); this.#debounceTimer = setTimeout(() => { this.#debounceTimer = null; - this.emit('changed', { owners: this.#debounceOwners }); + this.emit('changed', { owners: this.#debounceOwners, eventType }); this.#debounceOwners.clear(); }, this.#debounce).unref(); } @@ -110,7 +110,7 @@ class FilesWatcher extends EventEmitter { watcher.on('change', (eventType, fileName) => { // `fileName` can be `null` if it cannot be determined. See // https://github.com/nodejs/node/pull/49891#issuecomment-1744673430. - this.#onChange(recursive ? resolve(path, fileName ?? '') : path); + this.#onChange(recursive ? resolve(path, fileName ?? '') : path, eventType); }); this.#watchers.set(path, { handle: watcher, recursive }); if (recursive) {