Skip to content

Commit

Permalink
Extend ThatArePublicOrInternal to also look at the setter of proper…
Browse files Browse the repository at this point in the history
…ties (#2082)

Co-authored-by: IT-VBFK <49762557+IT-VBFK@users.noreply.github.com>
  • Loading branch information
Ruijin92 and IT-VBFK committed Jan 10, 2023
1 parent fc0ffde commit 8afc473
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 22 deletions.
6 changes: 3 additions & 3 deletions Src/FluentAssertions/Types/PropertyInfoSelector.cs
Expand Up @@ -40,16 +40,16 @@ public PropertyInfoSelector(IEnumerable<Type> types)
}

/// <summary>
/// Only select the properties that have a public or internal getter.
/// Only select the properties that have at least one public or internal accessor
/// </summary>
public PropertyInfoSelector ThatArePublicOrInternal
{
get
{
selectedProperties = selectedProperties.Where(property =>
{
MethodInfo getter = property.GetGetMethod(nonPublic: true);
return (getter is not null) && (getter.IsPublic || getter.IsAssembly);
return property.GetGetMethod(nonPublic: true) is { IsPublic: true } or { IsAssembly: true }
|| property.GetSetMethod(nonPublic: true) is { IsPublic: true } or { IsAssembly: true };
});

return this;
Expand Down
87 changes: 68 additions & 19 deletions Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using FluentAssertions.Types;
using Internal.Main.Test;
Expand Down Expand Up @@ -216,23 +215,6 @@ public void When_selecting_methods_that_do_not_return_a_specific_type_it_should_
properties.Should().HaveCount(4);
}

[Fact]
public void When_combining_filters_to_filter_methods_it_should_return_only_the_applicable_methods()
{
// Arrange
Type type = typeof(TestClassForPropertySelector);

// Act
IEnumerable<PropertyInfo> properties = type.Properties()
.ThatArePublicOrInternal
.OfType<string>()
.ThatAreDecoratedWith<DummyPropertyAttribute>()
.ToArray();

// Assert
properties.Should().ContainSingle();
}

[Fact]
public void When_selecting_properties_decorated_with_an_inheritable_attribute_it_should_only_return_the_applicable_properties()
{
Expand Down Expand Up @@ -355,6 +337,74 @@ public void When_selecting_properties_return_types_it_should_return_the_correct_
, typeof(string), typeof(int), typeof(int), typeof(int), typeof(int)
});
}

public class ThatArePublicOrInternal
{
[Fact]
public void When_combining_filters_to_filter_methods_it_should_return_only_the_applicable_methods()
{
// Arrange
Type type = typeof(TestClassForPropertySelector);

// Act
IEnumerable<PropertyInfo> properties = type.Properties()
.ThatArePublicOrInternal
.OfType<string>()
.ThatAreDecoratedWith<DummyPropertyAttribute>()
.ToArray();

// Assert
properties.Should().ContainSingle();
}

[Fact]
public void When_a_property_only_has_a_public_setter_it_should_be_included_in_the_applicable_properties()
{
// Arrange
Type type = typeof(TestClassForPublicSetter);

// Act
IEnumerable<PropertyInfo> properties = type.Properties().ThatArePublicOrInternal.ToArray();

// Assert
properties.Should().HaveCount(3);
}

private class TestClassForPublicSetter
{
private static string myPrivateStaticStringField;

public static string PublicStaticStringProperty { set => myPrivateStaticStringField = value; }

public static string InternalStaticStringProperty { get; set; }

public int PublicIntProperty { get; init; }
}

[Fact]
public void When_selecting_properties_with_at_least_one_accessor_being_private_should_return_the_applicable_properties()
{
// Arrange
Type type = typeof(TestClassForPrivateAccessors);

// Act
IEnumerable<PropertyInfo> properties = type.Properties().ThatArePublicOrInternal.ToArray();

// Assert
properties.Should().HaveCount(4);
}

private class TestClassForPrivateAccessors
{
public bool PublicBoolPrivateGet { private get; set; }

public bool PublicBoolPrivateSet { get; private set; }

internal bool InternalBoolPrivateGet { private get; set; }

internal bool InternalBoolPrivateSet { get; private set; }
}
}
}

#region Internal classes used in unit tests
Expand Down Expand Up @@ -455,5 +505,4 @@ public DummyPropertyAttribute(string value)

public string Value { get; private set; }
}

#endregion
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Expand Up @@ -22,6 +22,7 @@ sidebar:
* Added new extension methods to be able to write `Exactly.Times(n)`, `AtLeast.Times(n)` and `AtMost.Times(n)` in a more fluent way - [#2047](https://github.com/fluentassertions/fluentassertions/pull/2047)

### Fixes
* `PropertyInfoSelector.ThatArePublicOrInternal` now takes the setter into account when determining if a property is `public` or `internal` - [#2082] (https://github.com/fluentassertions/fluentassertions/pull/2082)
* Quering properties on classes, e.g. `typeof(MyClass).Properties()`, now also includes static properties - [#2054](https://github.com/fluentassertions/fluentassertions/pull/2054)
* Nested AssertionScopes now print the inner scope reportables - [#2044](https://github.com/fluentassertions/fluentassertions/pull/2044)
* Throw `ArgumentException` instead of `ArgumentNullException` when a required `string` argument is empty - [#2023](https://github.com/fluentassertions/fluentassertions/pull/2023)
Expand Down

0 comments on commit 8afc473

Please sign in to comment.