public async Task RequestNewBufferAsync_NeverRunsPastShadowBufferSize(int totalPreFetchBlocks, int shadowBufferSize)
        {
            int stopReadAt  = 5;
            int curPos      = 0;
            int forceStopAt = 100;
            var streamMock  = new Mock <Stream>(MockBehavior.Loose);

            streamMock.Setup(p => p.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((byte[] a, int b, int c, CancellationToken d) => { curPos += c; return(c); });
            BufferedStreamReaderConfig config = GetConfig(shadowBufferSize, totalPreFetchBlocks, stopReadAt);
            List <byte>       resArray        = new List <byte>();
            SynchronousReader pfh             = new SynchronousReader(streamMock.Object, config);

            int totRead = 0;
            int counter = 0;

            do
            {
                ShadowBufferData destBuffer = await pfh.RequestNewBufferAsync(CancellationToken.None);

                pfh.ReturnBuffer(destBuffer);
                totRead  = destBuffer?.byteCount ?? 0;
                counter += totRead;
            }while (totRead != 0 && counter < forceStopAt);

            Assert.AreEqual(stopReadAt, counter);
            Assert.AreEqual(stopReadAt, curPos);
        }
        public async Task RequestNewBufferAsync_Returns0BytesAtEOF(int totalPreFetchBlocks, int shadowBufferSize, int totBytes)
        {
            byte[] originalBuffer             = Enumerable.Range(1, totBytes).Select(f => (byte)f).ToArray();
            BufferedStreamReaderConfig config = GetConfig(shadowBufferSize, totalPreFetchBlocks);
            SynchronousReader          pfh    = new SynchronousReader(new MemoryStream(originalBuffer), config);

            while (true)
            {
                ShadowBufferData destBuffer = await pfh.RequestNewBufferAsync(CancellationToken.None);

                if (destBuffer == null || destBuffer.byteCount == 0)
                {
                    break;
                }
                pfh.ReturnBuffer(destBuffer);
            }
            ShadowBufferData lastDestBuffer = pfh.RequestNewBuffer();
            int lastRead = lastDestBuffer?.byteCount ?? 0;

            Assert.AreEqual(0, lastRead);
        }
        public async Task RequestNewBufferAsync_CorrectBytesAreReturned(int totalPreFetchBlocks, int shadowBufferSize, int totBytes)
        {
            byte[]      originalBuffer        = Enumerable.Range(1, totBytes).Select(f => (byte)f).ToArray();
            List <byte> resArray              = new List <byte>();
            BufferedStreamReaderConfig config = GetConfig(shadowBufferSize, totalPreFetchBlocks);
            SynchronousReader          pfh    = new SynchronousReader(new MemoryStream(originalBuffer), config);

            while (true)
            {
                ShadowBufferData destBuffer = await pfh.RequestNewBufferAsync(CancellationToken.None);

                if (destBuffer == null || destBuffer.byteCount == 0)
                {
                    break;
                }
                resArray.AddRange(destBuffer.buffer.Take(destBuffer.byteCount));
                pfh.ReturnBuffer(destBuffer);
            }

            Assert.AreEqual(originalBuffer, resArray.ToArray());
            Assert.DoesNotThrowAsync(pfh.AbortAsync);
        }