diff --git a/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs new file mode 100644 index 000000000..820b2d66a --- /dev/null +++ b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs @@ -0,0 +1,22 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.IO.Abstractions.TestingHelpers.Tests +{ + [TestFixture] + public class DirectoryInfoTests + { + [Test] + public void Parent_ForRootDirectory_ShouldReturnNull() + { + var wrapperFilesystem = new FileSystem(); + + var current = wrapperFilesystem.Directory.GetCurrentDirectory(); + var root = wrapperFilesystem.DirectoryInfo.FromDirectoryName(current).Root; + var rootsParent = root.Parent; + Assert.IsNull(rootsParent); + } + } +} diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs index a850a157d..0fcb8bfb1 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs @@ -55,6 +55,29 @@ public void MockDirectoryInfo_Exists(string path, bool expected) Assert.That(result, Is.EqualTo(expected)); } + [Test] + [WindowsOnly(WindowsSpecifics.UNCPaths)] + public void MockDirectoryInfo_GetFiles_ShouldWorkWithUNCPath() + { + var fileName = XFS.Path(@"\\unc\folder\file.txt"); + var directoryName = XFS.Path(@"\\unc\folder"); + // Arrange + var fileSystem = new MockFileSystem(new Dictionary + { + {fileName, ""} + }); + + var directoryInfo = new MockDirectoryInfo(fileSystem, directoryName); + + // Act + var files = directoryInfo.GetFiles(); + + // Assert + Assert.AreEqual(fileName, files[0].FullName); + } + + + [Test] public void MockDirectoryInfo_FullName_ShouldReturnFullNameWithoutIncludingTrailingPathDelimiter() { diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs index 250241dd2..72cf08c7e 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs @@ -182,7 +182,7 @@ public void MockDirectory_GetFiles_ShouldFilterByExtensionBasedSearchPatternWith var result = fileSystem.Directory.GetFiles(XFS.Path(@"c:\"), "*.gif", SearchOption.AllDirectories); // Assert - Assert.That(result, Is.EquivalentTo( expected)); + Assert.That(result, Is.EquivalentTo(expected)); } [Test] @@ -598,6 +598,29 @@ public void MockDirectory_Delete_ShouldDeleteDirectory() Assert.IsFalse(fileSystem.Directory.Exists(XFS.Path(@"c:\bar"))); } + [Test] + public void MockDirectory_Delete_ShouldNotDeleteAllDirectories() + { + // Arrange + var folder1Path = XFS.Path(@"D:\Test\Program"); + var folder1SubFolderPath = XFS.Path(@"D:\Test\Program\Subfolder"); + var folder2Path = XFS.Path(@"D:\Test\Program_bak"); + + var fileSystem = new MockFileSystem(); + + fileSystem.AddDirectory(folder1Path); + fileSystem.AddDirectory(folder2Path); + fileSystem.AddDirectory(folder1SubFolderPath); + + // Act + fileSystem.Directory.Delete(folder1Path, recursive: true); + + // Assert + Assert.IsFalse(fileSystem.Directory.Exists(folder1Path)); + Assert.IsFalse(fileSystem.Directory.Exists(folder1SubFolderPath)); + Assert.IsTrue(fileSystem.Directory.Exists(folder2Path)); + } + [Test] [WindowsOnly(WindowsSpecifics.CaseInsensitivity)] public void MockDirectory_Delete_ShouldDeleteDirectoryCaseInsensitively() @@ -700,7 +723,7 @@ public void MockDirectory_Delete_ShouldDeleteDirectoryRecursively() public void MockDirectory_GetFileSystemEntries_Returns_Files_And_Directories() { string testPath = XFS.Path(@"c:\foo\bar.txt"); - string testDir = XFS.Path(@"c:\foo\bar"); + string testDir = XFS.Path(@"c:\foo\bar"); var fileSystem = new MockFileSystem(new Dictionary { { testPath, new MockFileData("Demo text content") }, @@ -829,7 +852,7 @@ public void MockDirectory_GetFiles_ShouldFindFilesContainingTwoOrMoreDots() var actualResult = fileSystem.Directory.GetFiles(XFS.Path(@"c:\"), XFS.Path(@"foo..r\*")); // Assert - Assert.That(actualResult, Is.EquivalentTo(new [] { testPath })); + Assert.That(actualResult, Is.EquivalentTo(new[] { testPath })); } #if NET40 @@ -925,7 +948,7 @@ public void MockDirectory_GetDirectories_WithTopDirectories_ShouldOnlyReturnTopD var actualResult = fileSystem.Directory.GetDirectories(XFS.Path(@"c:\Folder\"), "*.foo"); // Assert - Assert.That(actualResult, Is.EquivalentTo(new []{XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo")})); + Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo") })); } [Test] @@ -1211,7 +1234,8 @@ public void MockDirectory_Move_ShouldMoveDirectoryWithReadOnlySubDirectory() } [Test] - public void MockDirectory_GetCurrentDirectory_ShouldReturnValueFromFileSystemConstructor() { + public void MockDirectory_GetCurrentDirectory_ShouldReturnValueFromFileSystemConstructor() + { string directory = XFS.Path(@"D:\folder1\folder2"); var fileSystem = new MockFileSystem(new Dictionary(), directory); @@ -1219,9 +1243,9 @@ public void MockDirectory_GetCurrentDirectory_ShouldReturnValueFromFileSystemCon Assert.AreEqual(directory, actual); } - + [Test] - public void MockDirectory_GetCurrentDirectory_ShouldReturnDefaultPathWhenNotSet() + public void MockDirectory_GetCurrentDirectory_ShouldReturnDefaultPathWhenNotSet() { string directory = XFS.Path(@"C:\"); @@ -1233,7 +1257,8 @@ public void MockDirectory_GetCurrentDirectory_ShouldReturnDefaultPathWhenNotSet( } [Test] - public void MockDirectory_SetCurrentDirectory_ShouldChangeCurrentDirectory() { + public void MockDirectory_SetCurrentDirectory_ShouldChangeCurrentDirectory() + { string directory = XFS.Path(@"D:\folder1\folder2"); var fileSystem = new MockFileSystem(); @@ -1278,7 +1303,7 @@ public void MockDirectory_GetParent_ShouldReturnADirectoryInfoIfPathDoesNotExist var fileSystem = new MockFileSystem(); // Act - var actualResult = fileSystem.Directory.GetParent(XFS.Path(@"c:\directory\does\not\exist")); + var actualResult = fileSystem.Directory.GetParent(XFS.Path(@"c:\directory\does\not\exist")); // Assert Assert.IsNotNull(actualResult); @@ -1331,9 +1356,9 @@ public static IEnumerable MockDirectory_GetParent_Cases { get { - yield return new [] { XFS.Path(@"c:\a"), XFS.Path(@"c:\") }; - yield return new [] { XFS.Path(@"c:\a\b\c\d"), XFS.Path(@"c:\a\b\c") }; - yield return new [] { XFS.Path(@"c:\a\b\c\d\"), XFS.Path(@"c:\a\b\c") }; + yield return new[] { XFS.Path(@"c:\a"), XFS.Path(@"c:\") }; + yield return new[] { XFS.Path(@"c:\a\b\c\d"), XFS.Path(@"c:\a\b\c") }; + yield return new[] { XFS.Path(@"c:\a\b\c\d\"), XFS.Path(@"c:\a\b\c") }; } } diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileMoveTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileMoveTests.cs index 1e839d797..fef5c3625 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileMoveTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileMoveTests.cs @@ -312,7 +312,7 @@ public void MockFile_Move_ShouldThrowFileNotFoundExceptionWhenSourceDoesNotExist var exception = Assert.Throws(() => fileSystem.File.Move(sourceFilePath, destFilePath)); - Assert.That(exception.Message, Is.EqualTo("The file \"" + XFS.Path("c:\\something\\demo.txt") + "\" could not be found.")); + Assert.That(exception.Message, Is.EqualTo("Could not find file '" + XFS.Path("c:\\something\\demo.txt") + "'.")); } [Test] diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs index 327f11e02..74985c7d6 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadAllLinesTests.cs @@ -51,5 +51,20 @@ public void MockFile_ReadAllLines_ShouldReturnOriginalDataWithCustomEncoding() new [] { "Hello", "there", "Bob", "Bob!" }, result); } + + [Test] + public void MockFile_ReadAllLines_NotExistingFile_ThrowsCorrectFileNotFoundException() + { + var absentFileNameFullPath = XFS.Path(@"c:\you surely don't have such file.hope-so"); + var mockFileSystem = new MockFileSystem(); + + var act = new TestDelegate(() => + mockFileSystem.File.ReadAllText(absentFileNameFullPath) + ); + + var exception = Assert.Catch(act); + Assert.That(exception.FileName, Is.EqualTo(absentFileNameFullPath)); + Assert.That(exception.Message, Is.EqualTo("Could not find file '" + absentFileNameFullPath + "'.")); + } } } \ No newline at end of file diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadLinesTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadLinesTests.cs index e9439b502..fdf2ef820 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadLinesTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileReadLinesTests.cs @@ -8,7 +8,8 @@ namespace System.IO.Abstractions.TestingHelpers.Tests using XFS = MockUnixSupport; - public class MockFileReadLinesTests { + public class MockFileReadLinesTests + { [Test] public void MockFile_ReadLines_ShouldReturnOriginalTextData() { @@ -48,7 +49,7 @@ public void MockFile_ReadLines_ShouldReturnOriginalDataWithCustomEncoding() // Assert CollectionAssert.AreEqual( - new [] { "Hello", "there", "Bob", "Bob!" }, + new[] { "Hello", "there", "Bob", "Bob!" }, result); } } diff --git a/System.IO.Abstractions.TestingHelpers.Tests/StringExtensionsTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/StringExtensionsTests.cs index 41f2ab2ce..e9a750040 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/StringExtensionsTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/StringExtensionsTests.cs @@ -112,5 +112,13 @@ public void TrimSlashes_SlashRoot_PreserveSlashRoot() { Assert.AreEqual("/", "/".TrimSlashes()); } + + [TestCase(@"\\unc\folder\file.txt", @"\\unc\folder\file.txt")] + [TestCase(@"//unc/folder/file.txt", @"\\unc\folder\file.txt")] + [WindowsOnly(WindowsSpecifics.UNCPaths)] + public void NormalizeSlashes_KeepsUNCPathPrefix(string path, string expectedValue) + { + Assert.AreEqual(expectedValue, path.NormalizeSlashes()); + } } } diff --git a/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj b/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj index 2b48a0d01..67608e9e3 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj +++ b/System.IO.Abstractions.TestingHelpers.Tests/System.IO.Abstractions.TestingHelpers.Tests.csproj @@ -47,7 +47,7 @@ - + diff --git a/System.IO.Abstractions.TestingHelpers/CommonExceptions.cs b/System.IO.Abstractions.TestingHelpers/CommonExceptions.cs new file mode 100644 index 000000000..66bdc287b --- /dev/null +++ b/System.IO.Abstractions.TestingHelpers/CommonExceptions.cs @@ -0,0 +1,58 @@ +using System.Globalization; + +namespace System.IO.Abstractions.TestingHelpers +{ + internal static class CommonExceptions + { + public static FileNotFoundException FileNotFound(string path) => + new FileNotFoundException( + string.Format( + CultureInfo.InvariantCulture, + StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), + path + ), + path + ); + + public static DirectoryNotFoundException CouldNotFindPartOfPath(string path) => + new DirectoryNotFoundException( + string.Format( + CultureInfo.InvariantCulture, + StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), + path + ) + ); + + public static UnauthorizedAccessException AccessDenied(string path) => + new UnauthorizedAccessException( + string.Format( + CultureInfo.InvariantCulture, + StringResources.Manager.GetString("ACCESS_TO_THE_PATH_IS_DENIED"), + path + ) + ); + + public static Exception InvalidUseOfVolumeSeparator() => + new NotSupportedException(StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM")); + + public static Exception PathIsNotOfALegalForm(string paramName) => + new ArgumentException( + StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM"), + paramName + ); + + public static ArgumentNullException FilenameCannotBeNull(string paramName) => + new ArgumentNullException( + paramName, + StringResources.Manager.GetString("FILENAME_CANNOT_BE_NULL") + ); + + public static ArgumentException IllegalCharactersInPath(string paramName = null) => + paramName != null + ? new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION"), paramName) + : new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION")); + + public static Exception InvalidUncPath(string paramName) => + new ArgumentException(@"The UNC path should be of the form \\server\share.", paramName); + } +} \ No newline at end of file diff --git a/System.IO.Abstractions.TestingHelpers/MockDirectory.cs b/System.IO.Abstractions.TestingHelpers/MockDirectory.cs index c38d0ce4a..280d88948 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDirectory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDirectory.cs @@ -14,7 +14,6 @@ public class MockDirectory : DirectoryBase private readonly IMockFileDataAccessor mockFileDataAccessor; private string currentDirectory; - // This constructor is retained to avoid breaking change public MockDirectory(IMockFileDataAccessor mockFileDataAccessor, FileBase fileBase, string currentDirectory) : this(mockFileDataAccessor, currentDirectory) { @@ -75,25 +74,34 @@ public override void Delete(string path) public override void Delete(string path, bool recursive) { path = mockFileDataAccessor.Path.GetFullPath(path).TrimSlashes(); + + var stringOps = mockFileDataAccessor.StringOperations; + var pathWithDirectorySeparatorChar = $"{path}{Path.DirectorySeparatorChar}"; + var affectedPaths = mockFileDataAccessor .AllPaths - .Where(p => mockFileDataAccessor.StringOperations.StartsWith(p, path)) + .Where(p => stringOps.Equals(p, path) || stringOps.StartsWith(p, pathWithDirectorySeparatorChar)) .ToList(); if (!affectedPaths.Any()) + { throw new DirectoryNotFoundException(path + " does not exist or could not be found."); - - if (!recursive && - affectedPaths.Count > 1) + } + + if (!recursive && affectedPaths.Count > 1) + { throw new IOException("The directory specified by " + path + " is read-only, or recursive is false and " + path + " is not an empty directory."); - + } + foreach (var affectedPath in affectedPaths) + { mockFileDataAccessor.RemoveFile(affectedPath); + } } public override bool Exists(string path) { - if (path == "/" && XFS.IsUnixPlatform()) + if (path == "/" && XFS.IsUnixPlatform()) { return true; } @@ -111,16 +119,16 @@ public override bool Exists(string path) } public override DirectorySecurity GetAccessControl(string path) - { + { mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); path = path.TrimSlashes(); - + if (!mockFileDataAccessor.Directory.Exists(path)) { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), path)); + throw CommonExceptions.CouldNotFindPartOfPath(path); } - var directoryData = (MockDirectoryData) mockFileDataAccessor.GetFile(path); + var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path); return directoryData.AccessControl; } @@ -203,11 +211,7 @@ private string[] GetFilesInternal( if (!Exists(path)) { - throw new DirectoryNotFoundException( - string.Format( - CultureInfo.InvariantCulture, - StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), - path)); + throw CommonExceptions.CouldNotFindPartOfPath(path); } path = EnsureAbsolutePath(path); @@ -402,7 +406,7 @@ public override void SetAccessControl(string path, DirectorySecurity directorySe if (!mockFileDataAccessor.Directory.Exists(path)) { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), path)); + throw CommonExceptions.CouldNotFindPartOfPath(path); } var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path); @@ -421,7 +425,7 @@ public override void SetCreationTimeUtc(string path, DateTime creationTimeUtc) public override void SetCurrentDirectory(string path) { - currentDirectory = path; + currentDirectory = path; } public override void SetLastAccessTime(string path, DateTime lastAccessTime) @@ -540,7 +544,7 @@ private void CheckSearchPattern(string searchPattern) var invalidPathChars = Path.GetInvalidPathChars(); if (searchPattern.IndexOfAny(invalidPathChars) > -1) { - throw new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION"), "searchPattern"); + throw CommonExceptions.IllegalCharactersInPath(nameof(searchPattern)); } } } diff --git a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index 0a9b651bc..a105d2217 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -293,7 +293,7 @@ private MockFileData GetMockFileDataForRead() private MockFileData GetMockFileDataForWrite() { return mockFileDataAccessor.GetFile(directoryPath) - ?? throw new FileNotFoundException(StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), directoryPath); + ?? throw CommonExceptions.FileNotFound(directoryPath); } public override string ToString() diff --git a/System.IO.Abstractions.TestingHelpers/MockFile.cs b/System.IO.Abstractions.TestingHelpers/MockFile.cs index a2d24d91f..1ca3ac9bf 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -89,20 +89,20 @@ public override void Copy(string sourceFileName, string destFileName, bool overw { if (sourceFileName == null) { - throw new ArgumentNullException(nameof(sourceFileName), StringResources.Manager.GetString("FILENAME_CANNOT_BE_NULL")); + throw CommonExceptions.FilenameCannotBeNull(nameof(sourceFileName)); } if (destFileName == null) { - throw new ArgumentNullException(nameof(destFileName), StringResources.Manager.GetString("FILENAME_CANNOT_BE_NULL")); + throw CommonExceptions.FilenameCannotBeNull(nameof(destFileName)); } - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(sourceFileName, "sourceFileName"); - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, "destFileName"); + mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(sourceFileName, nameof(sourceFileName)); + mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, nameof(destFileName)); if (!Exists(sourceFileName)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), sourceFileName)); + throw CommonExceptions.FileNotFound(sourceFileName); } VerifyDirectoryExists(destFileName); @@ -205,7 +205,7 @@ public override FileSecurity GetAccessControl(string path) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), path)); + throw CommonExceptions.FileNotFound(path); } var fileData = mockFileDataAccessor.GetFile(path); @@ -233,7 +233,7 @@ public override FileAttributes GetAttributes(string path) { if (path != null && path.Length == 0) { - throw new ArgumentException(StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM"), "path"); + throw CommonExceptions.PathIsNotOfALegalForm(nameof(path)); } mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); @@ -255,7 +255,7 @@ public override FileAttributes GetAttributes(string path) { VerifyDirectoryExists(path); - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Could not find file '{0}'.", path)); + throw CommonExceptions.FileNotFound(path); } } @@ -324,16 +324,16 @@ public override void Move(string sourceFileName, string destFileName) { if (sourceFileName == null) { - throw new ArgumentNullException(nameof(sourceFileName), StringResources.Manager.GetString("FILENAME_CANNOT_BE_NULL")); + throw CommonExceptions.FilenameCannotBeNull(nameof(sourceFileName)); } if (destFileName == null) { - throw new ArgumentNullException(nameof(destFileName), StringResources.Manager.GetString("FILENAME_CANNOT_BE_NULL")); + throw CommonExceptions.FilenameCannotBeNull(nameof(destFileName)); } - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(sourceFileName, "sourceFileName"); - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, "destFileName"); + mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(sourceFileName, nameof(sourceFileName)); + mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, nameof(destFileName)); if (mockFileDataAccessor.GetFile(destFileName) != null) { @@ -351,7 +351,9 @@ public override void Move(string sourceFileName, string destFileName) var sourceFile = mockFileDataAccessor.GetFile(sourceFileName); if (sourceFile == null) - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "The file \"{0}\" could not be found.", sourceFileName), sourceFileName); + { + throw CommonExceptions.FileNotFound(sourceFileName); + } VerifyDirectoryExists(destFileName); @@ -391,7 +393,7 @@ private Stream OpenInternal( throw new IOException(string.Format(CultureInfo.InvariantCulture, "The file '{0}' already exists.", path)); if ((mode == FileMode.Open || mode == FileMode.Truncate) && !exists) - throw new FileNotFoundException(path); + throw CommonExceptions.FileNotFound(path); if (!exists || mode == FileMode.CreateNew) return Create(path); @@ -442,7 +444,7 @@ public override byte[] ReadAllBytes(string path) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), path)); + throw CommonExceptions.FileNotFound(path); } return mockFileDataAccessor.GetFile(path).Contents; @@ -454,7 +456,7 @@ public override string[] ReadAllLines(string path) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), path)); + throw CommonExceptions.FileNotFound(path); } return mockFileDataAccessor @@ -474,7 +476,7 @@ public override string[] ReadAllLines(string path, Encoding encoding) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Can't find {0}", path)); + throw CommonExceptions.FileNotFound(path); } return encoding @@ -488,7 +490,7 @@ public override string ReadAllText(string path) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Can't find {0}", path)); + throw CommonExceptions.FileNotFound(path); } return ReadAllText(path, MockFileData.DefaultEncoding); @@ -541,12 +543,12 @@ public override void Replace(string sourceFileName, string destinationFileName, if (!mockFileDataAccessor.FileExists(sourceFileName)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), sourceFileName)); + throw CommonExceptions.FileNotFound(sourceFileName); } if (!mockFileDataAccessor.FileExists(destinationFileName)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), destinationFileName)); + throw CommonExceptions.FileNotFound(destinationFileName); } if (destinationBackupFileName != null) @@ -565,7 +567,7 @@ public override void SetAccessControl(string path, FileSecurity fileSecurity) if (!mockFileDataAccessor.FileExists(path)) { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Can't find {0}", path), path); + throw CommonExceptions.FileNotFound(path); } var fileData = mockFileDataAccessor.GetFile(path); @@ -586,7 +588,7 @@ public override void SetAttributes(string path, FileAttributes fileAttributes) } else { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_FILE_EXCEPTION"), path), path); + throw CommonExceptions.FileNotFound(path); } } else @@ -676,7 +678,7 @@ public override void WriteAllBytes(string path, byte[] bytes) mockFileDataAccessor.AddFile(path, new MockFileData(bytes)); } - /// + /// /// Creates a new file, writes a collection of strings to the file, and then closes the file. /// /// The file to write to. @@ -937,7 +939,7 @@ public override void WriteAllText(string path, string contents, Encoding encodin if (mockFileDataAccessor.Directory.Exists(path)) { - throw new UnauthorizedAccessException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("ACCESS_TO_THE_PATH_IS_DENIED"), path)); + throw CommonExceptions.AccessDenied(path); } VerifyDirectoryExists(path); @@ -976,11 +978,7 @@ private void VerifyDirectoryExists(string path) if (!mockFileDataAccessor.Directory.Exists(dir)) { - throw new DirectoryNotFoundException( - string.Format( - CultureInfo.InvariantCulture, - StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), - path)); + throw CommonExceptions.CouldNotFindPartOfPath(path); } } } diff --git a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 257f3317c..03d7e809e 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -32,7 +32,7 @@ public override FileAttributes Attributes { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.Attributes; } set { MockFileData.Attributes = value; } @@ -42,12 +42,12 @@ public override DateTime CreationTime { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.CreationTime.DateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.CreationTime = value; } } @@ -56,12 +56,12 @@ public override DateTime CreationTimeUtc { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.CreationTime.UtcDateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.CreationTime = value.ToLocalTime(); } } @@ -90,12 +90,12 @@ public override DateTime LastAccessTime { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.LastAccessTime.DateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.LastAccessTime = value; } } @@ -104,12 +104,12 @@ public override DateTime LastAccessTimeUtc { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.LastAccessTime.UtcDateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.LastAccessTime = value; } } @@ -118,12 +118,12 @@ public override DateTime LastWriteTime { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.LastWriteTime.DateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.LastWriteTime = value; } } @@ -132,12 +132,12 @@ public override DateTime LastWriteTimeUtc { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.LastWriteTime.UtcDateTime; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.LastWriteTime = value.ToLocalTime(); } } @@ -149,7 +149,7 @@ public override string Name public override StreamWriter AppendText() { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return new StreamWriter(new MockFileStream(mockFileSystem, FullName, MockFileStream.StreamType.APPEND)); } @@ -162,7 +162,7 @@ public override FileInfoBase CopyTo(string destFileName, bool overwrite) { if (!Exists) { - throw new FileNotFoundException("The file does not exist and can't be moved or copied.", FullName); + if (MockFileData == null) throw CommonExceptions.FileNotFound(FullName); } if (destFileName == FullName) { @@ -185,14 +185,14 @@ public override StreamWriter CreateText() #if NET40 public override void Decrypt() { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.Attributes &= ~FileAttributes.Encrypted; } public override void Encrypt() { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); MockFileData.Attributes |= FileAttributes.Encrypted; } @@ -236,7 +236,7 @@ public override Stream Open(FileMode mode, FileAccess access, FileShare share) public override Stream OpenRead() { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return new MockFileStream(mockFileSystem, path, MockFileStream.StreamType.READ); } @@ -290,12 +290,12 @@ public override bool IsReadOnly { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return (MockFileData.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; } set { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); if (value) MockFileData.Attributes |= FileAttributes.ReadOnly; else @@ -307,7 +307,7 @@ public override long Length { get { - if (MockFileData == null) throw new FileNotFoundException("File not found", path); + if (MockFileData == null) throw CommonExceptions.FileNotFound(path); return MockFileData.Contents.Length; } } diff --git a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 7e3d2f291..a6bee6e96 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -56,7 +56,7 @@ public MockFileStream( { if (StreamType.READ.Equals(streamType)) { - throw new FileNotFoundException("File not found.", path); + throw CommonExceptions.FileNotFound(path); } mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { })); } diff --git a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index cd3d15f64..d4bde1869 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -127,7 +127,7 @@ public void AddFile(string path, MockFileData mockFile) if (isReadOnly || isHidden) { - throw new UnauthorizedAccessException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("ACCESS_TO_THE_PATH_IS_DENIED"), path)); + throw CommonExceptions.AccessDenied(path); } } @@ -151,7 +151,7 @@ public void AddDirectory(string path) { if (FileExists(fixedPath) && (GetFile(fixedPath).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) - throw new UnauthorizedAccessException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("ACCESS_TO_THE_PATH_IS_DENIED"), fixedPath)); + throw CommonExceptions.AccessDenied(fixedPath); var lastIndex = 0; var isUnc = @@ -164,7 +164,7 @@ public void AddDirectory(string path) lastIndex = StringOperations.IndexOf(fixedPath, separator, 2); if (lastIndex < 0) - throw new ArgumentException(@"The UNC path should be of the form \\server\share.", "path"); + throw CommonExceptions.InvalidUncPath(nameof(path)); /* * Although CreateDirectory(@"\\server\share\") is not going to work in real code, we allow it here for the purposes of setting up test doubles. @@ -247,7 +247,7 @@ public void RemoveFile(string path) { if (FileExists(path) && (GetFile(path).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { - throw new UnauthorizedAccessException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("ACCESS_TO_THE_PATH_IS_DENIED"), path)); + throw CommonExceptions.AccessDenied(path); } files.Remove(path); diff --git a/System.IO.Abstractions.TestingHelpers/MockPath.cs b/System.IO.Abstractions.TestingHelpers/MockPath.cs index a1929b457..921f650e4 100644 --- a/System.IO.Abstractions.TestingHelpers/MockPath.cs +++ b/System.IO.Abstractions.TestingHelpers/MockPath.cs @@ -26,7 +26,7 @@ public override string GetFullPath(string path) if (path.Length == 0) { - throw new ArgumentException(StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM"), "path"); + throw CommonExceptions.PathIsNotOfALegalForm(nameof(path)); } path = path.Replace(AltDirectorySeparatorChar, DirectorySeparatorChar); @@ -53,7 +53,7 @@ public override string GetFullPath(string path) pathSegments = GetSegments(path); if (pathSegments.Length < 2) { - throw new ArgumentException(@"The UNC path should be of the form \\server\share.", "path"); + throw CommonExceptions.InvalidUncPath(nameof(path)); } } else if (mockFileDataAccessor.StringOperations.Equals(@"\", root) || diff --git a/System.IO.Abstractions.TestingHelpers/PathVerifier.cs b/System.IO.Abstractions.TestingHelpers/PathVerifier.cs index a1d11cfdd..c32680276 100644 --- a/System.IO.Abstractions.TestingHelpers/PathVerifier.cs +++ b/System.IO.Abstractions.TestingHelpers/PathVerifier.cs @@ -25,27 +25,28 @@ public void IsLegalAbsoluteOrRelative(string path, string paramName) { throw new ArgumentException("Empty file name is not legal.", paramName); } - + if (path.Trim() == string.Empty) { - throw new ArgumentException(StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM"), paramName); + throw CommonExceptions.PathIsNotOfALegalForm(paramName); } if (XFS.IsWindowsPlatform() && !IsValidUseOfVolumeSeparatorChar(path)) { - throw new NotSupportedException(StringResources.Manager.GetString("THE_PATH_IS_NOT_OF_A_LEGAL_FORM")); + + throw CommonExceptions.InvalidUseOfVolumeSeparator(); } if (ExtractFileName(path).IndexOfAny(_mockFileDataAccessor.Path.GetInvalidFileNameChars()) > -1) { - throw new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION")); + throw CommonExceptions.IllegalCharactersInPath(); } var filePath = ExtractFilePath(path); if (HasIllegalCharacters(filePath, checkAdditional: false)) { - throw new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION")); + throw CommonExceptions.IllegalCharactersInPath(); } } @@ -96,7 +97,7 @@ public void CheckInvalidPathChars(string path, bool checkAdditional = false) if (HasIllegalCharacters(path, checkAdditional)) { - throw new ArgumentException(StringResources.Manager.GetString("ILLEGAL_CHARACTERS_IN_PATH_EXCEPTION")); + throw CommonExceptions.IllegalCharactersInPath(); } } } diff --git a/System.IO.Abstractions.TestingHelpers/StringExtensions.cs b/System.IO.Abstractions.TestingHelpers/StringExtensions.cs index f8640c861..2d32641bc 100644 --- a/System.IO.Abstractions.TestingHelpers/StringExtensions.cs +++ b/System.IO.Abstractions.TestingHelpers/StringExtensions.cs @@ -99,7 +99,7 @@ public static string NormalizeSlashes(this string path) // UNC Paths start with double slash but no reason // to have more than 2 slashes at the start of a path - if (XFS.IsWindowsPlatform() && prefixSeps.Length > 2) + if (XFS.IsWindowsPlatform() && prefixSeps.Length >= 2) { prefixSeps = prefixSeps.Substring(0, 2); } diff --git a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj index 7c83ae1bd..84ed8553c 100644 --- a/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj +++ b/System.IO.Abstractions.TestingHelpers/System.IO.Abstractions.TestingHelpers.csproj @@ -38,7 +38,7 @@ - + runtime; build; native; contentfiles; analyzers all diff --git a/System.IO.Abstractions/DirectoryInfoWrapper.cs b/System.IO.Abstractions/DirectoryInfoWrapper.cs index ec7e4d5e8..2fe120a22 100644 --- a/System.IO.Abstractions/DirectoryInfoWrapper.cs +++ b/System.IO.Abstractions/DirectoryInfoWrapper.cs @@ -227,7 +227,17 @@ public override void SetAccessControl(DirectorySecurity directorySecurity) public override DirectoryInfoBase Parent { - get { return new DirectoryInfoWrapper(FileSystem, instance.Parent); } + get + { + if (instance.Parent == null) + { + return null; + } + else + { + return new DirectoryInfoWrapper(FileSystem, instance.Parent); + } + } } public override DirectoryInfoBase Root diff --git a/System.IO.Abstractions/FileWrapper.cs b/System.IO.Abstractions/FileWrapper.cs index f02b7ca47..7f6423f26 100644 --- a/System.IO.Abstractions/FileWrapper.cs +++ b/System.IO.Abstractions/FileWrapper.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using System.Security.AccessControl; using System.Text; -using System.IO; namespace System.IO.Abstractions { [Serializable] public class FileWrapper : FileBase { - public FileWrapper(FileSystem fileSystem) : base(fileSystem) + public FileWrapper(IFileSystem fileSystem) : base(fileSystem) { } diff --git a/System.IO.Abstractions/System.IO.Abstractions.csproj b/System.IO.Abstractions/System.IO.Abstractions.csproj index 5f8b13f8b..8dca9584d 100644 --- a/System.IO.Abstractions/System.IO.Abstractions.csproj +++ b/System.IO.Abstractions/System.IO.Abstractions.csproj @@ -50,7 +50,7 @@ - + runtime; build; native; contentfiles; analyzers all