From e22ff9f4300ab573ac25b91b9d972dd2daa104a2 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 19 Jul 2026 21:29:21 -0700 Subject: [PATCH] test(editor): cover source-side self-move guard in the pre-remap ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the case where the watcher's delete(old) arrives while the tab is still at the old path (before remap re-homes it): with a live self-move source stamp the tombstone must be suppressed. Pairs with the existing naked-delete control (no stamp → deleted) to pin the guard's behavior. Co-authored-by: Orca --- .../src/hooks/useEditorExternalWatch.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/renderer/src/hooks/useEditorExternalWatch.test.ts b/src/renderer/src/hooks/useEditorExternalWatch.test.ts index 1371e8cf141..a5b4135a9ba 100644 --- a/src/renderer/src/hooks/useEditorExternalWatch.test.ts +++ b/src/renderer/src/hooks/useEditorExternalWatch.test.ts @@ -266,6 +266,22 @@ describe('createExternalWatchEventHandler tombstone coalescing', () => { dispose() }) + it('does not tombstone a tab still at the old path when its delete is a self-move echo', () => { + // Pre-remap ordering: the watcher's delete(old) can arrive while the tab is + // still at the old path (remap hasn't run yet). Because the stamp is + // recorded before the rename, the source guard must still suppress the + // tombstone — the tab is about to be re-homed, not deleted. + recordSelfMove('/repo/notes.md', '/repo/subdir/notes.md') + const { handleFsChanged, dispose } = createExternalWatchEventHandler(findTarget) + + handleFsChanged(payload([{ kind: 'delete', absolutePath: '/repo/notes.md' }])) + vi.advanceTimersByTime(200) + + expect(setExternalMutation).not.toHaveBeenCalledWith('file-notes', 'deleted') + expect(setExternalMutation).not.toHaveBeenCalledWith('file-notes', 'renamed') + dispose() + }) + it('resolves batched delete+create in a single payload synchronously as renamed', () => { const { handleFsChanged, dispose } = createExternalWatchEventHandler(findTarget) handleFsChanged(