public async Task ReadAsync_CompletedInSecondIteration()
        {
            // Arrange
            var input    = new string('A', 1024 + 10);
            var encoding = Encoding.Unicode;
            var stream   = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[1024];
            var expected = Encoding.UTF8.GetBytes(input.Substring(0, bytes.Length));

            // Act
            var readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            // Assert
            Assert.Equal(bytes.Length, readBytes);
            Assert.Equal(expected, bytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(10, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);

            readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            Assert.Equal(10, readBytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(0, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);
        }
        public async Task ReadAsync_WithOverflowBuffer()
        {
            // Arrange
            // Test ensures that the overflow buffer works correctly
            var input    = new string('A', 4096 + 4);
            var encoding = Encoding.Unicode;
            var stream   = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[4096];
            var expected = Encoding.UTF8.GetBytes(input.Substring(0, bytes.Length));

            // Act
            var readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            // Assert
            Assert.Equal(bytes.Length, readBytes);
            Assert.Equal(expected, bytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(0, stream.CharBufferCount);
            Assert.Equal(4, stream.OverflowCount);

            readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            Assert.Equal(4, readBytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(0, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);
        }
        public async Task ReadAsync_WithOverflowBuffer()
        {
            // Arrange
            // Test ensures that the overflow buffer works correctly
            var input    = "☀";
            var encoding = Encoding.Unicode;

            using var stream = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[1];
            var expected = Encoding.UTF8.GetBytes(input);

            // Act
            var readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            // Assert
            Assert.Equal(1, readBytes);
            Assert.Equal(expected[0], bytes[0]);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(0, stream.CharBufferCount);
            Assert.Equal(2, stream.OverflowCount);

            bytes     = new byte[expected.Length - 1];
            readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            Assert.Equal(bytes.Length, readBytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(0, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);

            readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            Assert.Equal(0, readBytes);
        }
        private static async Task ReadAsyncTest(Encoding sourceEncoding, string message)
        {
            var input  = $"{{ \"Message\": \"{message}\" }}";
            var stream = new MemoryStream(sourceEncoding.GetBytes(input));

            var transcodingStream = new TranscodingReadStream(stream, sourceEncoding);

            var model = await JsonSerializer.DeserializeAsync(transcodingStream, typeof(TestModel));

            var testModel = Assert.IsType <TestModel>(model);

            Assert.Equal(message, testModel.Message);
        }
        public async Task ReadAsync_FillsBuffer()
        {
            // Arrange
            var input    = "Hello world";
            var encoding = Encoding.Unicode;
            var stream   = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[3];
            var expected = Encoding.UTF8.GetBytes(input.Substring(0, bytes.Length));

            // Act
            var readBytes = await stream.ReadAsync(bytes, 0, bytes.Length);

            // Assert
            Assert.Equal(3, readBytes);
            Assert.Equal(expected, bytes);
            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(8, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);
        }
        public async Task ReadAsync_SingleByte()
        {
            // Arrange
            var input    = "Hello world";
            var encoding = Encoding.Unicode;
            var stream   = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[4];

            // Act
            var readBytes = await stream.ReadAsync(bytes, 0, 1);

            // Assert
            Assert.Equal(1, readBytes);
            Assert.Equal((byte)'H', bytes[0]);
            Assert.Equal(0, bytes[1]);

            Assert.Equal(0, stream.ByteBufferCount);
            Assert.Equal(10, stream.CharBufferCount);
            Assert.Equal(0, stream.OverflowCount);
        }
        private static async Task <TranscodingReadStream> ReadAsync_WithOverflowBufferAtCharBufferBoundaries(string input, int bufferSize)
        {
            // Arrange
            // Test ensures that the overflow buffer works correctly
            var encoding = Encoding.Unicode;
            var stream   = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding);
            var bytes    = new byte[1];
            var expected = Encoding.UTF8.GetBytes(input);

            // Act
            int read;
            var buffer = new byte[bufferSize];
            var actual = new List <byte>();

            while ((read = await stream.ReadAsync(buffer)) != 0)
            {
                actual.AddRange(buffer);
            }

            Assert.Equal(expected, actual);
            return(stream);
        }