From 18d37a8f3ccf143f3ce436b08a32731cefbfee9c Mon Sep 17 00:00:00 2001 From: Robert Dailey Date: Thu, 30 Jun 2022 18:43:57 -0500 Subject: [PATCH] Better cache invalidation in MockDirectoryInfo When invoking the `Create()` and `Delete()` methods on `MockDirectoryInfo`, the `Exists` property should intrinsically invoke `Refresh()` the next time it is called. This is necessary to prevent returning stale state about the directory after those operations. Additional test cases have been added for `MoveTo()` as well, to ensure it also not returning stale state. For context, this change was motivated by PR #828 where similar issues were solved in `MockFileInfo`. --- .../MockDirectoryInfo.cs | 4 + .../MockDirectoryInfoTests.cs | 73 ++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index de8d52993..eb70a3a10 100644 --- a/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -42,6 +42,7 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire public override void Delete() { mockFileDataAccessor.Directory.Delete(directoryPath); + refreshOnNextRead = true; } /// @@ -160,12 +161,14 @@ public override string Name public override void Create() { mockFileDataAccessor.Directory.CreateDirectory(FullName); + refreshOnNextRead = true; } /// public override void Create(DirectorySecurity directorySecurity) { mockFileDataAccessor.Directory.CreateDirectory(FullName, directorySecurity); + refreshOnNextRead = true; } /// @@ -178,6 +181,7 @@ public override IDirectoryInfo CreateSubdirectory(string path) public override void Delete(bool recursive) { mockFileDataAccessor.Directory.Delete(directoryPath, recursive); + refreshOnNextRead = true; } /// diff --git a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs index 9ffd0cb58..d347b633f 100644 --- a/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs +++ b/tests/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryInfoTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Security.AccessControl; using NUnit.Framework; namespace System.IO.Abstractions.TestingHelpers.Tests @@ -444,6 +445,76 @@ public void MockDirectoryInfo_Exists_ShouldUpdateCachedDataOnRefresh() Assert.IsTrue(directoryInfo.Exists); } + [Test] + public void Directory_exists_after_creation() + { + // Arrange + var fileSystem = new MockFileSystem(); + var directoryInfo = fileSystem.DirectoryInfo.FromDirectoryName(XFS.Path(@"c:\abc")); + + // Act + directoryInfo.Create(); + + // Assert + Assert.IsTrue(directoryInfo.Exists); + } + + [Test, WindowsOnly(WindowsSpecifics.AccessControlLists)] + public void Directory_exists_after_creation_with_security() + { + // Arrange + var fileSystem = new MockFileSystem(); + var directoryInfo = fileSystem.DirectoryInfo.FromDirectoryName(XFS.Path(@"c:\abc")); + + // Act + directoryInfo.Create(new DirectorySecurity()); + + // Assert + Assert.IsTrue(directoryInfo.Exists); + } + + [Test] + public void Directory_does_not_exist_after_delete() + { + // Arrange + var fileSystem = new MockFileSystem(); + var directoryInfo = fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\abc")); + + // Act + directoryInfo.Delete(); + + // Assert + Assert.IsFalse(directoryInfo.Exists); + } + + [Test] + public void Directory_does_not_exist_after_recursive_delete() + { + // Arrange + var fileSystem = new MockFileSystem(); + var directoryInfo = fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\abc")); + + // Act + directoryInfo.Delete(true); + + // Assert + Assert.IsFalse(directoryInfo.Exists); + } + + [Test] + public void Directory_still_exists_after_move() + { + // Arrange + var fileSystem = new MockFileSystem(); + var directoryInfo = fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\abc")); + + // Act + directoryInfo.MoveTo(XFS.Path(@"c:\abc2")); + + // Assert + Assert.IsTrue(directoryInfo.Exists); + } + [Test] public void MockDirectoryInfo_LastAccessTime_ShouldReflectChangedValue() { @@ -584,4 +655,4 @@ public void MockDirectoryInfo_LastWriteTimeUtc_SetterShouldThrowDirectoryNotFoun } } -} \ No newline at end of file +}