Skip to content

Commit

Permalink
xunit/xunit#2803: Add support for KeyValuePair<,> in AssertEqualityCo…
Browse files Browse the repository at this point in the history
…mparer to enable collections in values
  • Loading branch information
bradwilson committed Oct 25, 2023
1 parent a92673b commit 4828bf1
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions Sdk/AssertEqualityComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ sealed class AssertEqualityComparer<T> : IEqualityComparer<T>
internal static readonly IEqualityComparer DefaultInnerComparer = new AssertEqualityComparerAdapter<object>(new AssertEqualityComparer<object>());

readonly Lazy<IEqualityComparer> innerComparer;
static readonly Type typeKeyValuePair = typeof(KeyValuePair<,>);

/// <summary>
/// Initializes a new instance of the <see cref="AssertEqualityComparer{T}" /> class.
Expand Down Expand Up @@ -84,8 +85,12 @@ public AssertEqualityComparer(IEqualityComparer innerComparer = null)
return equatable.Equals(y);

// Implements IEquatable<typeof(y)>?
var iequatableY = typeof(IEquatable<>).MakeGenericType(y.GetType()).GetTypeInfo();
if (iequatableY.IsAssignableFrom(x.GetType().GetTypeInfo()))
var xType = x.GetType();
var xTypeInfo = xType.GetTypeInfo();
var yType = y.GetType();

var iequatableY = typeof(IEquatable<>).MakeGenericType(yType).GetTypeInfo();
if (iequatableY.IsAssignableFrom(xTypeInfo))
{
var equalsMethod = iequatableY.GetDeclaredMethod(nameof(IEquatable<T>.Equals));
if (equalsMethod == null)
Expand Down Expand Up @@ -120,8 +125,8 @@ public AssertEqualityComparer(IEqualityComparer innerComparer = null)
}

// Implements IComparable<typeof(y)>?
var icomparableY = typeof(IComparable<>).MakeGenericType(y.GetType()).GetTypeInfo();
if (icomparableY.IsAssignableFrom(x.GetType().GetTypeInfo()))
var icomparableY = typeof(IComparable<>).MakeGenericType(yType).GetTypeInfo();
if (icomparableY.IsAssignableFrom(xTypeInfo))
{
var compareToMethod = icomparableY.GetDeclaredMethod(nameof(IComparable<T>.CompareTo));
if (compareToMethod == null)
Expand Down Expand Up @@ -159,6 +164,17 @@ public AssertEqualityComparer(IEqualityComparer innerComparer = null)
}
}

// Special case KeyValuePair<K,V>
if (xType.IsConstructedGenericType &&
xType.GetGenericTypeDefinition() == typeKeyValuePair &&
yType.IsConstructedGenericType &&
yType.GetGenericTypeDefinition() == typeKeyValuePair)
{
return
innerComparer.Value.Equals(xType.GetRuntimeProperty("Key")?.GetValue(x), yType.GetRuntimeProperty("Key")?.GetValue(y)) &&
innerComparer.Value.Equals(xType.GetRuntimeProperty("Value")?.GetValue(x), yType.GetRuntimeProperty("Value")?.GetValue(y));
}

// Last case, rely on object.Equals
return object.Equals(x, y);
}
Expand Down

0 comments on commit 4828bf1

Please sign in to comment.