diff --git a/Src/FluentAssertions/Types/MethodInfoSelector.cs b/Src/FluentAssertions/Types/MethodInfoSelector.cs index d4fa94c6be..99d901b686 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelector.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelector.cs @@ -133,6 +133,26 @@ public MethodInfoSelector ThatAreNotDecoratedWithOrInherit() return this; } + /// + /// Only return methods that are abstract + /// + /// + public MethodInfoSelector ThatAreAbstract() + { + selectedMethods = selectedMethods.Where(method => method.IsAbstract); + return this; + } + + /// + /// Only return methods that are not abstract + /// + /// + 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..7c93890a43 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -2466,11 +2466,13 @@ 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 { } @@ -2765,4 +2767,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..4cbc9f2754 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt @@ -2596,11 +2596,13 @@ 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 { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index 719ef3ffd9..7336745d9f 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -2468,11 +2468,13 @@ 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 { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index 719ef3ffd9..7336745d9f 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -2468,11 +2468,13 @@ 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 { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index db65bed2b7..2c94a2a004 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -2417,11 +2417,13 @@ 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 { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index 719ef3ffd9..7336745d9f 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -2468,11 +2468,13 @@ 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 { } diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs index 05a3ee9586..18a2720555 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs @@ -273,6 +273,34 @@ public void When_selecting_methods_not_decorated_with_a_noninheritable_attribute methods.Should().ContainSingle(); } + [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() { @@ -504,4 +532,27 @@ public class DummyMethodAttribute : Attribute public bool Filter { get; set; } } +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() { } +} + #endregion