private static DeepTestResult CollectionsAreIntersectionEquivalent <T>( IEnumerable <T> collection, IEnumerable <T> expected, object[] customEqualityMatchers) { return(CollectionCompare( collection, expected, (master, compare) => { while (master.Any()) { var currentMaster = master.First(); var compareMatch = compare.FirstOrDefault( c => AreIntersectionEqual( currentMaster, c, customEqualityMatchers).AreEqual); // TODO: add information about mismatch if (compareMatch == null) { return DeepTestResult.Fail( $"Found no match for item\n{currentMaster.Stringify()}" ); } master.Remove(currentMaster); compare.Remove(compareMatch); } return DeepTestResult.Pass; })); }
private static DeepTestResult CollectionsAreDeepEqual <T>( IEnumerable <T> collection, IEnumerable <T> expected, object[] customEqualityComparers ) { if (collection == null && expected == null) { return(DeepTestResult.Pass); } if (collection == null || expected == null) { return(DeepTestResult.Fail( expected == null ? $"Expected collection is null but actual is not" : $"Actual collection is null but expected is not" )); } var expectedCount = expected.Count(); var collectionCount = collection.Count(); if (expectedCount != collectionCount) { return(DeepTestResult.Fail( $"Expected collection with {expectedCount} items, but got {collectionCount}" )); } return(CollectionCompare( collection, expected, (master, compare) => master.Zip(compare, Tuple.Create) .Aggregate( null as DeepTestResult, (acc, cur) => { if (acc != null) { return acc; } var result = AreDeepEqual( cur.Item1, cur.Item2, customEqualityComparers); return result.AreEqual ? null : result; } ) ) ?? DeepTestResult.Pass); }