public static void NullInputsInConstructor_ExpectArgumentNullException(Stream stream, Encoding encoding, ArrayPool <byte> bytePool, ArrayPool <char> charPool)
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         var httpRequestStreamReader = new ProtoResponseStreamWriter(stream, encoding, 1, bytePool, charPool);
     });
 }
        public static async Task StreamDisposed_ExpectedObjectDisposedExceptionAsync(Func <ProtoResponseStreamWriter, Task> function)
        {
            var httpResponseStreamWriter = new ProtoResponseStreamWriter(new MemoryStream(), Encoding.UTF8, 10, ArrayPool <byte> .Shared, ArrayPool <char> .Shared);

            httpResponseStreamWriter.Dispose();

            await Assert.ThrowsAsync <ObjectDisposedException>(() =>
            {
                return(function(httpResponseStreamWriter));
            });
        }
        public static void StreamDisposed_ExpectedObjectDisposedException(Action <ProtoResponseStreamWriter> action)
        {
            var httpResponseStreamWriter = new ProtoResponseStreamWriter(new MemoryStream(), Encoding.UTF8, 10, ArrayPool <byte> .Shared, ArrayPool <char> .Shared);

            httpResponseStreamWriter.Dispose();

            Assert.Throws <ObjectDisposedException>(() =>
            {
                action(httpResponseStreamWriter);
            });
        }
        public async Task WriteCharArrayAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
                await writer.WriteAsync((new string('a', byteLength)).ToCharArray());

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task NoDataWritten_FlushAsync_DoesNotFlushUnderlyingStream()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
        public async Task DoesNotDispose_UnderlyingStream_OnDisposingWriter()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.WriteAsync("Hello world");

            writer.Dispose();

            // Assert
            Assert.Equal(0, stream.DisposeCallCount);
        }
        public async Task FlushesBuffer_OnDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task WritesData_InExpectedEncoding(string data, string encodingName)
        {
            // Arrange
            var encoding      = Encoding.GetEncoding(encodingName);
            var expectedBytes = encoding.GetBytes(data);
            var stream        = new MemoryStream();
            var writer        = new ProtoResponseStreamWriter(stream, encoding);

            // Act
            using (writer)
                await writer.WriteAsync(data);

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public async Task DoesNotWriteBOM()
        {
            // Arrange
            var memoryStream    = new MemoryStream();
            var encodingWithBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
            var writer          = new ProtoResponseStreamWriter(memoryStream, encodingWithBOM);
            var expectedData    = new byte[] { 97, 98, 99, 100 }; // without BOM

            // Act
            using (writer)
                await writer.WriteAsync("abcd");

            // Assert
            Assert.Equal(expectedData, memoryStream.ToArray());
        }
        public async Task WriteCharAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
                for (var i = 0; i < byteLength; i++)
                {
                    await writer.WriteAsync('a');
                }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task FlushesBuffer_ButNotStream_OnFlushAsync(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / ProtoResponseStreamWriter.DefaultBufferSize);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task WritesData_OfDifferentLength_InExpectedEncoding(
            char character,
            int charCount,
            string encodingName)
        {
            // Arrange
            var encoding      = Encoding.GetEncoding(encodingName);
            var data          = new string(character, charCount);
            var expectedBytes = encoding.GetBytes(data);
            var stream        = new MemoryStream();
            var writer        = new ProtoResponseStreamWriter(stream, encoding);

            // Act
            using (writer)
                await writer.WriteAsync(data);

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public void ProtoResponseStreamWriter_UsingPooledBuffers()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream   = new MemoryStream();

            var expectedBytes = encoding.GetBytes("Hello, World!");

            using (var writer = new ProtoResponseStreamWriter(
                       stream,
                       encoding,
                       1024,
                       ArrayPool <byte> .Shared,
                       ArrayPool <char> .Shared))
                // Act
                writer.Write("Hello, World!");

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public async Task ProtoResponseStreamWriter_WritesDataCorrectly_ForCharactersHavingSurrogatePairs(int characterSize)
        {
            // Arrange
            // Here "𐐀" (called Deseret Long I) actually represents 2 characters. Try to make this character split across
            // the boundary
            var content = new string('a', characterSize - 1) + "𐐀";
            var stream  = new TestMemoryStream();
            var writer  = new ProtoResponseStreamWriter(stream, Encoding.Unicode);

            // Act
            await writer.WriteAsync(content);

            await writer.FlushAsync();

            // Assert
            stream.Seek(0, SeekOrigin.Begin);
            var streamReader  = new StreamReader(stream, Encoding.Unicode);
            var actualContent = await streamReader.ReadToEndAsync();

            Assert.Equal(content, actualContent);
        }
        public async Task FlushWriteThrows_DontFlushInDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream()
            {
                ThrowOnWrite = true
            };
            var writer = new ProtoResponseStreamWriter(stream, Encoding.UTF8);

            await writer.WriteAsync(new string('a', byteLength));

            await Assert.ThrowsAsync <IOException>(() => writer.FlushAsync());

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(1, stream.WriteAsyncCallCount);
            Assert.Equal(0, stream.WriteCallCount);
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }