Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend ThatArePublicOrInternal to also look at the setter of properties #2082

Merged
merged 12 commits into from Jan 10, 2023
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 atleast one public or internal accessor
Ruijin92 marked this conversation as resolved.
Show resolved Hide resolved
/// </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
61 changes: 61 additions & 0 deletions Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs
Expand Up @@ -355,6 +355,45 @@ public void When_selecting_properties_return_types_it_should_return_the_correct_
, typeof(string), typeof(int), typeof(int), typeof(int), typeof(int)
});
}

[Fact]
public void When_selecting_properties_with_only_set_accessors_it_should_return_the_applicable_properties()
Ruijin92 marked this conversation as resolved.
Show resolved Hide resolved
{
// Arrange
Type type = typeof(TestClassForPropertyInfoSelector);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Although you just copied the way we did things before, I'd like us to start using an inline private class that only contains the relevant property(ies), right under the test. This makes the test much more readable and avoids unnecessarily long names like TestClassForPropertyInfoSelector.

Same for the other tests you introduced.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i unterstand it correctly, you want the tests inside the newly created ThatArePublicOrInternal class and under each of the tests?

I saw on other tests, that you introduced the "HelperTestClasses" in a seperated file partialling it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i unterstand it correctly, you want the tests inside the newly created ThatArePublicOrInternal class and under each of the tests?

Yes. If possible, we want our tests to be as self-explanatory as possible. And using reusable test classes spreaded around the code base doesn't help understanding why the number of properties is expected to be "3"

I saw on other tests, that you introduced the "HelperTestClasses" in a seperated file partialling it

That was a mistake ;-)


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

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

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

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

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

[Fact]
public void When_selecting_properties_with_atleast_one_accessor_being_private_should_return_the_applicable_properties()
{
// Arrange
Type type = typeof(TestClassForPropertyInfoSelectorWithOnePrivateAccessor);

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

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

#region Internal classes used in unit tests
Expand Down Expand Up @@ -456,4 +495,26 @@ public DummyPropertyAttribute(string value)
public string Value { get; private set; }
}

public class TestClassForPropertyInfoSelector
{
private static string myPrivateStaticStringField;

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

public static string InternalStaticStringProperty { get; set; }

public int PublicIntProperty { get; init; }
}

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

public bool PublicBoolPrivateSet { get; private set; }

internal bool InternalBoolPrivateGet { private get; set; }

internal bool InternalBoolPrivateSet { get; private set; }
}

#endregion
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Expand Up @@ -20,6 +20,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
* Fixed `ThatArePublicOrInternal` property of `PropertyInfoSelector` not including properties with set accessors - [#2084] (https://github.com/fluentassertions/fluentassertions/pull/2082)
Ruijin92 marked this conversation as resolved.
Show resolved Hide resolved
* 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