diff --git a/src/backend/Windows.zig b/src/backend/Windows.zig index 609e619..d4dacd2 100644 --- a/src/backend/Windows.zig +++ b/src/backend/Windows.zig @@ -183,8 +183,19 @@ fn thread_fn( if (info.Action == FILE_ACTION_RENAMED_NEW_NAME) { if (pending_rename) |pr| { const src = pr.path_buf[0..pr.path_len]; - // Re-scan renamed directory contents into cache so - // subsequent delete events for children resolve correctly. + // Cache the new path so future delete/rename events can + // resolve its type (OLD_NAME removed it from the cache). + if (pr.object_type != .unknown) cache_new: { + const gop = path_types.getOrPut(allocator, full_path) catch break :cache_new; + if (!gop.found_existing) { + gop.key_ptr.* = allocator.dupe(u8, full_path) catch { + _ = path_types.remove(full_path); + break :cache_new; + }; + } + gop.value_ptr.* = pr.object_type; + } + // For dirs, also scan children into cache. if (pr.object_type == .dir) scan_path_types_into(allocator, path_types, full_path); const next_entry_offset = info.NextEntryOffset; diff --git a/src/nightwatch_test.zig b/src/nightwatch_test.zig index 8230599..e94e7af 100644 --- a/src/nightwatch_test.zig +++ b/src/nightwatch_test.zig @@ -550,8 +550,6 @@ fn testMultipleFiles(comptime Watcher: type, allocator: std.mem.Allocator) !void } fn testRenameOrder(comptime Watcher: type, allocator: std.mem.Allocator) !void { - // inotify pairs MOVED_FROM + MOVED_TO into a single rename event; nothing to order. - if (builtin.os.tag == .linux) return error.SkipZigTest; const TH = MakeTestHandler(Watcher); @@ -581,6 +579,10 @@ fn testRenameOrder(comptime Watcher: type, allocator: std.mem.Allocator) !void { try std.fs.renameAbsolute(src_path, dst_path); try drainEvents(Watcher, &watcher); + // Backends that deliver a paired rename() callback (INotify, Windows) have + // no two-event ordering to verify - the pair is a single atomic event. + if (th.hasRename(src_path, dst_path)) return; + const src_idx = th.indexOfAnyPath(src_path) orelse return error.MissingSrcEvent; const dst_idx = th.indexOfChange(dst_path, .renamed, .file) orelse @@ -628,10 +630,12 @@ fn testRenameThenModify(comptime Watcher: type, allocator: std.mem.Allocator) !v } try drainEvents(Watcher, &watcher); - const rename_idx: usize = if (builtin.os.tag == .linux) - th.indexOfRename(src_path, dst_path) orelse return error.MissingRenameEvent - else - th.indexOfAnyPath(src_path) orelse return error.MissingSrcEvent; + // Prefer the paired rename event (INotify, Windows); fall back to any + // event touching src_path for backends that emit separate events. + const rename_idx: usize = + th.indexOfRename(src_path, dst_path) orelse + th.indexOfAnyPath(src_path) orelse + return error.MissingSrcEvent; const modify_idx = th.indexOfChange(dst_path, .modified, .file) orelse return error.MissingModifyEvent;