Selaa lähdekoodia

More tests for Select.

Bart De Smet 6 vuotta sitten
vanhempi
sitoutus
83a35c41d3

+ 487 - 1
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/Select.cs

@@ -15,7 +15,7 @@ namespace Tests
     public class Select : AsyncEnumerableTests
     {
         [Fact]
-        public void Select_Null()
+        public void Select_Sync_Null()
         {
             Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select<int, int>(default, x => x));
             Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select<int, int>(default, (x, i) => x));
@@ -254,6 +254,492 @@ namespace Tests
             await SequenceIdentity(ys);
         }
 
+        [Fact]
+        public void Select_Async_Null()
+        {
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select<int, int>(default, x => new ValueTask<int>(x)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(default, (int x, int i) => new ValueTask<int>(x)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(Return42, default(Func<int, ValueTask<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(Return42, default(Func<int, int, ValueTask<int>>)));
+        }
+
+        [Fact]
+        public async Task Select_Async_Simple()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Simple_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Simple_AsyncIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_AsyncIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Throws_Selector()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select(x => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Throws_Selector_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select(x => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Throws_Selector_AsyncIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select(x => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_Throws_Selector()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_Throws_Selector_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_Throws_Selector_AsyncIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_SelectSelect()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select(i => new ValueTask<int>(i + 3)).Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_SelectSelect_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select(i => new ValueTask<int>(i + 3)).Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_SelectSelect_AsyncIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select(i => new ValueTask<int>(i + 3)).Select(x => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_SequenceIdentity()
+        {
+            var xs = ToAsyncEnumerable(new[] { 1, 2, 3 });
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_SequenceIdentity_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 1, 2, 3 });
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_SequenceIdentity_AsyncIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select(x => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_SequenceIdentity()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_SequenceIdentity_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Indexed_SequenceIdentity_AsyncIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+#if !NO_DEEP_CANCELLATION
+
+        // REVIEW: These overloads are problematic for type inference. E.g. xs.Select((x, ct) => ...) is ambiguous.
+
+        [Fact]
+        public void Select_Async_Cancel_Null()
+        {
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(default, (int x, CancellationToken ct) => new ValueTask<int>(x)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(default, (int x, int i, CancellationToken ct) => new ValueTask<int>(x)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(Return42, default(Func<int, CancellationToken, ValueTask<int>>)));
+            Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.Select(Return42, default(Func<int, int, CancellationToken, ValueTask<int>>)));
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Simple()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Simple_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Simple_Async_CancelIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_Async_CancelIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'a');
+            await HasNextAsync(e, 'b');
+            await HasNextAsync(e, 'c');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Throws_Selector()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Throws_Selector_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Throws_Selector_Async_CancelIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<int>(1 / x));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_Throws_Selector()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_Throws_Selector_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_Throws_Selector_Async_CancelIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i, ct) => new ValueTask<int>(1 / i));
+
+            var e = ys.GetAsyncEnumerator();
+            await AssertThrowsAsync<DivideByZeroException>(e.MoveNextAsync().AsTask());
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SelectSelect()
+        {
+            var xs = ToAsyncEnumerable(new[] { 0, 1, 2 });
+            var ys = xs.Select((int i, CancellationToken ct) => new ValueTask<int>(i + 3)).Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SelectSelect_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 0, 1, 2 });
+            var ys = xs.Select((int i, CancellationToken ct) => new ValueTask<int>(i + 3)).Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SelectSelect_Async_CancelIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select((int i, CancellationToken ct) => new ValueTask<int>(i + 3)).Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            var e = ys.GetAsyncEnumerator();
+            await HasNextAsync(e, 'd');
+            await HasNextAsync(e, 'e');
+            await HasNextAsync(e, 'f');
+            await NoNextAsync(e);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SequenceIdentity()
+        {
+            var xs = ToAsyncEnumerable(new[] { 1, 2, 3 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SequenceIdentity_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 1, 2, 3 });
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_SequenceIdentity_Async_CancelIterator()
+        {
+            var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
+            var ys = xs.Select((int x, CancellationToken ct) => new ValueTask<char>((char)('a' + x)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_SequenceIdentity()
+        {
+            var xs = ToAsyncEnumerable(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_SequenceIdentity_IList()
+        {
+            var xs = ToAsyncEnumerableIList(new[] { 8, 5, 7 });
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+        [Fact]
+        public async Task Select_Async_Cancel_Indexed_SequenceIdentity_Async_CancelIterator()
+        {
+            var xs = new[] { 8, 5, 7 }.ToAsyncEnumerable();
+            var ys = xs.Select((x, i, ct) => new ValueTask<char>((char)('a' + i)));
+
+            await SequenceIdentity(ys);
+        }
+
+#endif
+
         private static IAsyncEnumerable<int> ToAsyncEnumerable(int[] xs) => new MyIterator(xs);
 
         private class MyIterator : IAsyncEnumerable<int>