test(editor): cover source-side self-move guard in the pre-remap ordering

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 <help@stably.ai>
This commit is contained in:
Neil
2026-07-19 21:29:21 -07:00
co-authored by Orca
parent 62e28ce784
commit e22ff9f430
@@ -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(