/// <summary> /// Tests the difference between to enumerations. /// </summary> /// <typeparam name="T">The item type</typeparam> /// <param name="a">The 'A' collection.</param> /// <param name="b">The 'B' collection.</param> /// <param name="expectedResult">The expected result.</param> /// <param name="comparer">The optional equality comparer for the <typeparamref name="T"/> type.</param> private static void TestDiff <T>( [NotNull] IReadOnlyList <T> a, [NotNull] IReadOnlyList <T> b, [NotNull] DiffResult <T> expectedResult, IEqualityComparer <T> comparer = null) { if (comparer == null) { comparer = EqualityComparer <T> .Default; } Assert.IsNotNull(a, "The 'A' collection cannot be null."); Assert.IsNotNull(b, "The 'B' collection cannot be null."); Assert.IsNotNull(expectedResult, "The expected result cannot be null."); Tuple <bool, IEnumerable <T>, IEnumerable <T> >[] er = expectedResult.ToArray(); CollectionAssert.AllItemsAreNotNull(er, "Expected result contains null."); Differences <T> actualResult = a.Diff(b, comparer); Assert.IsNotNull(actualResult, "The diff operation returned null."); Chunk <T>[] ar = actualResult.ToArray(); CollectionAssert.AllItemsAreNotNull(ar, "Actual result contains null."); Trace.WriteLine($"Chunks:\r\n{actualResult}"); Assert.AreEqual(er.Length, ar.Length, $"{ar.Length} actual results returned instead of the expected {er.Length}."); for (int i = 0; i < er.Length; i++) { Tuple <bool, IEnumerable <T>, IEnumerable <T> > eri = er[i]; Chunk <T> ari = ar[i]; Assert.IsNotNull(ari, $"The actual chunk of the #{i} difference was null."); Assert.AreEqual(eri.Item1, ari.AreEqual, $"The actual chunk of the #{i} difference was {(ari.AreEqual ? "equal" : "not equal")}, when the expected result was {(eri.Item1 ? "equal" : "not equal")}."); if (ari.A == null) { Assert.IsNull( eri.Item2, $"The actual chunk A of the #{i} difference was null, when the expected chunk A is not null."); } else { Assert.IsNotNull( eri.Item2, $"The actual chunk A of the #{i} difference was not null, when the expected chunk A is null."); IEnumerator <T> eriae = eri.Item2.GetEnumerator(); IEnumerator <T> ariae = ari.A.GetEnumerator(); int j = 0; while (eriae.MoveNext()) { Assert.IsTrue( ariae.MoveNext(), $"The actual chunk A of the #{i} difference only had {j} items, whilst more were expected."); Assert.IsTrue( comparer.Equals(eriae.Current, ariae.Current), $"The #{j} item '{ariae.Current}' of the A #{i} difference did not match the expected item '{eriae.Current}'."); j++; } Assert.IsFalse( ariae.MoveNext(), $"The actual chunk A of the #{i} difference has more than the {j} expected items."); } if (ari.B == null) { Assert.IsNull( eri.Item3, $"The actual chunk B of the #{i} difference was null, when the expected chunk B is not null."); } else { Assert.IsNotNull( eri.Item3, $"The actual chunk B of the #{i} difference was not null, when the expected chunk B is null."); IEnumerator <T> eribe = eri.Item3.GetEnumerator(); IEnumerator <T> aribe = ari.B.GetEnumerator(); int j = 0; while (eribe.MoveNext()) { Assert.IsTrue( aribe.MoveNext(), $"The actual chunk B of the #{i} difference only had {j} items, whilst more were expected."); Assert.IsTrue( comparer.Equals(eribe.Current, aribe.Current), $"The #{j} item '{aribe.Current}' of the B #{i} difference did not match the expected item '{eribe.Current}'."); j++; } Assert.IsFalse( aribe.MoveNext(), $"The actual chunk B of the #{i} difference has more than the {j} expected items."); } } }