diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs index d6c7df3e7..d2e4aa601 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs @@ -199,6 +199,22 @@ public IEnumerable EnumerateLocations( throw ExceptionFactory.DirectoryNotFound(location.FullPath); } + return EnumerateLocationsImpl(location, type, requestParentAccess, searchPattern, + enumerationOptions, parentContainer); + } + + /// + /// Internal implementation of location enumeration that uses yield return. + /// This method contains the actual enumeration logic and is only called after validation passes. + /// + private IEnumerable EnumerateLocationsImpl( + IStorageLocation location, + FileSystemTypes type, + bool requestParentAccess, + string searchPattern, + EnumerationOptions? enumerationOptions, + IStorageContainer parentContainer) + { IDisposable parentAccess = new NoOpDisposable(); if (requestParentAccess) { diff --git a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryInfoStatisticsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryInfoStatisticsTests.cs index 331f2ce96..6bb94e644 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryInfoStatisticsTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryInfoStatisticsTests.cs @@ -80,6 +80,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateDirectories_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); sut.DirectoryInfo.New("foo").EnumerateDirectories(); @@ -93,6 +94,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateDirectories_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -109,6 +111,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateDirectories_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -124,6 +127,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateDirectories_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; sut.DirectoryInfo.New("foo").EnumerateDirectories(searchPattern); @@ -138,6 +142,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFiles_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); sut.DirectoryInfo.New("foo").EnumerateFiles(); @@ -151,6 +156,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFiles_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -167,6 +173,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFiles_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -182,6 +189,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFiles_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; sut.DirectoryInfo.New("foo").EnumerateFiles(searchPattern); @@ -196,6 +204,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFileSystemInfos_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); sut.DirectoryInfo.New("foo").EnumerateFileSystemInfos(); @@ -209,6 +218,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFileSystemInfos_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -225,6 +235,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFileSystemInfos_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -240,6 +251,7 @@ await That(sut.Statistics.DirectoryInfo["foo"]) public async Task Method_EnumerateFileSystemInfos_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string searchPattern = "foo"; sut.DirectoryInfo.New("foo").EnumerateFileSystemInfos(searchPattern); diff --git a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryStatisticsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryStatisticsTests.cs index 2fe6338c5..a84f1fc7c 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryStatisticsTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/DirectoryStatisticsTests.cs @@ -103,6 +103,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall(nameof(IDirectory.De public async Task Method_EnumerateDirectories_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; sut.Directory.EnumerateDirectories(path); @@ -118,6 +119,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateDirectories_String_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -135,6 +137,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateDirectories_String_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -151,6 +154,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateDirectories_String_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; @@ -166,6 +170,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFiles_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; sut.Directory.EnumerateFiles(path); @@ -181,6 +186,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFiles_String_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -197,6 +203,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall(nameof(IDirectory.En public async Task Method_EnumerateFiles_String_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -213,6 +220,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFiles_String_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; @@ -228,6 +236,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFileSystemEntries_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; sut.Directory.EnumerateFileSystemEntries(path); @@ -243,6 +252,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFileSystemEntries_String_String_EnumerationOptions_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; EnumerationOptions enumerationOptions = new(); @@ -261,6 +271,7 @@ public async Task Method_EnumerateFileSystemEntries_String_String_SearchOption_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; SearchOption searchOption = SearchOption.AllDirectories; @@ -277,6 +288,7 @@ await That(sut.Statistics.Directory).OnlyContainsMethodCall( public async Task Method_EnumerateFileSystemEntries_String_String_ShouldRegisterCall() { MockFileSystem sut = new(); + sut.Initialize().WithSubdirectory("foo"); string path = "foo"; string searchPattern = "foo"; diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs index eff650e4d..b6735390a 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs @@ -41,6 +41,23 @@ await That(Act).Throws() await That(FileSystem.Directory.Exists(path)).IsFalse(); } + [Theory] + [AutoData] + public async Task + EnumerateDirectories_MissingDirectory_ShouldThrowDirectoryNotFoundExceptionImmediately( + string path) + { + string expectedPath = FileSystem.Path.Combine(BasePath, path); + + void Act() => + _ = FileSystem.Directory.EnumerateDirectories(path); + + await That(Act).Throws() + .WithMessageContaining($"'{expectedPath}'").And + .WithHResult(-2147024893); + await That(FileSystem.Directory.Exists(path)).IsFalse(); + } + [Fact] public async Task EnumerateDirectories_RelativePath_ShouldNotIncludeTrailingSlash() { diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFileSystemInfosTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFileSystemInfosTests.cs index 90c9e7953..6ebf8fe77 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFileSystemInfosTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFileSystemInfosTests.cs @@ -28,6 +28,23 @@ await That(Act).Throws() await That(FileSystem.Directory.Exists(path)).IsFalse(); } + [Theory] + [AutoData] + public async Task + EnumerateFileSystemEntries_MissingDirectory_ShouldThrowDirectoryNotFoundExceptionImmediately( + string path) + { + string expectedPath = FileSystem.Path.Combine(BasePath, path); + + void Act() => + _ = FileSystem.Directory.EnumerateFileSystemEntries(path); + + await That(Act).Throws() + .WithMessageContaining($"'{expectedPath}'").And + .WithHResult(-2147024893); + await That(FileSystem.Directory.Exists(path)).IsFalse(); + } + [Theory] [AutoData] public async Task diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFilesTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFilesTests.cs index 580008c0f..3fe74f4fe 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFilesTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateFilesTests.cs @@ -25,6 +25,23 @@ await That(Act).Throws() await That(FileSystem.Directory.Exists(path)).IsFalse(); } + [Theory] + [AutoData] + public async Task + EnumerateFiles_MissingDirectory_ShouldThrowDirectoryNotFoundExceptionImmediately( + string path) + { + string expectedPath = FileSystem.Path.Combine(BasePath, path); + + void Act() => + _ = FileSystem.Directory.EnumerateFiles(path); + + await That(Act).Throws() + .WithMessageContaining($"'{expectedPath}'").And + .WithHResult(-2147024893); + await That(FileSystem.Directory.Exists(path)).IsFalse(); + } + [Theory] [AutoData] public async Task