diff --git a/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs b/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs index 868c0ba910..86c06cf999 100644 --- a/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs +++ b/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs @@ -61,8 +61,6 @@ public IEnumerable UserEquivalencySteps public MemberVisibility IncludedFields => inner.IncludedFields; - public bool ExcludeNonBrowsable => inner.ExcludeNonBrowsable; - public bool CompareRecordsByValue => inner.CompareRecordsByValue; public EqualityStrategy GetEqualityStrategy(Type type) diff --git a/Src/FluentAssertions/Equivalency/Field.cs b/Src/FluentAssertions/Equivalency/Field.cs index 9c1720b9c6..04b06c32da 100644 --- a/Src/FluentAssertions/Equivalency/Field.cs +++ b/Src/FluentAssertions/Equivalency/Field.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Reflection; using FluentAssertions.Common; @@ -11,7 +10,6 @@ namespace FluentAssertions.Equivalency public class Field : Node, IMember { private readonly FieldInfo fieldInfo; - private bool? isBrowsable; public Field(FieldInfo fieldInfo, INode parent) : this(fieldInfo.ReflectedType, fieldInfo, parent) @@ -44,18 +42,5 @@ public object GetValue(object obj) public CSharpAccessModifier GetterAccessibility => fieldInfo.GetCSharpAccessModifier(); public CSharpAccessModifier SetterAccessibility => fieldInfo.GetCSharpAccessModifier(); - - public bool IsBrowsable - { - get - { - if (isBrowsable == null) - { - isBrowsable = fieldInfo.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; - } - - return isBrowsable.Value; - } - } } } diff --git a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs index fa6c28021d..bcc5a61199 100644 --- a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; - using FluentAssertions.Equivalency.Tracing; namespace FluentAssertions.Equivalency @@ -73,12 +71,6 @@ public interface IEquivalencyAssertionOptions /// MemberVisibility IncludedFields { get; } - /// - /// Gets a value indicating whether members marked with [EditorBrowsable] - /// and an EditorBrowsableState of Never should be excluded. - /// - bool ExcludeNonBrowsable { get; } - /// /// Gets a value indicating whether records should be compared by value instead of their members /// diff --git a/Src/FluentAssertions/Equivalency/IMember.cs b/Src/FluentAssertions/Equivalency/IMember.cs index 80e9107dd0..f14c39ab95 100644 --- a/Src/FluentAssertions/Equivalency/IMember.cs +++ b/Src/FluentAssertions/Equivalency/IMember.cs @@ -32,10 +32,5 @@ public interface IMember : INode /// Gets the access modifier for the setter of this member. /// CSharpAccessModifier SetterAccessibility { get; } - - /// - /// Gets a value indicating whether the member is browsable in the source code editor. This is controlled with the [EditorBrowsable] attribute. - /// - bool IsBrowsable { get; } } } diff --git a/Src/FluentAssertions/Equivalency/Property.cs b/Src/FluentAssertions/Equivalency/Property.cs index de3741bb9a..f53eeab7a0 100644 --- a/Src/FluentAssertions/Equivalency/Property.cs +++ b/Src/FluentAssertions/Equivalency/Property.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Reflection; using FluentAssertions.Common; @@ -12,7 +11,6 @@ namespace FluentAssertions.Equivalency public class Property : Node, IMember { private readonly PropertyInfo propertyInfo; - private bool? isBrowsable; public Property(PropertyInfo propertyInfo, INode parent) : this(propertyInfo.ReflectedType, propertyInfo, parent) @@ -45,18 +43,5 @@ public object GetValue(object obj) public CSharpAccessModifier GetterAccessibility => propertyInfo.GetGetMethod(nonPublic: true).GetCSharpAccessModifier(); public CSharpAccessModifier SetterAccessibility => propertyInfo.GetSetMethod(nonPublic: true).GetCSharpAccessModifier(); - - public bool IsBrowsable - { - get - { - if (isBrowsable == null) - { - isBrowsable = propertyInfo.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; - } - - return isBrowsable.Value; - } - } } } diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index a528d156c0..62121c73e9 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -56,7 +56,6 @@ public abstract class SelfReferenceEquivalencyAssertionOptions : IEquival private MemberVisibility includedProperties; private MemberVisibility includedFields; - private bool excludeNonBrowsable; private bool compareRecordsByValue; @@ -81,7 +80,6 @@ protected SelfReferenceEquivalencyAssertionOptions(IEquivalencyAssertionOptions useRuntimeTyping = defaults.UseRuntimeTyping; includedProperties = defaults.IncludedProperties; includedFields = defaults.IncludedFields; - excludeNonBrowsable = defaults.ExcludeNonBrowsable; compareRecordsByValue = defaults.CompareRecordsByValue; ConversionSelector = defaults.ConversionSelector.Clone(); @@ -164,8 +162,6 @@ IEnumerable IEquivalencyAssertionOptions.SelectionRules MemberVisibility IEquivalencyAssertionOptions.IncludedFields => includedFields; - bool IEquivalencyAssertionOptions.ExcludeNonBrowsable => excludeNonBrowsable; - public bool CompareRecordsByValue => compareRecordsByValue; EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type requestedType) @@ -316,26 +312,6 @@ public TSelf ExcludingProperties() return (TSelf)this; } - /// - /// Instructs the comparison to include non-browsable members (members with an EditorBrowsableState of Never). - /// - /// - public TSelf IncludingNonBrowsableMembers() - { - excludeNonBrowsable = false; - return (TSelf)this; - } - - /// - /// Instructs the comparison to exclude non-browsable members (members with an EditorBrowsableState of Never). - /// - /// - public TSelf ExcludingNonBrowsableMembers() - { - excludeNonBrowsable = true; - return (TSelf)this; - } - /// /// Instructs the comparison to respect the expectation's runtime type. /// @@ -751,15 +727,6 @@ public override string ToString() builder.AppendLine("- Compare records by their members"); } - if (excludeNonBrowsable) - { - builder.AppendLine("- Exclude non-browsable members"); - } - else - { - builder.AppendLine("- Include non-browsable members"); - } - foreach (Type valueType in valueTypes) { builder.AppendLine($"- Compare {valueType} by value"); diff --git a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs index c2a5f8b69b..845f8a2633 100644 --- a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs @@ -55,24 +55,21 @@ public class StructuralEqualityEquivalencyStep : IEquivalencyStep IMember matchingMember = FindMatchFor(selectedMember, context.CurrentNode, comparands.Subject, options); if (matchingMember is not null) { - if (!options.ExcludeNonBrowsable || matchingMember.IsBrowsable) + var nestedComparands = new Comparands { - var nestedComparands = new Comparands - { - Subject = matchingMember.GetValue(comparands.Subject), - Expectation = selectedMember.GetValue(comparands.Expectation), - CompileTimeType = selectedMember.Type - }; + Subject = matchingMember.GetValue(comparands.Subject), + Expectation = selectedMember.GetValue(comparands.Expectation), + CompileTimeType = selectedMember.Type + }; - if (selectedMember.Name != matchingMember.Name) - { - // In case the matching process selected a different member on the subject, - // adjust the current member so that assertion failures report the proper name. - selectedMember.Name = matchingMember.Name; - } - - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(selectedMember)); + if (selectedMember.Name != matchingMember.Name) + { + // In case the matching process selected a different member on the subject, + // adjust the current member so that assertion failures report the proper name. + selectedMember.Name = matchingMember.Name; } + + parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(selectedMember)); } } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index 97519bb273..f03027f71d 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -803,7 +803,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; set; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -824,7 +823,6 @@ namespace FluentAssertions.Equivalency FluentAssertions.Equivalency.ConversionSelector ConversionSelector { get; } FluentAssertions.Equivalency.CyclicReferenceHandling CyclicReferenceHandling { get; } FluentAssertions.Equivalency.EnumEquivalencyHandling EnumEquivalencyHandling { get; } - bool ExcludeNonBrowsable { get; } FluentAssertions.Equivalency.MemberVisibility IncludedFields { get; } FluentAssertions.Equivalency.MemberVisibility IncludedProperties { get; } bool IsRecursive { get; } @@ -860,7 +858,6 @@ namespace FluentAssertions.Equivalency { System.Type DeclaringType { get; } FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - bool IsBrowsable { get; } System.Type ReflectedType { get; } FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } object GetValue(object obj); @@ -964,7 +961,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -993,7 +989,6 @@ namespace FluentAssertions.Equivalency public TSelf ExcludingFields() { } public TSelf ExcludingMissingMembers() { } public TSelf ExcludingNestedObjects() { } - public TSelf ExcludingNonBrowsableMembers() { } public TSelf ExcludingProperties() { } public TSelf IgnoringCyclicReferences() { } public TSelf Including(System.Linq.Expressions.Expression> predicate) { } @@ -1003,7 +998,6 @@ namespace FluentAssertions.Equivalency public TSelf IncludingInternalFields() { } public TSelf IncludingInternalProperties() { } public TSelf IncludingNestedObjects() { } - public TSelf IncludingNonBrowsableMembers() { } public TSelf IncludingProperties() { } public TSelf RespectingDeclaredTypes() { } public TSelf RespectingRuntimeTypes() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index 951b5bbc90..2a2b438262 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -803,7 +803,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; set; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -824,7 +823,6 @@ namespace FluentAssertions.Equivalency FluentAssertions.Equivalency.ConversionSelector ConversionSelector { get; } FluentAssertions.Equivalency.CyclicReferenceHandling CyclicReferenceHandling { get; } FluentAssertions.Equivalency.EnumEquivalencyHandling EnumEquivalencyHandling { get; } - bool ExcludeNonBrowsable { get; } FluentAssertions.Equivalency.MemberVisibility IncludedFields { get; } FluentAssertions.Equivalency.MemberVisibility IncludedProperties { get; } bool IsRecursive { get; } @@ -860,7 +858,6 @@ namespace FluentAssertions.Equivalency { System.Type DeclaringType { get; } FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - bool IsBrowsable { get; } System.Type ReflectedType { get; } FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } object GetValue(object obj); @@ -964,7 +961,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -993,7 +989,6 @@ namespace FluentAssertions.Equivalency public TSelf ExcludingFields() { } public TSelf ExcludingMissingMembers() { } public TSelf ExcludingNestedObjects() { } - public TSelf ExcludingNonBrowsableMembers() { } public TSelf ExcludingProperties() { } public TSelf IgnoringCyclicReferences() { } public TSelf Including(System.Linq.Expressions.Expression> predicate) { } @@ -1003,7 +998,6 @@ namespace FluentAssertions.Equivalency public TSelf IncludingInternalFields() { } public TSelf IncludingInternalProperties() { } public TSelf IncludingNestedObjects() { } - public TSelf IncludingNonBrowsableMembers() { } public TSelf IncludingProperties() { } public TSelf RespectingDeclaredTypes() { } public TSelf RespectingRuntimeTypes() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index 905660df9d..53b96a5c6d 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -803,7 +803,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; set; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -824,7 +823,6 @@ namespace FluentAssertions.Equivalency FluentAssertions.Equivalency.ConversionSelector ConversionSelector { get; } FluentAssertions.Equivalency.CyclicReferenceHandling CyclicReferenceHandling { get; } FluentAssertions.Equivalency.EnumEquivalencyHandling EnumEquivalencyHandling { get; } - bool ExcludeNonBrowsable { get; } FluentAssertions.Equivalency.MemberVisibility IncludedFields { get; } FluentAssertions.Equivalency.MemberVisibility IncludedProperties { get; } bool IsRecursive { get; } @@ -860,7 +858,6 @@ namespace FluentAssertions.Equivalency { System.Type DeclaringType { get; } FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - bool IsBrowsable { get; } System.Type ReflectedType { get; } FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } object GetValue(object obj); @@ -964,7 +961,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -993,7 +989,6 @@ namespace FluentAssertions.Equivalency public TSelf ExcludingFields() { } public TSelf ExcludingMissingMembers() { } public TSelf ExcludingNestedObjects() { } - public TSelf ExcludingNonBrowsableMembers() { } public TSelf ExcludingProperties() { } public TSelf IgnoringCyclicReferences() { } public TSelf Including(System.Linq.Expressions.Expression> predicate) { } @@ -1003,7 +998,6 @@ namespace FluentAssertions.Equivalency public TSelf IncludingInternalFields() { } public TSelf IncludingInternalProperties() { } public TSelf IncludingNestedObjects() { } - public TSelf IncludingNonBrowsableMembers() { } public TSelf IncludingProperties() { } public TSelf RespectingDeclaredTypes() { } public TSelf RespectingRuntimeTypes() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index 1febb34719..97296cf147 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -796,7 +796,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; set; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -817,7 +816,6 @@ namespace FluentAssertions.Equivalency FluentAssertions.Equivalency.ConversionSelector ConversionSelector { get; } FluentAssertions.Equivalency.CyclicReferenceHandling CyclicReferenceHandling { get; } FluentAssertions.Equivalency.EnumEquivalencyHandling EnumEquivalencyHandling { get; } - bool ExcludeNonBrowsable { get; } FluentAssertions.Equivalency.MemberVisibility IncludedFields { get; } FluentAssertions.Equivalency.MemberVisibility IncludedProperties { get; } bool IsRecursive { get; } @@ -853,7 +851,6 @@ namespace FluentAssertions.Equivalency { System.Type DeclaringType { get; } FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - bool IsBrowsable { get; } System.Type ReflectedType { get; } FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } object GetValue(object obj); @@ -957,7 +954,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -986,7 +982,6 @@ namespace FluentAssertions.Equivalency public TSelf ExcludingFields() { } public TSelf ExcludingMissingMembers() { } public TSelf ExcludingNestedObjects() { } - public TSelf ExcludingNonBrowsableMembers() { } public TSelf ExcludingProperties() { } public TSelf IgnoringCyclicReferences() { } public TSelf Including(System.Linq.Expressions.Expression> predicate) { } @@ -996,7 +991,6 @@ namespace FluentAssertions.Equivalency public TSelf IncludingInternalFields() { } public TSelf IncludingInternalProperties() { } public TSelf IncludingNestedObjects() { } - public TSelf IncludingNonBrowsableMembers() { } public TSelf IncludingProperties() { } public TSelf RespectingDeclaredTypes() { } public TSelf RespectingRuntimeTypes() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index cb6de097da..812a1e0735 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -803,7 +803,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; set; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -824,7 +823,6 @@ namespace FluentAssertions.Equivalency FluentAssertions.Equivalency.ConversionSelector ConversionSelector { get; } FluentAssertions.Equivalency.CyclicReferenceHandling CyclicReferenceHandling { get; } FluentAssertions.Equivalency.EnumEquivalencyHandling EnumEquivalencyHandling { get; } - bool ExcludeNonBrowsable { get; } FluentAssertions.Equivalency.MemberVisibility IncludedFields { get; } FluentAssertions.Equivalency.MemberVisibility IncludedProperties { get; } bool IsRecursive { get; } @@ -860,7 +858,6 @@ namespace FluentAssertions.Equivalency { System.Type DeclaringType { get; } FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - bool IsBrowsable { get; } System.Type ReflectedType { get; } FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } object GetValue(object obj); @@ -964,7 +961,6 @@ namespace FluentAssertions.Equivalency public System.Type DeclaringType { get; } public override string Description { get; } public FluentAssertions.Common.CSharpAccessModifier GetterAccessibility { get; } - public bool IsBrowsable { get; } public System.Type ReflectedType { get; } public FluentAssertions.Common.CSharpAccessModifier SetterAccessibility { get; } public object GetValue(object obj) { } @@ -993,7 +989,6 @@ namespace FluentAssertions.Equivalency public TSelf ExcludingFields() { } public TSelf ExcludingMissingMembers() { } public TSelf ExcludingNestedObjects() { } - public TSelf ExcludingNonBrowsableMembers() { } public TSelf ExcludingProperties() { } public TSelf IgnoringCyclicReferences() { } public TSelf Including(System.Linq.Expressions.Expression> predicate) { } @@ -1003,7 +998,6 @@ namespace FluentAssertions.Equivalency public TSelf IncludingInternalFields() { } public TSelf IncludingInternalProperties() { } public TSelf IncludingNestedObjects() { } - public TSelf IncludingNonBrowsableMembers() { } public TSelf IncludingProperties() { } public TSelf RespectingDeclaredTypes() { } public TSelf RespectingRuntimeTypes() { } diff --git a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs b/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs deleted file mode 100644 index fc7948ee47..0000000000 --- a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.ComponentModel; -using System.Reflection; - -using BenchmarkDotNet.Attributes; - -namespace Benchmarks -{ - [MemoryDiagnoser] - public class CheckIfMemberIsBrowsableBenchmarks - { - [Params(true, false)] - public bool IsBrowsable { get; set; } - - public int BrowsableField; - [EditorBrowsable(EditorBrowsableState.Never)] - public int NonBrowsableField; - - public FieldInfo SubjectField => typeof(CheckIfMemberIsBrowsableBenchmarks) - .GetField(IsBrowsable ? nameof(BrowsableField) : nameof(NonBrowsableField)); - - [Benchmark] - public void CheckIfMemberIsBrowsable() - { - bool _ = - SubjectField.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; - } - } -} diff --git a/Tests/Benchmarks/Program.cs b/Tests/Benchmarks/Program.cs index 7409b520f4..4f917d4cad 100644 --- a/Tests/Benchmarks/Program.cs +++ b/Tests/Benchmarks/Program.cs @@ -22,7 +22,7 @@ public static void Main() var config = ManualConfig.CreateMinimumViable().AddExporter(exporter); - _ = BenchmarkRunner.Run(config); + _ = BenchmarkRunner.Run(config); } } } diff --git a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs index c95bf80054..0d087c06fd 100644 --- a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs +++ b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs @@ -69,8 +69,6 @@ private class Config : IEquivalencyAssertionOptions public MemberVisibility IncludedFields => throw new NotImplementedException(); - public bool ExcludeNonBrowsable => throw new NotImplementedException(); - public bool CompareRecordsByValue => throw new NotImplementedException(); public ITraceWriter TraceWriter => throw new NotImplementedException(); diff --git a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs index 97e548cb5f..84f742b874 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; @@ -1490,262 +1489,5 @@ public void Including_an_interface_property_through_inheritance_should_work() .Including(a => a.Value2) .RespectingRuntimeTypes()); } - - [Fact] - public void When_browsable_field_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { BrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { BrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_browsable_property_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { BrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { BrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_advanced_browsable_field_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { AdvancedBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { AdvancedBrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_advanced_browsable_property_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { AdvancedBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { AdvancedBrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_explicitly_browsable_field_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_explicitly_browsable_property_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_non_browsable_field_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { NonBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_non_browsable_property_differs_including_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.IncludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_browsable_field_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { BrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { BrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_browsable_property_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { BrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { BrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_advanced_browsable_field_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { AdvancedBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { AdvancedBrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_advanced_browsable_property_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { AdvancedBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { AdvancedBrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_explicilty_browsable_field_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableField = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_explicilty_browsable_property_differs_excluding_non_browsable_members_should_not_affect_result() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { ExplicitlyBrowsableProperty = 1 }; - - // Act - Action action = - () => subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - - // Assert - action.Should().Throw(); - } - - [Fact] - public void When_non_browsable_field_differs_excluding_non_browsable_members_should_make_it_succeed() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { NonBrowsableField = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableField = 1 }; - - // Act & Assert - subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - } - - [Fact] - public void When_non_browsable_property_differs_excluding_non_browsable_members_should_make_it_succeed() - { - // Arrange - var subject = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 0 }; - var expectation = new ClassWithNonBrowsableMembers() { NonBrowsableProperty = 1 }; - - // Act & Assert - subject.Should().BeEquivalentTo(expectation, config => config.ExcludingNonBrowsableMembers()); - } - - private class ClassWithNonBrowsableMembers - { - public int BrowsableField; - - public int BrowsableProperty { get; set; } - - [EditorBrowsable(EditorBrowsableState.Always)] - public int ExplicitlyBrowsableField; - - [EditorBrowsable(EditorBrowsableState.Always)] - public int ExplicitlyBrowsableProperty { get; set; } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public int AdvancedBrowsableField; - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public int AdvancedBrowsableProperty { get; set; } - - [EditorBrowsable(EditorBrowsableState.Never)] - public int NonBrowsableField; - - [EditorBrowsable(EditorBrowsableState.Never)] - public int NonBrowsableProperty { get; set; } - } } } diff --git a/docs/_pages/objectgraphs.md b/docs/_pages/objectgraphs.md index a21abb76ed..505e186e59 100644 --- a/docs/_pages/objectgraphs.md +++ b/docs/_pages/objectgraphs.md @@ -216,27 +216,6 @@ orderDto.Should().BeEquivalentTo(order, options => options Notice that you can also map properties to fields and vice-versa. -### Hidden Members - -Sometimes types have members out of necessity, to satisfy a contract, but they aren't logically a part of the type. In this case, they are often marked with the attribute `[EditorBrowsable(EditorBrowsableState.Never)]`, so that the object can satisfy the contract but the members don't show up in IntelliSense when writing code that uses the type. - -If you want to compare objects that have such fields, but you want to exclude the non-browsable "hidden" members (for instance, their implementations often simply throw `NotImplementedException`), you can call `ExcludingNonBrowsableMembers` on the options object: - -```csharp -class DataType -{ - public int X { get; } - - [EditorBrowsable(EditorBrowsableState.Never)] - public int Y => throw new NotImplementedException(); -} - -DataType original, derived; - -derived.Should().BeEquivalentTo(original, options => options - .ExcludingNonBrowsableMembers()); -``` - ### Equivalency Comparison Behavior In addition to influencing the members that are including in the comparison, you can also override the actual assertion operation that is executed on a particular member. diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index ca79d496b8..2f7856e182 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -11,7 +11,6 @@ sidebar: ### What's New * Annotated `[Not]MatchRegex(string)` with `[StringSyntax("Regex")]` which IDEs can use to colorize the regular expression argument - [#1816](https://github.com/fluentassertions/fluentassertions/pull/1816) -* Added the ability to exclude fields & properties marked as non-browsable in the code editor from structural equality equivalency comparisons - [#1807](https://github.com/fluentassertions/fluentassertions/pull/1807) ### Fixes * `EnumAssertions.Be` did not determine the caller name - [#1835](https://github.com/fluentassertions/fluentassertions/pull/1835) @@ -21,7 +20,7 @@ sidebar: ## 6.5.1 ### Fixes -* Fixed regression introduced in 6.5.0 where `collection.Should().BeInAscendingOrder(x => x)` would fail - [#1802](https://github.com/fluentassertions/fluentassertions/pull/1802) +* Fix regression introduced in 6.5.0 where `collection.Should().BeInAscendingOrder(x => x)` would fail - [#1802](https://github.com/fluentassertions/fluentassertions/pull/1802) ## 6.5.0