diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj b/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj index 37a53d008a572d..469005b661d886 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj @@ -28,7 +28,7 @@ + Link="Common\System\IO\PathInternal.cs" /> diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs index 5795394e13dfe7..a83e551abc396e 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs @@ -21,14 +21,24 @@ public FileSystemEventArgs(WatcherChangeTypes changeType, string directory, stri _changeType = changeType; _name = name; + _fullPath = Combine(directory, name); + } - if (directory.Length == 0) // empty directory means current working dir - { - directory = "."; - } + /// Combines a directory path and a relative file name into a single path. + /// The directory path. + /// The file name. + /// The combined name. + /// + /// This is like Path.Combine, except without argument validation, + /// and a separator is used even if the name argument is empty. + /// + internal static string Combine(string directory, string? name) + { + bool hasSeparator = directory.Length != 0 && PathInternal.IsDirectorySeparator(directory[^1]); - string fullDirectoryPath = Path.GetFullPath(directory); - _fullPath = string.IsNullOrEmpty(name) ? PathInternal.EnsureTrailingSeparator(fullDirectoryPath) : Path.Join(fullDirectoryPath, name); + return hasSeparator ? + directory + name : + directory + Path.DirectorySeparatorChar + name; } /// diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs index 17221c568dc32a..9d254e0c1f5760 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/RenamedEventArgs.cs @@ -18,14 +18,7 @@ public RenamedEventArgs(WatcherChangeTypes changeType, string directory, string? : base(changeType, directory, name) { _oldName = oldName; - - if (directory.Length == 0) // empty directory means current working dir - { - directory = "."; - } - - string fullDirectoryPath = Path.GetFullPath(directory); - _oldFullPath = string.IsNullOrEmpty(oldName) ? PathInternal.EnsureTrailingSeparator(fullDirectoryPath) : Path.Join(fullDirectoryPath, oldName); + _oldFullPath = Combine(directory, oldName); } /// diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs index d3abb21d9a2d3f..39e95c72c838ac 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs @@ -8,10 +8,10 @@ namespace System.IO.Tests public class FileSystemEventArgsTests { [Theory] - [InlineData(WatcherChangeTypes.Changed, "bar", "foo.txt")] - [InlineData(WatcherChangeTypes.All, "bar", "foo.txt")] - [InlineData((WatcherChangeTypes)0, "bar", "")] - [InlineData((WatcherChangeTypes)0, "bar", null)] + [InlineData(WatcherChangeTypes.Changed, "C:", "foo.txt")] + [InlineData(WatcherChangeTypes.All, "C:", "foo.txt")] + [InlineData((WatcherChangeTypes)0, "", "")] + [InlineData((WatcherChangeTypes)0, "", null)] public static void FileSystemEventArgs_ctor_NonPathPropertiesAreSetCorrectly(WatcherChangeTypes changeType, string directory, string name) { FileSystemEventArgs args = new FileSystemEventArgs(changeType, directory, name); @@ -59,44 +59,52 @@ public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Unix(string [Theory] [PlatformSpecific(TestPlatforms.Windows)] - [InlineData("", "")] - [InlineData("", "foo.txt")] - [InlineData("bar", "foo.txt")] - [InlineData("bar\\baz", "foo.txt")] - public static void FileSystemEventArgs_ctor_DirectoryIsRelativePath_Windows(string directory, string name) + [InlineData("", "", "\\")] + [InlineData("", "foo.txt", "\\foo.txt")] + [InlineData("bar", "foo.txt", "bar\\foo.txt")] + [InlineData("bar\\baz", "foo.txt", "bar\\baz\\foo.txt")] + public static void FileSystemEventArgs_ctor_DirectoryIsRelativePath_Windows(string directory, string name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); - var expectedDirectory = PathInternal.EnsureTrailingSeparator(Path.Combine(Directory.GetCurrentDirectory(), directory)); - Assert.Equal(Path.Combine(expectedDirectory, name), args.FullPath); + Assert.Equal(expectedFullPath, args.FullPath); } [Theory] [PlatformSpecific(TestPlatforms.AnyUnix)] - [InlineData("", "")] - [InlineData("", "foo.txt")] - [InlineData(" ", " ")] - [InlineData(" ", "foo.txt")] - [InlineData("bar", "foo.txt")] - [InlineData("bar/baz", "foo.txt")] - public static void FileSystemEventArgs_ctor_DirectoryIsRelativePath_Unix(string directory, string name) + [InlineData("", "", "/")] + [InlineData("", "foo.txt", "/foo.txt")] + [InlineData(" ", " ", " / ")] + [InlineData(" ", "foo.txt", " /foo.txt")] + [InlineData("bar", "foo.txt", "bar/foo.txt")] + [InlineData("bar/baz", "foo.txt", "bar/baz/foo.txt")] + public static void FileSystemEventArgs_ctor_DirectoryIsRelativePath_Unix(string directory, string name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); - var expectedDirectory = PathInternal.EnsureTrailingSeparator(Path.Combine(Directory.GetCurrentDirectory(), directory)); - Assert.Equal(Path.Combine(expectedDirectory, name), args.FullPath); + Assert.Equal(expectedFullPath, args.FullPath); } [Theory] - [InlineData("bar", "")] - [InlineData("bar", null)] - public static void FileSystemEventArgs_ctor_When_EmptyFileName_Then_FullPathReturnsTheDirectoryFullPath_WithTrailingSeparator(string directory, string name) + [PlatformSpecific(TestPlatforms.Windows)] + [InlineData("bar", "", "bar\\")] + [InlineData("bar", null, "bar\\")] + public static void FileSystemEventArgs_ctor_EmptyFileName_Windows(string directory, string name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); - directory = PathInternal.EnsureTrailingSeparator(directory); + Assert.Equal(expectedFullPath, args.FullPath); + } - Assert.Equal(PathInternal.EnsureTrailingSeparator(Directory.GetCurrentDirectory()) + directory, args.FullPath); + [Theory] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [InlineData("bar", "", "bar/")] + [InlineData("bar", null, "bar/")] + public static void FileSystemEventArgs_ctor_EmptyFileName_Unix(string directory, string name, string expectedFullPath) + { + FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); + + Assert.Equal(expectedFullPath, args.FullPath); } [Fact] diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs index 3a504a668b0872..d92324fc53291b 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs @@ -47,43 +47,52 @@ public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsAnAbsolutePath_U [Theory] [PlatformSpecific(TestPlatforms.Windows)] - [InlineData("", "", "")] - [InlineData("", "foo.txt", "bar.txt")] - [InlineData("bar", "foo.txt", "bar.txt")] - [InlineData("bar\\baz", "foo.txt", "bar.txt")] - public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsRelativePath_Windows(string directory, string name, string oldName) + [InlineData("", "", "", "\\")] + [InlineData("", "foo.txt", "bar.txt", "\\bar.txt")] + [InlineData("bar", "foo.txt", "bar.txt", "bar\\bar.txt")] + [InlineData("bar\\baz", "foo.txt", "bar.txt", "bar\\baz\\bar.txt")] + public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsRelativePath_Windows(string directory, string name, string oldName, string expectedOldFullPath) { RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); - var expectedDirectory = PathInternal.EnsureTrailingSeparator(Path.Combine(Directory.GetCurrentDirectory(), directory)); - Assert.Equal(Path.Combine(expectedDirectory, oldName), args.OldFullPath); + Assert.Equal(expectedOldFullPath, args.OldFullPath); } [Theory] [PlatformSpecific(TestPlatforms.AnyUnix)] - [InlineData("", "", "")] - [InlineData("", "foo.txt", "bar.txt")] - [InlineData("bar", "foo.txt", "bar.txt")] - [InlineData("bar/baz", "foo.txt", "bar.txt")] - public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsRelativePath_Unix(string directory, string name, string oldName) + [InlineData("", "", "", "/")] + [InlineData("", "foo.txt", "bar.txt", "/bar.txt")] + [InlineData("bar", "foo.txt", "bar.txt", "bar/bar.txt")] + [InlineData("bar/baz", "foo.txt", "bar.txt", "bar/baz/bar.txt")] + public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsRelativePath_Unix(string directory, string name, string oldName, string expectedOldFullPath) { RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); - var expectedDirectory = PathInternal.EnsureTrailingSeparator(Path.Combine(Directory.GetCurrentDirectory(), directory)); - Assert.Equal(Path.Combine(expectedDirectory, oldName), args.OldFullPath); + Assert.Equal(expectedOldFullPath, args.OldFullPath); } [Theory] - [InlineData("bar", "", "")] - [InlineData("bar", null, null)] - [InlineData("bar", "foo.txt", null)] - public static void RenamedEventArgs_ctor_When_EmptyOldFileName_Then_OldFullPathReturnsTheDirectoryFullPath_WithTrailingSeparator(string directory, string name, string oldName) + [PlatformSpecific(TestPlatforms.Windows)] + [InlineData("bar", "", "", "bar\\")] + [InlineData("bar", null, null, "bar\\")] + [InlineData("bar", "foo.txt", null, "bar\\")] + public static void RenamedEventArgs_ctor_EmptyOldFileName_Windows(string directory, string name, string oldName, string expectedOldFullPath) { RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); - directory = PathInternal.EnsureTrailingSeparator(directory); + Assert.Equal(expectedOldFullPath, args.OldFullPath); + } - Assert.Equal(PathInternal.EnsureTrailingSeparator(Directory.GetCurrentDirectory()) + directory, args.OldFullPath); + [Theory] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [InlineData("bar", "", "", "bar/")] + [InlineData("bar", null, null, "bar/")] + [InlineData("bar", "foo.txt", null, "bar/")] + public static void RenamedEventArgs_ctor_EmptyOldFileName_Unix(string directory, string name, string oldName, string expectedOldFullPath) + { + RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); + + Assert.Equal(expectedOldFullPath, args.OldFullPath); } [Fact]