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

Test that ComparingByMembers clears equalityStrategyCache #1724

Merged
merged 1 commit into from Oct 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Src/FluentAssertions/Common/TypeExtensions.cs
Expand Up @@ -217,7 +217,7 @@ public static IEnumerable<MemberInfo> GetNonPrivateMembers(this Type typeToRefle

public static IEnumerable<PropertyInfo> GetNonPrivateProperties(this Type typeToReflect, MemberVisibility visibility)
{
return NonPrivatePropertiesCache.GetOrAdd((typeToReflect, visibility), key =>
return NonPrivatePropertiesCache.GetOrAdd((typeToReflect, visibility), static key =>
{
IEnumerable<PropertyInfo> query =
from propertyInfo in GetPropertiesFromHierarchy(key.Type, key.Visibility)
Expand Down Expand Up @@ -245,7 +245,7 @@ private static IEnumerable<PropertyInfo> GetPropertiesFromHierarchy(Type typeToR

public static IEnumerable<FieldInfo> GetNonPrivateFields(this Type typeToReflect, MemberVisibility visibility)
{
return NonPrivateFieldsCache.GetOrAdd((typeToReflect, visibility), key =>
return NonPrivateFieldsCache.GetOrAdd((typeToReflect, visibility), static key =>
{
IEnumerable<FieldInfo> query =
from fieldInfo in GetFieldsFromHierarchy(key.Type, key.Visibility)
Expand Down Expand Up @@ -533,7 +533,7 @@ public static MethodInfo GetImplicitConversionOperator(this Type type, Type sour

public static bool HasValueSemantics(this Type type)
{
return HasValueSemanticsCache.GetOrAdd(type, t =>
return HasValueSemanticsCache.GetOrAdd(type, static t =>
t.OverridesEquals() &&
!t.IsAnonymousType() &&
!t.IsTuple() &&
Expand Down Expand Up @@ -583,7 +583,7 @@ private static bool IsAnonymousType(this Type type)

public static bool IsRecord(this Type type)
{
return TypeIsRecordCache.GetOrAdd(type, t =>
return TypeIsRecordCache.GetOrAdd(type, static t =>
t.GetMethod("<Clone>$") is not null &&
t.GetTypeInfo()
.DeclaredProperties
Expand Down
Expand Up @@ -166,6 +166,8 @@ IEnumerable<IMemberSelectionRule> IEquivalencyAssertionOptions.SelectionRules

EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type requestedType)
{
// As the valueFactory parameter captures instance members,
// be aware if the cache must be cleared on mutating the members.
return equalityStrategyCache.GetOrAdd(requestedType, type =>
{
EqualityStrategy strategy;
Expand Down
Expand Up @@ -95,7 +95,7 @@ public static bool TryGetFromWithKey(Type target, string role, Type key, out Dic

private static DictionaryInterfaceInfo[] GetDictionaryInterfacesFrom(Type target)
{
return Cache.GetOrAdd(target, key =>
return Cache.GetOrAdd(target, static key =>
{
if (Type.GetTypeCode(key) != TypeCode.Object)
{
Expand Down
41 changes: 39 additions & 2 deletions Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs
Expand Up @@ -54,9 +54,46 @@ public void It_should_not_throw()
}

[Collection("AssertionOptionsSpecs")]
public class When_modifying_global_settings_a_previous_assertion_should_not_have_any_effect : Given_temporary_global_assertion_options
public class When_modifying_global_reference_type_settings_a_previous_assertion_should_not_have_any_effect
: Given_temporary_global_assertion_options
{
public When_modifying_global_settings_a_previous_assertion_should_not_have_any_effect()
public When_modifying_global_reference_type_settings_a_previous_assertion_should_not_have_any_effect()
{
Given(() =>
{
// Trigger a first equivalency check using the default global settings
new MyValueType { Value = 1 }.Should().BeEquivalentTo(new MyValueType { Value = 2 });
});

When(() =>
{
AssertionOptions.AssertEquivalencyUsing(o => o.ComparingByMembers<MyValueType>());
});
}

[Fact]
public void It_should_try_to_compare_the_classes_by_member_semantics_and_thus_throw()
{
Action act = () => new MyValueType { Value = 1 }.Should().BeEquivalentTo(new MyValueType { Value = 2 });

act.Should().Throw<XunitException>();
}
}

internal class MyValueType
{
public int Value { get; set; }

public override bool Equals(object obj) => true;

public override int GetHashCode() => 0;
}

[Collection("AssertionOptionsSpecs")]
public class When_modifying_global_value_type_settings_a_previous_assertion_should_not_have_any_effect
: Given_temporary_global_assertion_options
{
public When_modifying_global_value_type_settings_a_previous_assertion_should_not_have_any_effect()
{
Given(() =>
{
Expand Down
Expand Up @@ -10,7 +10,7 @@ internal static class DictionaryExtensions

public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TValue : new() =>
dictionary.GetOrAdd(key, () => new TValue());
dictionary.GetOrAdd(key, static () => new TValue());

public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> newValue)
{
Expand Down