From e4a65db260262fe09ed1b2c5ea9392d6ddd99a60 Mon Sep 17 00:00:00 2001 From: Jonathan Gilbert Date: Fri, 25 Feb 2022 12:08:35 -0600 Subject: [PATCH] Added tests to verify that the ExcludingNonBrowsableMembers functionality works properly when the subject and expectation are different types and only one of them has the property marked non-browsable. Fixed AssertMemberEquality in StructuralEqualityEquivalencyStep.cs so that all of the tests pass. It was previously not factoring in whether the selected member itself was browsable. --- .../StructuralEqualityEquivalencyStep.cs | 2 +- .../SelectionRulesSpecs.cs | 71 +++++++++++++++++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs index c2a5f8b69b..5f9596b03b 100644 --- a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs @@ -55,7 +55,7 @@ public class StructuralEqualityEquivalencyStep : IEquivalencyStep IMember matchingMember = FindMatchFor(selectedMember, context.CurrentNode, comparands.Subject, options); if (matchingMember is not null) { - if (!options.ExcludeNonBrowsable || matchingMember.IsBrowsable) + if (!options.ExcludeNonBrowsable || (selectedMember.IsBrowsable && matchingMember.IsBrowsable)) { var nestedComparands = new Comparands { diff --git a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs index 97e548cb5f..0e89abbc3a 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs @@ -1723,29 +1723,92 @@ public void When_non_browsable_property_differs_excluding_non_browsable_members_ subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); } + [Fact] + public void When_property_is_non_browsable_only_in_subject_excluding_non_browsable_members_should_make_it_succeed() + { + // Arrange + var subject = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 0 }; + var expectation = new ClassWithMatchingMemberNamesButEverythingIsBrowsable() { NonBrowsableProperty = 1 }; + + // Act & Assert + subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); + } + + [Fact] + public void When_property_is_non_browsable_only_in_expectation_excluding_non_browsable_members_should_make_it_succeed() + { + // Arrange + var subject = new ClassWithMatchingMemberNamesButEverythingIsBrowsable() { NonBrowsableProperty = 0 }; + var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 1 }; + + // Act & Assert + subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); + } + + [Fact] + public void When_field_is_non_browsable_only_in_subject_excluding_non_browsable_members_should_make_it_succeed() + { + // Arrange + var subject = new ClassWithNonBrowsableMembers() { NonBrowsableField = 0 }; + var expectation = new ClassWithMatchingMemberNamesButEverythingIsBrowsable() { NonBrowsableField = 1 }; + + // Act & Assert + subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); + } + + [Fact] + public void When_field_is_non_browsable_only_in_expectation_excluding_non_browsable_members_should_make_it_succeed() + { + // Arrange + var subject = new ClassWithMatchingMemberNamesButEverythingIsBrowsable() { NonBrowsableField = 0 }; + var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableField = 1 }; + + // Act & Assert + subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); + } + private class ClassWithNonBrowsableMembers { - public int BrowsableField; + public int BrowsableField = -1; public int BrowsableProperty { get; set; } [EditorBrowsable(EditorBrowsableState.Always)] - public int ExplicitlyBrowsableField; + public int ExplicitlyBrowsableField = -1; [EditorBrowsable(EditorBrowsableState.Always)] public int ExplicitlyBrowsableProperty { get; set; } [EditorBrowsable(EditorBrowsableState.Advanced)] - public int AdvancedBrowsableField; + public int AdvancedBrowsableField = -1; [EditorBrowsable(EditorBrowsableState.Advanced)] public int AdvancedBrowsableProperty { get; set; } [EditorBrowsable(EditorBrowsableState.Never)] - public int NonBrowsableField; + public int NonBrowsableField = -1; [EditorBrowsable(EditorBrowsableState.Never)] public int NonBrowsableProperty { get; set; } } + + private class ClassWithMatchingMemberNamesButEverythingIsBrowsable + { + public int BrowsableField = -1; + + public int BrowsableProperty { get; set; } + + public int ExplicitlyBrowsableField = -1; + + public int ExplicitlyBrowsableProperty { get; set; } + + public int AdvancedBrowsableField = -1; + + public int AdvancedBrowsableProperty { get; set; } + + public int NonBrowsableField = -1; + + public int NonBrowsableProperty { get; set; } + } } }