Skip to content

Commit

Permalink
xunit/xunit#2431 Enabled equivalence checks for reference types insid…
Browse files Browse the repository at this point in the history
…e of value types (#57)
  • Loading branch information
koenigst committed Feb 12, 2023
1 parent 3716d30 commit 4899f6e
Showing 1 changed file with 13 additions and 37 deletions.
50 changes: 13 additions & 37 deletions Sdk/AssertHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,49 +113,25 @@ internal static class AssertHelper
{
var expectedType = expected.GetType();
var expectedTypeInfo = expectedType.GetTypeInfo();
var actualType = actual.GetType();
var actualTypeInfo = actualType.GetTypeInfo();

// KeyValuePair<,> should compare key and value for equivalence; since KVP is a value
// type, we want to avoid just calling Equals(), since it's not a good enough test of
// equivalence for us (we want equivalence tests for both key and value).
if (expectedTypeInfo.IsGenericType &&
expectedTypeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair<,>) &&
actualTypeInfo.IsGenericType &&
actualTypeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
{
var prefixDot = prefix == string.Empty ? string.Empty : prefix + ".";

var expectedKeyGetter = expectedType.GetRuntimeProperty("Key");
var actualKeyGetter = actualType.GetRuntimeProperty("Key");
if (expectedKeyGetter == null || actualKeyGetter == null)
throw new InvalidOperationException("Catastrophic failure: Could not find KeyValuePair<,>.Key via reflection");

var expectedKey = expectedKeyGetter.GetValue(expected);
var actualKey = actualKeyGetter.GetValue(actual);

var keyResult = VerifyEquivalence(expectedKey, actualKey, strict, prefixDot + "Key", expectedRefs, actualRefs);
if (keyResult != null)
return keyResult;

var expectedValueGetter = expectedType.GetRuntimeProperty("Value");
var actualValueGetter = actualType.GetRuntimeProperty("Value");
if (expectedValueGetter == null || actualValueGetter == null)
throw new InvalidOperationException("Catastrophic failure: Could not find KeyValuePair<,>.Value via reflection");

var expectedValue = expectedValueGetter.GetValue(expected);
var actualValue = actualValueGetter.GetValue(actual);

return VerifyEquivalence(expectedValue, actualValue, strict, prefixDot + "Value", expectedRefs, actualRefs);
}

// Value types and strings should just fall back to their Equals implementation
if (expectedTypeInfo.IsValueType || expectedType == typeof(string))
// Primitive types, enums and strings should just fall back to their Equals implementation
if (expectedTypeInfo.IsPrimitive || expectedTypeInfo.IsEnum || expectedType == typeof(string))
return
expected.Equals(actual)
? null
: EquivalentException.ForMemberValueMismatch(expected, actual, prefix);

// IComparable value types should fall back to their CompareTo implementation
if (expectedTypeInfo.IsValueType)
{
var expectedComparable = expected as IComparable;
if (expectedComparable != null)
return
expectedComparable.CompareTo(actual) == 0
? null
: EquivalentException.ForMemberValueMismatch(expected, actual, prefix);
}

// Enumerables? Check equivalence of individual members
var enumerableExpected = expected as IEnumerable;
var enumerableActual = actual as IEnumerable;
Expand Down

0 comments on commit 4899f6e

Please sign in to comment.