public void Should_Throws_When_Timeout_Expires()
        {
            var part0      = new byte[] { 0x00, 0x10 };
            var part1      = new byte[] { 0x20 };
            var stream     = new EmulateNetworkBehaviorStream();
            var connection = new Connection(stream);

            _ = Task.Run(async() =>
            {
                await stream.WriteAsync(part0, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(300)).ConfigureAwait(false);

                await stream.WriteAsync(part1, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(300)).ConfigureAwait(false);
            });
            Assert.Throws <AggregateException>(() => connection.Read <P0Packet>(150));
        }
        public async Task Should_Read_Packets_Normally_When_Data_Comes_With_A_Time()
        {
            var part0      = new byte[] { 0x00, 0x10, };
            var part1      = new byte[] { 0x20, 0x01, 0x44 };
            var part2      = new byte[] { 0x02, 0x0f, 0x0b };
            var part3      = new byte[] { 0x24, 0x21 };
            var part4      = new byte[] { 0x01 };
            var stream     = new EmulateNetworkBehaviorStream();
            var connection = new Connection(stream);

            _ = Task.Run(async() =>
            {
                await stream.WriteAsync(part0, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(150)).ConfigureAwait(false);

                await stream.WriteAsync(part1, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(250)).ConfigureAwait(false);

                await stream.WriteAsync(part2, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(10)).ConfigureAwait(false);

                await stream.WriteAsync(part3, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
                await Task.Delay(TimeSpan.FromMilliseconds(200)).ConfigureAwait(false);

                await stream.WriteAsync(part4, CancellationToken.None).ConfigureAwait(false);
                await stream.FlushAsync().ConfigureAwait(false);
            });

            var p0Packet = connection.Read <P0Packet>();
            var p1Packet = connection.Read <P1Packet>();
            var p2Packet = connection.Read <P2Packet>();

            Assert.Equal(new byte[] { 0x00, 0x10, 0x20 }, p0Packet.ToBytes());
            Assert.Equal(new byte[] { 0x01, 0x44 }, p1Packet.ToBytes());
            Assert.Equal(new byte[] { 0x02, 0x0f, 0x0b, 0x24, 0x21, 0x01 }, p2Packet.ToBytes());
        }
        public async Task Should_Read_Stream_Normally_If_Data_Gets_By_Parts(byte[] inputBytes)
        {
            //Arrange
            var stream = new EmulateNetworkBehaviorStream();

            _ = Task.Run(async() =>
            {
                foreach (var inputByte in inputBytes)
                {
                    await stream.WriteAsync(new[] { inputByte }, CancellationToken.None).ConfigureAwait(false);
                    await stream.FlushAsync(CancellationToken.None).ConfigureAwait(false);
                    await Task.Delay(TimeSpan.FromMilliseconds(200)).ConfigureAwait(false);
                }
            });


            //Act
            var result = await stream.ReadPacketAsync(inputBytes.Length, CancellationToken.None).ConfigureAwait(false);

            //Assert
            Assert.Equal(inputBytes, result);
        }