public void CannotWriteAfterCompletion()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWriteSafe(1);
            sut.Complete();
            sut.TryWriteSafe(2).ShouldBe(false);
            Should.Throw <OperationCanceledException>(() => sut.WriteAsync(2));
        }
        public void WritesSynchronouslyWhenBufferHasSpace()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWriteSafe(1).ShouldBe(true);
            sut.TryWriteSafe(2).ShouldBe(true);
            sut.TryWriteSafe(3).ShouldBe(false);
            sut.TryReadSafe(out int item).ShouldBe(true);
            item.ShouldBe(1);
            sut.TryWriteSafe(4).ShouldBe(true);
        }
        public void FailCompletesChannelEvenIfBufferIsNotEmpty()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWriteSafe(1);
            sut.TryWriteSafe(2);
            sut.Terminate(new InvalidOperationException());
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryReadSafe(out int _).ShouldBe(true);
            sut.TryReadSafe(out int _).ShouldBe(true);
            var result = Should.CompleteIn(() => sut.TryReadSafeAsync().AsTask(), TimeSpan.FromSeconds(1));

            result.HasValue.ShouldBeFalse();
            sut.Completion.IsFaulted.ShouldBeTrue();
        }
        public void CancellationCompletesChannel()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWriteSafe(1);
            sut.TryWriteSafe(2);
            sut.Terminate();
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryReadSafe(out int _).ShouldBe(true);
            sut.TryReadSafe(out int _).ShouldBe(true);
            var result = sut.TryReadSafeAsync().ShouldCompleteIn(Timeout1Sec);

            result.HasValue.ShouldBeFalse();
            sut.Completion.IsCanceled.ShouldBeTrue();
        }
        public void CanReadAfterCompletionUntilBufferIsEmpty()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWriteSafe(1);
            sut.TryWriteSafe(2);
            sut.TryComplete();
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryReadSafe(out int _).ShouldBe(true);
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryReadSafe(out int _).ShouldBe(true);
            sut.Completion.IsCompleted.ShouldBe(true);
            sut.TryReadSafe(out int _).ShouldBe(false);
            Should.Throw <TaskCanceledException>(() => sut.ReadAsync().AsTask());
        }
        public void TryReadReturnsTrueWhenBufferIsNotEmpty()
        {
            var sut = new BufferedChannel <int>(1);

            sut.TryWriteSafe(1).ShouldBe(true);
            sut.TryReadSafe(out int _).ShouldBe(true);
        }
        public void WritesSynchronouslyWhenThereIsPendingReadTask()
        {
            var sut      = new BufferedChannel <int>(0);
            var readTask = sut.ReadAsync();

            sut.TryWriteSafe(1).ShouldBe(false);
            sut.WriteAsync(1).ShouldCompleteIn(Timeout1Sec);
            Should.CompleteIn(readTask.AsTask(), TimeSpan.FromSeconds(1));
            readTask.Result.ShouldBe(1);
        }
        public void TryWriteReturnsTrueWhenBufferIsNotFull()
        {
            var sut = new BufferedChannel <int>(1);

            sut.TryWriteSafe(1).ShouldBe(true);
        }
        public void TryWriteReturnsFalseWhenBufferIsFull()
        {
            var sut = new BufferedChannel <int>(0);

            sut.TryWriteSafe(1).ShouldBe(false);
        }