From e60ff0bb9290f01371e2f8bda2d186b3322d20a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 10 Aug 2022 22:32:34 +0200 Subject: [PATCH 01/12] Adjust times in MockFileSystem Also apply time in MockFileStream Mark MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime as Windows-Only Fix name of unit tests to match the actual expected behavior --- .../IMockFileDataAccessor.cs | 8 + .../MockFile.cs | 42 ++- .../MockFileStream.cs | 10 +- .../MockFileSystem.cs | 42 ++- .../TimeAdjustments.cs | 30 ++ .../MockFileAdjustTimesTest.cs | 303 ++++++++++++++++++ .../MockFileGetCreationTimeTests.cs | 14 + .../MockFileGetCreationTimeUtcTests.cs | 14 + .../MockFileGetLastAccessTimeTests.cs | 14 + .../MockFileGetLastAccessTimeUtcTests.cs | 14 + .../MockFileGetLastWriteTimeTests.cs | 14 + .../MockFileGetLastWriteTimeUtcTests.cs | 14 + 12 files changed, 502 insertions(+), 17 deletions(-) create mode 100644 src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs create mode 100644 tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs diff --git a/src/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs b/src/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs index 1aeeb89d2..533e28be0 100644 --- a/src/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs +++ b/src/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs @@ -8,6 +8,14 @@ namespace System.IO.Abstractions.TestingHelpers /// public interface IMockFileDataAccessor : IFileSystem { + /// + /// Adjust the times of the . + /// + /// The for which the times should be adjusted. + /// The adjustments to make on the . + /// The adjusted file. + MockFileData AdjustTimes(MockFileData fileData, TimeAdjustments timeAdjustments); + /// /// Gets a file. /// diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs index 32b52a871..18efc944f 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -55,12 +55,13 @@ public override void AppendAllText(string path, string contents, Encoding encodi if (!mockFileDataAccessor.FileExists(path)) { VerifyDirectoryExists(path); - mockFileDataAccessor.AddFile(path, new MockFileData(contents, encoding)); + mockFileDataAccessor.AddFile(path, mockFileDataAccessor.AdjustTimes(new MockFileData(contents, encoding), TimeAdjustments.All)); } else { var file = mockFileDataAccessor.GetFile(path); file.CheckFileAccess(path, FileAccess.Write); + mockFileDataAccessor.AdjustTimes(file, TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime); var bytesToAppend = encoding.GetBytes(contents); file.Contents = file.Contents.Concat(bytesToAppend).ToArray(); } @@ -124,7 +125,7 @@ public override void Copy(string sourceFileName, string destFileName, bool overw var sourceFileData = mockFileDataAccessor.GetFile(sourceFileName); sourceFileData.CheckFileAccess(sourceFileName, FileAccess.Read); var destFileData = new MockFileData(sourceFileData); - destFileData.CreationTime = destFileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AdjustTimes(destFileData, TimeAdjustments.CreationTime | TimeAdjustments.LastAccessTime); mockFileDataAccessor.AddFile(destFileName, destFileData); } @@ -151,6 +152,7 @@ private Stream CreateInternal(string path, FileAccess access, FileOptions option VerifyDirectoryExists(path); var mockFileData = new MockFileData(new byte[0]); + mockFileDataAccessor.AdjustTimes(mockFileData, TimeAdjustments.All); mockFileDataAccessor.AddFile(path, mockFileData); return OpenInternal(path, FileMode.Open, access, options); } @@ -436,7 +438,7 @@ public override void Move(string sourceFileName, string destFileName) VerifyDirectoryExists(destFileName); mockFileDataAccessor.RemoveFile(sourceFileName); - mockFileDataAccessor.AddFile(destFileName, new MockFileData(sourceFile)); + mockFileDataAccessor.AddFile(destFileName, mockFileDataAccessor.AdjustTimes(new MockFileData(sourceFile), TimeAdjustments.LastAccessTime)); } #if FEATURE_FILE_MOVE_WITH_OVERWRITE @@ -480,9 +482,9 @@ public override void Move(string sourceFileName, string destFileName, bool overw throw CommonExceptions.ProcessCannotAccessFileInUse(); } VerifyDirectoryExists(destFileName); - + mockFileDataAccessor.RemoveFile(sourceFileName); - mockFileDataAccessor.AddFile(destFileName, new MockFileData(sourceFile)); + mockFileDataAccessor.AddFile(destFileName, mockFileDataAccessor.AdjustTimes(new MockFileData(sourceFile), TimeAdjustments.LastAccessTime)); } #endif @@ -539,6 +541,12 @@ private Stream OpenInternal( var mockFileData = mockFileDataAccessor.GetFile(path); mockFileData.CheckFileAccess(path, access); + var timeAdjustments = TimeAdjustments.LastAccessTime; + if (access != FileAccess.Read) + { + timeAdjustments |= TimeAdjustments.LastWriteTime; + } + mockFileDataAccessor.AdjustTimes(mockFileData, timeAdjustments); return new MockFileStream(mockFileDataAccessor, path, mode, access, options); } @@ -578,7 +586,9 @@ public override byte[] ReadAllBytes(string path) throw CommonExceptions.FileNotFound(path); } mockFileDataAccessor.GetFile(path).CheckFileAccess(path, FileAccess.Read); - return mockFileDataAccessor.GetFile(path).Contents.ToArray(); + var fileData = mockFileDataAccessor.GetFile(path); + mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); + return fileData.Contents.ToArray(); } /// @@ -590,10 +600,11 @@ public override string[] ReadAllLines(string path) { throw CommonExceptions.FileNotFound(path); } - mockFileDataAccessor.GetFile(path).CheckFileAccess(path, FileAccess.Read); + var fileData = mockFileDataAccessor.GetFile(path); + fileData.CheckFileAccess(path, FileAccess.Read); + mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); - return mockFileDataAccessor - .GetFile(path) + return fileData .TextContents .SplitLines(); } @@ -613,9 +624,11 @@ public override string[] ReadAllLines(string path, Encoding encoding) throw CommonExceptions.FileNotFound(path); } - mockFileDataAccessor.GetFile(path).CheckFileAccess(path, FileAccess.Read); + var fileData = mockFileDataAccessor.GetFile(path); + fileData.CheckFileAccess(path, FileAccess.Read); + mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); - using (var ms = new MemoryStream(mockFileDataAccessor.GetFile(path).Contents)) + using (var ms = new MemoryStream(fileData.Contents)) using (var sr = new StreamReader(ms, encoding)) { return sr.ReadToEnd().SplitLines(); @@ -713,6 +726,7 @@ public override void SetAccessControl(string path, FileSecurity fileSecurity) } var fileData = mockFileDataAccessor.GetFile(path); + mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); fileData.AccessControl = fileSecurity; } @@ -736,6 +750,7 @@ public override void SetAttributes(string path, FileAttributes fileAttributes) } else { + mockFileDataAccessor.AdjustTimes(possibleFileData, TimeAdjustments.LastAccessTime); possibleFileData.Attributes = fileAttributes; } } @@ -824,7 +839,7 @@ public override void WriteAllBytes(string path, byte[] bytes) mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); VerifyDirectoryExists(path); - mockFileDataAccessor.AddFile(path, new MockFileData(bytes.ToArray())); + mockFileDataAccessor.AddFile(path, mockFileDataAccessor.AdjustTimes(new MockFileData(bytes.ToArray()), TimeAdjustments.All)); } /// @@ -1094,7 +1109,7 @@ public override void WriteAllText(string path, string contents, Encoding encodin VerifyDirectoryExists(path); MockFileData data = contents == null ? new MockFileData(new byte[0]) : new MockFileData(contents, encoding); - mockFileDataAccessor.AddFile(path, data); + mockFileDataAccessor.AddFile(path, mockFileDataAccessor.AdjustTimes(data, TimeAdjustments.All)); } internal static string ReadAllBytes(byte[] contents, Encoding encoding) @@ -1110,6 +1125,7 @@ private string ReadAllTextInternal(string path, Encoding encoding) { var mockFileData = mockFileDataAccessor.GetFile(path); mockFileData.CheckFileAccess(path, FileAccess.Read); + mockFileDataAccessor.AdjustTimes(mockFileData, TimeAdjustments.LastAccessTime); return ReadAllBytes(mockFileData.Contents, encoding); } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 6b0c39303..ed7333a8d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -34,6 +34,7 @@ public MockFileStream( fileData = mockFileDataAccessor.GetFile(path); fileData.CheckFileAccess(path, access); + mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); var existingContents = fileData.Contents; var keepExistingContents = existingContents?.Length > 0 && @@ -60,7 +61,8 @@ public MockFileStream( } fileData = new MockFileData(new byte[] { }); - fileData.CreationTime = fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AdjustTimes(fileData, + TimeAdjustments.CreationTime | TimeAdjustments.LastAccessTime); mockFileDataAccessor.AddFile(path, fileData); } @@ -76,14 +78,16 @@ public MockFileStream( /// public override int Read(byte[] buffer, int offset, int count) { - fileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AdjustTimes(fileData, + TimeAdjustments.LastAccessTime); return base.Read(buffer, offset, count); } /// public override void Write(byte[] buffer, int offset, int count) { - fileData.LastWriteTime = fileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AdjustTimes(fileData, + TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime); base.Write(buffer, offset, count); } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index fa3203ac9..e563633d3 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -15,6 +15,9 @@ public class MockFileSystem : FileSystemBase, IMockFileDataAccessor private readonly IDictionary files; private readonly PathVerifier pathVerifier; + [NonSerialized] + private Func dateTimeProvider = defaultDateTimeProvider; + private static Func defaultDateTimeProvider = () => DateTime.Now; /// public MockFileSystem() : this(null) { } @@ -88,6 +91,19 @@ public MockFileSystem(IDictionary files, string currentDir /// public PathVerifier PathVerifier => pathVerifier; + /// + /// Replaces the time provider with a mocked instance. This allows to influence the used time in tests. + /// + /// If not set, the default implementation returns . + /// + /// The function that returns the current . + /// + public MockFileSystem MockTime(Func dateTimeProvider) + { + this.dateTimeProvider = dateTimeProvider ?? defaultDateTimeProvider; + return this; + } + private string FixPath(string path, bool checkCaps = false) { if (path == null) @@ -124,6 +140,28 @@ private string GetPathWithCorrectDirectoryCapitalization(string fullPath) return fullPath.TrimSlashes(); } + /// + public MockFileData AdjustTimes(MockFileData fileData, TimeAdjustments timeAdjustments) + { + var now = (dateTimeProvider ?? defaultDateTimeProvider)(); + if ((timeAdjustments & TimeAdjustments.CreationTime) != TimeAdjustments.None) + { + fileData.CreationTime = now; + } + + if ((timeAdjustments & TimeAdjustments.LastAccessTime) != TimeAdjustments.None) + { + fileData.LastAccessTime = now; + } + + if ((timeAdjustments & TimeAdjustments.LastWriteTime) != TimeAdjustments.None) + { + fileData.LastWriteTime = now; + } + + return fileData; + } + /// public MockFileData GetFile(string path) { @@ -143,6 +181,7 @@ public void AddFile(string path, MockFileData mockFile) var fixedPath = FixPath(path, true); lock (files) { + mockFile ??= new MockFileData(string.Empty); var file = GetFile(fixedPath); if (file != null) @@ -155,6 +194,7 @@ public void AddFile(string path, MockFileData mockFile) throw CommonExceptions.AccessDenied(path); } file.CheckFileAccess(fixedPath, FileAccess.Write); + mockFile.CreationTime = file.CreationTime; } var directoryPath = Path.GetDirectoryName(fixedPath); @@ -164,7 +204,7 @@ public void AddFile(string path, MockFileData mockFile) AddDirectory(directoryPath); } - SetEntry(fixedPath, mockFile ?? new MockFileData(string.Empty)); + SetEntry(fixedPath, mockFile); } } diff --git a/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs b/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs new file mode 100644 index 000000000..73f814e36 --- /dev/null +++ b/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs @@ -0,0 +1,30 @@ +namespace System.IO.Abstractions.TestingHelpers +{ + /// + /// Flags indicating which times to adjust for a . + /// + [Flags] + public enum TimeAdjustments + { + /// + /// Adjusts no times on the + /// + None = 0, + /// + /// Adjusts the + /// + CreationTime = 1 << 0, + /// + /// Adjusts the + /// + LastAccessTime = 1 << 1, + /// + /// Adjusts the + /// + LastWriteTime = 1 << 2, + /// + /// Adjusts all times on the + /// + All = ~0 + } +} \ No newline at end of file diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs new file mode 100644 index 000000000..0c56d480f --- /dev/null +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs @@ -0,0 +1,303 @@ +using System.Runtime.Versioning; +using System.Security.AccessControl; +using System.Text; +using NUnit.Framework; + +namespace System.IO.Abstractions.TestingHelpers.Tests +{ + [TestFixture] + public class MockFileAdjustTimesTest + { + [Test] + public void MockFile_AfterAppendAllText_ShouldUpdateLastAccessAndLastWriteTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.AppendAllText("foo.txt", "xyz"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(updateTime)); + } + + [Test] + public void MockFile_AfterCopy_ShouldUpdateCreationAndLastAccessTimeOfDestination() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.Copy("foo.txt", "bar.txt"); + + var actualSourceCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualDestinationCreationTime = fileSystem.File.GetCreationTime("bar.txt"); + var actualSourceLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualDestinationLastAccessTime = fileSystem.File.GetLastAccessTime("bar.txt"); + var actualSourceLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualDestinationLastWriteTime = fileSystem.File.GetLastWriteTime("bar.txt"); + + Assert.That(actualSourceCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualDestinationCreationTime, Is.EqualTo(updateTime)); + Assert.That(actualSourceLastAccessTime, Is.EqualTo(creationTime)); + Assert.That(actualDestinationLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualSourceLastWriteTime, Is.EqualTo(creationTime)); + Assert.That(actualDestinationLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterMove_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.Move("foo.txt", "bar.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("bar.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("bar.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("bar.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [TestCase(FileMode.Open, FileAccess.ReadWrite)] + [TestCase(FileMode.OpenOrCreate, FileAccess.Write)] + [TestCase(FileMode.Append, FileAccess.ReadWrite)] + public void MockFile_AfterOpen_WithWriteAccess_ShouldUpdateLastAccessAndLastWriteTime(FileMode fileMode, FileAccess fileAccess) + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.Open("foo.txt", fileMode, fileAccess); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(updateTime)); + } + + [TestCase(FileMode.Open, FileAccess.Read)] + [TestCase(FileMode.OpenOrCreate, FileAccess.Read)] + [TestCase(FileMode.Append, FileAccess.Read)] + public void MockFile_AfterOpen_WithReadOnlyAccess_ShouldUpdateLastAccessTime(FileMode fileMode, FileAccess fileAccess) + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.Open("foo.txt", fileMode, fileAccess); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterReadAllBytes_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.ReadAllBytes("foo.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterReadAllLines_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.ReadAllLines("foo.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterReadAllText_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.ReadAllText("foo.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.SetAttributes("foo.txt", FileAttributes.Hidden); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + [SupportedOSPlatform("windows")] + [WindowsOnly(WindowsSpecifics.AccessControlLists)] + public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.SetAccessControl("foo.txt", new FileSecurity()); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFile_AfterWriteAllBytes_ShouldUpdateLastAccessAndLastWriteTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.WriteAllBytes("foo.txt", Encoding.UTF8.GetBytes("xyz")); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(updateTime)); + } + + [Test] + public void MockFile_AfterWriteAllText_ShouldUpdateLastAccessAndLastWriteTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(updateTime)); + } + + [Test] + public void MockFileStream_OpenRead_ShouldUpdateLastAccessTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + _ = fileSystem.File.OpenRead("foo.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(creationTime)); + } + + [Test] + public void MockFileStream_OpenWrite_ShouldUpdateLastAccessAndLastWriteTime() + { + var creationTime = DateTime.Now.AddDays(10); + var updateTime = creationTime.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => creationTime); + fileSystem.File.WriteAllText("foo.txt", "abc"); + fileSystem.MockTime(() => updateTime); + _ = fileSystem.File.OpenWrite("foo.txt"); + + var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(actualCreationTime, Is.EqualTo(creationTime)); + Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); + Assert.That(actualLastWriteTime, Is.EqualTo(updateTime)); + } + } +} diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeTests.cs index 285948272..1d213924d 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeTests.cs @@ -32,5 +32,19 @@ public void MockFile_GetCreationTime_ShouldReturnDefaultTimeIfFileDoesNotExist() // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc).ToLocalTime(), actualCreationTime); } + + [Test] + public void MockFile_GetCreationTime_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetCreationTime("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Local)); + Assert.That(result, Is.EqualTo(now.ToLocalTime())); + } } } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeUtcTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeUtcTests.cs index 98f80fd8f..30cb6e1d5 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeUtcTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetCreationTimeUtcTests.cs @@ -32,5 +32,19 @@ public void MockFile_GetCreationTimeUtc_ShouldReturnDefaultTimeIfFileDoesNotExis // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), actualCreationTime); } + + [Test] + public void MockFile_GetCreationTimeUtc_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetCreationTimeUtc("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(result, Is.EqualTo(now.ToUniversalTime())); + } } } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeTests.cs index 8b74d23d8..fbf3ef09f 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeTests.cs @@ -32,5 +32,19 @@ public void MockFile_GetLastAccessTime_ShouldReturnDefaultTimeIfFileDoesNotExist // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc).ToLocalTime(), actualLastAccessTime); } + + [Test] + public void MockFile_GetLastAccessTime_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetLastAccessTime("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Local)); + Assert.That(result, Is.EqualTo(now.ToLocalTime())); + } } } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeUtcTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeUtcTests.cs index b72ff9adf..c42bc6c44 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeUtcTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastAccessTimeUtcTests.cs @@ -32,5 +32,19 @@ public void MockFile_GetLastAccessTimeUtc_ShouldReturnDefaultTimeIfFileDoesNotEx // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), actualLastAccessTime); } + + [Test] + public void MockFile_GetLastAccessTimeUtc_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(result, Is.EqualTo(now.ToUniversalTime())); + } } } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeTests.cs index c6e519583..5ceaf25f7 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeTests.cs @@ -32,5 +32,19 @@ public void MockFile_GetLastWriteTime_ShouldReturnDefaultTimeIfFileDoesNotExist( // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc).ToLocalTime(), actualLastWriteTime); } + + [Test] + public void MockFile_GetLastWriteTime_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetLastWriteTime("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Local)); + Assert.That(result, Is.EqualTo(now.ToLocalTime())); + } } } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeUtcTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeUtcTests.cs index 5a14d41d9..4783e7e7f 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeUtcTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileGetLastWriteTimeUtcTests.cs @@ -31,5 +31,19 @@ public void MockFile_GetLastWriteTimeUtc_ShouldReturnDefaultTimeIfFileDoesNotExi // Assert Assert.AreEqual(new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc), actualLastWriteTime); } + + [Test] + public void MockFile_GetLastWriteTimeUtc_ShouldBeSet() + { + var now = DateTime.Now.AddDays(10); + var fileSystem = new MockFileSystem() + .MockTime(() => now); + fileSystem.File.WriteAllText("foo.txt", "xyz"); + + var result = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); + + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(result, Is.EqualTo(now.ToUniversalTime())); + } } } \ No newline at end of file From 1b567e8ed44390a40d537a317a1248971f2c6767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 26 Aug 2022 11:54:08 +0200 Subject: [PATCH 02/12] Avoid `null` for `dateTimeProvider` when deserializing --- .../MockFileSystem.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index e563633d3..b82620bb8 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; + using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.Serialization; namespace System.IO.Abstractions.TestingHelpers { @@ -143,7 +144,7 @@ private string GetPathWithCorrectDirectoryCapitalization(string fullPath) /// public MockFileData AdjustTimes(MockFileData fileData, TimeAdjustments timeAdjustments) { - var now = (dateTimeProvider ?? defaultDateTimeProvider)(); + var now = dateTimeProvider(); if ((timeAdjustments & TimeAdjustments.CreationTime) != TimeAdjustments.None) { fileData.CreationTime = now; @@ -414,6 +415,12 @@ public IEnumerable AllDirectories } } + [OnDeserializing] + private void OnDeserializing(StreamingContext c) + { + dateTimeProvider = defaultDateTimeProvider; + } + private bool AnyFileIsReadOnly(string path) { return Directory.GetFiles(path).Any(file => FileIsReadOnly(file)); From 99ebdab5e2036ccd18291dc58053a00b05461f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 26 Aug 2022 11:55:42 +0200 Subject: [PATCH 03/12] Use `HasFlag` instead of bitwise flag comparison --- src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index b82620bb8..a216f05c2 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -145,17 +145,17 @@ private string GetPathWithCorrectDirectoryCapitalization(string fullPath) public MockFileData AdjustTimes(MockFileData fileData, TimeAdjustments timeAdjustments) { var now = dateTimeProvider(); - if ((timeAdjustments & TimeAdjustments.CreationTime) != TimeAdjustments.None) + if (timeAdjustments.HasFlag(TimeAdjustments.CreationTime)) { fileData.CreationTime = now; } - if ((timeAdjustments & TimeAdjustments.LastAccessTime) != TimeAdjustments.None) + if (timeAdjustments.HasFlag(TimeAdjustments.LastAccessTime)) { fileData.LastAccessTime = now; } - if ((timeAdjustments & TimeAdjustments.LastWriteTime) != TimeAdjustments.None) + if (timeAdjustments.HasFlag(TimeAdjustments.LastWriteTime)) { fileData.LastWriteTime = now; } From 3f86970b44b4aec1c23e6f5caaea059e5bccb8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 27 Aug 2022 11:47:13 +0200 Subject: [PATCH 04/12] also use `AdjustTmes`in CreateSymbolicLink --- src/System.IO.Abstractions.TestingHelpers/MockFile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs index 18efc944f..e36068aaf 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -190,7 +190,7 @@ public override IFileSystemInfo CreateSymbolicLink(string path, string pathToTar var sourceFileData = mockFileDataAccessor.GetFile(pathToTarget); sourceFileData.CheckFileAccess(pathToTarget, FileAccess.Read); var destFileData = new MockFileData(new byte[0]); - destFileData.CreationTime = destFileData.LastAccessTime = DateTime.Now; + mockFileDataAccessor.AdjustTimes(destFileData, TimeAdjustments.CreationTime | TimeAdjustments.LastAccessTime); destFileData.LinkTarget = pathToTarget; mockFileDataAccessor.AddFile(path, destFileData); From 6cfbb43df25a8878846fed5bc523e9fba1558b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 27 Aug 2022 11:54:18 +0200 Subject: [PATCH 05/12] Consistently store all times in UTC and return the correct `DateTimeKind` in the various methods/properties. --- .../MockDirectoryInfo.cs | 12 +- .../MockFileData.cs | 21 +++- .../MockFileInfo.cs | 10 +- .../MockFileSystem.cs | 2 +- .../MockDirectoryInfoTests.cs | 10 +- .../MockDirectoryTests.cs | 15 ++- .../MockFileAdjustTimesTest.cs | 118 +++++++++--------- .../MockFileInfoTests.cs | 8 +- 8 files changed, 111 insertions(+), 85 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index eb70a3a10..6ff27e344 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -62,7 +62,7 @@ public override FileAttributes Attributes /// public override DateTime CreationTime { - get { return GetMockFileDataForRead().CreationTime.DateTime; } + get { return GetMockFileDataForRead().CreationTime.LocalDateTime; } set { GetMockFileDataForWrite().CreationTime = value; } } @@ -70,7 +70,7 @@ public override DateTime CreationTime public override DateTime CreationTimeUtc { get { return GetMockFileDataForRead().CreationTime.UtcDateTime; } - set { GetMockFileDataForWrite().CreationTime = value.ToLocalTime(); } + set { GetMockFileDataForWrite().CreationTime = value; } } /// @@ -114,7 +114,7 @@ public override string FullName /// public override DateTime LastAccessTime { - get { return GetMockFileDataForRead().LastAccessTime.DateTime; } + get { return GetMockFileDataForRead().LastAccessTime.LocalDateTime; } set { GetMockFileDataForWrite().LastAccessTime = value; } } @@ -122,13 +122,13 @@ public override DateTime LastAccessTime public override DateTime LastAccessTimeUtc { get { return GetMockFileDataForRead().LastAccessTime.UtcDateTime; } - set { GetMockFileDataForWrite().LastAccessTime = value.ToLocalTime(); } + set { GetMockFileDataForWrite().LastAccessTime = value; } } /// public override DateTime LastWriteTime { - get { return GetMockFileDataForRead().LastWriteTime.DateTime; } + get { return GetMockFileDataForRead().LastWriteTime.LocalDateTime; } set { GetMockFileDataForWrite().LastWriteTime = value; } } @@ -136,7 +136,7 @@ public override DateTime LastWriteTime public override DateTime LastWriteTimeUtc { get { return GetMockFileDataForRead().LastWriteTime.UtcDateTime; } - set { GetMockFileDataForWrite().LastWriteTime = value.ToLocalTime(); } + set { GetMockFileDataForWrite().LastWriteTime = value; } } #if FEATURE_FILE_SYSTEM_INFO_LINK_TARGET diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 0fe04c386..4a886b21e 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -126,17 +126,32 @@ public string TextContents /// /// Gets or sets the date and time the was created. /// - public DateTimeOffset CreationTime { get; set; } = new DateTimeOffset(2010, 01, 02, 00, 00, 00, TimeSpan.FromHours(4)); + public DateTimeOffset CreationTime + { + get { return creationTime; } + set{ creationTime = value.ToUniversalTime(); } + } + private DateTimeOffset creationTime; /// /// Gets or sets the date and time of the was last accessed to. /// - public DateTimeOffset LastAccessTime { get; set; } = new DateTimeOffset(2010, 02, 04, 00, 00, 00, TimeSpan.FromHours(4)); + public DateTimeOffset LastAccessTime + { + get { return lastAccessTime; } + set { lastAccessTime = value.ToUniversalTime(); } + } + private DateTimeOffset lastAccessTime; /// /// Gets or sets the date and time of the was last written to. /// - public DateTimeOffset LastWriteTime { get; set; } = new DateTimeOffset(2010, 01, 04, 00, 00, 00, TimeSpan.FromHours(4)); + public DateTimeOffset LastWriteTime + { + get { return lastWriteTime; } + set { lastWriteTime = value.ToUniversalTime(); } + } + private DateTimeOffset lastWriteTime; #if FEATURE_FILE_SYSTEM_INFO_LINK_TARGET /// diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 66105a5bb..4a5d8fa16 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -60,7 +60,7 @@ public override DateTime CreationTime get { var mockFileData = GetMockFileDataForRead(); - return mockFileData.CreationTime.DateTime; + return mockFileData.CreationTime.LocalDateTime; } set { @@ -80,7 +80,7 @@ public override DateTime CreationTimeUtc set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.CreationTime = value.ToLocalTime(); + mockFileData.CreationTime = value; } } @@ -117,7 +117,7 @@ public override DateTime LastAccessTime get { var mockFileData = GetMockFileDataForRead(); - return mockFileData.LastAccessTime.DateTime; + return mockFileData.LastAccessTime.LocalDateTime; } set { @@ -147,7 +147,7 @@ public override DateTime LastWriteTime get { var mockFileData = GetMockFileDataForRead(); - return mockFileData.LastWriteTime.DateTime; + return mockFileData.LastWriteTime.LocalDateTime; } set { @@ -167,7 +167,7 @@ public override DateTime LastWriteTimeUtc set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.LastWriteTime = value.ToLocalTime(); + mockFileData.LastWriteTime = value; } } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index a216f05c2..8c4226e08 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -18,7 +18,7 @@ public class MockFileSystem : FileSystemBase, IMockFileDataAccessor private readonly PathVerifier pathVerifier; [NonSerialized] private Func dateTimeProvider = defaultDateTimeProvider; - private static Func defaultDateTimeProvider = () => DateTime.Now; + private static Func defaultDateTimeProvider = () => DateTime.UtcNow; /// public MockFileSystem() : this(null) { } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs index d347b633f..b7aafc785 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs @@ -542,7 +542,7 @@ public void MockDirectoryInfo_CreationTime_ShouldReturnDefaultTimeForNonExisting var result = directoryInfo.CreationTime; - Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.UtcDateTime)); + Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.LocalDateTime)); } [Test] @@ -551,9 +551,9 @@ public void MockDirectoryInfo_LastAccessTime_ShouldReturnDefaultTimeForNonExisti var fileSystem = new MockFileSystem(); var directoryInfo = new MockDirectoryInfo(fileSystem, XFS.Path(@"c:\non\existing")); - var result = directoryInfo.LastAccessTimeUtc; + var result = directoryInfo.LastAccessTime; - Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.UtcDateTime)); + Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.LocalDateTime)); } [Test] @@ -562,9 +562,9 @@ public void MockDirectoryInfo_LastWriteTime_ShouldReturnDefaultTimeForNonExistin var fileSystem = new MockFileSystem(); var directoryInfo = new MockDirectoryInfo(fileSystem, XFS.Path(@"c:\non\existing")); - var result = directoryInfo.LastWriteTimeUtc; + var result = directoryInfo.LastWriteTime; - Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.UtcDateTime)); + Assert.That(result, Is.EqualTo(MockFileData.DefaultDateTimeOffset.LocalDateTime)); } [Test] diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs index 0ab2617e9..e115964ee 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs @@ -411,7 +411,7 @@ public void MockDirectory_GetFiles_ShouldFilterForFilesWithNoExtensionsAndFilter Assert.That(result, Is.EquivalentTo(expected)); } - private void ExecuteTimeAttributeTest(Action setter, Func getter) + private void ExecuteTimeAttributeTest(DateTime time, Action setter, Func getter) { string path = XFS.Path(@"c:\something\demo.txt"); var fileSystem = new MockFileSystem(new Dictionary @@ -420,7 +420,6 @@ private void ExecuteTimeAttributeTest(Action sett }); // Act - var time = new DateTime(2010, 6, 4, 13, 26, 42); setter(fileSystem, path, time); var result = getter(fileSystem, path); @@ -432,6 +431,7 @@ private void ExecuteTimeAttributeTest(Action sett public void MockDirectory_GetCreationTime_ShouldReturnCreationTimeFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.File.SetCreationTime(p, d), (fs, p) => fs.Directory.GetCreationTime(p)); } @@ -440,6 +440,7 @@ public void MockDirectory_GetCreationTime_ShouldReturnCreationTimeFromFile() public void MockDirectory_GetCreationTimeUtc_ShouldReturnCreationTimeUtcFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.File.SetCreationTimeUtc(p, d), (fs, p) => fs.Directory.GetCreationTimeUtc(p)); } @@ -448,6 +449,7 @@ public void MockDirectory_GetCreationTimeUtc_ShouldReturnCreationTimeUtcFromFile public void MockDirectory_GetLastAccessTime_ShouldReturnLastAccessTimeFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.File.SetLastAccessTime(p, d), (fs, p) => fs.Directory.GetLastAccessTime(p)); } @@ -456,6 +458,7 @@ public void MockDirectory_GetLastAccessTime_ShouldReturnLastAccessTimeFromFile() public void MockDirectory_GetLastAccessTimeUtc_ShouldReturnLastAccessTimeUtcFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.File.SetLastAccessTimeUtc(p, d), (fs, p) => fs.Directory.GetLastAccessTimeUtc(p)); } @@ -464,6 +467,7 @@ public void MockDirectory_GetLastAccessTimeUtc_ShouldReturnLastAccessTimeUtcFrom public void MockDirectory_GetLastWriteTime_ShouldReturnLastWriteTimeFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.File.SetLastWriteTime(p, d), (fs, p) => fs.Directory.GetLastWriteTime(p)); } @@ -472,6 +476,7 @@ public void MockDirectory_GetLastWriteTime_ShouldReturnLastWriteTimeFromFile() public void MockDirectory_GetLastWriteTimeUtc_ShouldReturnLastWriteTimeUtcFromFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.File.SetLastWriteTimeUtc(p, d), (fs, p) => fs.Directory.GetLastWriteTimeUtc(p)); } @@ -480,6 +485,7 @@ public void MockDirectory_GetLastWriteTimeUtc_ShouldReturnLastWriteTimeUtcFromFi public void MockDirectory_SetCreationTime_ShouldSetCreationTimeOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.Directory.SetCreationTime(p, d), (fs, p) => fs.File.GetCreationTime(p)); } @@ -488,6 +494,7 @@ public void MockDirectory_SetCreationTime_ShouldSetCreationTimeOnFile() public void MockDirectory_SetCreationTimeUtc_ShouldSetCreationTimeUtcOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.Directory.SetCreationTimeUtc(p, d), (fs, p) => fs.File.GetCreationTimeUtc(p)); } @@ -496,6 +503,7 @@ public void MockDirectory_SetCreationTimeUtc_ShouldSetCreationTimeUtcOnFile() public void MockDirectory_SetLastAccessTime_ShouldSetLastAccessTimeOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.Directory.SetLastAccessTime(p, d), (fs, p) => fs.File.GetLastAccessTime(p)); } @@ -504,6 +512,7 @@ public void MockDirectory_SetLastAccessTime_ShouldSetLastAccessTimeOnFile() public void MockDirectory_SetLastAccessTimeUtc_ShouldSetLastAccessTimeUtcOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.Directory.SetLastAccessTimeUtc(p, d), (fs, p) => fs.File.GetLastAccessTimeUtc(p)); } @@ -512,6 +521,7 @@ public void MockDirectory_SetLastAccessTimeUtc_ShouldSetLastAccessTimeUtcOnFile( public void MockDirectory_SetLastWriteTime_ShouldSetLastWriteTimeOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42), (fs, p, d) => fs.Directory.SetLastWriteTime(p, d), (fs, p) => fs.File.GetLastWriteTime(p)); } @@ -520,6 +530,7 @@ public void MockDirectory_SetLastWriteTime_ShouldSetLastWriteTimeOnFile() public void MockDirectory_SetLastWriteTimeUtc_ShouldSetLastWriteTimeUtcOnFile() { ExecuteTimeAttributeTest( + new DateTime(2010, 6, 4, 13, 26, 42, DateTimeKind.Utc), (fs, p, d) => fs.Directory.SetLastWriteTimeUtc(p, d), (fs, p) => fs.File.GetLastWriteTimeUtc(p)); } diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs index 0c56d480f..e9feb27ab 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileAdjustTimesTest.cs @@ -11,7 +11,7 @@ public class MockFileAdjustTimesTest [Test] public void MockFile_AfterAppendAllText_ShouldUpdateLastAccessAndLastWriteTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -19,9 +19,9 @@ public void MockFile_AfterAppendAllText_ShouldUpdateLastAccessAndLastWriteTime() fileSystem.MockTime(() => updateTime); fileSystem.File.AppendAllText("foo.txt", "xyz"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -31,7 +31,7 @@ public void MockFile_AfterAppendAllText_ShouldUpdateLastAccessAndLastWriteTime() [Test] public void MockFile_AfterCopy_ShouldUpdateCreationAndLastAccessTimeOfDestination() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -39,12 +39,12 @@ public void MockFile_AfterCopy_ShouldUpdateCreationAndLastAccessTimeOfDestinatio fileSystem.MockTime(() => updateTime); fileSystem.File.Copy("foo.txt", "bar.txt"); - var actualSourceCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualDestinationCreationTime = fileSystem.File.GetCreationTime("bar.txt"); - var actualSourceLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualDestinationLastAccessTime = fileSystem.File.GetLastAccessTime("bar.txt"); - var actualSourceLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); - var actualDestinationLastWriteTime = fileSystem.File.GetLastWriteTime("bar.txt"); + var actualSourceCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualDestinationCreationTime = fileSystem.File.GetCreationTimeUtc("bar.txt"); + var actualSourceLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualDestinationLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("bar.txt"); + var actualSourceLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); + var actualDestinationLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("bar.txt"); Assert.That(actualSourceCreationTime, Is.EqualTo(creationTime)); Assert.That(actualDestinationCreationTime, Is.EqualTo(updateTime)); @@ -57,7 +57,7 @@ public void MockFile_AfterCopy_ShouldUpdateCreationAndLastAccessTimeOfDestinatio [Test] public void MockFile_AfterMove_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -65,9 +65,9 @@ public void MockFile_AfterMove_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.Move("foo.txt", "bar.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("bar.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("bar.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("bar.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("bar.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("bar.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("bar.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -79,7 +79,7 @@ public void MockFile_AfterMove_ShouldUpdateLastAccessTime() [TestCase(FileMode.Append, FileAccess.ReadWrite)] public void MockFile_AfterOpen_WithWriteAccess_ShouldUpdateLastAccessAndLastWriteTime(FileMode fileMode, FileAccess fileAccess) { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -87,9 +87,9 @@ public void MockFile_AfterOpen_WithWriteAccess_ShouldUpdateLastAccessAndLastWrit fileSystem.MockTime(() => updateTime); fileSystem.File.Open("foo.txt", fileMode, fileAccess); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -101,7 +101,7 @@ public void MockFile_AfterOpen_WithWriteAccess_ShouldUpdateLastAccessAndLastWrit [TestCase(FileMode.Append, FileAccess.Read)] public void MockFile_AfterOpen_WithReadOnlyAccess_ShouldUpdateLastAccessTime(FileMode fileMode, FileAccess fileAccess) { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -109,9 +109,9 @@ public void MockFile_AfterOpen_WithReadOnlyAccess_ShouldUpdateLastAccessTime(Fil fileSystem.MockTime(() => updateTime); fileSystem.File.Open("foo.txt", fileMode, fileAccess); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -121,7 +121,7 @@ public void MockFile_AfterOpen_WithReadOnlyAccess_ShouldUpdateLastAccessTime(Fil [Test] public void MockFile_AfterReadAllBytes_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -129,9 +129,9 @@ public void MockFile_AfterReadAllBytes_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.ReadAllBytes("foo.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -141,7 +141,7 @@ public void MockFile_AfterReadAllBytes_ShouldUpdateLastAccessTime() [Test] public void MockFile_AfterReadAllLines_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -149,9 +149,9 @@ public void MockFile_AfterReadAllLines_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.ReadAllLines("foo.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -161,7 +161,7 @@ public void MockFile_AfterReadAllLines_ShouldUpdateLastAccessTime() [Test] public void MockFile_AfterReadAllText_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -169,9 +169,9 @@ public void MockFile_AfterReadAllText_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.ReadAllText("foo.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -181,7 +181,7 @@ public void MockFile_AfterReadAllText_ShouldUpdateLastAccessTime() [Test] public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -189,9 +189,9 @@ public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.SetAttributes("foo.txt", FileAttributes.Hidden); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -203,7 +203,7 @@ public void MockFile_AfterSetAttributes_ShouldUpdateLastAccessTime() [WindowsOnly(WindowsSpecifics.AccessControlLists)] public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -211,9 +211,9 @@ public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); fileSystem.File.SetAccessControl("foo.txt", new FileSecurity()); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -223,7 +223,7 @@ public void MockFile_AfterSetAccessControl_ShouldUpdateLastAccessTime() [Test] public void MockFile_AfterWriteAllBytes_ShouldUpdateLastAccessAndLastWriteTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -231,9 +231,9 @@ public void MockFile_AfterWriteAllBytes_ShouldUpdateLastAccessAndLastWriteTime() fileSystem.MockTime(() => updateTime); fileSystem.File.WriteAllBytes("foo.txt", Encoding.UTF8.GetBytes("xyz")); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -243,7 +243,7 @@ public void MockFile_AfterWriteAllBytes_ShouldUpdateLastAccessAndLastWriteTime() [Test] public void MockFile_AfterWriteAllText_ShouldUpdateLastAccessAndLastWriteTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -251,9 +251,9 @@ public void MockFile_AfterWriteAllText_ShouldUpdateLastAccessAndLastWriteTime() fileSystem.MockTime(() => updateTime); fileSystem.File.WriteAllText("foo.txt", "xyz"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -263,7 +263,7 @@ public void MockFile_AfterWriteAllText_ShouldUpdateLastAccessAndLastWriteTime() [Test] public void MockFileStream_OpenRead_ShouldUpdateLastAccessTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -271,9 +271,9 @@ public void MockFileStream_OpenRead_ShouldUpdateLastAccessTime() fileSystem.MockTime(() => updateTime); _ = fileSystem.File.OpenRead("foo.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); @@ -283,7 +283,7 @@ public void MockFileStream_OpenRead_ShouldUpdateLastAccessTime() [Test] public void MockFileStream_OpenWrite_ShouldUpdateLastAccessAndLastWriteTime() { - var creationTime = DateTime.Now.AddDays(10); + var creationTime = DateTime.UtcNow.AddDays(10); var updateTime = creationTime.AddDays(10); var fileSystem = new MockFileSystem() .MockTime(() => creationTime); @@ -291,9 +291,9 @@ public void MockFileStream_OpenWrite_ShouldUpdateLastAccessAndLastWriteTime() fileSystem.MockTime(() => updateTime); _ = fileSystem.File.OpenWrite("foo.txt"); - var actualCreationTime = fileSystem.File.GetCreationTime("foo.txt"); - var actualLastAccessTime = fileSystem.File.GetLastAccessTime("foo.txt"); - var actualLastWriteTime = fileSystem.File.GetLastWriteTime("foo.txt"); + var actualCreationTime = fileSystem.File.GetCreationTimeUtc("foo.txt"); + var actualLastAccessTime = fileSystem.File.GetLastAccessTimeUtc("foo.txt"); + var actualLastWriteTime = fileSystem.File.GetLastWriteTimeUtc("foo.txt"); Assert.That(actualCreationTime, Is.EqualTo(creationTime)); Assert.That(actualLastAccessTime, Is.EqualTo(updateTime)); diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs index fbaa47307..0d0832f3e 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs @@ -180,7 +180,7 @@ public void MockFileInfo_CreationTime_ShouldReturnDefaultTimeForNonExistingFile( var result = fileInfo.CreationTime; - Assert.AreEqual(MockFileData.DefaultDateTimeOffset.DateTime, result); + Assert.AreEqual(MockFileData.DefaultDateTimeOffset.LocalDateTime, result); } [Test] @@ -400,7 +400,7 @@ public void MockFileInfo_LastWriteTime_ShouldReturnDefaultTimeForNonExistingFile var result = fileInfo.LastWriteTime; - Assert.AreEqual(MockFileData.DefaultDateTimeOffset.DateTime, result); + Assert.AreEqual(MockFileData.DefaultDateTimeOffset.LocalDateTime, result); } [Test] @@ -442,9 +442,9 @@ public void MockFileInfo_LastWriteTimeUtc_ShouldSetLastWriteTimeUtcOfFileInMemor var fileInfo = new MockFileInfo(fileSystem, XFS.Path(@"c:\a.txt")); var newUtcTime = DateTime.UtcNow; - fileInfo.LastWriteTime = newUtcTime; + fileInfo.LastWriteTimeUtc = newUtcTime; - Assert.AreEqual(newUtcTime, fileInfo.LastWriteTime); + Assert.AreEqual(newUtcTime, fileInfo.LastWriteTimeUtc); } [Test] From e3644d47678bca802eb21666052f0251316e3e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 2 Sep 2022 13:46:09 +0200 Subject: [PATCH 06/12] Fix time adjustments when creating streams according to the behaviour of a real file system --- .../MockFileStream.cs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index ed7333a8d..384e8314d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -34,7 +34,8 @@ public MockFileStream( fileData = mockFileDataAccessor.GetFile(path); fileData.CheckFileAccess(path, access); - mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime); + var timeAdjustments = GetTimeAdjustmentsForFileStreamWhenFileExists(mode, access); + mockFileDataAccessor.AdjustTimes(fileData, timeAdjustments); var existingContents = fileData.Contents; var keepExistingContents = existingContents?.Length > 0 && @@ -140,5 +141,30 @@ private void OnClose() mockFileDataAccessor.FileInfo.FromFileName(path).Encrypt(); } } + + private TimeAdjustments GetTimeAdjustmentsForFileStreamWhenFileExists(FileMode mode, FileAccess access) + { + switch (mode) + { + case FileMode.Append: + case FileMode.CreateNew: + if (access != FileAccess.Write) + { + return TimeAdjustments.LastAccessTime; + } + return TimeAdjustments.None; + case FileMode.Create: + case FileMode.Truncate: + if (access != FileAccess.Read) + { + return TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime; + } + return TimeAdjustments.LastAccessTime; + case FileMode.Open: + case FileMode.OpenOrCreate: + default: + return TimeAdjustments.None; + } + } } } \ No newline at end of file From 03d6d879567f9e28fad7ff02d7a4bff2aa920557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 2 Sep 2022 13:46:29 +0200 Subject: [PATCH 07/12] Implement review findings from @siprbaum --- src/System.IO.Abstractions.TestingHelpers/MockFile.cs | 2 +- src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs index e36068aaf..ed534ae2c 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -542,7 +542,7 @@ private Stream OpenInternal( var mockFileData = mockFileDataAccessor.GetFile(path); mockFileData.CheckFileAccess(path, access); var timeAdjustments = TimeAdjustments.LastAccessTime; - if (access != FileAccess.Read) + if (access.HasFlag(FileAccess.Write)) { timeAdjustments |= TimeAdjustments.LastWriteTime; } diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index 4a886b21e..e6b80b80f 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -49,7 +49,10 @@ public class MockFileData /// private MockFileData() { - // empty + var now = DateTime.UtcNow; + LastWriteTime = now; + LastAccessTime = now; + CreationTime = now; } /// From 932c5d6b4a587175469645ee55578dd7c6eaa529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 2 Sep 2022 13:54:03 +0200 Subject: [PATCH 08/12] Use Flags to detect the correct file access --- src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index 384e8314d..64bc5f4e3 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -148,14 +148,14 @@ private TimeAdjustments GetTimeAdjustmentsForFileStreamWhenFileExists(FileMode m { case FileMode.Append: case FileMode.CreateNew: - if (access != FileAccess.Write) + if (access.HasFlag(FileAccess.Read)) { return TimeAdjustments.LastAccessTime; } return TimeAdjustments.None; case FileMode.Create: case FileMode.Truncate: - if (access != FileAccess.Read) + if (access.HasFlag(FileAccess.Write)) { return TimeAdjustments.LastAccessTime | TimeAdjustments.LastWriteTime; } From 815bf817f9c2b982c4a1bfa7a2291d8bed2eb9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 10 Sep 2022 14:51:16 +0200 Subject: [PATCH 09/12] Initialize times in all constructors of MockFileData --- src/System.IO.Abstractions.TestingHelpers/MockFileData.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs index e6b80b80f..1c59dba63 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileData.cs @@ -81,6 +81,7 @@ public MockFileData(string textContents, Encoding encoding) /// The actual content. /// Thrown if is . public MockFileData(byte[] contents) + : this() { Contents = contents ?? throw new ArgumentNullException(nameof(contents)); } From de88c79e1213d0eff0b6f70cbf03b35bf3ff9279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 13 Sep 2022 13:27:52 +0200 Subject: [PATCH 10/12] Update src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs Co-authored-by: Florian Greinacher --- src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index 8c4226e08..f8d78b74d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -1,4 +1,4 @@ - using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.Serialization; From 477d8caa6f346c46cb8f8b29bdbfd403194cbffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Tue, 13 Sep 2022 13:27:57 +0200 Subject: [PATCH 11/12] Update src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs Co-authored-by: Florian Greinacher --- src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs b/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs index 73f814e36..321de416e 100644 --- a/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs +++ b/src/System.IO.Abstractions.TestingHelpers/TimeAdjustments.cs @@ -27,4 +27,4 @@ public enum TimeAdjustments /// All = ~0 } -} \ No newline at end of file +} From f0bc24e6d1a3a2435a628c03d44513f2e56e233d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 16 Sep 2022 08:36:47 +0200 Subject: [PATCH 12/12] Adjust DateTimeKind.Unspecified --- .../MockFileInfo.cs | 23 +++-- .../MockFileInfoTests.cs | 96 +++++++++++++++++++ 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 4a5d8fa16..96096a95d 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -1,6 +1,5 @@ using System.Runtime.Versioning; using System.Security.AccessControl; -using System.Text; namespace System.IO.Abstractions.TestingHelpers { @@ -65,7 +64,7 @@ public override DateTime CreationTime set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.CreationTime = value; + mockFileData.CreationTime = AdjustUnspecifiedKind(value, DateTimeKind.Local); } } @@ -80,7 +79,7 @@ public override DateTime CreationTimeUtc set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.CreationTime = value; + mockFileData.CreationTime = AdjustUnspecifiedKind(value, DateTimeKind.Utc); } } @@ -122,7 +121,7 @@ public override DateTime LastAccessTime set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.LastAccessTime = value; + mockFileData.LastAccessTime = AdjustUnspecifiedKind(value, DateTimeKind.Local); } } @@ -137,7 +136,7 @@ public override DateTime LastAccessTimeUtc set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.LastAccessTime = value; + mockFileData.LastAccessTime = AdjustUnspecifiedKind(value, DateTimeKind.Utc); } } @@ -152,7 +151,7 @@ public override DateTime LastWriteTime set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.LastWriteTime = value; + mockFileData.LastWriteTime = AdjustUnspecifiedKind(value, DateTimeKind.Local); } } @@ -167,7 +166,7 @@ public override DateTime LastWriteTimeUtc set { var mockFileData = GetMockFileDataForWrite(); - mockFileData.LastWriteTime = value; + mockFileData.LastWriteTime = AdjustUnspecifiedKind(value, DateTimeKind.Utc); } } @@ -381,6 +380,16 @@ public override string ToString() return originalPath; } + private static DateTime AdjustUnspecifiedKind(DateTime time, DateTimeKind fallbackKind) + { + if (time.Kind == DateTimeKind.Unspecified) + { + return DateTime.SpecifyKind(time, fallbackKind); + } + + return time; + } + private MockFileData GetMockFileDataForRead() { if (refreshOnNextRead) diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs index 0d0832f3e..2c413ef57 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockFileInfoTests.cs @@ -879,5 +879,101 @@ public void MockFileInfo_Delete_ShouldThrowIfFileAccessShareHasNoWriteOrDeleteAc Assert.Throws(typeof(System.IO.IOException), () => fi.Delete()); } + + [Test] + public void MockFileInfo_LastAccessTimeUtcWithUnspecifiedDateTimeKind_ShouldSetLastAccessTimeUtcOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + LastAccessTimeUtc = date + }; + + Assert.AreEqual(date, fileInfo.LastAccessTimeUtc); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.LastAccessTimeUtc); + } + + [Test] + public void MockFileInfo_LastAccessTimeWithUnspecifiedDateTimeKind_ShouldSetLastAccessTimeOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + LastAccessTime = date + }; + + Assert.AreEqual(date, fileInfo.LastAccessTime); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.LastAccessTime); + } + + [Test] + public void MockFileInfo_CreationTimeUtcWithUnspecifiedDateTimeKind_ShouldSetCreationTimeUtcOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + CreationTimeUtc = date + }; + + Assert.AreEqual(date, fileInfo.CreationTimeUtc); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.CreationTimeUtc); + } + + [Test] + public void MockFileInfo_CreationTimeWithUnspecifiedDateTimeKind_ShouldSetCreationTimeOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + CreationTime = date + }; + + Assert.AreEqual(date, fileInfo.CreationTime); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.CreationTime); + } + + [Test] + public void MockFileInfo_LastWriteTimeUtcWithUnspecifiedDateTimeKind_ShouldSetLastWriteTimeUtcOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + LastWriteTimeUtc = date + }; + + Assert.AreEqual(date, fileInfo.LastWriteTimeUtc); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.LastWriteTimeUtc); + } + + [Test] + public void MockFileInfo_LastWriteTimeWithUnspecifiedDateTimeKind_ShouldSetLastWriteTimeOfFileInFileSystem() + { + var date = DateTime.SpecifyKind(DateTime.Now.AddHours(-4), DateTimeKind.Unspecified); + var fileSystem = new MockFileSystem(); + fileSystem.Directory.CreateDirectory(@"c:\test"); + fileSystem.File.WriteAllText(@"c:\test\a.txt", "Demo text content"); + var fileInfo = new MockFileInfo(fileSystem, @"c:\test\a.txt") + { + LastWriteTime = date + }; + + Assert.AreEqual(date, fileInfo.LastWriteTime); + Assert.AreNotEqual(DateTimeKind.Unspecified, fileInfo.LastWriteTime); + } } }