From 885f873973a638f4ce9a35a46f150175a64d015f Mon Sep 17 00:00:00 2001 From: chvollm <37902729+chvollm@users.noreply.github.com> Date: Thu, 6 Jan 2022 14:21:36 +0100 Subject: [PATCH] Adds ThatAreStatic and ThatAreNotStatic to method-level Reflection assertions (#1740) --- .../Types/MethodInfoSelector.cs | 20 ++++++++++- .../FluentAssertions/net47.verified.txt | 2 ++ .../netcoreapp2.1.verified.txt | 2 ++ .../netcoreapp3.0.verified.txt | 2 ++ .../netstandard2.0.verified.txt | 2 ++ .../netstandard2.1.verified.txt | 2 ++ .../Types/MethodInfoSelectorSpecs.cs | 35 +++++++++++++++++++ docs/_pages/releases.md | 3 +- 8 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Types/MethodInfoSelector.cs b/Src/FluentAssertions/Types/MethodInfoSelector.cs index e3ba8ca102..f800d0d656 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelector.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelector.cs @@ -35,7 +35,7 @@ public MethodInfoSelector(IEnumerable types) Guard.ThrowIfArgumentContainsNull(types, nameof(types)); selectedMethods = types.SelectMany(t => t - .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(method => !HasSpecialName(method))); } @@ -151,6 +151,24 @@ public MethodInfoSelector ThatAreNotAsync() return this; } + /// + /// Only return methods that are static. + /// + public MethodInfoSelector ThatAreStatic() + { + selectedMethods = selectedMethods.Where(method => method.IsStatic); + return this; + } + + /// + /// Only return methods that are not static. + /// + public MethodInfoSelector ThatAreNotStatic() + { + selectedMethods = selectedMethods.Where(method => !method.IsStatic); + return this; + } + /// /// Only return methods that are virtual. /// diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index ee73949aa0..0f7328406c 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -2363,7 +2363,9 @@ namespace FluentAssertions.Types where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } public FluentAssertions.Types.MethodInfoSelector ThatReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index d5b927c7d6..8427581cf0 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -2365,7 +2365,9 @@ namespace FluentAssertions.Types where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } public FluentAssertions.Types.MethodInfoSelector ThatReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index 62d7b60d9a..d0c715644a 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -2365,7 +2365,9 @@ namespace FluentAssertions.Types where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } public FluentAssertions.Types.MethodInfoSelector ThatReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index 45c197d938..9b13b251b7 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -2316,7 +2316,9 @@ namespace FluentAssertions.Types where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } public FluentAssertions.Types.MethodInfoSelector ThatReturn() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index 49ebf2d8c8..ea94174c5a 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -2365,7 +2365,9 @@ namespace FluentAssertions.Types where TAttribute : System.Attribute { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotDecoratedWithOrInherit() where TAttribute : System.Attribute { } + public FluentAssertions.Types.MethodInfoSelector ThatAreNotStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreNotVirtual() { } + public FluentAssertions.Types.MethodInfoSelector ThatAreStatic() { } public FluentAssertions.Types.MethodInfoSelector ThatAreVirtual() { } public FluentAssertions.Types.MethodInfoSelector ThatDoNotReturn() { } public FluentAssertions.Types.MethodInfoSelector ThatReturn() { } diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs index f32f2c9911..e56e41f242 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs @@ -332,6 +332,34 @@ public void When_selecting_methods_that_are_not_virtual_it_should_only_return_th .And.NotContain(m => m.Name == "PublicVirtualVoidMethodWithAttribute") .And.NotContain(m => m.Name == "ProtectedVirtualVoidMethodWithAttribute"); } + + [Fact] + public void When_selecting_methods_that_are_static_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithStaticAndNonStaticMethod); + + // Act + MethodInfo[] methods = type.Methods().ThatAreStatic().ToArray(); + + // Assert + methods.Should().ContainSingle() + .Which.Name.Should().Be("PublicStaticMethod"); + } + + [Fact] + public void When_selecting_methods_that_are_not_static_it_should_only_return_the_applicable_methods() + { + // Arrange + Type type = typeof(TestClassForMethodSelectorWithStaticAndNonStaticMethod); + + // Act + MethodInfo[] methods = type.Methods().ThatAreNotStatic().ToArray(); + + // Assert + methods.Should().ContainSingle() + .Which.Name.Should().Be("PublicNonStaticMethod"); + } [Fact] public void When_selecting_methods_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() @@ -435,6 +463,13 @@ internal class TestClassForMethodSelectorWithAsyncAndNonAsyncMethod public Task PublicNonAsyncMethod() => Task.CompletedTask; } + internal class TestClassForMethodSelectorWithStaticAndNonStaticMethod + { + public static void PublicStaticMethod() { } + + public void PublicNonStaticMethod() { } + } + internal class TestClassForMethodReturnTypesSelector { public void SomeMethod() { } diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index efad6be024..be1359083f 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -18,10 +18,11 @@ sidebar: ### What's New * Adding `ThatAreAsync()` and `ThatAreNotAsync()` for filtering in method assertions - [#1725](https://github.com/fluentassertions/fluentassertions/pull/1725) * Adding `ThatAreVirtual()` and `ThatAreNotVirtual()` for filtering in method assertions - [#1744](https://github.com/fluentassertions/fluentassertions/pull/1744) +* Adding `ThatAreStatic()` and `ThatAreNotStatic()` for filtering in method assertions - [#1740](https://github.com/fluentassertions/fluentassertions/pull/1740) * Adding collection content to assertion messages for `HaveCountGreaterThan()`, `HaveCountGreaterThanOrEqualTo()`, `HaveCountLessThan()` and `HaveCountLessThanOrEqualTo()` - [#1760](https://github.com/fluentassertions/fluentassertions/pull/1760) - ### Fixes * Prevent multiple enumeration of `IEnumerable`s in parameter-less `ContainSingle()` - [#1753](https://github.com/fluentassertions/fluentassertions/pull/1753) +* Querying methods on classes, e.g. `typeof(MyController).Methods()`, now also includes static methods - [#1740](https://github.com/fluentassertions/fluentassertions/pull/1740) * Change `HaveCount()` assertion message order to state expected and actual collection count before dumping its content` - [#1760](https://github.com/fluentassertions/fluentassertions/pull/1760) * `CompleteWithinAsync` did not take initial sync computation into account when measuring execution time - [1762](https://github.com/fluentassertions/fluentassertions/pull/1762).