public void ReadByte_ReadsEffectiveLengthTimes(
            int from,
            int to,
            int innerLength,
            int effectiveLength
            )
        {
            // Arrange
            var mockInnerStream = new Mock <Stream>();

            mockInnerStream.Setup(s => s.CanSeek).Returns(true);
            mockInnerStream.Setup(s => s.Length).Returns(innerLength);
            var range   = new RangeItemHeaderValue(from, to);
            var counter = 0;

            using (var rangeStream = new ByteRangeStream(mockInnerStream.Object, range))
            {
                // Act
                while (rangeStream.ReadByte() != -1)
                {
                    counter++;
                }

                // Assert
                mockInnerStream.Verify(s => s.ReadByte(), Times.Exactly(effectiveLength));
                Assert.Equal(effectiveLength, counter);
                Assert.Equal(effectiveLength, rangeStream.Position);
            }
        }
        public async Task ReadByte_CanReadAfterLength()
        {
            // Arrange
            var originalText = "This is the whole text.";
            var range        = new RangeItemHeaderValue(0L, null);

            using (var innerStream = new MemoryStream())
                using (var writer = new StreamWriter(innerStream))
                {
                    await writer.WriteAsync(originalText);

                    await writer.FlushAsync();

                    using (var rangeStream = new ByteRangeStream(innerStream, range))
                    {
                        rangeStream.Position = 50L;

                        // Act
                        var read = rangeStream.ReadByte();

                        // Assert
                        Assert.Equal(-1, read);
                    }
                }
        }
        public async Task Seek_PositionsNextRead(int offset, SeekOrigin origin)
        {
            // Arrange
            var originalText = "890123456789";
            var range        = new RangeItemHeaderValue(2L, null);

            using (var innerStream = new MemoryStream())
                using (var writer = new StreamWriter(innerStream))
                {
                    await writer.WriteAsync(originalText);

                    await writer.FlushAsync();

                    using (var rangeStream = new ByteRangeStream(innerStream, range))
                    {
                        // Act
                        rangeStream.Seek(offset, origin);

                        // Assert
                        var read = rangeStream.ReadByte();
                        Assert.Equal('5', (char)read);
                    }
                }
        }
        public void ReadByte_ReadsEffectiveLengthTimes(int from, int to, int innerLength, int effectiveLength)
        {
            // Arrange
            Mock<Stream> mockInnerStream = new Mock<Stream>();
            mockInnerStream.Setup(s => s.CanSeek).Returns(true);
            mockInnerStream.Setup(s => s.Length).Returns(innerLength);
            RangeItemHeaderValue range = new RangeItemHeaderValue(from, to);

            // Act
            ByteRangeStream rangeStream = new ByteRangeStream(mockInnerStream.Object, range);
            int counter = 0;
            while (rangeStream.ReadByte() != -1)
            {
                counter++;
            }

            // Assert
            Assert.Equal(effectiveLength, counter);
            mockInnerStream.Verify(s => s.ReadByte(), Times.Exactly(effectiveLength));
        }