refactor: add move in/out tests
This commit is contained in:
parent
adf172cea6
commit
bfd1125449
3 changed files with 243 additions and 7 deletions
|
|
@ -643,6 +643,146 @@ fn testRenameThenModify(comptime Watcher: type, allocator: std.mem.Allocator) !v
|
|||
try std.testing.expect(rename_idx < modify_idx);
|
||||
}
|
||||
|
||||
fn testMoveOutFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||
const TH = MakeTestHandler(Watcher);
|
||||
|
||||
const watched = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(watched);
|
||||
allocator.free(watched);
|
||||
}
|
||||
const other = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(other);
|
||||
allocator.free(other);
|
||||
}
|
||||
|
||||
const th = try TH.init(allocator);
|
||||
defer th.deinit();
|
||||
|
||||
var watcher = try Watcher.init(allocator, &th.handler);
|
||||
defer watcher.deinit();
|
||||
try watcher.watch(watched);
|
||||
|
||||
const src_path = try std.fs.path.join(allocator, &.{ watched, "moveme.txt" });
|
||||
defer allocator.free(src_path);
|
||||
const dst_path = try std.fs.path.join(allocator, &.{ other, "moveme.txt" });
|
||||
defer allocator.free(dst_path);
|
||||
|
||||
{
|
||||
const f = try std.fs.createFileAbsolute(src_path, .{});
|
||||
f.close();
|
||||
}
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
try std.fs.renameAbsolute(src_path, dst_path);
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
// File moved out of the watched tree: appears as deleted (INotify, Windows)
|
||||
// or renamed (kqueue, which holds a vnode fd and sees NOTE_RENAME).
|
||||
const src_gone = th.hasChange(src_path, .deleted, .file) or
|
||||
th.hasChange(src_path, .renamed, .file);
|
||||
try std.testing.expect(src_gone);
|
||||
// No event for the destination - it is in an unwatched directory.
|
||||
try std.testing.expect(!th.hasChange(dst_path, .created, .file));
|
||||
}
|
||||
|
||||
fn testMoveInFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||
const TH = MakeTestHandler(Watcher);
|
||||
|
||||
const watched = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(watched);
|
||||
allocator.free(watched);
|
||||
}
|
||||
const other = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(other);
|
||||
allocator.free(other);
|
||||
}
|
||||
|
||||
const th = try TH.init(allocator);
|
||||
defer th.deinit();
|
||||
|
||||
var watcher = try Watcher.init(allocator, &th.handler);
|
||||
defer watcher.deinit();
|
||||
try watcher.watch(watched);
|
||||
|
||||
const src_path = try std.fs.path.join(allocator, &.{ other, "moveme.txt" });
|
||||
defer allocator.free(src_path);
|
||||
const dst_path = try std.fs.path.join(allocator, &.{ watched, "moveme.txt" });
|
||||
defer allocator.free(dst_path);
|
||||
|
||||
{
|
||||
const f = try std.fs.createFileAbsolute(src_path, .{});
|
||||
f.close();
|
||||
}
|
||||
|
||||
try std.fs.renameAbsolute(src_path, dst_path);
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
// File moved into the watched tree: appears as created.
|
||||
try std.testing.expect(th.hasChange(dst_path, .created, .file));
|
||||
// No event for the source - it was in an unwatched directory.
|
||||
try std.testing.expect(!th.hasChange(src_path, .deleted, .file));
|
||||
}
|
||||
|
||||
fn testMoveInSubdir(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||
const TH = MakeTestHandler(Watcher);
|
||||
|
||||
const watched = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(watched);
|
||||
allocator.free(watched);
|
||||
}
|
||||
const other = try makeTempDir(allocator);
|
||||
defer {
|
||||
removeTempDir(other);
|
||||
allocator.free(other);
|
||||
}
|
||||
|
||||
const th = try TH.init(allocator);
|
||||
defer th.deinit();
|
||||
|
||||
var watcher = try Watcher.init(allocator, &th.handler);
|
||||
defer watcher.deinit();
|
||||
try watcher.watch(watched);
|
||||
|
||||
const src_sub = try std.fs.path.join(allocator, &.{ other, "sub" });
|
||||
defer allocator.free(src_sub);
|
||||
const dst_sub = try std.fs.path.join(allocator, &.{ watched, "sub" });
|
||||
defer allocator.free(dst_sub);
|
||||
const src_file = try std.fs.path.join(allocator, &.{ src_sub, "f.txt" });
|
||||
defer allocator.free(src_file);
|
||||
const dst_file = try std.fs.path.join(allocator, &.{ dst_sub, "f.txt" });
|
||||
defer allocator.free(dst_file);
|
||||
|
||||
// Create subdir with a file in the unwatched root, then move it in.
|
||||
try std.fs.makeDirAbsolute(src_sub);
|
||||
{
|
||||
const f = try std.fs.createFileAbsolute(src_file, .{});
|
||||
f.close();
|
||||
}
|
||||
try std.fs.renameAbsolute(src_sub, dst_sub);
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
try std.testing.expect(th.hasChange(dst_sub, .created, .dir));
|
||||
|
||||
// Delete the file inside the moved-in subdir.
|
||||
try std.fs.deleteFileAbsolute(dst_file);
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
// Object type must be .file, not .unknown - backend must have seeded
|
||||
// the path_types cache when the subdir was moved in.
|
||||
try std.testing.expect(th.hasChange(dst_file, .deleted, .file));
|
||||
|
||||
// Delete the now-empty subdir.
|
||||
try std.fs.deleteDirAbsolute(dst_sub);
|
||||
try drainEvents(Watcher, &watcher);
|
||||
|
||||
try std.testing.expect(th.hasChange(dst_sub, .deleted, .dir));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test blocks - each runs its case across all available variants.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -724,3 +864,21 @@ test "rename-then-modify: rename event precedes the subsequent modify event" {
|
|||
try testRenameThenModify(nw.Create(variant), std.testing.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
test "moving a file out of the watched tree appears as deleted or renamed" {
|
||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
||||
try testMoveOutFile(nw.Create(variant), std.testing.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
test "moving a file into the watched tree appears as created" {
|
||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
||||
try testMoveInFile(nw.Create(variant), std.testing.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
test "moving a subdir into the watched tree: contents can be deleted with correct types" {
|
||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
||||
try testMoveInSubdir(nw.Create(variant), std.testing.allocator);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ if (-not (Test-Path $NW)) {
|
|||
exit 1
|
||||
}
|
||||
|
||||
$TESTDIR = Join-Path $env:TEMP "nightwatch_manual_$PID"
|
||||
$TESTDIR2 = Join-Path $env:TEMP "nightwatch_manual2_$PID"
|
||||
New-Item -ItemType Directory -Path $TESTDIR | Out-Null
|
||||
New-Item -ItemType Directory -Path $TESTDIR2 | Out-Null
|
||||
$TESTDIR = Join-Path $env:TEMP "nightwatch_manual_$PID"
|
||||
$TESTDIR2 = Join-Path $env:TEMP "nightwatch_manual2_$PID"
|
||||
$UNWATCHED = Join-Path $env:TEMP "nightwatch_unwatched_$PID"
|
||||
New-Item -ItemType Directory -Path $TESTDIR | Out-Null
|
||||
New-Item -ItemType Directory -Path $TESTDIR2 | Out-Null
|
||||
New-Item -ItemType Directory -Path $UNWATCHED | Out-Null
|
||||
|
||||
Write-Host "--- watching $TESTDIR and $TESTDIR2 ---"
|
||||
Write-Host "--- watching $TESTDIR and $TESTDIR2 (unwatched: $UNWATCHED) ---"
|
||||
Write-Host "--- starting nightwatch (Ctrl-C to stop early) ---"
|
||||
Write-Host ""
|
||||
|
||||
|
|
@ -104,9 +106,47 @@ Write-Host "[op] rename subA: dir1 -> dir2 (subdir across roots)"
|
|||
Move-Item -Path "$TESTDIR\subA" -Destination "$TESTDIR2\subA2"
|
||||
Start-Sleep -Milliseconds 500
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "# move in/out (one side unwatched)"
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "[op] touch outfile.txt in dir1"
|
||||
New-Item -ItemType File -Path "$TESTDIR\outfile.txt" | Out-Null
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] move outfile.txt: dir1 -> unwatched (move out)"
|
||||
Move-Item -Path "$TESTDIR\outfile.txt" -Destination "$UNWATCHED\outfile.txt"
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] move outfile.txt: unwatched -> dir1 (move in)"
|
||||
Move-Item -Path "$UNWATCHED\outfile.txt" -Destination "$TESTDIR\outfile.txt"
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] delete outfile.txt"
|
||||
Remove-Item -Path "$TESTDIR\outfile.txt"
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] mkdir unwatched\subdir with a file"
|
||||
New-Item -ItemType Directory -Path "$UNWATCHED\subdir" | Out-Null
|
||||
New-Item -ItemType File -Path "$UNWATCHED\subdir\inside.txt" | Out-Null
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] move unwatched\subdir -> dir1\subdir (move subdir in)"
|
||||
Move-Item -Path "$UNWATCHED\subdir" -Destination "$TESTDIR\subdir"
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] delete dir1\subdir\inside.txt"
|
||||
Remove-Item -Path "$TESTDIR\subdir\inside.txt"
|
||||
Start-Sleep -Milliseconds 400
|
||||
|
||||
Write-Host "[op] rmdir dir1\subdir"
|
||||
Remove-Item -Path "$TESTDIR\subdir"
|
||||
Start-Sleep -Milliseconds 500
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "--- done, stopping nightwatch ---"
|
||||
Stop-Process -Id $proc.Id -ErrorAction SilentlyContinue
|
||||
$proc.WaitForExit()
|
||||
Remove-Item -Recurse -Force -Path $TESTDIR
|
||||
Remove-Item -Recurse -Force -Path $TESTDIR2
|
||||
Remove-Item -Recurse -Force -Path $UNWATCHED
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ fi
|
|||
|
||||
TESTDIR=$(mktemp -d)
|
||||
TESTDIR2=$(mktemp -d)
|
||||
echo "--- watching $TESTDIR and $TESTDIR2 ---"
|
||||
UNWATCHED=$(mktemp -d)
|
||||
echo "--- watching $TESTDIR and $TESTDIR2 (unwatched: $UNWATCHED) ---"
|
||||
echo "--- starting nightwatch (Ctrl-C to stop early) ---"
|
||||
echo ""
|
||||
|
||||
|
|
@ -101,8 +102,45 @@ echo "[op] rename subA: dir1 -> dir2 (subdir across roots)"
|
|||
mv "$TESTDIR/subA" "$TESTDIR2/subA2"
|
||||
sleep 0.5
|
||||
|
||||
echo ""
|
||||
echo "# move in/out (one side unwatched)"
|
||||
echo ""
|
||||
|
||||
echo "[op] touch outfile.txt in dir1"
|
||||
touch "$TESTDIR/outfile.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] move outfile.txt: dir1 -> unwatched (move out)"
|
||||
mv "$TESTDIR/outfile.txt" "$UNWATCHED/outfile.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] move outfile.txt: unwatched -> dir1 (move in)"
|
||||
mv "$UNWATCHED/outfile.txt" "$TESTDIR/outfile.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] delete outfile.txt"
|
||||
rm "$TESTDIR/outfile.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] mkdir unwatched/subdir with a file"
|
||||
mkdir "$UNWATCHED/subdir"
|
||||
touch "$UNWATCHED/subdir/inside.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] move unwatched/subdir -> dir1/subdir (move subdir in)"
|
||||
mv "$UNWATCHED/subdir" "$TESTDIR/subdir"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] delete dir1/subdir/inside.txt"
|
||||
rm "$TESTDIR/subdir/inside.txt"
|
||||
sleep 0.4
|
||||
|
||||
echo "[op] rmdir dir1/subdir"
|
||||
rmdir "$TESTDIR/subdir"
|
||||
sleep 0.5
|
||||
|
||||
echo ""
|
||||
echo "--- done, stopping nightwatch ---"
|
||||
kill $NW_PID 2>/dev/null
|
||||
wait $NW_PID 2>/dev/null
|
||||
rm -rf "$TESTDIR" "$TESTDIR2"
|
||||
rm -rf "$TESTDIR" "$TESTDIR2" "$UNWATCHED"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue