mirror of
https://github.com/chylex/.NET-Community-Toolkit.git
synced 2024-11-25 01:42:46 +01:00
151 lines
6.1 KiB
C#
151 lines
6.1 KiB
C#
// Licensed to the .NET Foundation under one or more agreements.
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Buffers;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using CommunityToolkit.HighPerformance.Buffers;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
namespace CommunityToolkit.HighPerformance.UnitTests.Streams;
|
|
|
|
[TestClass]
|
|
public class Test_IBufferWriterStream
|
|
{
|
|
[TestMethod]
|
|
public void Test_IBufferWriterStream_Lifecycle()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
|
|
// Get a stream from a buffer writer and validate that it can only be written to.
|
|
// This is to mirror the same functionality as the IBufferWriter<T> interface.
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
Assert.IsFalse(stream.CanRead);
|
|
Assert.IsFalse(stream.CanSeek);
|
|
Assert.IsTrue(stream.CanWrite);
|
|
|
|
_ = Assert.ThrowsException<NotSupportedException>(() => stream.Length);
|
|
_ = Assert.ThrowsException<NotSupportedException>(() => stream.Position);
|
|
|
|
// Dispose the stream and check that no operation is now allowed
|
|
stream.Dispose();
|
|
|
|
Assert.IsFalse(stream.CanRead);
|
|
Assert.IsFalse(stream.CanSeek);
|
|
Assert.IsFalse(stream.CanWrite);
|
|
_ = Assert.ThrowsException<NotSupportedException>(() => stream.Length);
|
|
_ = Assert.ThrowsException<NotSupportedException>(() => stream.Position);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test_IBufferWriterStream_Write_Array()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
byte[] data = Test_MemoryStream.CreateRandomData(64);
|
|
|
|
// Write random data to the stream wrapping the buffer writer, and validate
|
|
// that the state of the writer is consistent, and the written content matches.
|
|
stream.Write(data, 0, data.Length);
|
|
|
|
Assert.AreEqual(writer.WrittenCount, data.Length);
|
|
Assert.IsTrue(writer.WrittenSpan.SequenceEqual(data));
|
|
|
|
// A few tests with invalid inputs (null buffers, invalid indices, etc.)
|
|
_ = Assert.ThrowsException<ArgumentNullException>(() => stream.Write(null!, 0, 10));
|
|
_ = Assert.ThrowsException<ArgumentOutOfRangeException>(() => stream.Write(data, -1, 10));
|
|
_ = Assert.ThrowsException<ArgumentException>(() => stream.Write(data, 200, 10));
|
|
_ = Assert.ThrowsException<ArgumentOutOfRangeException>(() => stream.Write(data, 0, -24));
|
|
_ = Assert.ThrowsException<ArgumentException>(() => stream.Write(data, 0, 200));
|
|
|
|
stream.Dispose();
|
|
|
|
_ = Assert.ThrowsException<ObjectDisposedException>(() => stream.Write(data, 0, data.Length));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Test_IBufferWriterStream_WriteAsync_Array()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
byte[] data = Test_MemoryStream.CreateRandomData(64);
|
|
|
|
// Same test as above, but using an asynchronous write instead
|
|
await stream.WriteAsync(data, 0, data.Length);
|
|
|
|
Assert.AreEqual(writer.WrittenCount, data.Length);
|
|
Assert.IsTrue(writer.WrittenSpan.SequenceEqual(data));
|
|
|
|
_ = await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => stream.WriteAsync(null!, 0, 10));
|
|
_ = await Assert.ThrowsExceptionAsync<ArgumentOutOfRangeException>(() => stream.WriteAsync(data, -1, 10));
|
|
_ = await Assert.ThrowsExceptionAsync<ArgumentException>(() => stream.WriteAsync(data, 200, 10));
|
|
_ = await Assert.ThrowsExceptionAsync<ArgumentOutOfRangeException>(() => stream.WriteAsync(data, 0, -24));
|
|
_ = await Assert.ThrowsExceptionAsync<ArgumentException>(() => stream.WriteAsync(data, 0, 200));
|
|
|
|
stream.Dispose();
|
|
|
|
_ = await Assert.ThrowsExceptionAsync<ObjectDisposedException>(() => stream.WriteAsync(data, 0, data.Length));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test_IBufferWriterStream_WriteByte()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
ReadOnlySpan<byte> data = stackalloc byte[] { 1, 128, 255, 32 };
|
|
|
|
foreach (HighPerformance.Enumerables.ReadOnlySpanEnumerable<byte>.Item item in data.Enumerate())
|
|
{
|
|
// Since we're enumerating, we can also double check the current written count
|
|
// at each iteration, to ensure the writes are done correctly every time.
|
|
Assert.AreEqual(writer.WrittenCount, item.Index);
|
|
|
|
// Write a number of bytes one by one to test this API as well
|
|
stream.WriteByte(item.Value);
|
|
}
|
|
|
|
// Validate the final written length and actual data
|
|
Assert.AreEqual(writer.WrittenCount, data.Length);
|
|
Assert.IsTrue(data.SequenceEqual(writer.WrittenSpan));
|
|
|
|
_ = Assert.ThrowsException<NotSupportedException>(() => stream.ReadByte());
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Test_IBufferWriterStream_Write_Span()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
Memory<byte> data = Test_MemoryStream.CreateRandomData(64);
|
|
|
|
// This will use the extension when on .NET Standard 2.0, as the
|
|
// Stream class doesn't have Spam<T> or Memory<T> public APIs there.
|
|
stream.Write(data.Span);
|
|
|
|
Assert.AreEqual(writer.WrittenCount, data.Length);
|
|
Assert.IsTrue(data.Span.SequenceEqual(writer.WrittenSpan));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task Test_IBufferWriterStream_WriteAsync_Memory()
|
|
{
|
|
ArrayPoolBufferWriter<byte> writer = new();
|
|
Stream stream = ((IBufferWriter<byte>)writer).AsStream();
|
|
|
|
Memory<byte> data = Test_MemoryStream.CreateRandomData(64);
|
|
|
|
// Same as the other asynchronous test above, but writing from a Memory<T>
|
|
await stream.WriteAsync(data);
|
|
|
|
Assert.AreEqual(writer.WrittenCount, data.Length);
|
|
Assert.IsTrue(data.Span.SequenceEqual(writer.WrittenSpan));
|
|
}
|
|
}
|