From 1616ca1d6708353c012d76709d7791699fc8a828 Mon Sep 17 00:00:00 2001 From: 94sedighi Date: Fri, 2 Dec 2022 14:10:11 +0100 Subject: [PATCH] Add ThatAre[Not]Abstract, ThatAre[Not]Overridable to MethodInfoSelector (as mentioned in More Assertions on types #645) --- .../Types/MethodInfoSelector.cs | 36 +++++++++ .../FluentAssertions/net47.verified.txt | 6 +- .../FluentAssertions/net6.0.verified.txt | 4 + .../netcoreapp2.1.verified.txt | 4 + .../netcoreapp3.0.verified.txt | 4 + .../netstandard2.0.verified.txt | 4 + .../netstandard2.1.verified.txt | 4 + .../Types/MethodInfoSelectorSpecs.cs | 79 +++++++++++++++++++ 8 files changed, 140 insertions(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Types/MethodInfoSelector.cs b/Src/FluentAssertions/Types/MethodInfoSelector.cs index d4fa94c6be..031a5d26b0 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelector.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelector.cs @@ -133,6 +133,42 @@ public MethodInfoSelector ThatAreNotDecoratedWithOrInherit() return this; } + /// + /// Only return methods that are overridable + /// + /// + public MethodInfoSelector ThatAreOverridable() + { + selectedMethods = selectedMethods.Where(method => !method.IsFinal && method.IsVirtual); + return this; + } + + /// + /// Only return methods that are not overridable + /// + /// + public MethodInfoSelector ThatAreNotOverridable() + { + selectedMethods = selectedMethods.Where(method => method.IsFinal || !method.IsVirtual); + return this; + } + + /// + /// Only return methods that are abstract + /// + /// + public MethodInfoSelector ThatAreAbstract() + { + selectedMethods = selectedMethods.Where(method => method.IsAbstract); + return this; + } + + public MethodInfoSelector ThatAreNotAbstract() + { + selectedMethods = selectedMethods.Where(method => !method.IsAbstract); + return this; + } + /// /// Only return methods that are async. /// diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index d9ee0bbaf3..de5e30aa78 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -2466,18 +2466,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } @@ -2765,4 +2769,4 @@ namespace FluentAssertions.Xml public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } -} +} \ No newline at end of file diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt index 645fd533da..a8eac78974 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt @@ -2596,18 +2596,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index 719ef3ffd9..1a005f4b1d 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -2468,18 +2468,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index 719ef3ffd9..1a005f4b1d 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -2468,18 +2468,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index db65bed2b7..48d6caaad2 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -2417,18 +2417,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index 719ef3ffd9..1a005f4b1d 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -2468,18 +2468,22 @@ namespace FluentAssertions.Types public FluentAssertions.Types.MethodInfoSelector ThatReturnVoid { get; } public System.Collections.Generic.IEnumerator GetEnumerator() { } public FluentAssertions.Types.TypeSelector ReturnTypes() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotAbstract() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotAsync() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWith() where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreOverridable() { } public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs index 05a3ee9586..a39a4991ef 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs @@ -273,6 +273,62 @@ public void When_selecting_methods_not_decorated_with_a_noninheritable_attribute methods.Should().ContainSingle(); } + [Fact] + public void When_selecting_methods_that_are_overridable_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithAbstractAndVirtualMethods); + + // Act + IEnumerable methods = type.Methods().ThatAreOverridable().ToArray(); + + // Assert + int overridableMethodsCount = 6; + methods.Should().HaveCount(overridableMethodsCount); + } + + [Fact] + public void When_selecting_methods_that_are_not_overridable_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithAbstractAndVirtualMethods); + + // Act + IEnumerable methods = type.Methods().ThatAreNotOverridable(); + + // Assert + int notOverridableCount = 4; + methods.Should().HaveCount(notOverridableCount); + } + + [Fact] + public void When_selecting_methods_that_are_abstract_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithAbstractAndVirtualMethods); + + // Act + IEnumerable methods = type.Methods().ThatAreAbstract().ToArray(); + + // Assert + int abstractMethodsCount = 3; + methods.Should().HaveCount(abstractMethodsCount); + } + + [Fact] + public void When_selecting_methods_that_are_not_abstract_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithAbstractAndVirtualMethods); + + // Act + IEnumerable methods = type.Methods().ThatAreNotAbstract().ToArray(); + + // Assert + int notAbstractMethodsCount = 7; + methods.Should().HaveCount(notAbstractMethodsCount); + } + [Fact] public void When_selecting_methods_that_are_async_it_should_only_return_the_applicable_methods() { @@ -483,6 +539,29 @@ internal class TestClassForMethodSelectorWithStaticAndNonStaticMethod public void PublicNonStaticMethod() { } } +internal abstract class TestClassForMethodSelectorWithAbstractAndVirtualMethods +{ + public abstract void PublicAbstractMethod(); + + protected abstract void ProtectedAbstractMethod(); + + internal abstract void InternalAbstractMethod(); + + public virtual void PublicVirtualMethod() { } + + protected virtual void ProptectedVirtualMethod() { } + + internal virtual void InternalVirtualMethod() { } + + public void PublicNotAbstractMethod() { } + + protected void ProtectedNotAbstractMethod() { } + + internal void InternalNotAbstractMethod() { } + + private void PrivateAbstractMethod() { } +} + internal class TestClassForMethodReturnTypesSelector { public void SomeMethod() { }