From 5da01b6345a1f26f081473d2ce7a54d1c77d82a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Fri, 1 Sep 2023 11:36:15 +0200 Subject: [PATCH] refactor: simplify assertion names (#44) Simplify and consolidate the assertion names, e.g. - `HasSingleDirectory` -> `HasDirectory` - `HasDirectoriesMatching` -> `HasDirectories` - `HasSingleFile` -> `HasFile` - `HasFilesMatching` -> `HasFiles` --- README.md | 2 +- .../DirectoryAssertions.cs | 84 ++++---- .../DirectoryInfoAssertions.cs | 26 +-- .../DirectoryAssertionsTests.cs | 200 +++++++++--------- .../DirectoryInfoAssertionsTests.cs | 144 ++++++------- 5 files changed, 228 insertions(+), 228 deletions(-) diff --git a/README.md b/README.md index 938c659..fb03cda 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ This library is an extension to [FluentAssertions](https://github.com/fluentasse or ```csharp IDirectoryInfo directoryInfo = fileSystem.DirectoryInfo.New("."); - directoryInfo.Should().HaveSingleDirectory("foo"); + directoryInfo.Should().HaveDirectory("foo"); ``` 3. Verify, that the file "foo.txt" has text content "bar": diff --git a/Source/Testably.Abstractions.FluentAssertions/DirectoryAssertions.cs b/Source/Testably.Abstractions.FluentAssertions/DirectoryAssertions.cs index 9de56b5..25de33f 100644 --- a/Source/Testably.Abstractions.FluentAssertions/DirectoryAssertions.cs +++ b/Source/Testably.Abstractions.FluentAssertions/DirectoryAssertions.cs @@ -20,9 +20,9 @@ internal DirectoryAssertions(IDirectoryInfo? instance) /// Asserts that the current directory has at least directories which match the /// . /// - public AndConstraint HasDirectoriesMatching( - string searchPattern = "*", - int minimumCount = 1, + public AndConstraint HasDirectories( + string searchPattern, + int minimumCount, string because = "", params object[] becauseArgs) { @@ -52,54 +52,45 @@ public AndConstraint HasDirectoriesMatching( /// /// Asserts that the current directory has at least one directory which matches the . /// - public AndConstraint HasDirectoryMatching( + public AndConstraint HasDirectories( string searchPattern = "*", string because = "", params object[] becauseArgs) - => HasDirectoriesMatching(searchPattern, 1, because, becauseArgs); + => HasDirectories(searchPattern, 1, because, becauseArgs); /// - /// Asserts that the current directory has at least one file which matches the . + /// Asserts that the directory contains exactly one directory matching the given . /// - public AndConstraint HasFileMatching( + public AndWhichConstraint HasDirectory( string searchPattern = "*", string because = "", params object[] becauseArgs) - => HasFilesMatching(searchPattern, 1, because, becauseArgs); - - /// - /// Asserts that the current directory has at least files which match the - /// . - /// - public AndConstraint HasFilesMatching( - string searchPattern = "*", - int minimumCount = 1, - string because = "", - params object[] becauseArgs) { Execute.Assertion .WithDefaultIdentifier(Identifier) .BecauseOf(because, becauseArgs) .ForCondition(Subject != null) .FailWith( - "You can't assert a directory having files if the DirectoryInfo is null.") + "You can't assert a directory having a given directory if it is null.") .Then .ForCondition(!string.IsNullOrEmpty(searchPattern)) .FailWith( - "You can't assert a directory having files if you don't pass a proper search pattern.") + "You can't assert a directory having a given directory if you don't pass a proper search pattern.") .Then .Given(() => Subject!) .ForCondition(directoryInfo - => directoryInfo.GetFiles(searchPattern).Length >= minimumCount) + => directoryInfo.GetDirectories(searchPattern).Length == 1) .FailWith( - $"Expected {{context}} {{1}} to contain at least {(minimumCount == 1 ? "one file" : $"{minimumCount} files")} matching {{0}}{{reason}}, but {(minimumCount == 1 ? "none was" : "only {2} were")} found.", + "Expected {context} {1} to contain exactly one directory matching {0}{reason}, but found {2}.", _ => searchPattern, directoryInfo => directoryInfo.Name, - directoryInfo => directoryInfo.GetFiles(searchPattern).Length); + directoryInfo => directoryInfo.GetDirectories(searchPattern).Length); - return new AndConstraint(this); + return new AndWhichConstraint( + new FileSystemAssertions(Subject!.FileSystem), + new DirectoryAssertions(Subject!.GetDirectories(searchPattern).Single())); } /// - /// Asserts that the directory contains exactly one directory matching the given . + /// Asserts that the directory contains exactly one file matching the given . /// - public AndWhichConstraint HasSingleDirectoryMatching( + public AndWhichConstraint HasFile( string searchPattern = "*", string because = "", params object[] becauseArgs) { Execute.Assertion @@ -107,54 +98,63 @@ public AndWhichConstraint HasSingleDi .BecauseOf(because, becauseArgs) .ForCondition(Subject != null) .FailWith( - "You can't assert a directory having a given directory if it is null.") + "You can't assert a directory having a given file if it is null.") .Then .ForCondition(!string.IsNullOrEmpty(searchPattern)) .FailWith( - "You can't assert a directory having a given directory if you don't pass a proper search pattern.") + "You can't assert a directory having a given file if you don't pass a proper search pattern.") .Then .Given(() => Subject!) .ForCondition(directoryInfo - => directoryInfo.GetDirectories(searchPattern).Length == 1) + => directoryInfo.GetFiles(searchPattern).Length == 1) .FailWith( - "Expected {context} {1} to contain exactly one directory matching {0}{reason}, but found {2}.", + "Expected {context} {1} to contain exactly one file matching {0}{reason}, but found {2}.", _ => searchPattern, directoryInfo => directoryInfo.Name, - directoryInfo => directoryInfo.GetDirectories(searchPattern).Length); + directoryInfo => directoryInfo.GetFiles(searchPattern).Length); - return new AndWhichConstraint( + return new AndWhichConstraint( new FileSystemAssertions(Subject!.FileSystem), - new DirectoryAssertions(Subject!.GetDirectories(searchPattern).Single())); + new FileAssertions(Subject!.GetFiles(searchPattern).Single())); } /// - /// Asserts that the directory contains exactly one file matching the given . + /// Asserts that the current directory has at least one file which matches the . /// - public AndWhichConstraint HasSingleFileMatching( + public AndConstraint HasFiles( string searchPattern = "*", string because = "", params object[] becauseArgs) + => HasFiles(searchPattern, 1, because, becauseArgs); + + /// + /// Asserts that the current directory has at least files which match the + /// . + /// + public AndConstraint HasFiles( + string searchPattern, + int minimumCount, + string because = "", + params object[] becauseArgs) { Execute.Assertion .WithDefaultIdentifier(Identifier) .BecauseOf(because, becauseArgs) .ForCondition(Subject != null) .FailWith( - "You can't assert a directory having a given file if it is null.") + "You can't assert a directory having files if the DirectoryInfo is null.") .Then .ForCondition(!string.IsNullOrEmpty(searchPattern)) .FailWith( - "You can't assert a directory having a given file if you don't pass a proper search pattern.") + "You can't assert a directory having files if you don't pass a proper search pattern.") .Then .Given(() => Subject!) .ForCondition(directoryInfo - => directoryInfo.GetFiles(searchPattern).Length == 1) + => directoryInfo.GetFiles(searchPattern).Length >= minimumCount) .FailWith( - "Expected {context} {1} to contain exactly one file matching {0}{reason}, but found {2}.", + $"Expected {{context}} {{1}} to contain at least {(minimumCount == 1 ? "one file" : $"{minimumCount} files")} matching {{0}}{{reason}}, but {(minimumCount == 1 ? "none was" : "only {2} were")} found.", _ => searchPattern, directoryInfo => directoryInfo.Name, directoryInfo => directoryInfo.GetFiles(searchPattern).Length); - return new AndWhichConstraint( - new FileSystemAssertions(Subject!.FileSystem), - new FileAssertions(Subject!.GetFiles(searchPattern).Single())); + return new AndConstraint(this); } } diff --git a/Source/Testably.Abstractions.FluentAssertions/DirectoryInfoAssertions.cs b/Source/Testably.Abstractions.FluentAssertions/DirectoryInfoAssertions.cs index eb0d9ae..1fb7c5a 100644 --- a/Source/Testably.Abstractions.FluentAssertions/DirectoryInfoAssertions.cs +++ b/Source/Testably.Abstractions.FluentAssertions/DirectoryInfoAssertions.cs @@ -17,40 +17,40 @@ internal DirectoryInfoAssertions(IDirectoryInfo? instance) /// /// Asserts that the current directory has at least one directory which matches the . /// - public AndConstraint HaveDirectoryMatching( + public AndConstraint HaveDirectories( string searchPattern = "*", string because = "", params object[] becauseArgs) { - new DirectoryAssertions(Subject).HasDirectoryMatching(searchPattern, because, becauseArgs); + new DirectoryAssertions(Subject).HasDirectories(searchPattern, because, becauseArgs); return new AndConstraint(this); } /// - /// Asserts that the current directory has at least one file which matches the . + /// Asserts that the directory contains exactly one directory matching the given . /// - public AndConstraint HaveFileMatching( + public AndWhichConstraint HaveDirectory( string searchPattern = "*", string because = "", params object[] becauseArgs) { - new DirectoryAssertions(Subject).HasFileMatching(searchPattern, because, becauseArgs); - return new AndConstraint(this); + return new DirectoryAssertions(Subject).HasDirectory(searchPattern, because, + becauseArgs); } /// - /// Asserts that the directory contains exactly one directory matching the given . + /// Asserts that the directory contains exactly one file matching the given . /// - public AndWhichConstraint HaveSingleDirectory( + public AndWhichConstraint HaveFile( string searchPattern = "*", string because = "", params object[] becauseArgs) { - return new DirectoryAssertions(Subject).HasSingleDirectoryMatching(searchPattern, because, + return new DirectoryAssertions(Subject).HasFile(searchPattern, because, becauseArgs); } /// - /// Asserts that the directory contains exactly one file matching the given . + /// Asserts that the current directory has at least one file which matches the . /// - public AndWhichConstraint HaveSingleFile( + public AndConstraint HaveFiles( string searchPattern = "*", string because = "", params object[] becauseArgs) { - return new DirectoryAssertions(Subject).HasSingleFileMatching(searchPattern, because, - becauseArgs); + new DirectoryAssertions(Subject).HasFiles(searchPattern, because, becauseArgs); + return new AndConstraint(this); } } diff --git a/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryAssertionsTests.cs b/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryAssertionsTests.cs index a99e119..e750cfb 100644 --- a/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryAssertionsTests.cs +++ b/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryAssertionsTests.cs @@ -8,42 +8,10 @@ namespace Testably.Abstractions.FluentAssertions.Tests; public class DirectoryAssertionsTests { - [Theory] - [InlineAutoData(3, 5)] - [InlineAutoData(1, 2)] - public void HasDirectoriesMatching_WithoutTooLittleDirectories_ShouldThrow( - int matchingCount, - int expectedCount, - string directoryName, - string directoryNamePrefix, - string because) - { - MockFileSystem fileSystem = new(); - fileSystem.Initialize() - .WithSubdirectory(directoryName); - for (int i = 0; i < matchingCount; i++) - { - fileSystem.Directory.CreateDirectory( - fileSystem.Path.Combine(directoryName, $"{directoryNamePrefix}-{i}")); - } - - DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; - - Exception? exception = Record.Exception(() => - { - sut.HasDirectoriesMatching($"{directoryNamePrefix}*", expectedCount, because); - }); - - exception.Should().NotBeNull(); - exception!.Message.Should() - .Be( - $"Expected directory \"{directoryName}\" to contain at least {expectedCount} directories matching \"{directoryNamePrefix}*\" {because}, but only {matchingCount} were found."); - } - [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HasDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, + public void HasDirectories_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, string because) { MockFileSystem fileSystem = new(); @@ -53,7 +21,7 @@ public void HasDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? invali Exception? exception = Record.Exception(() => { - sut.HasDirectoryMatching(invalidDirectoryName!, because); + sut.HasDirectories(invalidDirectoryName!, because); }); exception.Should().NotBeNull(); @@ -63,7 +31,7 @@ public void HasDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? invali [Theory] [AutoData] - public void HasDirectoryMatching_WithMatchingDirectory_ShouldNotThrow( + public void HasDirectories_WithMatchingDirectory_ShouldNotThrow( string directoryName, string subdirectoryName) { @@ -73,12 +41,12 @@ public void HasDirectoryMatching_WithMatchingDirectory_ShouldNotThrow( .WithSubdirectory(subdirectoryName)); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; - sut.HasDirectoryMatching(subdirectoryName); + sut.HasDirectories(subdirectoryName); } [Theory] [AutoData] - public void HasDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( + public void HasDirectories_WithoutMatchingDirectory_ShouldThrow( string directoryName, string subdirectoryName, string because) @@ -91,7 +59,7 @@ public void HasDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( Exception? exception = Record.Exception(() => { - sut.HasDirectoryMatching(subdirectoryName, because); + sut.HasDirectories(subdirectoryName, because); }); exception.Should().NotBeNull(); @@ -100,10 +68,44 @@ public void HasDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( $"Expected directory \"{directoryName}\" to contain at least one directory matching \"{subdirectoryName}\" {because}, but none was found."); } + [Theory] + [InlineAutoData(3, 5)] + [InlineAutoData(1, 2)] + public void HasDirectories_WithoutTooLittleDirectories_ShouldThrow( + int matchingCount, + int expectedCount, + string directoryName, + string directoryNamePrefix, + string because) + { + MockFileSystem fileSystem = new(); + fileSystem.Initialize() + .WithSubdirectory(directoryName); + for (int i = 0; i < matchingCount; i++) + { + fileSystem.Directory.CreateDirectory( + fileSystem.Path.Combine(directoryName, $"{directoryNamePrefix}-{i}")); + } + + DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; + + Exception? exception = Record.Exception(() => + { + sut.HasDirectories($"{directoryNamePrefix}*", expectedCount, because); + }); + + exception.Should().NotBeNull(); + exception!.Message.Should() + .Be( + $"Expected directory \"{directoryName}\" to contain at least {expectedCount} directories matching \"{directoryNamePrefix}*\" {because}, but only {matchingCount} were found."); + } + [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HasFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName, string because) + public void HasDirectory_InvalidDirectoryName_ShouldThrow( + string? invalidDirectoryName, + string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() @@ -112,7 +114,7 @@ public void HasFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName, Exception? exception = Record.Exception(() => { - sut.HasFileMatching(invalidFileName!, because); + sut.HasDirectory(invalidDirectoryName!, because); }); exception.Should().NotBeNull(); @@ -122,81 +124,72 @@ public void HasFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName, [Theory] [AutoData] - public void HasFileMatching_WithMatchingFile_ShouldNotThrow( + public void HasDirectory_WithMatchingDirectory_ShouldNotThrow( string directoryName, - string fileName) + string subdirectoryName) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithFile(fileName)); + .WithSubdirectory(subdirectoryName)); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; - sut.HasFileMatching(fileName); + sut.HasDirectory(subdirectoryName); } [Theory] [AutoData] - public void HasFileMatching_WithoutMatchingFile_ShouldThrow( + public void HasDirectory_WithMultipleMatchingDirectory_ShouldThrow( string directoryName, - string fileName, + string subdirectoryName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithFile("not-matching-file")); + .WithSubdirectory($"{subdirectoryName}-1.txt") + .WithSubdirectory($"{subdirectoryName}-2.txt")); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasFileMatching(fileName, because); + sut.HasDirectory($"{subdirectoryName}*", because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain at least one file matching \"{fileName}\" {because}, but none was found."); + $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}*\" {because}, but found 2."); } [Theory] - [InlineAutoData(3, 5)] - [InlineAutoData(1, 2)] - public void HasFilesMatching_WithoutTooLittleFiles_ShouldThrow( - int matchingCount, - int expectedCount, + [AutoData] + public void HasDirectory_WithoutMatchingDirectory_ShouldThrow( string directoryName, - string fileNamePrefix, + string subdirectoryName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() - .WithSubdirectory(directoryName); - for (int i = 0; i < matchingCount; i++) - { - fileSystem.File.WriteAllText( - fileSystem.Path.Combine(directoryName, $"{fileNamePrefix}-{i}.txt"), - "some content"); - } - + .WithSubdirectory(directoryName).Initialized(d => d + .WithSubdirectory("not-matching-directory")); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasFilesMatching($"{fileNamePrefix}*", expectedCount, because); + sut.HasDirectory(subdirectoryName, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain at least {expectedCount} files matching \"{fileNamePrefix}*\" {because}, but only {matchingCount} were found."); + $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}\" {because}, but found 0."); } [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HasSingleDirectoryMatching_InvalidDirectoryName_ShouldThrow( - string? invalidDirectoryName, + public void HasFile_InvalidFileName_ShouldThrow(string? invalidFileName, string because) { MockFileSystem fileSystem = new(); @@ -206,7 +199,7 @@ public void HasSingleDirectoryMatching_InvalidDirectoryName_ShouldThrow( Exception? exception = Record.Exception(() => { - sut.HasSingleDirectoryMatching(invalidDirectoryName!, because); + sut.HasFile(invalidFileName!, because); }); exception.Should().NotBeNull(); @@ -216,73 +209,72 @@ public void HasSingleDirectoryMatching_InvalidDirectoryName_ShouldThrow( [Theory] [AutoData] - public void HasSingleDirectoryMatching_WithMatchingDirectory_ShouldNotThrow( + public void HasFile_WithMatchingFile_ShouldNotThrow( string directoryName, - string subdirectoryName) + string fileName) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory(subdirectoryName)); + .WithFile(fileName)); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; - sut.HasSingleDirectoryMatching(subdirectoryName); + sut.HasFile(fileName); } [Theory] [AutoData] - public void HasSingleDirectoryMatching_WithMultipleMatchingDirectory_ShouldThrow( + public void HasFile_WithMultipleMatchingFile_ShouldThrow( string directoryName, - string subdirectoryName, + string fileName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory($"{subdirectoryName}-1.txt") - .WithSubdirectory($"{subdirectoryName}-2.txt")); + .WithFile($"{fileName}-1.txt") + .WithFile($"{fileName}-2.txt")); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasSingleDirectoryMatching($"{subdirectoryName}*", because); + sut.HasFile($"{fileName}*", because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}*\" {because}, but found 2."); + $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}*\" {because}, but found 2."); } [Theory] [AutoData] - public void HasSingleDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( + public void HasFile_WithoutMatchingFile_ShouldThrow( string directoryName, - string subdirectoryName, + string fileName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory("not-matching-directory")); + .WithFile("not-matching-file")); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasSingleDirectoryMatching(subdirectoryName, because); + sut.HasFile(fileName, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}\" {because}, but found 0."); + $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}\" {because}, but found 0."); } [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HasSingleFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName, - string because) + public void HasFiles_InvalidFileName_ShouldThrow(string? invalidFileName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() @@ -291,7 +283,7 @@ public void HasSingleFileMatching_InvalidFileName_ShouldThrow(string? invalidFil Exception? exception = Record.Exception(() => { - sut.HasSingleFileMatching(invalidFileName!, because); + sut.HasFiles(invalidFileName!, because); }); exception.Should().NotBeNull(); @@ -301,7 +293,7 @@ public void HasSingleFileMatching_InvalidFileName_ShouldThrow(string? invalidFil [Theory] [AutoData] - public void HasSingleFileMatching_WithMatchingFile_ShouldNotThrow( + public void HasFiles_WithMatchingFile_ShouldNotThrow( string directoryName, string fileName) { @@ -311,12 +303,12 @@ public void HasSingleFileMatching_WithMatchingFile_ShouldNotThrow( .WithFile(fileName)); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; - sut.HasSingleFileMatching(fileName); + sut.HasFiles(fileName); } [Theory] [AutoData] - public void HasSingleFileMatching_WithMultipleMatchingFile_ShouldThrow( + public void HasFiles_WithoutMatchingFile_ShouldThrow( string directoryName, string fileName, string because) @@ -324,42 +316,50 @@ public void HasSingleFileMatching_WithMultipleMatchingFile_ShouldThrow( MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithFile($"{fileName}-1.txt") - .WithFile($"{fileName}-2.txt")); + .WithFile("not-matching-file")); DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasSingleFileMatching($"{fileName}*", because); + sut.HasFiles(fileName, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}*\" {because}, but found 2."); + $"Expected directory \"{directoryName}\" to contain at least one file matching \"{fileName}\" {because}, but none was found."); } [Theory] - [AutoData] - public void HasSingleFileMatching_WithoutMatchingFile_ShouldThrow( + [InlineAutoData(3, 5)] + [InlineAutoData(1, 2)] + public void HasFiles_WithoutTooLittleFiles_ShouldThrow( + int matchingCount, + int expectedCount, string directoryName, - string fileName, + string fileNamePrefix, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() - .WithSubdirectory(directoryName).Initialized(d => d - .WithFile("not-matching-file")); + .WithSubdirectory(directoryName); + for (int i = 0; i < matchingCount; i++) + { + fileSystem.File.WriteAllText( + fileSystem.Path.Combine(directoryName, $"{fileNamePrefix}-{i}.txt"), + "some content"); + } + DirectoryAssertions? sut = fileSystem.Should().HaveDirectory(directoryName).Which; Exception? exception = Record.Exception(() => { - sut.HasSingleFileMatching(fileName, because); + sut.HasFiles($"{fileNamePrefix}*", expectedCount, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}\" {because}, but found 0."); + $"Expected directory \"{directoryName}\" to contain at least {expectedCount} files matching \"{fileNamePrefix}*\" {because}, but only {matchingCount} were found."); } } diff --git a/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryInfoAssertionsTests.cs b/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryInfoAssertionsTests.cs index 7cd0a80..9544347 100644 --- a/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryInfoAssertionsTests.cs +++ b/Tests/Testably.Abstractions.FluentAssertions.Tests/DirectoryInfoAssertionsTests.cs @@ -12,7 +12,7 @@ public class DirectoryInfoAssertionsTests [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HaveDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, + public void HaveDirectories_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, string because) { MockFileSystem fileSystem = new(); @@ -22,7 +22,7 @@ public void HaveDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? inval Exception? exception = Record.Exception(() => { - sut.Should().HaveDirectoryMatching(invalidDirectoryName!, because); + sut.Should().HaveDirectories(invalidDirectoryName!, because); }); exception.Should().NotBeNull(); @@ -32,13 +32,13 @@ public void HaveDirectoryMatching_InvalidDirectoryName_ShouldThrow(string? inval [Theory] [AutoData] - public void HaveDirectoryMatching_Null_ShouldThrow(string because) + public void HaveDirectories_Null_ShouldThrow(string because) { IDirectoryInfo? sut = null; Exception? exception = Record.Exception(() => { - sut.Should().HaveDirectoryMatching(because: because); + sut.Should().HaveDirectories(because: because); }); exception.Should().NotBeNull(); @@ -48,7 +48,7 @@ public void HaveDirectoryMatching_Null_ShouldThrow(string because) [Theory] [AutoData] - public void HaveDirectoryMatching_WithMatchingDirectory_ShouldNotThrow( + public void HaveDirectories_WithMatchingDirectory_ShouldNotThrow( string directoryName, string subdirectoryName) { @@ -58,12 +58,12 @@ public void HaveDirectoryMatching_WithMatchingDirectory_ShouldNotThrow( .WithSubdirectory(subdirectoryName)); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); - sut.Should().HaveDirectoryMatching(subdirectoryName); + sut.Should().HaveDirectories(subdirectoryName); } [Theory] [AutoData] - public void HaveDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( + public void HaveDirectories_WithoutMatchingDirectory_ShouldThrow( string directoryName, string subdirectoryName, string because) @@ -76,7 +76,7 @@ public void HaveDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( Exception? exception = Record.Exception(() => { - sut.Should().HaveDirectoryMatching(subdirectoryName, because); + sut.Should().HaveDirectories(subdirectoryName, because); }); exception.Should().NotBeNull(); @@ -88,7 +88,7 @@ public void HaveDirectoryMatching_WithoutMatchingDirectory_ShouldThrow( [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HaveFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName, + public void HaveDirectory_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, string because) { MockFileSystem fileSystem = new(); @@ -98,7 +98,7 @@ public void HaveFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName Exception? exception = Record.Exception(() => { - sut.Should().HaveFileMatching(invalidFileName!, because); + sut.Should().HaveDirectory(invalidDirectoryName!, because); }); exception.Should().NotBeNull(); @@ -108,13 +108,13 @@ public void HaveFileMatching_InvalidFileName_ShouldThrow(string? invalidFileName [Theory] [AutoData] - public void HaveFileMatching_Null_ShouldThrow(string because) + public void HaveDirectory_Null_ShouldThrow(string because) { IDirectoryInfo? sut = null; Exception? exception = Record.Exception(() => { - sut.Should().HaveFileMatching(because: because); + sut.Should().HaveDirectory(because: because); }); exception.Should().NotBeNull(); @@ -124,47 +124,71 @@ public void HaveFileMatching_Null_ShouldThrow(string because) [Theory] [AutoData] - public void HaveFileMatching_WithMatchingFile_ShouldNotThrow( + public void HaveDirectory_WithMatchingDirectory_ShouldNotThrow( string directoryName, - string fileName) + string subdirectoryName) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithFile(fileName)); + .WithSubdirectory(subdirectoryName)); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); - sut.Should().HaveFileMatching(fileName); + sut.Should().HaveDirectory(subdirectoryName); } [Theory] [AutoData] - public void HaveFileMatching_WithoutMatchingFile_ShouldThrow( + public void HaveDirectory_WithMultipleMatchingDirectory_ShouldThrow( string directoryName, - string fileName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithFile("not-matching-file")); + .WithSubdirectory("directory1.txt") + .WithSubdirectory("directory2.txt")); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); Exception? exception = Record.Exception(() => { - sut.Should().HaveFileMatching(fileName, because); + sut.Should().HaveDirectory("directory*.txt", because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain at least one file matching \"{fileName}\" {because}, but none was found."); + $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"directory*.txt\" {because}, but found 2."); + } + + [Theory] + [AutoData] + public void HaveDirectory_WithoutMatchingDirectory_ShouldThrow( + string directoryName, + string subdirectoryName, + string because) + { + MockFileSystem fileSystem = new(); + fileSystem.Initialize() + .WithSubdirectory(directoryName).Initialized(d => d + .WithSubdirectory("not-matching-directory")); + IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); + + Exception? exception = Record.Exception(() => + { + sut.Should().HaveDirectory(subdirectoryName, because); + }); + + exception.Should().NotBeNull(); + exception!.Message.Should() + .Be( + $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}\" {because}, but found 0."); } [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HaveSingleDirectory_InvalidDirectoryName_ShouldThrow(string? invalidDirectoryName, + public void HaveFile_InvalidFileName_ShouldThrow(string? invalidFileName, string because) { MockFileSystem fileSystem = new(); @@ -174,7 +198,7 @@ public void HaveSingleDirectory_InvalidDirectoryName_ShouldThrow(string? invalid Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleDirectory(invalidDirectoryName!, because); + sut.Should().HaveFile(invalidFileName!, because); }); exception.Should().NotBeNull(); @@ -184,13 +208,13 @@ public void HaveSingleDirectory_InvalidDirectoryName_ShouldThrow(string? invalid [Theory] [AutoData] - public void HaveSingleDirectory_Null_ShouldThrow(string because) + public void HaveFile_Null_ShouldThrow(string because) { IDirectoryInfo? sut = null; Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleDirectory(because: because); + sut.Should().HaveFile(because: because); }); exception.Should().NotBeNull(); @@ -200,71 +224,71 @@ public void HaveSingleDirectory_Null_ShouldThrow(string because) [Theory] [AutoData] - public void HaveSingleDirectory_WithMatchingDirectory_ShouldNotThrow( + public void HaveFile_WithMatchingFile_ShouldNotThrow( string directoryName, - string subdirectoryName) + string fileName) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory(subdirectoryName)); + .WithFile(fileName)); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); - sut.Should().HaveSingleDirectory(subdirectoryName); + sut.Should().HaveFile(fileName); } [Theory] [AutoData] - public void HaveSingleDirectory_WithMultipleMatchingDirectory_ShouldThrow( + public void HaveFile_WithMultipleMatchingFile_ShouldThrow( string directoryName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory("directory1.txt") - .WithSubdirectory("directory2.txt")); + .WithFile("file1.txt") + .WithFile("file2.txt")); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleDirectory("directory*.txt", because); + sut.Should().HaveFile("file*.txt", because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"directory*.txt\" {because}, but found 2."); + $"Expected directory \"{directoryName}\" to contain exactly one file matching \"file*.txt\" {because}, but found 2."); } [Theory] [AutoData] - public void HaveSingleDirectory_WithoutMatchingDirectory_ShouldThrow( + public void HaveFile_WithoutMatchingFile_ShouldThrow( string directoryName, - string subdirectoryName, + string fileName, string because) { MockFileSystem fileSystem = new(); fileSystem.Initialize() .WithSubdirectory(directoryName).Initialized(d => d - .WithSubdirectory("not-matching-directory")); + .WithFile("not-matching-file")); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleDirectory(subdirectoryName, because); + sut.Should().HaveFile(fileName, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one directory matching \"{subdirectoryName}\" {because}, but found 0."); + $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}\" {because}, but found 0."); } [Theory] [InlineAutoData(null)] [InlineAutoData("")] - public void HaveSingleFile_InvalidFileName_ShouldThrow(string? invalidFileName, + public void HaveFiles_InvalidFileName_ShouldThrow(string? invalidFileName, string because) { MockFileSystem fileSystem = new(); @@ -274,7 +298,7 @@ public void HaveSingleFile_InvalidFileName_ShouldThrow(string? invalidFileName, Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleFile(invalidFileName!, because); + sut.Should().HaveFiles(invalidFileName!, because); }); exception.Should().NotBeNull(); @@ -284,13 +308,13 @@ public void HaveSingleFile_InvalidFileName_ShouldThrow(string? invalidFileName, [Theory] [AutoData] - public void HaveSingleFile_Null_ShouldThrow(string because) + public void HaveFiles_Null_ShouldThrow(string because) { IDirectoryInfo? sut = null; Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleFile(because: because); + sut.Should().HaveFiles(because: because); }); exception.Should().NotBeNull(); @@ -300,7 +324,7 @@ public void HaveSingleFile_Null_ShouldThrow(string because) [Theory] [AutoData] - public void HaveSingleFile_WithMatchingFile_ShouldNotThrow( + public void HaveFiles_WithMatchingFile_ShouldNotThrow( string directoryName, string fileName) { @@ -310,36 +334,12 @@ public void HaveSingleFile_WithMatchingFile_ShouldNotThrow( .WithFile(fileName)); IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); - sut.Should().HaveSingleFile(fileName); - } - - [Theory] - [AutoData] - public void HaveSingleFile_WithMultipleMatchingFile_ShouldThrow( - string directoryName, - string because) - { - MockFileSystem fileSystem = new(); - fileSystem.Initialize() - .WithSubdirectory(directoryName).Initialized(d => d - .WithFile("file1.txt") - .WithFile("file2.txt")); - IDirectoryInfo sut = fileSystem.DirectoryInfo.New(directoryName); - - Exception? exception = Record.Exception(() => - { - sut.Should().HaveSingleFile("file*.txt", because); - }); - - exception.Should().NotBeNull(); - exception!.Message.Should() - .Be( - $"Expected directory \"{directoryName}\" to contain exactly one file matching \"file*.txt\" {because}, but found 2."); + sut.Should().HaveFiles(fileName); } [Theory] [AutoData] - public void HaveSingleFile_WithoutMatchingFile_ShouldThrow( + public void HaveFiles_WithoutMatchingFile_ShouldThrow( string directoryName, string fileName, string because) @@ -352,12 +352,12 @@ public void HaveSingleFile_WithoutMatchingFile_ShouldThrow( Exception? exception = Record.Exception(() => { - sut.Should().HaveSingleFile(fileName, because); + sut.Should().HaveFiles(fileName, because); }); exception.Should().NotBeNull(); exception!.Message.Should() .Be( - $"Expected directory \"{directoryName}\" to contain exactly one file matching \"{fileName}\" {because}, but found 0."); + $"Expected directory \"{directoryName}\" to contain at least one file matching \"{fileName}\" {because}, but none was found."); } }