using System; using System.Collections.Generic; using System.IO; using System.Linq; using Developpez.Dotnet.Collections; using NUnit.Framework; namespace Developpez.Dotnet.Tests.Collections { [TestFixture] public class EnumerableExtensionsTests { [Test] public void FormatAll_With_Format_And_Separator() { string expected = "1-A-F-14-20-FF"; string actual = _bytes.FormatAll("{0:X}", "-"); Assert.AreEqual(expected, actual); } [Test] public void FormatAll_With_Format_Without_Separator() { string expected = "010a0f1420ff"; string actual = _bytes.FormatAll("x2", null); Assert.AreEqual(expected, actual); } [Test] public void FormatAll_Without_Format_Without_Separator() { string expected = "110152032255"; string actual = _bytes.FormatAll(null, null); Assert.AreEqual(expected, actual); } [Test] public void FormatAll_Without_Format_With_Separator() { string expected = "1-10-15-20-32-255"; string actual = _bytes.FormatAll(null, "-"); Assert.AreEqual(expected, actual); } [Test] public void FormatAll_Delegate() { string expected = "1-A-F-14-20-FF"; string actual = _bytes.FormatAll(b => Convert.ToString(b, 16).ToUpper(), "-"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le bon fonctionnement de la méthode IsNullOrEmpty")] public void Check_IsNullOrEmpty_ICollection() { List nullList = null; List emptyList = new List(); List notNullOrEmptyList = new List { 42 }; Assert.IsTrue(nullList.IsNullOrEmpty()); Assert.IsTrue(emptyList.IsNullOrEmpty()); Assert.IsFalse(notNullOrEmptyList.IsNullOrEmpty()); Array nullArray = null; Array emptyArray = Array.CreateInstance(typeof(int), 0); Array notNullOrEmptyArray = Array.CreateInstance(typeof(int), 1); Assert.IsTrue(nullArray.IsNullOrEmpty()); Assert.IsTrue(emptyArray.IsNullOrEmpty()); Assert.IsFalse(notNullOrEmptyArray.IsNullOrEmpty()); int[] nullArrayOfInt = null; int[] emptyArrayOfInt = new int[0]; int[] notNullOrEmptyArrayOfInt = new[] { 42 }; Assert.IsTrue(nullArrayOfInt.IsNullOrEmpty()); Assert.IsTrue(emptyArrayOfInt.IsNullOrEmpty()); Assert.IsFalse(notNullOrEmptyArrayOfInt.IsNullOrEmpty()); } [Test(Description = "Vérifie le fonctionnement de la méthode Shuffle. Note: ce test a une probabilité d'échec à cause de la nature aléatoire de la fonctionnalité testée")] public void Check_Shuffle() { List lst = new List(); for (int i = 0; i < 1500; i++) { lst.Add(i.ToString()); } List lst2 = new List(lst); lst2.Shuffle(); Assert.IsFalse(lst.SequenceEqual(lst2)); } [Test(Description = "Vérifie le fonctionnement de la méthode Swap")] public void Check_Swap() { List lst = new List { "hello", "world", "the", "sun", "is", "shining", "today" }; lst.Swap(0, 1); Assert.AreEqual(lst[0], "world"); Assert.AreEqual(lst[1], "hello"); } [Test(Description = "Vérifie le fonctionnement de la méthode ToCsvString")] public void Check_ToCsvString() { List lst1 = new List(); lst1.Add("Hello"); lst1.Add("World"); lst1.Add("!"); string csv1 = lst1.ToCsvString(","); Assert.AreEqual(csv1, "Hello,World,!"); List lst2 = new List(); lst2.Add(42); lst2.Add(7); lst2.Add(13); string csv2 = lst2.ToCsvString("|"); Assert.AreEqual(csv2, "42|7|13"); } [Test(Description = "Vérifie le fonctionnement de la méthode ListFromCsv")] public void Check_ListFromCsv_No_Null_Values() { string csv1 = "Hello,World,!"; var expected1 = new string[] { "Hello", "World", "!" }; var actual1 = csv1.ListFromCsv(","); CollectionAssert.AreEqual(expected1, actual1); string csv2 = "42|7|13"; var expected2 = new int[] { 42, 7, 13 }; var actual2 = csv2.ListFromCsv("|"); CollectionAssert.AreEqual(expected2, actual2); } [Test(Description = "Vérifie le fonctionnement de la méthode ListFromCsv")] public void Check_ListFromCsv_With_Null_Values() { string csv1 = "Hello,,!"; var expected1 = new string[] { "Hello", null, "!" }; var actual1 = csv1.ListFromCsv(","); CollectionAssert.AreEqual(expected1, actual1); string csv2 = "42||13"; var expected2 = new int[] { 42, 0, 13 }; var actual2 = csv2.ListFromCsv("|"); CollectionAssert.AreEqual(expected2, actual2); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrdered")] public void Check_IsOrdered() { List list = new List(); Assert.IsTrue(list.IsOrdered()); list.Add(5); Assert.IsTrue(list.IsOrdered()); list.Add(6); Assert.IsTrue(list.IsOrdered()); list.Add(3); Assert.IsFalse(list.IsOrdered()); list.Sort(); Assert.IsTrue(list.IsOrdered()); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrderedDescending")] public void Check_IsOrderedDescending_ForBaseClass() { List list = new List(); Assert.IsTrue(list.IsOrderedDescending()); list.Add(5); Assert.IsTrue(list.IsOrderedDescending()); list.Add(3); Assert.IsTrue(list.IsOrderedDescending()); list.Add(6); Assert.IsFalse(list.IsOrderedDescending()); list.Sort(Comparer.Default.Reverse()); Assert.IsTrue(list.IsOrderedDescending()); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrderedDescending avec Comparateur")] public void Check_IsOrderedDescending_ForCustomClass_WithComparer() { List list = new List(); Assert.IsTrue(list.IsOrderedDescending(new FooComparer())); list.Add(new Foo { Value = "world" }); Assert.IsTrue(list.IsOrderedDescending(new FooComparer())); list.Add(new Foo { Value = "prout" }); Assert.IsTrue(list.IsOrderedDescending(new FooComparer())); list.Add(new Foo { Value = "hello" }); Assert.IsTrue(list.IsOrderedDescending(new FooComparer())); list.Sort(new FooComparer().Reverse()); Assert.IsTrue(list.IsOrderedDescending(new FooComparer())); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrderedDescending avec une classe implémentant IComparable")] public void Check_IsOrderedDescending_ForCustom_Icomparable_Class() { List list = new List(); Assert.IsTrue(list.IsOrderedDescending()); list.Add(new FooFoo { Value = "world" }); Assert.IsTrue(list.IsOrderedDescending()); list.Add(new FooFoo { Value = "prout" }); Assert.IsTrue(list.IsOrderedDescending()); list.Add(new FooFoo { Value = "hello" }); Assert.IsTrue(list.IsOrderedDescending()); list.Sort(Comparer.Default.Reverse()); Assert.IsTrue(list.IsOrderedDescending()); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrderedBy")] public void Check_IsOrderedBy() { List list = new List(); Assert.IsTrue(list.IsOrderedBy(f => f.Value)); list.Add(new Foo { Value = "hello" }); Assert.IsTrue(list.IsOrderedBy(f => f.Value)); list.Add(new Foo { Value = "world" }); Assert.IsTrue(list.IsOrderedBy(f => f.Value)); list.Add(new Foo { Value = "prout" }); Assert.IsFalse(list.IsOrderedBy(f => f.Value)); list.Sort((x, y) => string.Compare(x.Value, y.Value)); Assert.IsTrue(list.IsOrderedBy(f => f.Value)); } [Test(Description = "Vérifie le fonctionnement de la méthode IsOrderedByDescending")] public void Check_IsOrderedByDescending() { List list = new List(); Assert.IsTrue(list.IsOrderedByDescending(f => f.Value)); list.Add(new Foo { Value = "world" }); Assert.IsTrue(list.IsOrderedByDescending(f => f.Value)); list.Add(new Foo { Value = "hello" }); Assert.IsTrue(list.IsOrderedByDescending(f => f.Value)); list.Add(new Foo { Value = "prout" }); Assert.IsFalse(list.IsOrderedByDescending(f => f.Value)); list.Sort((x, y) => string.Compare(y.Value, x.Value)); Assert.IsTrue(list.IsOrderedByDescending(f => f.Value)); } #if !DOTNET4 [Test(Description = "Vérifie le fonctionnement de la méthode Zip")] public void Test_Zip() { var expected = new[] { new { Name = "Jack", Value = 4 }, new { Name = "Kate", Value = 8 }, new { Name = "Sayid", Value = 15 }, new { Name = "Sun", Value = 16 }, new { Name = "Sawyer", Value = 23 }, new { Name = "John", Value = 42 } }; // Cas 1 : même longueur var names = expected.Select(x => x.Name); var values = expected.Select(x => x.Value); var actual = names.Zip(values, (n, v) => new { Name = n, Value = v }); CollectionAssert.AreEqual(expected, actual); // Cas 2 : names plus long que values names = expected.Select(x => x.Name); values = expected.Select(x => x.Value).Take(4); actual = names.Zip(values, (n, v) => new { Name = n, Value = v }); CollectionAssert.AreEqual(expected.Take(4), actual); // Cas 3 : values plus long que names names = expected.Select(x => x.Name).Take(4); values = expected.Select(x => x.Value); actual = names.Zip(values, (n, v) => new { Name = n, Value = v }); CollectionAssert.AreEqual(expected.Take(4), actual); } #endif [Test(Description = "Vérifie le comportement de la méthode FirstOrDefault, sans prédicat")] public void Test_FirstOrDefault_NoPredicate() { var lst = Enumerable.Empty(); string expected = "toto"; string actual = lst.FirstOrDefault("toto"); Assert.AreEqual(expected, actual); lst = new string[] { "hello", "world" }; expected = "hello"; actual = lst.FirstOrDefault("toto"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le comportement de la méthode FirstOrDefault, avec un prédicat")] public void Test_FirstOrDefault_WithPredicate() { var lst = new string[] { "hello", "world", "foo", "bar", "titi" }; string expected = "toto"; string actual = lst.FirstOrDefault(s => s[0] > 'x' ,"toto"); Assert.AreEqual(expected, actual); expected = "world"; actual = lst.FirstOrDefault(s => s[0] > 'n', "toto"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le comportement de la méthode LastOrDefault, sans prédicat")] public void Test_LastOrDefault_NoPredicate() { var lst = Enumerable.Empty(); string expected = "toto"; string actual = lst.LastOrDefault("toto"); Assert.AreEqual(expected, actual); lst = new string[] { "hello", "world" }; expected = "world"; actual = lst.LastOrDefault("toto"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le comportement de la méthode LastOrDefault, avec un prédicat")] public void Test_LastOrDefault_WithPredicate() { var lst = new string[] { "hello", "world", "foo", "bar", "titi" }; string expected = "toto"; string actual = lst.LastOrDefault(s => s[0] > 'x', "toto"); Assert.AreEqual(expected, actual); expected = "titi"; actual = lst.LastOrDefault(s => s[0] > 'n', "toto"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le comportement de la méthode ElementAtOrDefault")] public void Test_ElementAtOrDefault() { var lst = new string[] { "hello", "world" }; string expected = "toto"; string actual = lst.ElementAtOrDefault(2, "toto"); Assert.AreEqual(expected, actual); expected = "world"; actual = lst.ElementAtOrDefault(1, "toto"); Assert.AreEqual(expected, actual); } [Test(Description = "Vérifie le comportement de la méthode SingleOrDefault, sans prédicat")] public void Test_SingleOrDefault_NoPredicate() { var lst = Enumerable.Empty(); string expected = "toto"; string actual = lst.SingleOrDefault("toto"); Assert.AreEqual(expected, actual); lst = new string[] { "hello" }; expected = "hello"; actual = lst.LastOrDefault("toto"); Assert.AreEqual(expected, actual); lst = new string[] { "hello", "world" }; Assert.Throws( () => lst.SingleOrDefault("toto")); } [Test(Description = "Vérifie le comportement de la méthode SingleOrDefault, avec un prédicat")] public void Test_SingleOrDefault_WithPredicate() { var lst = new string[] { "hello", "world", "foo", "bar", "titi" }; string expected = "toto"; string actual = lst.SingleOrDefault(s => s[0] > 'x', "toto"); Assert.AreEqual(expected, actual); expected = "titi"; actual = lst.SingleOrDefault(s => s.Length == 4, "toto"); Assert.AreEqual(expected, actual); Assert.Throws( () => lst.SingleOrDefault(s => s[0] > 'n', "toto")); } [Test] public void Test_BinarySearch() { var list = GetFoos(); foreach (var item in list) { var foundItem = list.BinarySearch(f => f.Value, item.Value); Assert.AreEqual(item, foundItem); } Assert.Throws( () => list.BinarySearch(f => f.Value, "joe")); } [Test] public void Test_BinarySearchOrDefault() { var list = GetFoos(); var defaultFoo = new Foo { Value = "joe" }; foreach (var item in list) { var foundItem = list.BinarySearchOrDefault(f => f.Value, item.Value); Assert.AreEqual(item, foundItem); foundItem = list.BinarySearchOrDefault(f => f.Value, item.Value, defaultFoo); Assert.AreEqual(item, foundItem); } Foo expected = null; var actual = list.BinarySearchOrDefault(f => f.Value, defaultFoo.Value); Assert.AreEqual(expected, actual); expected = defaultFoo; actual = list.BinarySearchOrDefault(f => f.Value, defaultFoo.Value, defaultFoo); Assert.AreEqual(expected, actual); } [Test] public void Test_TryBinarySearch() { var list = GetFoos(); var defaultFoo = new Foo { Value = "joe" }; foreach (var item in list) { Foo foundItem; var found = list.TryBinarySearch(f => f.Value, item.Value, out foundItem); Assert.IsTrue(found); Assert.AreEqual(item, foundItem); } bool expected = false; Foo expectedItem = null; Foo actualItem; bool actual = list.TryBinarySearch(f => f.Value, defaultFoo.Value, out actualItem); Assert.AreEqual(expected, actual); Assert.AreEqual(expectedItem, actualItem); } [Test] public void Test_MaxBy() { var foos = GetFoos(); foos.Shuffle(); var fooWithMaxValue = foos.MaxBy(f => f.Value); var expected = "xyz"; var actual = fooWithMaxValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_MaxBy_EmptySequence() { var foos = new Foo[] { }; Assert.Throws(() => foos.MaxBy(f => f.Value)); } [Test] public void Test_MaxBy_WithComparer() { var foos = GetFoos(); foos.Shuffle(); var fooWithMaxValue = foos.MaxBy(f => f.Value, Comparer.Default.Reverse()); var expected = "abcd"; var actual = fooWithMaxValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_MinBy() { var foos = GetFoos(); foos.Shuffle(); var fooWithMinValue = foos.MinBy(f => f.Value); var expected = "abcd"; var actual = fooWithMinValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_MinBy_EmptySequence() { var foos = new Foo[] { }; Assert.Throws(() => foos.MinBy(f => f.Value)); } [Test] public void Test_MinBy_WithComparer() { var foos = GetFoos(); foos.Shuffle(); var fooWithMinValue = foos.MinBy(f => f.Value, Comparer.Default.Reverse()); var expected = "xyz"; var actual = fooWithMinValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_Max_WithComparer() { var foos = GetFoos(); foos.Shuffle(); var fooWithMaxValue = foos.Max(new FooComparer()); var expected = "xyz"; var actual = fooWithMaxValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_Max_WithComparer_EmptySequence() { var foos = new Foo[] { }; Assert.Throws(() => foos.Max(new FooComparer())); } [Test] public void Test_Min_WithComparer() { var foos = GetFoos(); foos.Shuffle(); var fooWithMinValue = foos.Min(new FooComparer()); var expected = "abcd"; var actual = fooWithMinValue.Value; Assert.AreEqual(expected, actual); } [Test] public void Test_Min_WithComparer_EmptySequence() { var foos = new Foo[] { }; Assert.Throws(() => foos.Min(new FooComparer())); } [Test] public void Test_AllMaxBy() { var items = new[] { new { Name = "A", Value = 10 }, new { Name = "B", Value = 17 }, new { Name = "C", Value = 18 }, new { Name = "D", Value = 8 }, new { Name = "E", Value = 18 }, }; var max = items.AllMaxBy(x => x.Value).ToArray(); Assert.AreEqual(2, max.Length); Assert.AreEqual("C", max[0].Name); Assert.AreEqual("E", max[1].Name); } [Test] public void Test_AllMinBy() { var items = new[] { new { Name = "A", Value = 8 }, new { Name = "B", Value = 17 }, new { Name = "C", Value = 18 }, new { Name = "D", Value = 8 }, new { Name = "E", Value = 18 }, }; var min = items.AllMinBy(x => x.Value).ToArray(); Assert.AreEqual(2, min.Length); Assert.AreEqual("A", min[0].Name); Assert.AreEqual("D", min[1].Name); } [Test] public void Test_QuickSort_Default() { Random rnd = new Random(); byte[] values = new byte[100]; rnd.NextBytes(values); values.QuickSort(); Assert.That(values, Is.Ordered); } [Test] public void Test_QuickSort_Comparison() { Random rnd = new Random(); byte[] values = new byte[100]; rnd.NextBytes(values); // Les nombres pairs en premier, puis triés par ordre décroissant Comparison comparison = (a, b) => { if (a % 2 == 0 && b % 2 == 1) return -1; if (a % 2 == 1 && b % 2 == 0) return 1; return -a.CompareTo(b); }; var expected = values.ToList(); expected.Sort(comparison); values.QuickSort(comparison); CollectionAssert.AreEqual(expected, values); } [Test] public void Test_QuickSortBy() { Random rnd = new Random(); byte[] values = new byte[100]; rnd.NextBytes(values); var foos = values.Select(x => new Foo { Value = x.ToString() }).ToList(); foos.QuickSortBy(f => f.Value); Assert.That(foos, Is.Ordered.By("Value")); } [Test] public void Test_Append() { var foos = GetFoos(); var item = new Foo { Value = "zzz" }; var expected = foos.ToList(); expected.Add(item); var actual = foos.Append(item); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_Prepend() { var foos = GetFoos(); var item = new Foo { Value = "zzz" }; var expected = foos.ToList(); expected.Insert(0, item); var actual = foos.Prepend(item); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_AsIndexed_Unindex() { var foos = GetFoos(); var indexed = foos.AsIndexed().ToList(); for (int i = 0; i < indexed.Count; i++) { Assert.AreEqual(i, indexed[i].Index); } var unindexed = indexed.Unindex(); CollectionAssert.AreEqual(foos, unindexed); } [Test] public void Test_GroupEvery() { var foos = GetFoos(); var grouped = foos.GroupEvery(3).ToList(); Assert.AreEqual(3, grouped.Count); Assert.AreEqual(3, grouped[0].Count()); Assert.AreEqual(3, grouped[1].Count()); Assert.AreEqual(1, grouped[2].Count()); } [Test] public void Test_TakeEvery() { var numbers = Enumerable.Range(0, 10); var expected = new[] { 2, 5, 8 }; var actual = numbers.TakeEvery(3, 2); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_SkipEvery() { var numbers = Enumerable.Range(0, 10); var expected = new[] { 0, 1, 3, 4, 6, 7, 9 }; var actual = numbers.SkipEvery(3, 2); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_SkipFirst() { var input = new[] { "foo", "bar", "baz", "bar" }; var expected = new[] { "foo", "baz", "bar" }; var actual = input.SkipFirst(s => s == "bar"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_SkipLast() { var input = new[] { "foo", "bar", "baz", "bar", "zoo" }; var expected = new[] { "foo", "bar", "baz", "zoo" }; var actual = input.SkipLast(s => s == "bar"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_SkipAt() { var input = new[] { "foo", "bar", "baz", "bar" }; var expected = new[] { "foo", "baz", "bar" }; var actual = input.SkipAt(1); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_Replace() { var input = new[] { "foo", "bar", "baz", "bar" }; var expected = new[] { "foo", "zoo", "baz", "zoo" }; var actual = input.Replace("bar", "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_ReplaceAt() { var input = new[] { "foo", "bar", "baz", "bar" }; var expected = new[] { "foo", "zoo", "baz", "bar" }; var actual = input.ReplaceAt(1, "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_InsertAt() { var input = new[] { "foo", "baz", "bar" }; var expected = new[] { "foo", "zoo", "baz", "bar" }; var actual = input.InsertAt(1, "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_InsertBeforeFirst() { var input = new[] { "foo", "baz", "bar", "baz" }; var expected = new[] { "foo", "zoo", "baz", "bar", "baz" }; var actual = input.InsertBeforeFirst("baz", "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_InsertAfterFirst() { var input = new[] { "foo", "baz", "bar", "baz" }; var expected = new[] { "foo", "baz", "zoo", "bar", "baz" }; var actual = input.InsertAfterFirst("baz", "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_InsertBefore() { var input = new[] { "foo", "baz", "bar", "baz" }; var expected = new[] { "foo", "zoo", "baz", "bar", "zoo", "baz" }; var actual = input.InsertBefore("baz", "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_InsertAfter() { var input = new[] { "foo", "baz", "bar", "baz" }; var expected = new[] { "foo", "baz", "zoo", "bar", "baz", "zoo" }; var actual = input.InsertAfter("baz", "zoo"); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_None() { var empty = new int[0]; var notEmpty = new int[] { 42 }; Assert.IsTrue(empty.None()); Assert.IsFalse(notEmpty.None()); } [Test] public void Test_None_With_Predicate() { var allOdds = new int[] { 5, 15, 23 }; var oddsAndEvens = new int[] { 5, 8, 15, 16, 23, 42 }; Func isEven = n => n % 2 == 0; Assert.IsTrue(allOdds.None(isEven)); Assert.IsFalse(oddsAndEvens.None(isEven)); } [Test] public void Test_IndexOf_Item() { var source = Enumerable.Range(0, 10); int expected = 3; int actual = source.IndexOf(3); Assert.AreEqual(expected, actual); expected = -1; actual = source.IndexOf(42); Assert.AreEqual(expected, actual); } [Test] public void Test_IndexOf_Predicate() { var source = Enumerable.Range(0, 10); int expected = 3; int actual = source.IndexOf(x => x == 3); Assert.AreEqual(expected, actual); expected = -1; actual = source.IndexOf(x => x == 42); Assert.AreEqual(expected, actual); } [Test] public void Test_LastIndexOf_Item() { var source = Enumerable.Range(0, 10).Concat(Enumerable.Range(0, 10)); int expected = 13; int actual = source.LastIndexOf(3); Assert.AreEqual(expected, actual); expected = -1; actual = source.LastIndexOf(42); Assert.AreEqual(expected, actual); } [Test] public void Test_LastIndexOf_Predicate() { var source = Enumerable.Range(0, 10).Concat(Enumerable.Range(0, 10)); int expected = 13; int actual = source.LastIndexOf(x => x == 3); Assert.AreEqual(expected, actual); expected = -1; actual = source.LastIndexOf(x => x == 42); Assert.AreEqual(expected, actual); } [Test] public void Test_CopyTo() { var source = Enumerable.Range(1, 10); var array = new int[12]; source.CopyTo(array, 0); CollectionAssert.AreEqual(source, array.Take(10)); source.CopyTo(array, 2); CollectionAssert.AreEqual(source, array.Skip(2).Take(10)); Assert.Throws( () => source.CopyTo(array, -1)); Assert.Throws( () => source.CopyTo(array, 12)); Assert.Throws( () => source.CopyTo(array, 3)); } [Test] public void Test_ContainsAny() { var list = new[] { 4, 8, 15, 16, 23, 42 }; var items1 = new[] { 15, 30, 40 }; var items2 = new[] { 1, 2, 3 }; Assert.IsTrue(list.ContainsAny(items1)); Assert.IsFalse(list.ContainsAny(items2)); } [Test] public void Test_Apply_WithClass() { var foos = GetFoos(); var actual = foos.Apply(f => f.Value += "*").ToArray(); Assert.IsTrue(actual.All(f => f.Value.EndsWith("*"))); } [Test] public void Test_Apply_WithStruct() { var bars = GetBars(); var actual = bars.Apply((ref Bar b) => b.Value += "*").ToArray(); Assert.IsTrue(actual.All(b => b.Value.EndsWith("*"))); } [Test] public void Test_IndexOfSequence() { string haystack = "ABC ABCDAB ABCDABCDABDE"; string needle = "ABCDABD"; int expected = haystack.IndexOf(needle); int actual = haystack.IndexOfSequence(needle); Assert.AreEqual(expected, actual); } [Test] public void Test_ToHierarchy() { var items = GetHItems(); var hierarchical = items.ToHierarchy( f => f.ParentId == 0, (p, c) => p.Id == c.ParentId) .ToList(); Assert.AreEqual(2, hierarchical.Count); Assert.AreEqual(1, hierarchical[0].Item.Id); // 1 Assert.AreEqual(2, hierarchical[0].Children[0].Item.Id); // 1.1 Assert.AreEqual(3, hierarchical[0].Children[1].Item.Id); // 1.2 Assert.AreEqual(6, hierarchical[0].Children[1].Children[0].Item.Id); // 1.2.1 Assert.AreEqual(4, hierarchical[1].Item.Id); // 2 Assert.AreEqual(5, hierarchical[1].Children[0].Item.Id); // 2.1 Assert.AreEqual(7, hierarchical[1].Children[0].Children[0].Item.Id); // 2.1 Assert.AreEqual(8, hierarchical[1].Children[1].Item.Id); // 2.2 Assert.AreEqual(null, hierarchical[0].Parent); Assert.AreEqual(hierarchical[0], hierarchical[0].Children[0].Parent); } [Test] public void Test_DumpHierarchy() { var items = GetHItems(); var hierarchy = items.ToHierarchy( f => f.ParentId == 0, (p, c) => p.Id == c.ParentId) .ToList(); string expected = "1\r\n-1.1\r\n-1.2\r\n--1.2.1\r\n2\r\n-2.1\r\n--2.1.1\r\n-2.2\r\n"; string actual; using (var writer = new StringWriter()) { hierarchy.DumpHierarchy(writer, "-", item => item.Name); actual = writer.ToString(); } Assert.AreEqual(expected, actual); } [Test] public void Test_Flatten_DepthFirst() { var items = GetHItems(); var hierarchical = items.ToHierarchy( f => f.ParentId == 0, (p, c) => p.Id == c.ParentId) .ToList(); var expected = new[] { 1, 2, 3, 6, 4, 5, 7, 8 }; var actual = hierarchical .Flatten(node => node.Children, TreeTraversalMode.DepthFirst) .Select(node => node.Item.Id); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_Flatten_BreadthFirst() { var items = GetHItems(); var hierarchical = items.ToHierarchy( f => f.ParentId == 0, (p, c) => p.Id == c.ParentId) .ToList(); var expected = new[] { 1, 4, 2, 3, 5, 8, 6, 7 }; var actual = hierarchical .Flatten(node => node.Children, TreeTraversalMode.BreadthFirst) .Select(node => node.Item.Id); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_TakeLast_WithIList() { var numbers = new[] { 4, 8, 15, 16, 23, 42 }; var expected = numbers; var actual = numbers.TakeLast(10); CollectionAssert.AreEqual(expected, actual); expected = new int[0]; actual = numbers.TakeLast(0); CollectionAssert.AreEqual(expected, actual); expected = new[] { 16, 23, 42 }; actual = numbers.TakeLast(3); CollectionAssert.AreEqual(expected, actual); Assert.Throws(() => numbers.TakeLast(-1)); } [Test] public void Test_TakeLast_WithNoIList() { var numbers = LostNumbers(); var expected = numbers; var actual = numbers.TakeLast(10); CollectionAssert.AreEqual(expected, actual); expected = new int[0]; actual = numbers.TakeLast(0); CollectionAssert.AreEqual(expected, actual); expected = new[] { 16, 23, 42 }; actual = numbers.TakeLast(3); CollectionAssert.AreEqual(expected, actual); Assert.Throws(() => numbers.TakeLast(-1)); } [Test] public void Test_Split() { var source = new[] { 0, 1, 2, 0, 3, 4, 0 }; var expected = new[] { new[] { 1, 2 }, new[] { 3, 4 } }; var actual = source.Split(i => i == 0).ToArray(); Assert.AreEqual(expected.Length, actual.Length); for (int i = 0; i < actual.Length; i++) { CollectionAssert.AreEqual(expected[i], actual[i]); } } [Test] public void Test_DistinctBy() { var items = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, new { Id = 5, Foo = 3, Bar = "C" }, }; var expected = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, }; var actual = items.DistinctBy(i => i.Foo); CollectionAssert.AreEqual(expected, actual); expected = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, }; actual = items.DistinctBy(i => i.Bar); CollectionAssert.AreEqual(expected, actual); expected = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, }; actual = items.DistinctBy(i => new { i.Foo, i.Bar }); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_ExceptBy() { var items1 = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, new { Id = 5, Foo = 3, Bar = "C" }, }; var items2 = new[] { new { Id = 3, Foo = 42, Bar = "Z" }, new { Id = 4, Foo = 33, Bar = "X" }, }; var expected = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 5, Foo = 3, Bar = "C" }, }; var actual = items1.ExceptBy(items2, i => i.Id); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_UnionBy() { var items1 = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 5, Foo = 3, Bar = "C" }, }; var items2 = new[] { new { Id = 3, Foo = 42, Bar = "Z" }, new { Id = 4, Foo = 33, Bar = "X" }, }; var expected = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 5, Foo = 3, Bar = "C" }, new { Id = 4, Foo = 33, Bar = "X" }, }; var actual = items1.UnionBy(items2, i => i.Id); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_IntersectBy() { var items1 = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, new { Id = 5, Foo = 3, Bar = "C" }, }; var items2 = new[] { new { Id = 3, Foo = 42, Bar = "Z" }, new { Id = 4, Foo = 33, Bar = "X" }, new { Id = 6, Foo = 10, Bar = "Y" }, }; var expected = new[] { new { Id = 3, Foo = 2, Bar = "C" }, new { Id = 4, Foo = 3, Bar = "C" }, }; var actual = items1.IntersectBy(items2, i => i.Id); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_SequenceEqualBy() { var items1 = new[] { new { Id = 3, Foo = 42, Bar = "X" }, new { Id = 4, Foo = 33, Bar = "X" }, new { Id = 6, Foo = 10, Bar = "X" }, }; var items2 = new[] { new { Id = 1, Foo = 1, Bar = "A" }, new { Id = 2, Foo = 1, Bar = "B" }, }; var items3 = new[] { new { Id = 3, Foo = 42, Bar = "Z" }, new { Id = 4, Foo = 33, Bar = "X" }, new { Id = 6, Foo = 10, Bar = "Y" }, }; var items4 = new[] { new { Id = 1, Foo = 0, Bar = "X" }, new { Id = 2, Foo = 10, Bar = "X" }, new { Id = 3, Foo = 20, Bar = "X" }, }; // Different length Assert.IsFalse(items1.SequenceEqualBy(items2, i => i.Bar)); // Different values for Bar Assert.IsFalse(items1.SequenceEqualBy(items3, i => i.Bar)); // Same values for Bar Assert.IsTrue(items1.SequenceEqualBy(items4, i => i.Bar)); } [Test] public void Test_GetElementType() { var array = new[] {new {Foo = "Hello", Bar = 42}}; Assert.AreEqual(array.GetType().GetElementType(), array.GetElementType()); } [Test] public void Test_CommonPrefix_DefaultComparer() { var first = new[] { 4, 8, 15, 16, 23, 42 }; var second = new[] { 4, 8, 15, 16, 42, 23 }; var expected = new[] { 4, 8, 15, 16 }; var actual = first.CommonPrefix(second); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_CommonPrefix_SpecificComparer() { var first = new[] { "Foo", "Bar", "Baz", "Titi", "Tata", "Toto" }; var second = new[] { "FOO", "bAR", "baz", "tata", "Toto" }; var expected = new[] { "Foo", "Bar", "Baz" }; var actual = first.CommonPrefix(second, StringComparer.CurrentCultureIgnoreCase); CollectionAssert.AreEqual(expected, actual); } [Test] public void Test_RankBy() { var players = GetPlayers(); var ranks = players.RankBy(p => p.Score, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(8, ranks["William"]); Assert.AreEqual(7, ranks["Cheeta"]); Assert.AreEqual(4, ranks["Joe"]); Assert.AreEqual(4, ranks["Averell"]); Assert.AreEqual(4, ranks["Jane"]); Assert.AreEqual(2, ranks["Jack"]); Assert.AreEqual(2, ranks["Flipper"]); Assert.AreEqual(1, ranks["Tarzan"]); } [Test] public void Test_RankBy_SpecificComparer() { var players = GetPlayers(); var comparer = Comparer.Default.Reverse(); var ranks = players.RankBy(p => p.Score, comparer, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(1, ranks["William"]); Assert.AreEqual(2, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(6, ranks["Jack"]); Assert.AreEqual(6, ranks["Flipper"]); Assert.AreEqual(8, ranks["Tarzan"]); } [Test] public void Test_RankByDescending() { var players = GetPlayers(); var ranks = players.RankByDescending(p => p.Score, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(1, ranks["William"]); Assert.AreEqual(2, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(6, ranks["Jack"]); Assert.AreEqual(6, ranks["Flipper"]); Assert.AreEqual(8, ranks["Tarzan"]); } [Test] public void Test_RankByDescending_SpecificComparer() { var players = GetPlayers(); var comparer = Comparer.Default.Reverse(); var ranks = players.RankByDescending(p => p.Score, comparer, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(8, ranks["William"]); Assert.AreEqual(7, ranks["Cheeta"]); Assert.AreEqual(4, ranks["Joe"]); Assert.AreEqual(4, ranks["Averell"]); Assert.AreEqual(4, ranks["Jane"]); Assert.AreEqual(2, ranks["Jack"]); Assert.AreEqual(2, ranks["Flipper"]); Assert.AreEqual(1, ranks["Tarzan"]); } [Test] public void Test_DenseRankBy() { var players = GetPlayers(); var ranks = players.DenseRankBy(p => p.Score, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(5, ranks["William"]); Assert.AreEqual(4, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(2, ranks["Jack"]); Assert.AreEqual(2, ranks["Flipper"]); Assert.AreEqual(1, ranks["Tarzan"]); } [Test] public void Test_DenseRankBy_SpecificComparer() { var players = GetPlayers(); var comparer = Comparer.Default.Reverse(); var ranks = players.DenseRankBy(p => p.Score, comparer, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(1, ranks["William"]); Assert.AreEqual(2, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(4, ranks["Jack"]); Assert.AreEqual(4, ranks["Flipper"]); Assert.AreEqual(5, ranks["Tarzan"]); } [Test] public void Test_DenseRankByDescending() { var players = GetPlayers(); var ranks = players.DenseRankByDescending(p => p.Score, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(1, ranks["William"]); Assert.AreEqual(2, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(4, ranks["Jack"]); Assert.AreEqual(4, ranks["Flipper"]); Assert.AreEqual(5, ranks["Tarzan"]); } [Test] public void Test_DenseRankByDescending_SpecificComparer() { var players = GetPlayers(); var comparer = Comparer.Default.Reverse(); var ranks = players.DenseRankByDescending(p => p.Score, comparer, (p, rank) => new { p.Name, Rank = rank }) .ToDictionary(p => p.Name, p => p.Rank); Assert.AreEqual(5, ranks["William"]); Assert.AreEqual(4, ranks["Cheeta"]); Assert.AreEqual(3, ranks["Joe"]); Assert.AreEqual(3, ranks["Averell"]); Assert.AreEqual(3, ranks["Jane"]); Assert.AreEqual(2, ranks["Jack"]); Assert.AreEqual(2, ranks["Flipper"]); Assert.AreEqual(1, ranks["Tarzan"]); } [Test] public void Test_AddRange() { IList list = Enumerable.Range(0, 3).ToList(); list.AddRange(Enumerable.Range(3, 3)); Assert.That(list.Count, Is.EqualTo(6)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(0, 6).ToList())); } [Test] public void Test_RemoveRange() { IList list = Enumerable.Range(0, 6).ToList(); list.RemoveRange(0, 0); Assert.That(list.Count, Is.EqualTo(6)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(0, 6).ToList())); list = Enumerable.Range(0, 6).ToList(); list.RemoveRange(0, 1); Assert.That(list.Count, Is.EqualTo(5)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(1, 5).ToList())); list = Enumerable.Range(0, 6).ToList(); list.RemoveRange(5, 1); Assert.That(list.Count, Is.EqualTo(5)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(0, 5).ToList())); list = Enumerable.Range(0, 6).ToList(); list.RemoveRange(2, 2); Assert.That(list.Count, Is.EqualTo(4)); Assert.That(list, Is.EquivalentTo(new[] { 0, 1, 4, 5 })); list = Enumerable.Range(0, 6).ToList(); list.RemoveRange(0, 6); Assert.That(list.Count, Is.EqualTo(0)); Assert.That(list, Is.EquivalentTo(new int[0])); list = Enumerable.Range(0, 6).ToList(); Assert.Throws(() => list.RemoveRange(6, 1)); Assert.Throws(() => list.RemoveRange(0, 7)); Assert.Throws(() => list.RemoveRange(-1, 1)); } [Test] public void Test_InsertRange() { IList list = Enumerable.Range(0, 3).ToList(); list.InsertRange(0, Enumerable.Empty()); Assert.That(list.Count, Is.EqualTo(3)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(0, 3).ToList())); list = Enumerable.Range(0, 3).ToList(); list.InsertRange(0, new[] { 42 }); Assert.That(list.Count, Is.EqualTo(4)); Assert.That(list, Is.EquivalentTo(new[] { 42, 0, 1, 2 })); list = Enumerable.Range(0, 3).ToList(); list.InsertRange(0, new[] { 42, 99 }); Assert.That(list.Count, Is.EqualTo(5)); Assert.That(list, Is.EquivalentTo(new[] { 42, 99, 0, 1, 2 })); list = Enumerable.Range(0, 3).ToList(); list.InsertRange(3, new[] { 42 }); Assert.That(list.Count, Is.EqualTo(4)); Assert.That(list, Is.EquivalentTo(new[] { 0, 1, 2, 42 })); list = Enumerable.Range(0, 3).ToList(); list.InsertRange(2, new[] { 42, 99 }); Assert.That(list.Count, Is.EqualTo(5)); Assert.That(list, Is.EquivalentTo(new[] { 0, 1, 42, 99, 2 })); list = Enumerable.Range(0, 3).ToList(); Assert.Throws(() => list.InsertRange(4, Enumerable.Empty())); Assert.Throws(() => list.InsertRange(-1, Enumerable.Empty())); } [Test] public void Test_RemoveAll() { IList list = Enumerable.Range(0, 10).ToList(); int removed = list.RemoveAll(x => true); Assert.That(removed, Is.EqualTo(10)); Assert.That(list.Count, Is.EqualTo(0)); Assert.That(list, Is.EquivalentTo(new int[0])); list = Enumerable.Range(0, 10).ToList(); removed = list.RemoveAll(x => false); Assert.That(removed, Is.EqualTo(0)); Assert.That(list.Count, Is.EqualTo(10)); Assert.That(list, Is.EquivalentTo(Enumerable.Range(0, 10).ToList())); list = Enumerable.Range(0, 10).ToList(); removed = list.RemoveAll(x => x % 2 == 0); Assert.That(removed, Is.EqualTo(5)); Assert.That(list.Count, Is.EqualTo(5)); Assert.That(list, Is.EquivalentTo(new[] { 1, 3, 5, 7, 9 })); } [Test] public void Test_DistinctUntilChanged() { var items = new[] { 1, 1, 1, 2, 3, 3, 2, 2, 2, 2, 3, 3, 1 }; var expected = new[] { 1, 2, 3, 2, 3, 1 }; var actual = items.DistinctUntilChanged(); Assert.That(actual, Is.EquivalentTo(expected)); } [Test] public void Test_DistinctUntilChanged_WithComparer() { var items = new[] { "a", "A", "a", "b", "C", "c", "b", "b", "B", "B", "c", "C", "A" }; var expected = new[] { "a", "b", "C", "b", "c", "A" }; var actual = items.DistinctUntilChanged(StringComparer.CurrentCultureIgnoreCase); Assert.That(actual, Is.EquivalentTo(expected)); } [Test] public void Test_DistinctUntilChanged_WithKey() { var items = new[] { "a", "A", "a", "b", "C", "c", "b", "b", "B", "B", "c", "C", "A" }; var expected = new[] { "a", "b", "C", "b", "c", "A" }; var actual = items.DistinctUntilChanged(s => s.ToLower()); Assert.That(actual, Is.EquivalentTo(expected)); } [Test] public void Test_DistinctUntilChanged_WithKeyAndComparer() { var items = new[] { "a", "A", "a", "b", "C", "c", "b", "b", "B", "B", "c", "C", "A" }; var expected = new[] { "a", "b", "C", "b", "c", "A" }; var actual = items.DistinctUntilChanged(s => string.Format("[{0}]", s), StringComparer.CurrentCultureIgnoreCase); Assert.That(actual, Is.EquivalentTo(expected)); } #region Test helpers, classes and data class Player { public string Name { get; set; } public int Score { get; set; } } private static IEnumerable GetPlayers() { return new[] { new Player { Name = "Joe", Score = 42 }, new Player { Name = "Jack", Score = 25 }, new Player { Name = "William", Score = 100 }, new Player { Name = "Averell", Score = 42 }, new Player { Name = "Tarzan", Score = 1 }, new Player { Name = "Jane", Score = 42 }, new Player { Name = "Cheeta", Score = 50 }, new Player { Name= "Flipper", Score = 25 }, }; } class HItem { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } } internal class Foo { public string Value { get; set; } } internal struct Bar { public string Value { get; set; } } internal class FooFoo : IComparable { internal string Value { get; set; } public int CompareTo(FooFoo other) { return this.Value.CompareTo(other.Value); } } internal class FooComparer : IComparer { public int Compare(Foo x, Foo y) { if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; return StringComparer.CurrentCulture.Compare(x.Value, y.Value); } } private static IList GetFoos() { return new List { new Foo { Value = "abcd" }, new Foo { Value = "efgh" }, new Foo { Value = "ijkl" }, new Foo { Value = "mnop" }, new Foo { Value = "qrst" }, new Foo { Value = "uvw" }, new Foo { Value = "xyz" } }; } private static IList GetBars() { return new List { new Bar { Value = "abcd" }, new Bar { Value = "efgh" }, new Bar { Value = "ijkl" }, new Bar { Value = "mnop" }, new Bar { Value = "qrst" }, new Bar { Value = "uvw" }, new Bar { Value = "xyz" } }; } private static IEnumerable GetHItems() { return new[] { new HItem { Id = 1, Name = "1" }, new HItem { Id = 2, Name = "1.1", ParentId = 1 }, new HItem { Id = 3, Name = "1.2", ParentId = 1 }, new HItem { Id = 4, Name = "2" }, new HItem { Id = 5, Name = "2.1", ParentId = 4 }, new HItem { Id = 6, Name = "1.2.1", ParentId = 3 }, new HItem { Id = 7, Name = "2.1.1", ParentId = 5 }, new HItem { Id = 8, Name = "2.2", ParentId = 4 }, }; } readonly byte[] _bytes = new byte[] { 1, 10, 15, 20, 32, 255 }; private static IEnumerable LostNumbers() { yield return 4; yield return 8; yield return 15; yield return 16; yield return 23; yield return 42; } #endregion } }