#region Copyright 2012-2014 by Roger Knapp, Licensed under the Apache License, Version 2.0 /* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #endregion using System; using System.Collections.Generic; using System.IO; using CSharpTest.Net.Collections; using CSharpTest.Net.Serialization; using NUnit.Framework; namespace CSharpTest.Net.Library.Test { [TestFixture] public class TestOrderedEnumeration { #region TestFixture SetUp/TearDown [TestFixtureSetUp] public virtual void Setup() { } [TestFixtureTearDown] public virtual void Teardown() { } #endregion [Test] public void TestKeyValueComparer() { KeyValueComparer cmp = new KeyValueComparer(); Assert.IsTrue(ReferenceEquals(Comparer.Default, cmp.Comparer)); Assert.IsTrue(ReferenceEquals(Comparer.Default, KeyValueComparer.Default.Comparer)); Assert.AreEqual(-1, cmp.Compare(new KeyValuePair(1, 1), new KeyValuePair(2, 1))); Assert.AreEqual(0, cmp.Compare(new KeyValuePair(1, 1), new KeyValuePair(1, 2))); Assert.AreEqual(1, cmp.Compare(new KeyValuePair(2, 1), new KeyValuePair(1, 1))); } [Test] public void TestMergeSortBasicOverloads() { Guid[] test, arrTest = new Guid[255]; for (int i = 1; i < arrTest.Length; i++) arrTest[i] = Guid.NewGuid(); Guid[] expect = (Guid[])arrTest.Clone(); Array.Sort(expect); test = (Guid[])arrTest.Clone(); MergeSort.Sort(test); AssertArrayEquals(Comparer.Default, expect, test); test = (Guid[])arrTest.Clone(); MergeSort.Sort(test, delegate(Guid x, Guid y) { return x.CompareTo(y); }); AssertArrayEquals(Comparer.Default, expect, test); test = (Guid[])arrTest.Clone(); MergeSort.Sort(test, Comparer.Default); AssertArrayEquals(Comparer.Default, expect, test); } static void AssertArrayEquals(IComparer cmp, T[] x, T[] y) { Assert.AreEqual(x.Length, y.Length); for (int i = 0; i < x.Length; i++) Assert.AreEqual(0, cmp.Compare(x[i], y[i])); } [Test] public void TestMergeSortRangeOverloads() { char[] input = "zrogera".ToCharArray(); MergeSort.Sort(input, 1, 5, Comparer.Default); Assert.AreEqual("zegorra", new string(input)); input = "zrogera".ToCharArray(); MergeSort.Sort(input, 1, 5, delegate(char x, char y) { return y.CompareTo(x); } ); Assert.AreEqual("zrrogea", new string(input)); } class AllEqual : IComparable { public int CompareTo(AllEqual other) { return 0; } } [Test] public void TestMergeSortStable() { AllEqual[] set = new[] { new AllEqual(), new AllEqual(), new AllEqual() }; AllEqual[] copy = (AllEqual[])set.Clone(); MergeSort.Sort(copy); Assert.IsTrue(ReferenceEquals(set[0], copy[0])); Assert.IsTrue(ReferenceEquals(set[1], copy[1])); Assert.IsTrue(ReferenceEquals(set[2], copy[2])); } [Test] public void TestOrderedEnum() { byte[] input = new byte[256]; new Random().NextBytes(input); byte last = 0; foreach (byte b in new OrderedEnumeration(input)) { Assert.IsTrue(last <= b); last = b; } } class ReverseOrder : IComparer { readonly IComparer _compare; public ReverseOrder(IComparer compare) { _compare = compare; } public int Compare(T x, T y) { return -_compare.Compare(x, y); } } [Test] public void TestDedupFirst() { AllEqual[] set = new[] { new AllEqual(), new AllEqual(), new AllEqual() }; List arr = new List( OrderedEnumeration.WithDuplicateHandling( set, Comparer.Default, DuplicateHandling.FirstValueWins)); Assert.AreEqual(1, arr.Count); Assert.IsTrue(ReferenceEquals(set[0], arr[0])); arr = new List( OrderedEnumeration.WithDuplicateHandling( set, Comparer.Default, DuplicateHandling.LastValueWins)); Assert.AreEqual(1, arr.Count); Assert.IsTrue(ReferenceEquals(set[2], arr[0])); arr = new List( OrderedEnumeration.WithDuplicateHandling( set, Comparer.Default, DuplicateHandling.None)); Assert.AreEqual(3, arr.Count); Assert.IsTrue(ReferenceEquals(set[0], arr[0])); Assert.IsTrue(ReferenceEquals(set[1], arr[1])); Assert.IsTrue(ReferenceEquals(set[2], arr[2])); try { new List( OrderedEnumeration.WithDuplicateHandling( set, Comparer.Default, DuplicateHandling.RaisesException)); Assert.Fail(); } catch(ArgumentException) { } } [Test, ExpectedException(typeof(InvalidDataException))] public void TestUnorderedAssertion() { new List(OrderedEnumeration.WithDuplicateHandling( new [] { 2, 1 }, Comparer.Default, DuplicateHandling.RaisesException)); } private static IEnumerable FailBeforeYield(bool bFail) { if (bFail) throw new InvalidOperationException(); yield break; } [Test] public void TestOrderedEnumProperties() { var ordered = new OrderedEnumeration(Comparer.Default, FailBeforeYield(true)); Assert.IsTrue(ReferenceEquals(Comparer.Default, ordered.Comparer)); ordered.Comparer = new ReverseOrder(ordered.Comparer); Assert.IsTrue(ordered.Comparer is ReverseOrder); Assert.IsNull(ordered.Serializer); ordered.Serializer = PrimitiveSerializer.Byte; Assert.IsTrue(ReferenceEquals(ordered.Serializer, PrimitiveSerializer.Byte)); Assert.AreEqual(0x10000, ordered.InMemoryLimit); Assert.AreEqual(10, ordered.InMemoryLimit = 10); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(DuplicateHandling.FirstValueWins, ordered.DuplicateHandling = DuplicateHandling.FirstValueWins); } [Test] public void TestOrderedEnumDedup() { byte[] input = new byte[512]; new Random().NextBytes(input); var ordered = new OrderedEnumeration(input); ordered.InMemoryLimit = 10; ordered.DuplicateHandling = DuplicateHandling.FirstValueWins; int last = -1, count = 0; byte[] test = new List(ordered).ToArray(); foreach (byte b in test) { count++; Assert.IsTrue(last < b); last = b; } Assert.IsTrue(count <= 256); } [Test] public void TestOrderedEnumPaginated() { byte[] input = new byte[512]; new Random().NextBytes(input); var ordered = new OrderedEnumeration(input); ordered.Serializer = PrimitiveSerializer.Byte; ordered.InMemoryLimit = 10; ordered.DuplicateHandling = DuplicateHandling.FirstValueWins; int last = -1, count = 0; byte[] test = new List(ordered).ToArray(); foreach (byte b in test) { count++; Assert.IsTrue(last < b); last = b; } Assert.IsTrue(count <= 256); } [Test] public void TestOrderedEnumPaginatedCleanup() { byte[] input = new byte[512]; new Random().NextBytes(input); var ordered = new OrderedEnumeration(input); ordered.Serializer = PrimitiveSerializer.Byte; ordered.InMemoryLimit = 10; ordered.DuplicateHandling = DuplicateHandling.FirstValueWins; using (var e = ordered.GetEnumerator()) Assert.IsTrue(e.MoveNext()); } [Test] public void TestEnumTwiceFails() { var ordered = new OrderedEnumeration(new byte[0]); using (var e = ordered.GetEnumerator()) Assert.IsFalse(e.MoveNext()); try { ((System.Collections.IEnumerable) ordered).GetEnumerator(); Assert.Fail(); } catch (InvalidOperationException) { } } [Test] public void TestMergeEnumerations() { char[] x = "aeiou".ToCharArray(); char[] y = "bcdfg".ToCharArray(); char[] z = "ez".ToCharArray(); var order = OrderedEnumeration.Merge(x, y, z); Assert.AreEqual("abcdeefgiouz", new string(new List(order).ToArray())); order = OrderedEnumeration.Merge(Comparer.Default, DuplicateHandling.LastValueWins, x, y, z); Assert.AreEqual("abcdefgiouz", new string(new List(order).ToArray())); order = OrderedEnumeration.Merge(Comparer.Default, x, y); order = OrderedEnumeration.WithDuplicateHandling(order, Comparer.Default, DuplicateHandling.FirstValueWins); Assert.AreEqual("abcdefgiou", new string(new List(order).ToArray())); } [Test] public void TestEnumInvalid() { var order = new OrderedEnumeration(new byte[1]); System.Collections.IEnumerator e = ((System.Collections.IEnumerable)order).GetEnumerator(); Assert.IsTrue(e.MoveNext()); Assert.IsFalse(e.MoveNext()); try { object val = e.Current; GC.KeepAlive(val); Assert.Fail(); } catch (InvalidOperationException) { } try { e.Reset(); Assert.Fail(); } catch (NotSupportedException) { } } [Test] public void TestOrderedKeyValuePairsMerge() { var x = new[] { new KeyValuePair(1, 1) }; var y = new[] { new KeyValuePair(2, 2) }; IEnumerator> e = OrderedKeyValuePairs .Merge(new ReverseOrder(Comparer.Default), x, y) .GetEnumerator(); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(2, e.Current.Key); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(1, e.Current.Key); Assert.IsFalse(e.MoveNext()); } [Test] public void TestOrderedKeyValuePairsMergeOnDuplicate() { var x = new[] { new KeyValuePair(1, 1) }; var y = new[] { new KeyValuePair(1, 2), new KeyValuePair(2, 2) }; IEnumerator> e = OrderedKeyValuePairs .Merge(Comparer.Default, DuplicateHandling.FirstValueWins, x, y) .GetEnumerator(); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(1, e.Current.Key); Assert.AreEqual(1, e.Current.Value); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(2, e.Current.Key); Assert.AreEqual(2, e.Current.Value); Assert.IsFalse(e.MoveNext()); e = OrderedKeyValuePairs .Merge(Comparer.Default, DuplicateHandling.LastValueWins, x, y) .GetEnumerator(); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(1, e.Current.Key); Assert.AreEqual(2, e.Current.Value); Assert.IsTrue(e.MoveNext()); Assert.AreEqual(2, e.Current.Key); Assert.AreEqual(2, e.Current.Value); Assert.IsFalse(e.MoveNext()); } [Test] public void TestOrderedKeyValuePairsOverloads() { IEnumerable> e = new KeyValuePair[0]; OrderedKeyValuePairs ordered; ordered = new OrderedKeyValuePairs(e); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(ReferenceEquals(Comparer.Default, ((KeyValueComparer)ordered.Comparer).Comparer)); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(0x10000, ordered.InMemoryLimit); Assert.AreEqual(null, ordered.Serializer); ordered = new OrderedKeyValuePairs(new ReverseOrder(Comparer.Default), e); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(((KeyValueComparer)ordered.Comparer).Comparer is ReverseOrder); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(0x10000, ordered.InMemoryLimit); Assert.AreEqual(null, ordered.Serializer); KeyValueSerializer ser = new KeyValueSerializer(PrimitiveSerializer.Int32, PrimitiveSerializer.Int32); ordered = new OrderedKeyValuePairs(new ReverseOrder(Comparer.Default), e, ser); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(((KeyValueComparer)ordered.Comparer).Comparer is ReverseOrder); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(0x10000, ordered.InMemoryLimit); Assert.AreEqual(ser, ordered.Serializer); ordered = new OrderedKeyValuePairs(new ReverseOrder(Comparer.Default), e, ser, 42); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(((KeyValueComparer)ordered.Comparer).Comparer is ReverseOrder); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(42, ordered.InMemoryLimit); Assert.AreEqual(ser, ordered.Serializer); ordered = new OrderedKeyValuePairs(new ReverseOrder(Comparer.Default), e, PrimitiveSerializer.Int32, PrimitiveSerializer.Int32); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(((KeyValueComparer)ordered.Comparer).Comparer is ReverseOrder); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(0x10000, ordered.InMemoryLimit); Assert.IsNotNull(ordered.Serializer); ordered = new OrderedKeyValuePairs(new ReverseOrder(Comparer.Default), e, PrimitiveSerializer.Int32, PrimitiveSerializer.Int32, 42); Assert.IsTrue(ordered.Comparer is KeyValueComparer); Assert.IsTrue(((KeyValueComparer)ordered.Comparer).Comparer is ReverseOrder); Assert.AreEqual(DuplicateHandling.None, ordered.DuplicateHandling); Assert.AreEqual(42, ordered.InMemoryLimit); Assert.IsNotNull(ordered.Serializer); } } }