浏览代码

Merge pull request #232 from jnm2/cancancel-test-fix

CanCancel test fix
Oren Novotny 9 年之前
父节点
当前提交
94be05fd83
共有 1 个文件被更改,包括 52 次插入3 次删除
  1. 52 3
      Ix.NET/Source/Tests/AsyncTests.Bugs.cs

+ 52 - 3
Ix.NET/Source/Tests/AsyncTests.Bugs.cs

@@ -180,8 +180,7 @@ namespace Tests
         [Fact]
         public void CanCancelMoveNext()
         {
-            var evt = new ManualResetEvent(false);
-            var xs = Blocking(evt).ToAsyncEnumerable().Select(x => x).Where(x => true);
+            var xs = new CancellationTestEnumerable().Select(x => x).Where(x => true);
 
             var e = xs.GetEnumerator();
             var cts = new CancellationTokenSource();
@@ -198,12 +197,62 @@ namespace Tests
             {
                 Assert.True(t.IsCanceled);
             }
+        }
+
+        /// <summary>
+        /// Waits WaitTimeoutMs or until cancellation is requested. If cancellation was not requested, MoveNext returns true.
+        /// </summary>
+        private sealed class CancellationTestEnumerable : IAsyncEnumerable<object>
+        {
+            public IAsyncEnumerator<object> GetEnumerator() => new TestEnumerator();
+
+            private sealed class TestEnumerator : IAsyncEnumerator<object>
+            {
+                public void Dispose()
+                {
+                }
+                
+                public object Current { get; }
+                
+                public async Task<bool> MoveNext(CancellationToken cancellationToken)
+                {
+                    await Task.Delay(WaitTimeoutMs, cancellationToken);
+                    cancellationToken.ThrowIfCancellationRequested();
+                    return true;
+                }
+            }
+        }
+
+        [Fact]
+        public void ToAsyncEnumeratorCannotCancelOnceRunning()
+        {
+            var evt = new ManualResetEvent(false);
+            var isRunningEvent = new ManualResetEvent(false);
+            var xs = Blocking(evt, isRunningEvent).ToAsyncEnumerable();
+
+            var e = xs.GetEnumerator();
+            var cts = new CancellationTokenSource();
+            var t = e.MoveNext(cts.Token);
+
+            isRunningEvent.WaitOne();
+            cts.Cancel();
+
+            try
+            {
+                t.Wait(0);
+                Assert.False(t.IsCanceled);
+            }
+            catch
+            {
+                Assert.False(true);
+            }
 
             evt.Set();
         }
 
-        static IEnumerable<int> Blocking(ManualResetEvent evt)
+        static IEnumerable<int> Blocking(ManualResetEvent evt, ManualResetEvent blockingStarted)
         {
+            blockingStarted.Set();
             evt.WaitOne();
             yield return 42;
         }