diff --git a/TestHelpers.Tests/MockFileCopyTests.cs b/TestHelpers.Tests/MockFileCopyTests.cs index 7dffee39f..af446a884 100644 --- a/TestHelpers.Tests/MockFileCopyTests.cs +++ b/TestHelpers.Tests/MockFileCopyTests.cs @@ -271,5 +271,25 @@ public void MockFile_Copy_ShouldThrowArgumentExceptionWhenTargetIsEmpty_Message( Assert.That(exception.Message, Is.StringStarting("Empty file name is not legal.")); } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFile_Copy_ShouldThrowExceptionWhenSourceDoesNotExist() + { + string sourceFilePath = XFS.Path(@"c:\something\demo.txt"); + var fileSystem = new MockFileSystem(); + + fileSystem.File.Copy(sourceFilePath, XFS.Path(@"c:\something\demo2.txt")); + } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFile_Copy_ShouldThrowExceptionWhenSourceDoesNotExist_EvenWhenCopyingToItself() + { + string sourceFilePath = XFS.Path(@"c:\something\demo.txt"); + var fileSystem = new MockFileSystem(); + + fileSystem.File.Copy(sourceFilePath, XFS.Path(@"c:\something\demo.txt")); + } } } \ No newline at end of file diff --git a/TestHelpers.Tests/MockFileInfoTests.cs b/TestHelpers.Tests/MockFileInfoTests.cs index 659820d56..6c57e73b7 100644 --- a/TestHelpers.Tests/MockFileInfoTests.cs +++ b/TestHelpers.Tests/MockFileInfoTests.cs @@ -476,5 +476,66 @@ public void MockFileInfo_MoveTo_ShouldUpdateFileInfoDirectoryAndFullName() Assert.AreEqual(fileInfo.DirectoryName, destinationFolder); Assert.AreEqual(fileInfo.FullName, destination); } + + [Test] + public void MockFileInfo_MoveTo_SameSourceAndTargetIsANoOp() + { + // Arrange + var fileSystem = new MockFileSystem(); + fileSystem.AddFile(XFS.Path(@"c:\temp\file.txt"), new MockFileData(@"line 1\r\nline 2")); + var fileInfo = fileSystem.FileInfo.FromFileName(XFS.Path(@"c:\temp\file.txt")); + + // Act + string destination = XFS.Path(XFS.Path(@"c:\temp\file.txt")); + fileInfo.MoveTo(destination); + + Assert.AreEqual(fileInfo.FullName, destination); + Assert.True(fileInfo.Exists); + } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFileInfo_MoveTo_SameSourceAndTargetThrowsExceptionIfSourceDoesntExist() + { + // Arrange + var fileSystem = new MockFileSystem(); + var fileInfo = fileSystem.FileInfo.FromFileName(XFS.Path(@"c:\temp\file.txt")); + + // Act + string destination = XFS.Path(XFS.Path(@"c:\temp\file.txt")); + fileInfo.MoveTo(destination); + + Assert.AreEqual(fileInfo.FullName, destination); + } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFileInfo_MoveTo_ThrowsExceptionIfSourceDoesntExist() + { + // Arrange + var fileSystem = new MockFileSystem(); + var fileInfo = fileSystem.FileInfo.FromFileName(XFS.Path(@"c:\temp\file.txt")); + + // Act + string destination = XFS.Path(XFS.Path(@"c:\temp\file2.txt")); + fileInfo.MoveTo(destination); + + Assert.AreEqual(fileInfo.FullName, destination); + } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFileInfo_CopyTo_ThrowsExceptionIfSourceDoesntExist() + { + // Arrange + var fileSystem = new MockFileSystem(); + var fileInfo = fileSystem.FileInfo.FromFileName(XFS.Path(@"c:\temp\file.txt")); + + // Act + string destination = XFS.Path(XFS.Path(@"c:\temp\file2.txt")); + fileInfo.CopyTo(destination); + + Assert.AreEqual(fileInfo.FullName, destination); + } } } \ No newline at end of file diff --git a/TestHelpers.Tests/MockFileMoveTests.cs b/TestHelpers.Tests/MockFileMoveTests.cs index 090a6b23f..71da040d5 100644 --- a/TestHelpers.Tests/MockFileMoveTests.cs +++ b/TestHelpers.Tests/MockFileMoveTests.cs @@ -29,6 +29,25 @@ public void MockFile_Move_ShouldMoveFileWithinMemoryFileSystem() Assert.That(fileSystem.FileExists(sourceFilePath), Is.False); } + [Test] + public void MockFile_Move_SameSourceAndTargetIsANoOp() + { + string sourceFilePath = XFS.Path(@"c:\something\demo.txt"); + string sourceFileContent = "this is some content"; + var fileSystem = new MockFileSystem(new Dictionary + { + {sourceFilePath, new MockFileData(sourceFileContent)}, + {XFS.Path(@"c:\somethingelse\dummy.txt"), new MockFileData(new byte[] {0})} + }); + + string destFilePath = XFS.Path(@"c:\somethingelse\demo.txt"); + + fileSystem.File.Move(sourceFilePath, destFilePath); + + Assert.That(fileSystem.FileExists(destFilePath), Is.True); + Assert.That(fileSystem.GetFile(destFilePath).TextContents, Is.EqualTo(sourceFileContent)); + } + [Test] public void MockFile_Move_ShouldThrowIOExceptionWhenTargetAlreadyExists() { @@ -286,5 +305,25 @@ public void MockFile_Move_ShouldThrowDirectoryNotFoundExceptionWhenSourcePathDoe Assert.That(() => fileSystem.File.Move(sourceFilePath, destFilePath), Throws.InstanceOf().With.Message.StartsWith(@"Could not find a part of the path")); } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFile_Move_ShouldThrowExceptionWhenSourceDoesNotExist() + { + string sourceFilePath = XFS.Path(@"c:\something\demo.txt"); + var fileSystem = new MockFileSystem(); + + fileSystem.File.Move(sourceFilePath, XFS.Path(@"c:\something\demo2.txt")); + } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFile_Move_ShouldThrowExceptionWhenSourceDoesNotExist_EvenWhenCopyingToItself() + { + string sourceFilePath = XFS.Path(@"c:\something\demo.txt"); + var fileSystem = new MockFileSystem(); + + fileSystem.File.Move(sourceFilePath, XFS.Path(@"c:\something\demo.txt")); + } } } \ No newline at end of file diff --git a/TestHelpers.Tests/MockFileStreamTests.cs b/TestHelpers.Tests/MockFileStreamTests.cs index 66b6412b9..a07f7e743 100644 --- a/TestHelpers.Tests/MockFileStreamTests.cs +++ b/TestHelpers.Tests/MockFileStreamTests.cs @@ -15,7 +15,7 @@ public void MockFileStream_Flush_WritesByteToFile() // Arrange var filepath = XFS.Path(@"c:\something\foo.txt"); var filesystem = new MockFileSystem(new Dictionary()); - var cut = new MockFileStream(filesystem, filepath); + var cut = new MockFileStream(filesystem, filepath, MockFileStream.StreamType.WRITE); // Act cut.WriteByte(255); @@ -44,5 +44,19 @@ public void MockFileStream_Dispose_ShouldNotResurrectFile() Assert.AreEqual(0, fileCount2, "File should have been deleted"); Assert.AreEqual(0, fileCount3, "Disposing stream should not have resurrected the file"); } + + [Test] + [ExpectedException(typeof(FileNotFoundException))] + public void MockFileStream_Constructor_Reading_Nonexistent_File_Throws_Exception() + { + // Arrange + var nonexistentFilePath = XFS.Path(@"c:\something\foo.txt"); + var filesystem = new MockFileSystem(new Dictionary()); + + // Act + var illegalFileStream = new MockFileStream(filesystem, nonexistentFilePath, MockFileStream.StreamType.READ); + + // Assert - expect an exception + } } } diff --git a/TestingHelpers/MockFile.cs b/TestingHelpers/MockFile.cs index 0d2506032..75dd86935 100644 --- a/TestingHelpers/MockFile.cs +++ b/TestingHelpers/MockFile.cs @@ -99,6 +99,7 @@ public override void Copy(string sourceFileName, string destFileName) public override void Copy(string sourceFileName, string destFileName, bool overwrite) { + //This is the order that checks are executed in MSCORLIB. if (sourceFileName == null) { throw new ArgumentNullException("sourceFileName", Properties.Resources.FILENAME_CANNOT_BE_NULL); @@ -108,9 +109,12 @@ public override void Copy(string sourceFileName, string destFileName, bool overw { throw new ArgumentNullException("destFileName", Properties.Resources.FILENAME_CANNOT_BE_NULL); } - mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(sourceFileName, "sourceFileName"); mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, "destFileName"); + if (!Exists(sourceFileName)) + { + throw new FileNotFoundException(); + } var directoryNameOfDestination = mockPath.GetDirectoryName(destFileName); if (!mockFileDataAccessor.Directory.Exists(directoryNameOfDestination)) @@ -323,7 +327,16 @@ public override void Move(string sourceFileName, string destFileName) mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(destFileName, "destFileName"); if (mockFileDataAccessor.GetFile(destFileName) != null) - throw new IOException("A file can not be created if it already exists."); + { + if (destFileName.Equals(sourceFileName)) + { + return; + } else + { + throw new IOException("A file can not be created if it already exists."); + } + } + var sourceFile = mockFileDataAccessor.GetFile(sourceFileName); @@ -399,7 +412,7 @@ public override Stream OpenWrite(string path) { mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - return new MockFileStream(mockFileDataAccessor, path); + return new MockFileStream(mockFileDataAccessor, path, MockFileStream.StreamType.WRITE); } public override byte[] ReadAllBytes(string path) diff --git a/TestingHelpers/MockFileInfo.cs b/TestingHelpers/MockFileInfo.cs index d881af155..b4144f7e3 100644 --- a/TestingHelpers/MockFileInfo.cs +++ b/TestingHelpers/MockFileInfo.cs @@ -155,18 +155,25 @@ public override string Name { public override StreamWriter AppendText() { if (MockFileData == null) throw new FileNotFoundException("File not found", path); - return new StreamWriter(new MockFileStream(mockFileSystem, FullName, true)); + return new StreamWriter(new MockFileStream(mockFileSystem, FullName, MockFileStream.StreamType.APPEND)); //return ((MockFileDataModifier) MockFileData).AppendText(); } public override FileInfoBase CopyTo(string destFileName) { - new MockFile(mockFileSystem).Copy(FullName, destFileName); - return mockFileSystem.FileInfo.FromFileName(destFileName); + return CopyTo(destFileName, false); } 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 (destFileName == FullName) + { + return this; + } new MockFile(mockFileSystem).Copy(FullName, destFileName, overwrite); return mockFileSystem.FileInfo.FromFileName(destFileName); } @@ -210,6 +217,10 @@ public override FileSecurity GetAccessControl(AccessControlSections includeSecti public override void MoveTo(string destFileName) { var movedFileInfo = CopyTo(destFileName); + if (destFileName == FullName) + { + return; + } Delete(); path = movedFileInfo.FullName; } @@ -231,7 +242,8 @@ public override Stream Open(FileMode mode, FileAccess access, FileShare share) public override Stream OpenRead() { - return new MockFileStream(mockFileSystem, path); + if (MockFileData == null) throw new FileNotFoundException("File not found", path); + return new MockFileStream(mockFileSystem, path, MockFileStream.StreamType.READ); } public override StreamReader OpenText() @@ -241,7 +253,7 @@ public override StreamReader OpenText() public override Stream OpenWrite() { - return new MockFileStream(mockFileSystem, path); + return new MockFileStream(mockFileSystem, path, MockFileStream.StreamType.WRITE); } public override FileInfoBase Replace(string destinationFileName, string destinationBackupFileName) diff --git a/TestingHelpers/MockFileStream.cs b/TestingHelpers/MockFileStream.cs index 0af1ac962..88312b3c3 100644 --- a/TestingHelpers/MockFileStream.cs +++ b/TestingHelpers/MockFileStream.cs @@ -6,7 +6,14 @@ public class MockFileStream : MemoryStream private readonly IMockFileDataAccessor mockFileDataAccessor; private readonly string path; - public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, bool forAppend = false) + public enum StreamType + { + READ, + WRITE, + APPEND + } + + public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, StreamType streamType) { if (mockFileDataAccessor == null) { @@ -23,13 +30,17 @@ public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, b if (data != null && data.Length > 0) { Write(data, 0, data.Length); - Seek(0, forAppend + Seek(0, StreamType.APPEND.Equals(streamType) ? SeekOrigin.End : SeekOrigin.Begin); } } else { + if (StreamType.READ.Equals(streamType)) + { + throw new FileNotFoundException("File not found.", path); + } mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { })); } }