Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: reinstate deleted code, refactor, add MoveFile tests
  • Loading branch information
stogle committed Sep 18, 2025
commit e6182dd5aaf4e5cbb840002da98b47e82d934036
Original file line number Diff line number Diff line change
Expand Up @@ -347,30 +347,11 @@ protected override void Dispose(bool disposing)

private bool MatchesFilter(ChangeDescription changeDescription)
{
string fullPath = _fileSystem.Execute.Path.GetFullPath(Path);
if (IncludeSubdirectories)
{
if (!changeDescription.Path.StartsWith(fullPath,
_fileSystem.Execute.StringComparisonMode))
{
if (!(changeDescription.ChangeType == WatcherChangeTypes.Renamed &&
changeDescription.OldPath?.StartsWith(fullPath,
_fileSystem.Execute.StringComparisonMode) == true))
{
return false;
}
}
}
else if (!string.Equals(
_fileSystem.Execute.Path.GetDirectoryName(changeDescription.Path),
fullPath,
_fileSystem.Execute.StringComparisonMode))
if (!MatchesWatcherPath(changeDescription.Path))
{
if (!(changeDescription.ChangeType == WatcherChangeTypes.Renamed &&
string.Equals(
_fileSystem.Execute.Path.GetDirectoryName(changeDescription.OldPath),
fullPath,
_fileSystem.Execute.StringComparisonMode)))
if (changeDescription.ChangeType != WatcherChangeTypes.Renamed ||
changeDescription.OldPath == null ||
!MatchesWatcherPath(changeDescription.OldPath))
{
return false;
}
Expand All @@ -394,6 +375,18 @@ private bool MatchesFilter(ChangeDescription changeDescription)
filter));
}

private bool MatchesWatcherPath(string path)
{
string fullPath = _fileSystem.Execute.Path.GetFullPath(Path);
if (IncludeSubdirectories)
{
return path.StartsWith(fullPath, _fileSystem.Execute.StringComparisonMode);
}

return string.Equals(_fileSystem.Execute.Path.GetDirectoryName(path), fullPath,
_fileSystem.Execute.StringComparisonMode);
}

private void NotifyChange(ChangeDescription item)
{
InternalEvent?.Invoke(this, new ChangeDescriptionEventArgs(item));
Expand Down Expand Up @@ -548,6 +541,16 @@ private string TransformPathAndName(
}

name = transformedName;
if (!_fileSystem.Path.IsPathRooted(Path))
{
string rootedWatchedPath = _fileSystem.Path.GetFullPath(Path);
if (path?.StartsWith(rootedWatchedPath, _fileSystem.Execute.StringComparisonMode) ==
true)
{
path = _fileSystem.Path.Combine(Path, path.Substring(rootedWatchedPath.Length));
}
}

return path ?? "";
}

Expand All @@ -562,38 +565,16 @@ private void TriggerRenameNotification(ChangeDescription item)
}
else if (item.OldPath != null)
{
string fullPath = _fileSystem.Execute.Path.GetFullPath(Path);
if (IncludeSubdirectories)
if (MatchesWatcherPath(item.OldPath))
{
if (item.OldPath.StartsWith(fullPath, _fileSystem.Execute.StringComparisonMode))
{
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
}
if (item.Path.StartsWith(fullPath, _fileSystem.Execute.StringComparisonMode))
{
Created?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Created, item.Path, item.Name));
}
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
}
else

if (MatchesWatcherPath(item.Path))
{
if (string.Equals(
_fileSystem.Execute.Path.GetDirectoryName(item.OldPath),
fullPath,
_fileSystem.Execute.StringComparisonMode))
{
Deleted?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Deleted, item.OldPath, item.OldName));
}
if (string.Equals(
_fileSystem.Execute.Path.GetDirectoryName(item.Path),
fullPath,
_fileSystem.Execute.StringComparisonMode))
{
Created?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Created, item.Path, item.Name));
}
Created?.Invoke(this, ToFileSystemEventArgs(
WatcherChangeTypes.Created, item.Path, item.Name));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public async Task RenamedEventArgs_ShouldUseDirectorySeparatorFromSimulatedFileS
fileSystem.File.WriteAllText(expectedOldFullPath, "foo");

using IFileSystemWatcher fileSystemWatcher =
fileSystem.FileSystemWatcher.New(parentDirectory);
fileSystem.FileSystemWatcher.New(fileSystem.Path.GetFullPath(parentDirectory));
using ManualResetEventSlim ms = new();
fileSystemWatcher.Renamed += (_, eventArgs) =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,98 @@ public async Task NotifyFilter_MoveFile_DifferentDirectories_ShouldNotNotify_OnW
await That(result).IsNull();
}

[Theory]
[InlineAutoData(true)]
[InlineAutoData(false)]
public async Task NotifyFilter_MoveFileOutOfTheWatchedDirectory_ShouldTriggerDeleted_OnWindows(
bool includeSubdirectories, string sourcePath, string sourceName,
string destinationPath, string destinationName)
{
SkipIfLongRunningTestsShouldBeSkipped();
Skip.IfNot(Test.RunsOnWindows);

FileSystem.Initialize()
.WithSubdirectory(sourcePath).Initialized(s => s
.WithFile(sourceName))
.WithSubdirectory(destinationPath);
FileSystemEventArgs? result = null;
using ManualResetEventSlim ms = new();
using IFileSystemWatcher fileSystemWatcher =
FileSystem.FileSystemWatcher.New(sourcePath);
fileSystemWatcher.Deleted += (_, eventArgs) =>
{
// ReSharper disable once AccessToDisposedClosure
try
{
result = eventArgs;
ms.Set();
}
catch (ObjectDisposedException)
{
// Ignore any ObjectDisposedException
}
};

fileSystemWatcher.IncludeSubdirectories = includeSubdirectories;
fileSystemWatcher.EnableRaisingEvents = true;

FileSystem.File.Move(
FileSystem.Path.Combine(sourcePath, sourceName),
FileSystem.Path.Combine(destinationPath, destinationName));

await That(ms.Wait(ExpectSuccess, TestContext.Current.CancellationToken)).IsTrue();
await That(result).IsNotNull();
await That(result!.ChangeType).IsEqualTo(WatcherChangeTypes.Deleted);
await That(result.FullPath).IsEqualTo(FileSystem.Path.Combine(BasePath, sourcePath, sourceName));
await That(result.Name).IsEqualTo(FileSystem.Path.Combine(sourcePath, sourceName));
}

[Theory]
[InlineAutoData(true)]
[InlineAutoData(false)]
public async Task NotifyFilter_MoveFileInToTheWatchedDirectory_ShouldTriggerCreated_OnWindows(
bool includeSubdirectories, string sourcePath, string sourceName,
string destinationPath, string destinationName)
{
SkipIfLongRunningTestsShouldBeSkipped();
Skip.IfNot(Test.RunsOnWindows);

FileSystem.Initialize()
.WithSubdirectory(sourcePath).Initialized(s => s
.WithFile(sourceName))
.WithSubdirectory(destinationPath);
FileSystemEventArgs? result = null;
using ManualResetEventSlim ms = new();
using IFileSystemWatcher fileSystemWatcher =
FileSystem.FileSystemWatcher.New(destinationPath);
fileSystemWatcher.Created += (_, eventArgs) =>
{
// ReSharper disable once AccessToDisposedClosure
try
{
result = eventArgs;
ms.Set();
}
catch (ObjectDisposedException)
{
// Ignore any ObjectDisposedException
}
};

fileSystemWatcher.IncludeSubdirectories = includeSubdirectories;
fileSystemWatcher.EnableRaisingEvents = true;

FileSystem.File.Move(
FileSystem.Path.Combine(sourcePath, sourceName),
FileSystem.Path.Combine(destinationPath, destinationName));

await That(ms.Wait(ExpectSuccess, TestContext.Current.CancellationToken)).IsTrue();
await That(result).IsNotNull();
await That(result!.ChangeType).IsEqualTo(WatcherChangeTypes.Created);
await That(result.FullPath).IsEqualTo(FileSystem.Path.Combine(BasePath, destinationPath, destinationName));
await That(result.Name).IsEqualTo(FileSystem.Path.Combine(destinationPath, destinationName));
}

[Theory]
[AutoData]
public async Task NotifyFilter_MoveFile_ShouldNotNotifyOnOtherFilters(
Expand Down Expand Up @@ -692,7 +784,7 @@ public async Task NotifyFilter_MoveDirectoryOutOfTheWatchedDirectory_ShouldTrigg
await That(ms.Wait(ExpectSuccess, TestContext.Current.CancellationToken)).IsTrue();
await That(result).IsNotNull();
await That(result!.ChangeType).IsEqualTo(WatcherChangeTypes.Deleted);
await That(result.FullPath).IsEqualTo(FileSystem.Path.GetFullPath(sourcePath));
await That(result.FullPath).IsEqualTo(sourcePath);
await That(result.Name).IsEqualTo(sourceName);
}

Expand Down Expand Up @@ -735,8 +827,8 @@ public async Task NotifyFilter_MoveDirectoryInToTheWatchedDirectory_ShouldTrigge
await That(ms.Wait(ExpectSuccess, TestContext.Current.CancellationToken)).IsTrue();
await That(result).IsNotNull();
await That(result!.ChangeType).IsEqualTo(WatcherChangeTypes.Created);
await That(result.FullPath).IsEqualTo(FileSystem.Path.GetFullPath(destinationPath));
await That(result.Name).IsEqualTo(destinationPath);
await That(result.FullPath).IsEqualTo(destinationPath);
await That(result.Name).IsEqualTo(destinationName);
}

[Theory]
Expand Down
Loading