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

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

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

            sut.TryWrite(1);
            sut.TryWrite(2);
            sut.Terminate(new InvalidOperationException());
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryRead(out int _).ShouldBe(true);
            sut.TryRead(out int _).ShouldBe(true);
            Should.Throw <InvalidOperationException>(() => sut.TryReadAsync().AsTask(), Timeout1Sec);
            sut.Completion.IsFaulted.ShouldBeTrue();
        }
        public void CancellationCompletesChannel()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWrite(1);
            sut.TryWrite(2);
            sut.Terminate();
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryRead(out int _).ShouldBe(true);
            sut.TryRead(out int _).ShouldBe(true);
            Should.Throw <TaskCanceledException>(sut.TryReadAsync().AsTask(), Timeout1Sec);
            sut.Completion.IsCanceled.ShouldBeTrue();
        }
        public void CanReadAfterCompletionUntilBufferIsEmpty()
        {
            var sut = new BufferedChannel <int>(2);

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

            sut.TryWrite(1).ShouldBe(true);
            sut.TryRead(out int _).ShouldBe(true);
        }
        public void TerminatesOnWriteTimeout()
        {
            var sut = new BufferedChannel <int>(1, Timeout100Ms);

            Should.NotThrow(sut.WriteAsync(1), Timeout1Sec);
            sut.TryWrite(1).ShouldBe(false);
            Should.Throw <ChannelWriteTimeoutException>(sut.WaitWriteAvailableAsync(), Timeout1Sec);
            Should.Throw <ChannelWriteTimeoutException>(sut.Out.Completion, Timeout1Sec);
            sut.TryRead(out _).ShouldBe(true);
            Should.Throw <Exception>(sut.Completion, Timeout1Sec);
        }
        public async Task SlidesWriteTimeoutAfterWriteAvailable()
        {
            var sut = new BufferedChannel <int>(1, Timeout50Ms);

            sut.TryWrite(1).ShouldBe(true);
            await Task.Delay(Timeout10Ms).ConfigureAwait(false);

            sut.TryRead(out _).ShouldBe(true);
            await Task.Delay(Timeout100Ms).ConfigureAwait(false);

            sut.Out.Completion.IsCompleted.ShouldBeFalse();
            Should.NotThrow(() => sut.WriteAsync(1), Timeout1Sec);
            await Task.Delay(Timeout10Ms).ConfigureAwait(false);

            sut.TryRead(out _).ShouldBe(true);
        }
        public void TryWriteReturnsTrueWhenBufferIsNotFull()
        {
            var sut = new BufferedChannel <int>(1);

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

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