From ee57ac85bf672e4e94e4d2377d8254103a9ce0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=BCtzmacher?= Date: Sat, 19 Nov 2022 19:18:39 +0100 Subject: [PATCH] New tests for better code coverage on collection assertions --- ...lectionAssertionSpecs.AllBeAssignableTo.cs | 38 +++++++-- .../CollectionAssertionSpecs.AllBeOfType.cs | 38 +++++++-- .../CollectionAssertionSpecs.Contain.cs | 78 +++++++++++++++++++ ...CollectionAssertionSpecs.ContainInOrder.cs | 15 ++++ .../CollectionAssertionSpecs.HaveCount.cs | 18 +++++ ...ollectionAssertionSpecs.NotContainNulls.cs | 36 +++++++++ ...ctionAssertionSpecs.OnlyHaveUniqueItems.cs | 61 +++++++++++++++ 7 files changed, 270 insertions(+), 14 deletions(-) diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeAssignableTo.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeAssignableTo.cs index 1bf5df8f2a..777f53fdd5 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeAssignableTo.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeAssignableTo.cs @@ -17,7 +17,7 @@ public class AllBeAssignableTo public void When_the_types_in_a_collection_is_matched_against_a_null_type_it_should_throw() { // Arrange - var collection = new int[0]; + var collection = Array.Empty(); // Act Action act = () => collection.Should().AllBeAssignableTo(null); @@ -49,7 +49,17 @@ public void When_collection_is_null_then_all_be_assignable_to_should_fail() public void When_all_of_the_types_in_a_collection_match_expected_type_it_should_succeed() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; + + // Act / Assert + collection.Should().AllBeAssignableTo(typeof(int)); + } + + [Fact] + public void When_all_of_the_types_in_a_collection_match_expected_generic_type_it_should_succeed() + { + // Arrange + var collection = new[] { 1, 2, 3 }; // Act / Assert collection.Should().AllBeAssignableTo(); @@ -59,7 +69,7 @@ public void When_all_of_the_types_in_a_collection_match_expected_type_it_should_ public void When_matching_a_collection_against_a_type_it_should_return_the_casted_items() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; // Act / Assert collection.Should().AllBeAssignableTo() @@ -70,7 +80,7 @@ public void When_matching_a_collection_against_a_type_it_should_return_the_caste public void When_all_of_the_types_in_a_collection_match_the_type_or_subtype_it_should_succeed() { // Arrange - var collection = new object[] { new Exception(), new ArgumentException() }; + var collection = new object[] { new Exception(), new ArgumentException("foo") }; // Act / Assert collection.Should().AllBeAssignableTo(); @@ -82,6 +92,20 @@ public void When_one_of_the_types_does_not_match_it_should_throw_with_a_clear_ex // Arrange var collection = new object[] { 1, "2", 3 }; + // Act + Action act = () => collection.Should().AllBeAssignableTo(typeof(int), "because they are of different type"); + + // Assert + act.Should().Throw().WithMessage( + "Expected type to be \"System.Int32\" because they are of different type, but found \"[System.Int32, System.String, System.Int32]\"."); + } + + [Fact] + public void When_one_of_the_types_does_not_match_the_generic_type_it_should_throw_with_a_clear_explanation() + { + // Arrange + var collection = new object[] { 1, "2", 3 }; + // Act Action act = () => collection.Should().AllBeAssignableTo("because they are of different type"); @@ -108,7 +132,7 @@ public void When_one_of_the_elements_is_null_it_should_throw_with_a_clear_explan public void When_collection_is_of_matching_types_it_should_succeed() { // Arrange - var collection = new Type[] { typeof(Exception), typeof(ArgumentException) }; + var collection = new[] { typeof(Exception), typeof(ArgumentException) }; // Act / Assert collection.Should().AllBeAssignableTo(); @@ -118,7 +142,7 @@ public void When_collection_is_of_matching_types_it_should_succeed() public void When_collection_of_types_contains_one_type_that_does_not_match_it_should_throw_with_a_clear_explanation() { // Arrange - var collection = new Type[] { typeof(int), typeof(string), typeof(int) }; + var collection = new[] { typeof(int), typeof(string), typeof(int) }; // Act Action act = () => collection.Should().AllBeAssignableTo("because they are of different type"); @@ -142,7 +166,7 @@ public void When_collection_of_types_and_objects_are_all_of_matching_types_it_sh public void When_collection_of_different_types_and_objects_are_all_assignable_to_type_it_should_succeed() { // Arrange - var collection = new object[] { typeof(Exception), new ArgumentException() }; + var collection = new object[] { typeof(Exception), new ArgumentException("foo") }; // Act / Assert collection.Should().AllBeAssignableTo(); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeOfType.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeOfType.cs index 390c0f0a0b..b130455f73 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeOfType.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllBeOfType.cs @@ -17,7 +17,7 @@ public class AllBeOfType public void When_the_types_in_a_collection_is_matched_against_a_null_type_exactly_it_should_throw() { // Arrange - var collection = new int[0]; + var collection = Array.Empty(); // Act Action act = () => collection.Should().AllBeOfType(null); @@ -49,7 +49,17 @@ public void When_collection_is_null_then_all_be_of_type_should_fail() public void When_all_of_the_types_in_a_collection_match_expected_type_exactly_it_should_succeed() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; + + // Act / Assert + collection.Should().AllBeOfType(typeof(int)); + } + + [Fact] + public void When_all_of_the_types_in_a_collection_match_expected_generic_type_exactly_it_should_succeed() + { + // Arrange + var collection = new[] { 1, 2, 3 }; // Act / Assert collection.Should().AllBeOfType(); @@ -59,7 +69,7 @@ public void When_all_of_the_types_in_a_collection_match_expected_type_exactly_it public void When_matching_a_collection_against_an_exact_type_it_should_return_the_casted_items() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; // Act / Assert collection.Should().AllBeOfType() @@ -70,7 +80,21 @@ public void When_matching_a_collection_against_an_exact_type_it_should_return_th public void When_one_of_the_types_does_not_match_exactly_it_should_throw_with_a_clear_explanation() { // Arrange - var collection = new object[] { new Exception(), new ArgumentException() }; + var collection = new object[] { new Exception(), new ArgumentException("foo") }; + + // Act + Action act = () => collection.Should().AllBeOfType(typeof(Exception), "because they are of different type"); + + // Assert + act.Should().Throw().WithMessage( + "Expected type to be \"System.Exception\" because they are of different type, but found \"[System.Exception, System.ArgumentException]\"."); + } + + [Fact] + public void When_one_of_the_types_does_not_match_exactly_the_generic_type_it_should_throw_with_a_clear_explanation() + { + // Arrange + var collection = new object[] { new Exception(), new ArgumentException("foo") }; // Act Action act = () => collection.Should().AllBeOfType("because they are of different type"); @@ -98,7 +122,7 @@ public void When_one_of_the_elements_is_null_for_an_exact_match_it_should_throw_ public void When_collection_of_types_match_expected_type_exactly_it_should_succeed() { // Arrange - var collection = new Type[] { typeof(int), typeof(int), typeof(int) }; + var collection = new[] { typeof(int), typeof(int), typeof(int) }; // Act / Assert collection.Should().AllBeOfType(); @@ -108,7 +132,7 @@ public void When_collection_of_types_match_expected_type_exactly_it_should_succe public void When_collection_of_types_and_objects_match_type_exactly_it_should_succeed() { // Arrange - var collection = new object[] { typeof(ArgumentException), new ArgumentException() }; + var collection = new object[] { typeof(ArgumentException), new ArgumentException("foo") }; // Act / Assert collection.Should().AllBeOfType(); @@ -118,7 +142,7 @@ public void When_collection_of_types_and_objects_match_type_exactly_it_should_su public void When_collection_of_types_and_objects_do_not_match_type_exactly_it_should_throw() { // Arrange - var collection = new object[] { typeof(Exception), new ArgumentException() }; + var collection = new object[] { typeof(Exception), new ArgumentException("foo") }; // Act Action act = () => collection.Should().AllBeOfType(); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs index a7f77d44dd..be5a20c965 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs @@ -79,6 +79,38 @@ public void When_a_collection_does_not_contain_another_collection_it_should_thro "Expected collection {1, 2, 3} to contain {3, 4, 5} because we do, but could not find {4, 5}."); } + [Fact] + public void When_a_collection_does_not_contain_a_single_element_collection_it_should_throw_with_clear_explanation() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => collection.Should().Contain(new[] { 4 }, "because {0}", "we do"); + + // Assert + act.Should().Throw().WithMessage( + "Expected collection {1, 2, 3} to contain 4 because we do."); + } + + [Fact] + public void When_a_collection_does_not_contain_other_collection_with_assertion_scope_it_should_throw_with_clear_explanation() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().Contain(new[] { 4 }).And.Contain(new[] { 5, 6 }); + }; + + // Assert + act.Should().Throw().WithMessage( + "*to contain 4*to contain {5, 6}*"); + } + [Fact] public void When_the_contents_of_a_collection_are_checked_against_an_empty_collection_it_should_throw_clear_explanation() { @@ -331,6 +363,21 @@ public void When_asserting_collection_does_not_contain_item_against_null_collect "Expected collection to not contain 1 because we want to test the behaviour with a null subject, but found ."); } + [Fact] + public void When_collection_contains_unexpected_item_it_should_throw() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => collection.Should() + .NotContain(new[] { 2 }, "because we {0} like them", "don't"); + + // Assert + act.Should().Throw().WithMessage( + "Expected collection {1, 2, 3} to not contain 2 because we don't like them."); + } + [Fact] public void When_collection_contains_unexpected_items_it_should_throw() { @@ -346,6 +393,37 @@ public void When_collection_contains_unexpected_items_it_should_throw() "Expected collection {1, 2, 3} to not contain {1, 2, 4} because we don't like them, but found {1, 2}."); } + [Fact] + public void When_asserting_multiple_collection_in_assertion_scope_all_should_be_reported() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().NotContain(new[] { 1, 2 }).And.NotContain(new[] { 3 }); + }; + + // Assert + act.Should().Throw().WithMessage( + "*to not contain {1, 2}*to not contain 3*"); + } + + [Fact] + public void When_asserting_collection_to_not_contain_an_empty_collection_it_should_throw() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => collection.Should().NotContain(Array.Empty()); + + // Assert + act.Should().Throw().WithMessage("Cannot verify*"); + } + [Fact] public void When_asserting_collection_does_not_contain_predicate_item_against_null_collection_it_should_fail() { diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs index b16d1ca46a..aebb9e1e47 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs @@ -89,6 +89,21 @@ public void When_a_collection_does_not_contain_an_ordered_item_it_should_throw_w "but 4 (index 0) did not appear (in the right order)."); } + [Fact] + public void When_a_collection_does_not_contain_items_with_assertion_scope_all_items_are_reported() + { + // Act + Action act = () => + { + using var _ = new AssertionScope(); + new[] { 1, 2, 3 }.Should().ContainInOrder(4).And.ContainInOrder(5); + }; + + // Assert + act.Should().Throw().WithMessage( + "*but 4 (index 0)*but 5 (index 0)*"); + } + [Fact] public void When_passing_in_null_while_checking_for_ordered_containment_it_should_throw_with_a_clear_explanation() { diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs index f065280108..55ed2067e4 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs @@ -59,6 +59,24 @@ public void When_collection_has_a_count_larger_than_the_minimum_it_should_not_th collection.Should().HaveCount(c => c >= 3); } + [Fact] + public void When_asserting_a_collection_with_incorrect_predicates_in_assertion_scope_all_are_reported() + { + // Arrange + var collection = new[] { 1, 2, 3 }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().HaveCount(c => c > 3).And.HaveCount(c => c < 3); + }; + + // Assert + act.Should().Throw().WithMessage( + "*to have a count (c > 3)*to have a count (c < 3)*"); + } + [Fact] public void When_collection_has_a_count_that_not_matches_the_predicate_it_should_throw() { diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.NotContainNulls.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.NotContainNulls.cs index b5dd88252b..1243c9cc28 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.NotContainNulls.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.NotContainNulls.cs @@ -37,6 +37,24 @@ public void When_collection_contains_nulls_that_are_unexpected_it_should_throw() "Expected collection not to contain s because they are evil, but found one at index 1."); } + [Fact] + public void When_collection_contains_nulls_that_are_unexpected_it_supports_chaining() + { + // Arrange + var collection = new[] { new object(), null }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().NotContainNulls().And.HaveCount(c => c > 1); + }; + + // Assert + act.Should().Throw().WithMessage( + "*but found one*"); + } + [Fact] public void When_collection_contains_multiple_nulls_that_are_unexpected_it_should_throw() { @@ -51,6 +69,24 @@ public void When_collection_contains_multiple_nulls_that_are_unexpected_it_shoul "Expected collection not to contain s*because they are evil*{1, 3}*"); } + [Fact] + public void When_collection_contains_multiple_nulls_that_are_unexpected_it_supports_chaining() + { + // Arrange + var collection = new[] { new object(), null, new object(), null }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().NotContainNulls().And.HaveCount(c => c > 1); + }; + + // Assert + act.Should().Throw().WithMessage( + "*but found several*"); + } + [Fact] public void When_asserting_collection_to_not_contain_nulls_but_collection_is_null_it_should_throw() { diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs index 771cb532ad..99526e92ca 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs @@ -37,6 +37,24 @@ public void When_a_collection_contains_duplicate_items_it_should_throw() "Expected collection to only have unique items because we don't like duplicates, but item 3 is not unique."); } + [Fact] + public void When_a_collection_contains_duplicate_items_it_supports_chaining() + { + // Arrange + var collection = new[] { 1, 2, 3, 3 }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().OnlyHaveUniqueItems().And.HaveCount(c => c > 1); + }; + + // Assert + act.Should().Throw().WithMessage( + "*but item 3 is not unique."); + } + [Fact] public void When_a_collection_contains_multiple_duplicate_items_it_should_throw() { @@ -51,6 +69,24 @@ public void When_a_collection_contains_multiple_duplicate_items_it_should_throw( "Expected collection to only have unique items because we don't like duplicates, but items {2, 3} are not unique."); } + [Fact] + public void When_a_collection_contains_multiple_duplicate_items_it_supports_chaining() + { + // Arrange + var collection = new[] { 1, 2, 2, 3, 3 }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().OnlyHaveUniqueItems().And.HaveCount(c => c > 1); + }; + + // Assert + act.Should().Throw().WithMessage( + "*but items {2, 3} are not unique."); + } + [Fact] public void When_asserting_collection_to_only_have_unique_items_but_collection_is_null_it_should_throw() { @@ -140,6 +176,31 @@ public void When_a_collection_contains_multiple_duplicate_items_with_a_predicate "Expected collection to only have unique items*on e.Text*because we don't like duplicates, but items*two*two*three*three*are not unique."); } + [Fact] + public void When_a_collection_contains_multiple_duplicates_on_different_properties_all_should_be_reported() + { + // Arrange + IEnumerable collection = new[] + { + new SomeClass { Text = "one", Number = 1 }, + new SomeClass { Text = "two", Number = 2 }, + new SomeClass { Text = "two", Number = 2 }, + new SomeClass { Text = "three", Number = 3 }, + new SomeClass { Text = "three", Number = 4 } + }; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + collection.Should().OnlyHaveUniqueItems(e => e.Text).And.OnlyHaveUniqueItems(e => e.Number); + }; + + // Assert + act.Should().Throw().WithMessage( + "*have unique items on e.Text*have unique items on e.Number*"); + } + [Fact] public void When_asserting_with_a_predicate_a_collection_to_only_have_unique_items_but_collection_is_null_it_should_throw() {