From 0bfb02190887a3024d576d48c14767724ec5d663 Mon Sep 17 00:00:00 2001 From: Davyd McColl Date: Wed, 13 Nov 2024 12:02:35 +0200 Subject: [PATCH] :recycle: better error messages for deep equivalence - also, perhaps a bug? when testing the output, I noticed two different collections not triggering failure, and it's likely because they were collections of ints where the default value is not null; at any rate, rewriting seems to have solved this --- src/NExpect/CollectionDeepEqualityMatchers.cs | 2 +- .../CollectionDeepEquivalenceMatchers.cs | 58 +++++++++++++++---- ...ectionIntersectionEquivalenceExtensions.cs | 10 +++- src/NExpect/CollectionMatchers.cs | 2 +- src/NExpect/DeepEqualityMatchers.cs | 2 +- src/NExpect/Helpers/DeepTestHelpers.cs | 8 +-- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/NExpect/CollectionDeepEqualityMatchers.cs b/src/NExpect/CollectionDeepEqualityMatchers.cs index edaef91..19ecca4 100644 --- a/src/NExpect/CollectionDeepEqualityMatchers.cs +++ b/src/NExpect/CollectionDeepEqualityMatchers.cs @@ -223,7 +223,7 @@ object[] customEqualityComparers } var result = - AreDeepEqual( + Compare( cur.Item1, cur.Item2, customEqualityComparers, diff --git a/src/NExpect/CollectionDeepEquivalenceMatchers.cs b/src/NExpect/CollectionDeepEquivalenceMatchers.cs index eb55ec6..ac88780 100644 --- a/src/NExpect/CollectionDeepEquivalenceMatchers.cs +++ b/src/NExpect/CollectionDeepEquivalenceMatchers.cs @@ -90,6 +90,12 @@ params object[] customEqualityComparers expected, customEqualityComparers ); + var errors = result.Errors.Any() + ? new[] + { + "" + }.Concat(result.Errors).ToArray() + : result.Errors; return new MatcherResult( result.AreEqual, () => FinalMessageFor( @@ -97,9 +103,9 @@ params object[] customEqualityComparers { "Expected", collection.LimitedPrint(), - $"{result.AreEqual.AsNot()} to be deep equivalent to", + $"\n{result.AreEqual.AsNot()}to be deep equivalent to\n", expected.LimitedPrint() - }.Concat(result.Errors).ToArray(), + }.Concat(errors).ToArray(), customMessageGenerator ) ); @@ -147,25 +153,53 @@ object[] customEqualityComparers } var ignoreProperties = currentMaster.FindOrAddPropertyIgnoreListMetadata(); - var compareMatch = compare.FirstOrDefault( - c => AreDeepEqual( - currentMaster, - c, - customEqualityComparers, - ignoreProperties - ).AreEqual + var hasMatch = HasDeepEqualValueInCollection( + compare, + currentMaster, + customEqualityComparers, + ignoreProperties, + out var matched ); - if (compareMatch == null) + if (!hasMatch) { - return new DeepTestResult(false, $"no match for item {currentMaster.Stringify()}"); + return new DeepTestResult( + false, + $"no match for item {currentMaster.Stringify()}" + ); } master.Remove(currentMaster); - compare.Remove(compareMatch); + compare.Remove(matched); } return DeepTestResult.Pass; } ); } + + private static bool HasDeepEqualValueInCollection( + IEnumerable collection, + T find, + object[] customEqualityComparers, + HashSet ignoreProperties, + out T matched + ) + { + matched = default; + foreach (var item in collection) + { + if (Compare( + find, + item, + customEqualityComparers, + ignoreProperties + ).AreEqual) + { + matched = item; + return true; + } + } + + return false; + } } \ No newline at end of file diff --git a/src/NExpect/CollectionIntersectionEquivalenceExtensions.cs b/src/NExpect/CollectionIntersectionEquivalenceExtensions.cs index 86f8002..e14bad7 100644 --- a/src/NExpect/CollectionIntersectionEquivalenceExtensions.cs +++ b/src/NExpect/CollectionIntersectionEquivalenceExtensions.cs @@ -93,6 +93,12 @@ params object[] customEqualityComparers expectedArray, customEqualityComparers ); + var errors = result.Errors.Any() + ? new[] + { + "" + }.Concat(result.Errors).ToArray() + : result.Errors; return new MatcherResult( result.AreEqual, FinalMessageFor( @@ -100,9 +106,9 @@ params object[] customEqualityComparers { "Expected", actualArray.LimitedPrint(), - $"{result.AreEqual.AsNot()} to be intersection equivalent to", + $"\n{result.AreEqual.AsNot()} to be intersection equivalent to\n", expectedArray.LimitedPrint() - }.Concat(result.Errors).ToArray(), + }.Concat(errors).ToArray(), customMessageGenerator ) ); diff --git a/src/NExpect/CollectionMatchers.cs b/src/NExpect/CollectionMatchers.cs index 16d3d07..d73ede9 100644 --- a/src/NExpect/CollectionMatchers.cs +++ b/src/NExpect/CollectionMatchers.cs @@ -1345,7 +1345,7 @@ params object[] customEqualityComparers (o1, o2) => { var ignoreProperties = o1.FindOrAddPropertyIgnoreListMetadata(); - return DeepTestHelpers.AreDeepEqual( + return DeepTestHelpers.Compare( o1, o2, customEqualityComparers, diff --git a/src/NExpect/DeepEqualityMatchers.cs b/src/NExpect/DeepEqualityMatchers.cs index e33a6ef..730796e 100644 --- a/src/NExpect/DeepEqualityMatchers.cs +++ b/src/NExpect/DeepEqualityMatchers.cs @@ -147,7 +147,7 @@ params object[] customEqualityComparers actual => { var ignoreProperties = actual.FindOrAddPropertyIgnoreListMetadata(); - var deepEqualResult = DeepTestHelpers.AreDeepEqual( + var deepEqualResult = DeepTestHelpers.Compare( actual, expected, customEqualityComparers, diff --git a/src/NExpect/Helpers/DeepTestHelpers.cs b/src/NExpect/Helpers/DeepTestHelpers.cs index 7f773b9..877ff28 100644 --- a/src/NExpect/Helpers/DeepTestHelpers.cs +++ b/src/NExpect/Helpers/DeepTestHelpers.cs @@ -61,14 +61,14 @@ HashSet ignoreProperties ); } - internal static DeepTestResult AreDeepEqual( + internal static DeepTestResult Compare( object item1, object item2, object[] customEqualityComparers, HashSet ignoreProperties ) { - return AreDeepEqual( + return Compare( item1, item2, customEqualityComparers, @@ -76,7 +76,7 @@ HashSet ignoreProperties ); } - internal static DeepTestResult AreDeepEqual( + internal static DeepTestResult Compare( object item1, object item2, object[] customEqualityComparers, @@ -148,7 +148,7 @@ Func, List, DeepTestResult> finalComparison { return DeepTestResult.Fail( expected == null - ? $"Expected collection is null but actual is not" + ? "Expected collection is null but actual is not" : "Actual collection is null but expected is not" ); }