浏览代码

Add sequence identity tests

Oren Novotny 9 年之前
父节点
当前提交
74768ebf53

+ 14 - 0
Ix.NET/Source/Tests/AsyncTests.Exceptions.cs

@@ -8,6 +8,7 @@ using System.Linq;
 using System.Text;
 using Xunit;
 using System.Threading;
+using System.Threading.Tasks;
 
 namespace Tests
 {
@@ -270,6 +271,19 @@ namespace Tests
             NoNext(e);
         }
 
+        [Fact]
+        public async Task Catch13()
+        {
+            var ex = new InvalidOperationException("Bang!");
+
+            var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Concat(AsyncEnumerable.Throw<int>(ex));
+            var ys = new[] { 4, 5, 6 }.ToAsyncEnumerable();
+
+            var res = AsyncEnumerable.Catch(new[] { xs, xs, ys, ys });
+
+            await SequenceIdentity(res);
+        }
+
         [Fact]
         public void Finally_Null()
         {

+ 50 - 0
Ix.NET/Source/Tests/AsyncTests.Multiple.cs

@@ -115,6 +115,56 @@ namespace Tests
             AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single().Message == "Bang!");
         }
 
+        [Fact]
+        public void Concat7()
+        {
+            var ws = new[] { 1, 2, 3 }.ToAsyncEnumerable();
+            var xs = new[] { 4, 5 }.ToAsyncEnumerable();
+            var ys = new[] { 6, 7, 8 }.ToAsyncEnumerable();
+            var zs = new[] { 9, 10, 11 }.ToAsyncEnumerable();
+
+            var res = ws.Concat(xs).Concat(ys).Concat(zs);
+
+            var e = res.GetEnumerator();
+            HasNext(e, 1);
+            HasNext(e, 2);
+            HasNext(e, 3);
+            HasNext(e, 4);
+            HasNext(e, 5);
+            HasNext(e, 6);
+            HasNext(e, 7);
+            HasNext(e, 8);
+            HasNext(e, 9);
+            HasNext(e, 10);
+            HasNext(e, 11);
+            NoNext(e);
+        }
+
+        [Fact]
+        public async Task Concat8()
+        {
+            var ws = new[] { 1, 2, 3 }.ToAsyncEnumerable();
+            var xs = new[] { 4, 5 }.ToAsyncEnumerable();
+            var ys = new[] { 6, 7, 8 }.ToAsyncEnumerable();
+            var zs = new[] { 9, 10, 11 }.ToAsyncEnumerable();
+
+            var res = ws.Concat(xs).Concat(ys).Concat(zs);
+
+            await SequenceIdentity(res);
+        }
+
+        [Fact]
+        public async Task Concat9()
+        {
+            var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable();
+            var ys = new[] { 4, 5 }.ToAsyncEnumerable();
+            var zs = new[] { 6, 7, 8 }.ToAsyncEnumerable();
+
+            var res = AsyncEnumerable.Concat(xs, ys, zs);
+
+            await SequenceIdentity(res);
+        }
+
         static IEnumerable<IAsyncEnumerable<int>> ConcatXss()
         {
             yield return new[] { 1, 2, 3 }.ToAsyncEnumerable();

+ 10 - 1
Ix.NET/Source/Tests/AsyncTests.Single.cs

@@ -4,14 +4,15 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Text;
 using Xunit;
 using System.Threading;
 using System.Threading.Tasks;
-
 namespace Tests
 {
+
     public partial class AsyncTests
     {
         [Fact]
@@ -2454,6 +2455,14 @@ namespace Tests
             Assert.False(e.MoveNext().Result);
         }
 
+        [Fact]
+        public async Task Buffer4()
+        {
+            var xs = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Buffer(3, 2);
+
+            await SequenceIdentity(xs);
+        }
+
         [Fact]
         public void DistinctUntilChanged_Null()
         {

+ 84 - 1
Ix.NET/Source/Tests/AsyncTests.cs

@@ -3,14 +3,16 @@
 // See the LICENSE file in the project root for more information. 
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
+using System.Reflection;
 using System.Threading.Tasks;
 using Xunit;
 
 namespace Tests
 {
-    
     public partial class AsyncTests
     {
         public void AssertThrows<E>(Action a)
@@ -58,5 +60,86 @@ namespace Tests
             Assert.True(e.MoveNext().Result);
             Assert.Equal(value, e.Current);
         }
+
+        public async Task SequenceIdentity<T>(IAsyncEnumerable<T> enumerable)
+        {
+            Assert.True(await enumerable.SequenceEqual(enumerable, SequenceIdentityComparer<T>.Instance));
+        }
+
+        private class SequenceIdentityComparer<T> : IEqualityComparer<T>
+        {
+            readonly IEqualityComparer<T> innerComparer = EqualityComparer<T>.Default;
+            public SequenceIdentityComparer()
+            {
+                var itemType = GetAnyElementType(typeof(T));
+
+                // if not the same as T, then it's a list
+                if (itemType != typeof(T))
+                {
+                    // invoke the Instance method of the type we need
+
+                    var eqType = typeof(SequenceIdentityComparer<,>).MakeGenericType(typeof(T), itemType);
+                    innerComparer = (IEqualityComparer<T>)eqType.GetRuntimeProperty("Instance").GetValue(null);
+                }
+            }
+
+
+            public static SequenceIdentityComparer<T> Instance => new SequenceIdentityComparer<T>();
+            public bool Equals(T x, T y)
+            {
+                return innerComparer.Equals(x, y);
+            }
+
+            public int GetHashCode(T obj)
+            {
+                return innerComparer.GetHashCode(obj);
+            }
+
+            static Type GetAnyElementType(Type type)
+            {
+                // Type is Array
+                // short-circuit if you expect lots of arrays 
+                if (typeof(Array).IsAssignableFrom(type))
+                    return type.GetElementType();
+
+                // type is IEnumerable<T>;
+                if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+                    return type.GetGenericArguments()[0];
+
+                // type implements/extends IEnumerable<T>;
+                var enumType = type.GetInterfaces()
+                                        .Where(t => t.GetTypeInfo().IsGenericType &&
+                                               t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+                                        .Select(t => t.GenericTypeArguments[0]).FirstOrDefault();
+                return enumType ?? type;
+            }
+        
+        }
+
+
+        private class SequenceIdentityComparer<TList, TItem> : IEqualityComparer<TList> where TList : IEnumerable<TItem>
+        {
+            readonly IEqualityComparer<TItem> innerComparer = EqualityComparer<TItem>.Default;
+
+
+            public static IEqualityComparer<TList> Instance => new SequenceIdentityComparer<TList, TItem>();
+            public bool Equals(TList x, TList y)
+            {
+                return x.SequenceEqual(y);
+            }
+
+            public int GetHashCode(TList obj)
+            {
+                return obj.Aggregate(0, (i, item) =>
+                                        {
+                                            unchecked
+                                            {
+                                                i += innerComparer.GetHashCode(item);
+                                            }
+                                            return i;
+                                        }
+                                        );
+            }
+        }
     }
 }