public async Task ReadAsync_WithOverflowBuffer()
        {
            // Arrange
            // Test ensures that the overflow buffer works correctly
            string   input    = "\u2600";
            Encoding encoding = Encoding.Unicode;

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

                // Act
                int 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);
            }
        }
        public async Task ReadAsync_CompletedInSecondIteration()
        {
            // Arrange
            string   input    = new string('A', 1024 + 10);
            Encoding encoding = Encoding.Unicode;

            using (TranscodingReadStream stream = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding))
            {
                var    bytes    = new byte[1024];
                byte[] expected = Encoding.UTF8.GetBytes(input.Substring(0, bytes.Length));

                // Act
                int 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 TestOneToOneTranscodingAsync()
        {
            Encoding sourceEncoding = Encoding.GetEncoding(28591);
            string   message        = '"' + new string('A', TranscodingReadStream.MaxByteBufferSize - 2 + 1) + '"';

            Stream stream = new MemoryStream(sourceEncoding.GetBytes(message));

            using (TranscodingReadStream transcodingStream = new TranscodingReadStream(stream, sourceEncoding))
            {
                string deserializedMessage = await JsonSerializer.DeserializeAsync <string>(transcodingStream);

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

            using (var transcodingStream = new TranscodingReadStream(stream, sourceEncoding))
            {
                object model = await JsonSerializer.DeserializeAsync(transcodingStream, typeof(TestModel));

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

                Assert.Equal(message, testModel.Message);
            }
        }
        public async Task ReadAsync_FillsBuffer()
        {
            // Arrange
            string   input    = "Hello world";
            Encoding encoding = Encoding.Unicode;

            using (TranscodingReadStream stream = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding))
            {
                byte[] bytes    = new byte[3];
                byte[] expected = Encoding.UTF8.GetBytes(input.Substring(0, bytes.Length));

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

                // Assert
                Assert.Equal(3, readBytes);
                Assert.Equal(expected, bytes);
                Assert.Equal(0, stream.ByteBufferCount);
                Assert.Equal(0, stream.CharBufferCount);
                Assert.Equal(8, stream.OverflowCount);
            }
        }
        private static async Task ReadAsync_WithOverflowBufferAtCharBufferBoundaries(string input, int bufferSize)
        {
            // Arrange
            // Test ensures that the overflow buffer works correctly
            Encoding encoding = Encoding.Unicode;

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

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

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

                Assert.Equal(expected, actual);
            }
        }
        public async Task ReadAsync_SingleByte()
        {
            // Arrange
            string   input    = "Hello world";
            Encoding encoding = Encoding.Unicode;

            using (TranscodingReadStream stream = new TranscodingReadStream(new MemoryStream(encoding.GetBytes(input)), encoding))
            {
                var bytes = new byte[4];

                // Act
                int 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(0, stream.CharBufferCount);
                Assert.Equal(10, stream.OverflowCount);
            }
        }