diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs index d1b23cb92..a14e5d7cc 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -125,7 +125,9 @@ public override void Copy(string sourceFileName, string destFileName, bool overw var sourceFileData = mockFileDataAccessor.GetFile(sourceFileName); sourceFileData.CheckFileAccess(sourceFileName, FileAccess.Read); - mockFileDataAccessor.AddFile(destFileName, new MockFileData(sourceFileData)); + var destFileData = new MockFileData(sourceFileData); + destFileData.CreationTime = destFileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AddFile(destFileName, destFileData); } /// diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 755d6d19e..6b0c39303 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -8,7 +8,7 @@ public class MockFileStream : MemoryStream private readonly string path; private readonly FileAccess access = FileAccess.ReadWrite; private readonly FileOptions options; - + private readonly MockFileData fileData; private bool disposed; /// @@ -31,7 +31,7 @@ public MockFileStream( throw CommonExceptions.FileAlreadyExists(path); } - var fileData = mockFileDataAccessor.GetFile(path); + fileData = mockFileDataAccessor.GetFile(path); fileData.CheckFileAccess(path, access); var existingContents = fileData.Contents; @@ -40,8 +40,8 @@ public MockFileStream( mode != FileMode.Truncate && mode != FileMode.Create; if (keepExistingContents) { - Write(existingContents, 0, existingContents.Length); - Seek(0, mode == FileMode.Append + base.Write(existingContents, 0, existingContents.Length); + base.Seek(0, mode == FileMode.Append ? SeekOrigin.End : SeekOrigin.Begin); } @@ -59,7 +59,9 @@ public MockFileStream( throw CommonExceptions.FileNotFound(path); } - mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { })); + fileData = new MockFileData(new byte[] { }); + fileData.CreationTime = fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AddFile(path, fileData); } this.access = access; @@ -71,6 +73,20 @@ public MockFileStream( /// public override bool CanWrite => access.HasFlag(FileAccess.Write); + /// + public override int Read(byte[] buffer, int offset, int count) + { + fileData.LastAccessTime = DateTime.Now; + return base.Read(buffer, offset, count); + } + + /// + public override void Write(byte[] buffer, int offset, int count) + { + fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now; + base.Write(buffer, offset, count); + } + /// protected override void Dispose(bool disposing) { diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileCopyTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileCopyTests.cs index 8ab4d11cf..49c54fa71 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileCopyTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileCopyTests.cs @@ -27,6 +27,23 @@ public void MockFile_Copy_ShouldOverwriteFileWhenOverwriteFlagIsTrue() Assert.AreEqual(copyResult.Contents, sourceContents.Contents); } + [Test] + public void MockFile_Copy_ShouldAdjustTimestampsOnDestination() + { + var sourceFileName = XFS.Path(@"c:\source\demo.txt"); + var destFileName = XFS.Path(@"c:\source\demo_copy.txt"); + + var mockFileSystem = new MockFileSystem(); + mockFileSystem.AddFile(sourceFileName, "Original"); + mockFileSystem.File.Copy(sourceFileName, destFileName); + + var sourceFileInfo = mockFileSystem.FileInfo.FromFileName(sourceFileName); + var destFileInfo = mockFileSystem.FileInfo.FromFileName(destFileName); + Assert.AreEqual(sourceFileInfo.LastWriteTime, destFileInfo.LastWriteTime); + Assert.LessOrEqual(DateTime.Now - destFileInfo.CreationTime, TimeSpan.FromSeconds(1)); + Assert.AreEqual(destFileInfo.CreationTime, destFileInfo.LastAccessTime); + } + [Test] public void MockFile_Copy_ShouldCloneContents() { diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileOpenTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileOpenTests.cs index 2dd397168..678498627 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileOpenTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileOpenTests.cs @@ -1,3 +1,5 @@ +using System.Threading.Tasks; + namespace System.IO.Abstractions.TestingHelpers.Tests { using Collections.Generic; @@ -217,7 +219,7 @@ public void MockFile_OpenText_ShouldRetainLastWriteTime() } [Test] - public void MockFile_OpenText_ShouldRetainLastAccessTime() + public void MockFile_OpenText_ShouldUpdateLastAccessTime() { // Arrange var fs = new MockFileSystem(); @@ -234,7 +236,101 @@ public void MockFile_OpenText_ShouldRetainLastAccessTime() } // Assert - Assert.AreEqual(lastAccessTime, fs.FileInfo.FromFileName(filepath).LastAccessTime); + Assert.LessOrEqual(DateTime.Now - fs.FileInfo.FromFileName(filepath).LastAccessTime, TimeSpan.FromSeconds(1)); + } + + [Test] + public void MockFile_Read_ShouldRetainCreationTimeAndUpdateLastAccessTime() + { + // Arrange + var fs = new MockFileSystem(); + var filepath = XFS.Path(@"C:\TestData\test.txt"); + var file = new MockFileData(new byte[] { 1, 2, 3 }); + var lastAccessTime = new DateTime(2012, 03, 21); + file.LastAccessTime = lastAccessTime; + var creationTime = new DateTime(2012, 03, 20); + file.CreationTime = creationTime; + fs.AddFile(filepath, file); + + var fi = fs.FileInfo.FromFileName(filepath); + var stream = fi.OpenRead(); + var buffer = new byte[16]; + stream.Read(buffer, 0, buffer.Length); + fi.Refresh(); + // Assert + Assert.AreEqual(creationTime, fi.CreationTime); + Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1)); + } + + [Test] + public async Task MockFile_ReadAsync_ShouldRetainCreationTimeAndUpdateLastAccessTime() + { + // Arrange + var fs = new MockFileSystem(); + var filepath = XFS.Path(@"C:\TestData\test.txt"); + var file = new MockFileData(new byte[] { 1, 2, 3 }); + var lastAccessTime = new DateTime(2012, 03, 21); + file.LastAccessTime = lastAccessTime; + var creationTime = new DateTime(2012, 03, 20); + file.CreationTime = creationTime; + fs.AddFile(filepath, file); + + var fi = fs.FileInfo.FromFileName(filepath); + var stream = fi.OpenRead(); + var buffer = new byte[16]; + await stream.ReadAsync(buffer, 0, buffer.Length); + fi.Refresh(); + // Assert + Assert.AreEqual(creationTime, fi.CreationTime); + Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1)); + } + + [Test] + public void MockFile_Write_ShouldRetainCreationTimeAndUpdateLastAccessTimeAndLastWriteTime() + { + // Arrange + var fs = new MockFileSystem(); + var filepath = XFS.Path(@"C:\TestData\test.txt"); + var file = new MockFileData(new byte[] { 1, 2, 3 }); + var lastAccessTime = new DateTime(2012, 03, 21); + file.LastAccessTime = lastAccessTime; + var creationTime = new DateTime(2012, 03, 20); + file.CreationTime = creationTime; + fs.AddFile(filepath, file); + + var fi = fs.FileInfo.FromFileName(filepath); + var stream = fi.OpenWrite(); + var buffer = new byte[16]; + stream.Write(buffer, 0, buffer.Length); + fi.Refresh(); + // Assert + Assert.AreEqual(creationTime, fi.CreationTime); + Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1)); + Assert.LessOrEqual(DateTime.Now - fi.LastWriteTime, TimeSpan.FromSeconds(1)); + } + + [Test] + public async Task MockFile_WriteAsync_ShouldRetainCreationTimeAndUpdateLastAccessTimeAndLastWriteTime() + { + // Arrange + var fs = new MockFileSystem(); + var filepath = XFS.Path(@"C:\TestData\test.txt"); + var file = new MockFileData(new byte[] { 1, 2, 3 }); + var lastAccessTime = new DateTime(2012, 03, 21); + file.LastAccessTime = lastAccessTime; + var creationTime = new DateTime(2012, 03, 20); + file.CreationTime = creationTime; + fs.AddFile(filepath, file); + + var fi = fs.FileInfo.FromFileName(filepath); + var stream = fi.OpenWrite(); + var buffer = new byte[16]; + await stream.WriteAsync(buffer, 0, buffer.Length); + fi.Refresh(); + // Assert + Assert.AreEqual(creationTime, fi.CreationTime); + Assert.LessOrEqual(DateTime.Now - fi.LastAccessTime, TimeSpan.FromSeconds(1)); + Assert.LessOrEqual(DateTime.Now - fi.LastWriteTime, TimeSpan.FromSeconds(1)); } [Test]