Imported Upstream version 5.10.0.47

Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-24 17:04:36 +00:00
parent 88ff76fe28
commit e46a49ecf1
5927 changed files with 226314 additions and 129848 deletions

View File

@@ -5,12 +5,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Xunit;
namespace System.IO.Tests
{
public class BinaryReaderTests
public partial class BinaryReaderTests
{
protected virtual Stream CreateStream()
{
@@ -130,5 +131,62 @@ namespace System.IO.Tests
}
}
}
[Theory]
[InlineData(100, 0, 100, 100, 100)]
[InlineData(100, 25, 50, 100, 50)]
[InlineData(50, 0, 100, 100, 50)]
[InlineData(0, 0, 10, 10, 0)]
public void Read_CharArray(int sourceSize, int index, int count, int destinationSize, int expectedReadLength)
{
using (var stream = CreateStream())
{
var source = new char[sourceSize];
var random = new Random(345);
for (int i = 0; i < sourceSize; i++)
{
source[i] = (char)random.Next(0, 127);
}
stream.Write(Encoding.ASCII.GetBytes(source), 0, source.Length);
stream.Position = 0;
using (var reader = new BinaryReader(stream, Encoding.ASCII))
{
var destination = new char[destinationSize];
int readCount = reader.Read(destination, index, count);
Assert.Equal(expectedReadLength, readCount);
Assert.Equal(source.Take(readCount), destination.Skip(index).Take(readCount));
// Make sure we didn't write past the end
Assert.True(destination.Skip(readCount + index).All(b => b == default(char)));
}
}
}
[Theory]
[InlineData(new[] { 'h', 'e', 'l', 'l', 'o' }, 5, new[] { 'h', 'e', 'l', 'l', 'o' })]
[InlineData(new[] { 'h', 'e', 'l', 'l', 'o' }, 8, new[] { 'h', 'e', 'l', 'l', 'o' })]
[InlineData(new[] { 'h', 'e', '\0', '\0', 'o' }, 5, new[] { 'h', 'e', '\0', '\0', 'o' })]
[InlineData(new[] { 'h', 'e', 'l', 'l', 'o' }, 0, new char[0])]
[InlineData(new char[0], 5, new char[0])]
public void ReadChars(char[] source, int readLength, char[] expected)
{
using (var stream = CreateStream())
{
stream.Write(Encoding.ASCII.GetBytes(source), 0, source.Length);
stream.Position = 0;
using (var reader = new BinaryReader(stream))
{
var destination = reader.ReadChars(readLength);
Assert.Equal(expected, destination);
}
}
}
}
}

View File

@@ -0,0 +1,97 @@
using System.Linq;
using System.Text;
using Xunit;
namespace System.IO.Tests
{
public partial class BinaryReaderTests
{
[Theory]
[InlineData(100, 100, 100)]
[InlineData(100, 50, 50)]
[InlineData(50, 100, 50)]
[InlineData(10, 0, 0)]
[InlineData(0, 10, 0)]
public void Read_ByteSpan(int sourceSize, int destinationSize, int expectedReadLength)
{
using (var stream = CreateStream())
{
var source = new byte[sourceSize];
new Random(345).NextBytes(source);
stream.Write(source, 0, source.Length);
stream.Position = 0;
using (var reader = new BinaryReader(stream))
{
var destination = new byte[destinationSize];
int readCount = reader.Read(new Span<byte>(destination));
Assert.Equal(expectedReadLength, readCount);
Assert.Equal(source.Take(expectedReadLength), destination.Take(expectedReadLength));
// Make sure we didn't write past the end
Assert.True(destination.Skip(expectedReadLength).All(b => b == default(byte)));
}
}
}
[Fact]
public void Read_ByteSpan_ThrowIfDisposed()
{
using (var memStream = CreateStream())
{
var binaryReader = new BinaryReader(memStream);
binaryReader.Dispose();
Assert.Throws<ObjectDisposedException>(() => binaryReader.Read(new Span<byte>()));
}
}
[Theory]
[InlineData(100, 100, 100)]
[InlineData(100, 50, 50)]
[InlineData(50, 100, 50)]
[InlineData(10, 0, 0)]
[InlineData(0, 10, 0)]
public void Read_CharSpan(int sourceSize, int destinationSize, int expectedReadLength)
{
using (var stream = CreateStream())
{
var source = new char[sourceSize];
var random = new Random(345);
for (int i = 0; i < sourceSize; i++)
{
source[i] = (char)random.Next(0, 127);
}
stream.Write(Encoding.ASCII.GetBytes(source), 0, source.Length);
stream.Position = 0;
using (var reader = new BinaryReader(stream, Encoding.ASCII))
{
var destination = new char[destinationSize];
int readCount = reader.Read(new Span<char>(destination));
Assert.Equal(expectedReadLength, readCount);
Assert.Equal(source.Take(expectedReadLength), destination.Take(expectedReadLength));
// Make sure we didn't write past the end
Assert.True(destination.Skip(expectedReadLength).All(b => b == default(char)));
}
}
}
[Fact]
public void Read_CharSpan_ThrowIfDisposed()
{
using (var memStream = CreateStream())
{
var binaryReader = new BinaryReader(memStream);
binaryReader.Dispose();
Assert.Throws<ObjectDisposedException>(() => binaryReader.Read(new Span<char>()));
}
}
}
}

View File

@@ -9,7 +9,7 @@ using System.Text;
namespace System.IO.Tests
{
public class BinaryWriter_WriteByteCharTests
public partial class BinaryWriter_WriteByteCharTests
{
protected virtual Stream CreateStream()
{

View File

@@ -0,0 +1,49 @@
// 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 Xunit;
using System;
using System.IO;
using System.Text;
namespace System.IO.Tests
{
public partial class BinaryWriter_WriteByteCharTests
{
[Fact]
public void BinaryWriter_WriteSpan()
{
byte[] bytes = new byte[] { 4, 2, 7, 0xFF };
char[] chars = new char[] { 'a', '7', Char.MaxValue };
Span<byte> byteSpan = new Span<byte>(bytes);
Span<char> charSpan = new Span<char>(chars);
using (Stream memoryStream = CreateStream())
{
using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.Unicode))
{
binaryWriter.Write(byteSpan);
binaryWriter.Write(charSpan);
Stream baseStream = binaryWriter.BaseStream;
baseStream.Position = 2;
Assert.Equal(7, baseStream.ReadByte());
Assert.Equal(0xFF, baseStream.ReadByte());
char testChar;
testChar = BitConverter.ToChar(new byte[] { (byte)baseStream.ReadByte(), (byte)baseStream.ReadByte() }, 0);
Assert.Equal('a', testChar);
testChar = BitConverter.ToChar(new byte[] { (byte)baseStream.ReadByte(), (byte)baseStream.ReadByte() }, 0);
Assert.Equal('7', testChar);
testChar = BitConverter.ToChar(new byte[] { (byte)baseStream.ReadByte(), (byte)baseStream.ReadByte() }, 0);
Assert.Equal(Char.MaxValue, testChar);
}
}
}
}
}

View File

@@ -29,7 +29,7 @@ namespace System.IO.Tests
{
tasks[i] = stream.WriteAsync(data, 250 * i, 250);
}
Assert.False(tasks.All(t => t.IsCompleted));
Assert.All(tasks, t => Assert.Equal(TaskStatus.WaitingForActivation, t.Status));
mcaos.Release();
await Task.WhenAll(tasks);
@@ -54,8 +54,10 @@ namespace System.IO.Tests
Assert.Equal(TaskStatus.Faulted, stream.FlushAsync().Status);
}
[Fact]
public async Task CopyToAsyncTest_RequiresAsyncFlushingOfWrites()
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task CopyToTest_RequiresFlushingOfWrites(bool copyAsynchronously)
{
byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)(i % 256)).ToArray();
@@ -70,17 +72,27 @@ namespace System.IO.Tests
src.WriteByte(42);
dst.WriteByte(42);
Task copyTask = src.CopyToAsync(dst);
manualReleaseStream.Release();
await copyTask;
if (copyAsynchronously)
{
Task copyTask = src.CopyToAsync(dst);
manualReleaseStream.Release();
await copyTask;
}
else
{
manualReleaseStream.Release();
src.CopyTo(dst);
}
Assert.Equal(data, dst.ToArray());
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task CopyToAsyncTest_ReadBeforeCopy_CopiesAllData(bool wrappedStreamCanSeek)
[InlineData(false, false)]
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
public async Task CopyToTest_ReadBeforeCopy_CopiesAllData(bool copyAsynchronously, bool wrappedStreamCanSeek)
{
byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)(i % 256)).ToArray();
@@ -94,7 +106,14 @@ namespace System.IO.Tests
src.ReadByte();
var dst = new MemoryStream();
await src.CopyToAsync(dst);
if (copyAsynchronously)
{
await src.CopyToAsync(dst);
}
else
{
src.CopyTo(dst);
}
var expected = new byte[data.Length - 1];
Array.Copy(data, 1, expected, 0, expected.Length);
@@ -245,13 +264,22 @@ namespace System.IO.Tests
}
}
internal sealed class ManuallyReleaseAsyncOperationsStream : MemoryStream
internal sealed class ManuallyReleaseAsyncOperationsStream : Stream
{
private readonly MemoryStream _stream = new MemoryStream();
private readonly TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
private bool _canSeek = true;
public override bool CanSeek => _canSeek;
public override bool CanRead => _stream.CanRead;
public override bool CanWrite => _stream.CanWrite;
public override long Length => _stream.Length;
public override long Position { get => _stream.Position; set => _stream.Position = value; }
public void SetCanSeek(bool canSeek) => _canSeek = canSeek;
public void Release() { _tcs.SetResult(true); }
@@ -259,38 +287,44 @@ namespace System.IO.Tests
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
await _tcs.Task;
return await base.ReadAsync(buffer, offset, count, cancellationToken);
return await _stream.ReadAsync(buffer, offset, count, cancellationToken);
}
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
await _tcs.Task;
await base.WriteAsync(buffer, offset, count, cancellationToken);
await _stream.WriteAsync(buffer, offset, count, cancellationToken);
}
public override async Task FlushAsync(CancellationToken cancellationToken)
{
await _tcs.Task;
await base.FlushAsync(cancellationToken);
await _stream.FlushAsync(cancellationToken);
}
public override void Flush() => _stream.Flush();
public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin);
public override void SetLength(long value) => _stream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => _stream.Write(buffer, offset, count);
}
internal sealed class ThrowsExceptionFromAsyncOperationsStream : MemoryStream
{
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
public override int Read(byte[] buffer, int offset, int count) =>
throw new InvalidOperationException("Exception from ReadAsync");
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
public override void Write(byte[] buffer, int offset, int count) =>
throw new InvalidOperationException("Exception from ReadAsync");
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
throw new InvalidOperationException("Exception from ReadAsync");
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
throw new InvalidOperationException("Exception from WriteAsync");
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
public override Task FlushAsync(CancellationToken cancellationToken) =>
throw new InvalidOperationException("Exception from FlushAsync");
}
}
public class BufferedStream_NS17

View File

@@ -2,7 +2,8 @@
// 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.IO;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
@@ -23,5 +24,67 @@ namespace System.IO.Tests
var bufferedStream = new BufferedStream(new MemoryStream(), 1234);
Assert.Equal(1234, bufferedStream.BufferSize);
}
[Theory]
[InlineData(1, 1)]
[InlineData(1, 2)]
[InlineData(1024, 4096)]
[InlineData(4096, 4097)]
[InlineData(4096, 1)]
[InlineData(2047, 4096)]
public void ReadSpan_WriteSpan_AllDataCopied(int spanSize, int bufferSize)
{
byte[] data = new byte[80000];
new Random(42).NextBytes(data);
var result = new MemoryStream();
using (var output = new BufferedStream(result, bufferSize))
using (var input = new BufferedStream(new MemoryStream(data), bufferSize))
{
Span<byte> span = new byte[spanSize];
int bytesRead;
while ((bytesRead = input.Read(span)) != 0)
{
output.Write(span.Slice(0, bytesRead));
}
}
Assert.Equal(data, result.ToArray());
}
[Theory]
[InlineData(1, 1)]
[InlineData(1, 2)]
[InlineData(1024, 4096)]
[InlineData(4096, 4097)]
[InlineData(4096, 1)]
[InlineData(2047, 4096)]
public async Task ReadMemory_WriteMemory_AllDataCopied(int spanSize, int bufferSize)
{
byte[] data = new byte[80000];
new Random(42).NextBytes(data);
var result = new MemoryStream();
using (var output = new BufferedStream(result, bufferSize))
using (var input = new BufferedStream(new MemoryStream(data), bufferSize))
{
Memory<byte> memory = new byte[spanSize];
int bytesRead;
while ((bytesRead = await input.ReadAsync(memory)) != 0)
{
await output.WriteAsync(memory.Slice(0, bytesRead));
}
}
Assert.Equal(data, result.ToArray());
}
[Fact]
public void ReadWriteMemory_Precanceled_Throws()
{
using (var bs = new BufferedStream(new MemoryStream()))
{
Assert.Equal(TaskStatus.Canceled, bs.ReadAsync(new byte[1], new CancellationToken(true)).AsTask().Status);
Assert.Equal(TaskStatus.Canceled, bs.WriteAsync(new byte[1], new CancellationToken(true)).Status);
}
}
}
}

View File

@@ -3,14 +3,11 @@
// See the LICENSE file in the project root for more information.
using Xunit;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
namespace System.IO.Tests
{
public class MemoryStreamTests
public partial class MemoryStreamTests
{
[Fact]
public static void MemoryStream_Write_BeyondCapacity()
@@ -204,7 +201,7 @@ namespace System.IO.Tests
using (memoryStream = new MemoryStream())
{
AssertExtensions.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null));
// Validate the destination parameter first.
AssertExtensions.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: 0));
AssertExtensions.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: -1));
@@ -263,7 +260,7 @@ namespace System.IO.Tests
var stream2 = new MemoryStream(data2) { Position = 1 };
yield return new object[] { stream2, new byte[] { 0xf3, 0xf0 } };
// Stream is positioned after end of data
var data3 = data2;
var stream3 = new MemoryStream(data3) { Position = data3.Length + 1 };

View File

@@ -0,0 +1,180 @@
// 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 Xunit;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace System.IO.Tests
{
public partial class MemoryStreamTests
{
[Fact]
public void WriteSpan_DataWrittenAndPositionUpdated_Success()
{
const int Iters = 100;
var rand = new Random();
byte[] data = Enumerable.Range(0, (Iters * (Iters + 1)) / 2).Select(_ => (byte)rand.Next(256)).ToArray();
var s = new MemoryStream();
int expectedPos = 0;
for (int i = 0; i <= Iters; i++)
{
s.Write(new ReadOnlySpan<byte>(data, expectedPos, i));
expectedPos += i;
Assert.Equal(expectedPos, s.Position);
}
Assert.Equal(data, s.ToArray());
}
[Fact]
public void ReadSpan_DataReadAndPositionUpdated_Success()
{
const int Iters = 100;
var rand = new Random();
byte[] data = Enumerable.Range(0, (Iters * (Iters + 1)) / 2).Select(_ => (byte)rand.Next(256)).ToArray();
var s = new MemoryStream(data);
int expectedPos = 0;
for (int i = 0; i <= Iters; i++)
{
var toRead = new Span<byte>(new byte[i * 3]); // enough room to read the data and have some offset and have slack at the end
// Do the read and validate we read the expected number of bytes
Assert.Equal(i, s.Read(toRead.Slice(i, i)));
// The contents prior to and after the read should be empty.
Assert.Equal<byte>(new byte[i], toRead.Slice(0, i).ToArray());
Assert.Equal<byte>(new byte[i], toRead.Slice(i * 2, i).ToArray());
// And the data read should match what was expected.
Assert.Equal(new Span<byte>(data, expectedPos, i).ToArray(), toRead.Slice(i, i).ToArray());
// Updated position should match
expectedPos += i;
Assert.Equal(expectedPos, s.Position);
}
// A final read should be empty
Assert.Equal(0, s.Read(new Span<byte>(new byte[1])));
}
[Fact]
public void DerivedMemoryStream_ReadWriteSpanCalled_ReadWriteArrayUsed()
{
var s = new ReadWriteOverridingMemoryStream();
Assert.False(s.WriteArrayInvoked);
Assert.False(s.ReadArrayInvoked);
s.Write((ReadOnlySpan<byte>)new byte[1]);
Assert.True(s.WriteArrayInvoked);
Assert.False(s.ReadArrayInvoked);
s.Position = 0;
s.Read((Span<byte>)new byte[1]);
Assert.True(s.WriteArrayInvoked);
Assert.True(s.ReadArrayInvoked);
}
[Fact]
public async Task WriteAsyncReadOnlyMemory_DataWrittenAndPositionUpdated_Success()
{
const int Iters = 100;
var rand = new Random();
byte[] data = Enumerable.Range(0, (Iters * (Iters + 1)) / 2).Select(_ => (byte)rand.Next(256)).ToArray();
var s = new MemoryStream();
int expectedPos = 0;
for (int i = 0; i <= Iters; i++)
{
await s.WriteAsync(new ReadOnlyMemory<byte>(data, expectedPos, i));
expectedPos += i;
Assert.Equal(expectedPos, s.Position);
}
Assert.Equal(data, s.ToArray());
}
[Fact]
public async Task ReadAsyncMemory_DataReadAndPositionUpdated_Success()
{
const int Iters = 100;
var rand = new Random();
byte[] data = Enumerable.Range(0, (Iters * (Iters + 1)) / 2).Select(_ => (byte)rand.Next(256)).ToArray();
var s = new MemoryStream(data);
int expectedPos = 0;
for (int i = 0; i <= Iters; i++)
{
var toRead = new Memory<byte>(new byte[i * 3]); // enough room to read the data and have some offset and have slack at the end
// Do the read and validate we read the expected number of bytes
Assert.Equal(i, await s.ReadAsync(toRead.Slice(i, i)));
// The contents prior to and after the read should be empty.
Assert.Equal<byte>(new byte[i], toRead.Slice(0, i).ToArray());
Assert.Equal<byte>(new byte[i], toRead.Slice(i * 2, i).ToArray());
// And the data read should match what was expected.
Assert.Equal(new Span<byte>(data, expectedPos, i).ToArray(), toRead.Slice(i, i).ToArray());
// Updated position should match
expectedPos += i;
Assert.Equal(expectedPos, s.Position);
}
// A final read should be empty
Assert.Equal(0, await s.ReadAsync(new Memory<byte>(new byte[1])));
}
[Fact]
public async Task DerivedMemoryStream_ReadWriteAsyncMemoryCalled_ReadWriteAsyncArrayUsed()
{
var s = new ReadWriteOverridingMemoryStream();
Assert.False(s.WriteArrayInvoked);
Assert.False(s.ReadArrayInvoked);
await s.WriteAsync((ReadOnlyMemory<byte>)new byte[1]);
Assert.True(s.WriteArrayInvoked);
Assert.False(s.ReadArrayInvoked);
s.Position = 0;
await s.ReadAsync((Memory<byte>)new byte[1]);
Assert.True(s.WriteArrayInvoked);
Assert.True(s.ReadArrayInvoked);
}
private class ReadWriteOverridingMemoryStream : MemoryStream
{
public bool ReadArrayInvoked, WriteArrayInvoked;
public bool ReadAsyncArrayInvoked, WriteAsyncArrayInvoked;
public override int Read(byte[] buffer, int offset, int count)
{
ReadArrayInvoked = true;
return base.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
WriteArrayInvoked = true;
base.Write(buffer, offset, count);
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
ReadAsyncArrayInvoked = true;
return base.ReadAsync(buffer, offset, count, cancellationToken);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
WriteAsyncArrayInvoked = true;
return base.WriteAsync(buffer, offset, count, cancellationToken);
}
}
}
}

View File

@@ -2,9 +2,7 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -12,7 +10,7 @@ using Xunit;
namespace System.IO.Tests
{
public class NullTests
public partial class NullTests
{
[Fact]
public async static Task TestNullStream_Flush()
@@ -87,8 +85,8 @@ namespace System.IO.Tests
int read = source.Read(buffer, offset, count);
Assert.Equal(0, read);
Assert.Equal(copy, buffer); // Make sure Read doesn't modify the buffer
Assert.Equal(0, source.Position);
Assert.Equal(0, source.Position);
read = await source.ReadAsync(buffer, offset, count);
Assert.Equal(0, read);
Assert.Equal(copy, buffer);
@@ -114,8 +112,8 @@ namespace System.IO.Tests
source.Write(buffer, offset, count);
Assert.Equal(copy, buffer); // Make sure Write doesn't modify the buffer
Assert.Equal(0, source.Position);
Assert.Equal(0, source.Position);
await source.WriteAsync(buffer, offset, count);
Assert.Equal(copy, buffer);
Assert.Equal(0, source.Position);

View File

@@ -0,0 +1,41 @@
// 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.Linq;
using Xunit;
namespace System.IO.Tests
{
public partial class NullTests
{
[Theory]
[MemberData(nameof(NullStream_ReadWriteData))]
public void TestNullStream_ReadSpan(byte[] buffer, int offset, int count)
{
if (buffer == null) return;
byte[] copy = buffer.ToArray();
Stream source = Stream.Null;
int read = source.Read(new Span<byte>(buffer, offset, count));
Assert.Equal(0, read);
Assert.Equal(copy, buffer); // Make sure Read doesn't modify the buffer
Assert.Equal(0, source.Position);
}
[Theory]
[MemberData(nameof(NullStream_ReadWriteData))]
public void TestNullStream_WriteSpan(byte[] buffer, int offset, int count)
{
if (buffer == null) return;
byte[] copy = buffer.ToArray();
Stream source = Stream.Null;
source.Write(new Span<byte>(buffer, offset, count));
Assert.Equal(copy, buffer); // Make sure Write doesn't modify the buffer
Assert.Equal(0, source.Position);
}
}
}

View File

@@ -0,0 +1,189 @@
// 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.Buffers;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public class Stream_ReadWriteSpan
{
[Fact]
public void ReadSpan_DelegatesToRead_Success()
{
bool readInvoked = false;
var s = new DelegateStream(
canReadFunc: () => true,
readFunc: (array, offset, count) =>
{
readInvoked = true;
Assert.NotNull(array);
Assert.Equal(0, offset);
Assert.Equal(20, count);
for (int i = 0; i < 10; i++) array[offset + i] = (byte)i;
return 10;
});
Span<byte> totalSpan = new byte[30];
Span<byte> targetSpan = totalSpan.Slice(5, 20);
Assert.Equal(10, s.Read(targetSpan));
Assert.True(readInvoked);
for (int i = 0; i < 10; i++) Assert.Equal(i, targetSpan[i]);
for (int i = 10; i < 20; i++) Assert.Equal(0, targetSpan[i]);
readInvoked = false;
}
[Fact]
public void WriteSpan_DelegatesToWrite_Success()
{
bool writeInvoked = false;
var s = new DelegateStream(
canWriteFunc: () => true,
writeFunc: (array, offset, count) =>
{
writeInvoked = true;
Assert.NotNull(array);
Assert.Equal(0, offset);
Assert.Equal(3, count);
for (int i = 0; i < count; i++) Assert.Equal(i, array[offset + i]);
});
Span<byte> span = new byte[10];
span[3] = 1;
span[4] = 2;
s.Write(span.Slice(2, 3));
Assert.True(writeInvoked);
writeInvoked = false;
}
[Fact]
public async Task ReadAsyncMemory_WrapsArray_DelegatesToReadAsyncArray_Success()
{
bool readInvoked = false;
var s = new DelegateStream(
canReadFunc: () => true,
readAsyncFunc: (array, offset, count, cancellationToken) =>
{
readInvoked = true;
Assert.NotNull(array);
Assert.Equal(5, offset);
Assert.Equal(20, count);
for (int i = 0; i < 10; i++)
{
array[offset + i] = (byte)i;
}
return Task.FromResult(10);
});
Memory<byte> totalMemory = new byte[30];
Memory<byte> targetMemory = totalMemory.Slice(5, 20);
Assert.Equal(10, await s.ReadAsync(targetMemory));
Assert.True(readInvoked);
for (int i = 0; i < 10; i++)
Assert.Equal(i, targetMemory.Span[i]);
for (int i = 10; i < 20; i++)
Assert.Equal(0, targetMemory.Span[i]);
readInvoked = false;
}
[Fact]
public async Task ReadAsyncMemory_WrapsNative_DelegatesToReadAsyncArrayWithPool_Success()
{
bool readInvoked = false;
var s = new DelegateStream(
canReadFunc: () => true,
readAsyncFunc: (array, offset, count, cancellationToken) =>
{
readInvoked = true;
Assert.NotNull(array);
Assert.Equal(0, offset);
Assert.Equal(20, count);
for (int i = 0; i < 10; i++)
{
array[offset + i] = (byte)i;
}
return Task.FromResult(10);
});
using (var totalNativeMemory = new NativeOwnedMemory(30))
{
Memory<byte> totalMemory = totalNativeMemory.Memory;
Memory<byte> targetMemory = totalMemory.Slice(5, 20);
Assert.Equal(10, await s.ReadAsync(targetMemory));
Assert.True(readInvoked);
for (int i = 0; i < 10; i++)
Assert.Equal(i, targetMemory.Span[i]);
readInvoked = false;
}
}
[Fact]
public async Task WriteAsyncMemory_WrapsArray_DelegatesToWrite_Success()
{
bool writeInvoked = false;
var s = new DelegateStream(
canWriteFunc: () => true,
writeAsyncFunc: (array, offset, count, cancellationToken) =>
{
writeInvoked = true;
Assert.NotNull(array);
Assert.Equal(2, offset);
Assert.Equal(3, count);
for (int i = 0; i < count; i++)
Assert.Equal(i, array[offset + i]);
return Task.CompletedTask;
});
Memory<byte> memory = new byte[10];
memory.Span[3] = 1;
memory.Span[4] = 2;
await s.WriteAsync(memory.Slice(2, 3));
Assert.True(writeInvoked);
writeInvoked = false;
}
[Fact]
public async Task WriteAsyncMemory_WrapsNative_DelegatesToWrite_Success()
{
bool writeInvoked = false;
var s = new DelegateStream(
canWriteFunc: () => true,
writeAsyncFunc: (array, offset, count, cancellationToken) =>
{
writeInvoked = true;
Assert.NotNull(array);
Assert.Equal(0, offset);
Assert.Equal(3, count);
for (int i = 0; i < count; i++)
Assert.Equal(i, array[i]);
return Task.CompletedTask;
});
using (var nativeMemory = new NativeOwnedMemory(10))
{
Memory<byte> memory = nativeMemory.Memory;
memory.Span[2] = 0;
memory.Span[3] = 1;
memory.Span[4] = 2;
await s.WriteAsync(memory.Slice(2, 3));
Assert.True(writeInvoked);
writeInvoked = false;
}
}
}
}

View File

@@ -40,33 +40,7 @@ namespace System.IO.Tests
protected Tuple<char[], StreamReader> GetCharArrayStream()
{
var chArr = new char[]{
char.MinValue
,char.MaxValue
,'\t'
,' '
,'$'
,'@'
,'#'
,'\0'
,'\v'
,'\''
,'\u3190'
,'\uC3A0'
,'A'
,'5'
,'\r'
,'\uFE70'
,'-'
,';'
,'\r'
,'\n'
,'T'
,'3'
,'\n'
,'K'
,'\u00E6'
};
var chArr = TestDataProvider.CharData;
var ms = CreateStream();
var sw = new StreamWriter(ms);

View File

@@ -20,7 +20,7 @@ namespace System.IO.Tests
[Fact]
public void WriteChars()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Write a wide variety of characters and read them back
@@ -40,30 +40,6 @@ namespace System.IO.Tests
}
}
private static char[] setupArray()
{
return new char[]{
char.MinValue
,char.MaxValue
,'\t'
,' '
,'$'
,'@'
,'#'
,'\0'
,'\v'
,'\''
,'\u3190'
,'\uC3A0'
,'A'
,'5'
,'\uFE70'
,'-'
,';'
,'\u00E6'
};
}
[Fact]
public void NullArray()
{
@@ -78,7 +54,7 @@ namespace System.IO.Tests
[Fact]
public void NegativeOffset()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Exception if offset is negative
Stream ms = CreateStream();
@@ -91,7 +67,7 @@ namespace System.IO.Tests
[Fact]
public void NegativeCount()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Exception if count is negative
Stream ms = CreateStream();
@@ -104,7 +80,7 @@ namespace System.IO.Tests
[Fact]
public void WriteCustomLenghtStrings()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Write some custom length strings
Stream ms = CreateStream();
@@ -127,7 +103,7 @@ namespace System.IO.Tests
[Fact]
public void WriteToStreamWriter()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Just construct a streamwriter and write to it
//-------------------------------------------------
Stream ms = CreateStream();
@@ -149,7 +125,7 @@ namespace System.IO.Tests
[Fact]
public void TestWritingPastEndOfArray()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
Stream ms = CreateStream();
StreamWriter sw = new StreamWriter(ms);
@@ -160,7 +136,7 @@ namespace System.IO.Tests
[Fact]
public void VerifyWrittenString()
{
char[] chArr = setupArray();
char[] chArr = TestDataProvider.CharData;
// [] Write string with wide selection of characters and read it back
StringBuilder sb = new StringBuilder(40);

View File

@@ -8,7 +8,7 @@ using Xunit;
namespace System.IO.Tests
{
public class ReaderTests
public partial class StringReaderTests
{
[Fact]
public static void StringReaderWithNullString()

View File

@@ -0,0 +1,122 @@
// 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.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public partial class StringReaderTests
{
[Fact]
public void ReadSpan_Success()
{
string input = "abcdef";
var reader = new StringReader(input);
Span<char> s = new char[2];
Assert.Equal(2, reader.Read(s));
Assert.Equal("ab", new string(s.ToArray()));
Assert.Equal(1, reader.Read(s.Slice(0, 1)));
Assert.Equal("cb", new string(s.ToArray()));
Assert.Equal(2, reader.Read(s));
Assert.Equal("de", new string(s.ToArray()));
Assert.Equal(1, reader.Read(s));
Assert.Equal("f", new string(s.Slice(0, 1).ToArray()));
Assert.Equal(0, reader.Read(s));
}
[Fact]
public void ReadBlockSpan_Success()
{
string input = "abcdef";
var reader = new StringReader(input);
Span<char> s = new char[2];
Assert.Equal(2, reader.ReadBlock(s));
Assert.Equal("ab", new string(s.ToArray()));
Assert.Equal(1, reader.ReadBlock(s.Slice(0, 1)));
Assert.Equal("cb", new string(s.ToArray()));
Assert.Equal(2, reader.ReadBlock(s));
Assert.Equal("de", new string(s.ToArray()));
Assert.Equal(1, reader.ReadBlock(s));
Assert.Equal("f", new string(s.Slice(0, 1).ToArray()));
Assert.Equal(0, reader.ReadBlock(s));
}
[Fact]
public async Task ReadMemoryAsync_Success()
{
string input = "abcdef";
var reader = new StringReader(input);
Memory<char> m = new char[2];
Assert.Equal(2, await reader.ReadAsync(m));
Assert.Equal("ab", new string(m.ToArray()));
Assert.Equal(1, await reader.ReadAsync(m.Slice(0, 1)));
Assert.Equal("cb", new string(m.ToArray()));
Assert.Equal(2, await reader.ReadAsync(m));
Assert.Equal("de", new string(m.ToArray()));
Assert.Equal(1, await reader.ReadAsync(m));
Assert.Equal("f", new string(m.Slice(0, 1).ToArray()));
Assert.Equal(0, await reader.ReadAsync(m));
}
[Fact]
public async Task ReadBlockMemoryAsync_Success()
{
string input = "abcdef";
var reader = new StringReader(input);
Memory<char> m = new char[2];
Assert.Equal(2, await reader.ReadBlockAsync(m));
Assert.Equal("ab", new string(m.ToArray()));
Assert.Equal(1, await reader.ReadBlockAsync(m.Slice(0, 1)));
Assert.Equal("cb", new string(m.ToArray()));
Assert.Equal(2, await reader.ReadBlockAsync(m));
Assert.Equal("de", new string(m.ToArray()));
Assert.Equal(1, await reader.ReadBlockAsync(m));
Assert.Equal("f", new string(m.Slice(0, 1).ToArray()));
Assert.Equal(0, await reader.ReadBlockAsync(m));
}
[Fact]
public void Disposed_ThrowsException()
{
var reader = new StringReader("abc");
reader.Dispose();
Assert.Throws<ObjectDisposedException>(() => reader.Read(Span<char>.Empty));
Assert.Throws<ObjectDisposedException>(() => reader.ReadBlock(Span<char>.Empty));
Assert.Throws<ObjectDisposedException>(() => { reader.ReadAsync(Memory<char>.Empty); });
Assert.Throws<ObjectDisposedException>(() => { reader.ReadBlockAsync(Memory<char>.Empty); });
}
[Fact]
public async Task Precanceled_ThrowsException()
{
var reader = new StringReader("abc");
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => reader.ReadAsync(Memory<char>.Empty, new CancellationToken(true)).AsTask());
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => reader.ReadBlockAsync(Memory<char>.Empty, new CancellationToken(true)).AsTask());
}
}
}

View File

@@ -11,39 +11,15 @@ using System.Threading.Tasks;
namespace System.IO.Tests
{
public class StringWriterTests
public partial class StringWriterTests
{
static int[] iArrInvalidValues = new int[] { -1, -2, -100, -1000, -10000, -100000, -1000000, -10000000, -100000000, -1000000000, int.MinValue, short.MinValue };
static int[] iArrLargeValues = new int[] { int.MaxValue, int.MaxValue - 1, int.MaxValue / 2, int.MaxValue / 10, int.MaxValue / 100 };
static int[] iArrValidValues = new int[] { 10000, 100000, int.MaxValue / 2000, int.MaxValue / 5000, short.MaxValue };
private static char[] getCharArray()
{
return new char[]{
char.MinValue
,char.MaxValue
,'\t'
,' '
,'$'
,'@'
,'#'
,'\0'
,'\v'
,'\''
,'\u3190'
,'\uC3A0'
,'A'
,'5'
,'\uFE70'
,'-'
,';'
,'\u00E6'
};
}
private static StringBuilder getSb()
{
var chArr = getCharArray();
var chArr = TestDataProvider.CharData;
var sb = new StringBuilder(40);
for (int i = 0; i < chArr.Length; i++)
sb.Append(chArr[i]);
@@ -88,7 +64,7 @@ namespace System.IO.Tests
[Fact]
public static void WriteArray()
{
var chArr = getCharArray();
var chArr = TestDataProvider.CharData;
StringBuilder sb = getSb();
StringWriter sw = new StringWriter(sb);
@@ -125,7 +101,7 @@ namespace System.IO.Tests
[Fact]
public static void CantWriteIndexLargeValues()
{
var chArr = getCharArray();
var chArr = TestDataProvider.CharData;
for (int i = 0; i < iArrLargeValues.Length; i++)
{
StringWriter sw = new StringWriter();
@@ -136,7 +112,7 @@ namespace System.IO.Tests
[Fact]
public static void CantWriteCountLargeValues()
{
var chArr = getCharArray();
var chArr = TestDataProvider.CharData;
for (int i = 0; i < iArrLargeValues.Length; i++)
{
StringWriter sw = new StringWriter();
@@ -150,7 +126,7 @@ namespace System.IO.Tests
StringWriter sw = new StringWriter();
StringReader sr;
var chArr = getCharArray();
var chArr = TestDataProvider.CharData;
sw.Write(chArr, 2, 5);

View File

@@ -0,0 +1,40 @@
// 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.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public partial class StringWriterTests
{
[Fact]
public async Task WriteSpanMemory_Success()
{
var sw = new StringWriter();
sw.Write((Span<char>)new char[0]);
sw.Write((Span<char>)new char[] { 'a' });
sw.Write((Span<char>)new char[] { 'b', 'c', 'd' });
sw.WriteLine((Span<char>)new char[] { 'e' });
await sw.WriteAsync((ReadOnlyMemory<char>)new char[0]);
await sw.WriteAsync((ReadOnlyMemory<char>)new char[] { 'f' });
await sw.WriteAsync((ReadOnlyMemory<char>)new char[] { 'g', 'h', 'i' });
await sw.WriteLineAsync((ReadOnlyMemory<char>)new char[] { 'j' });
Assert.Equal("abcde" + Environment.NewLine + "fghij" + Environment.NewLine, sw.ToString());
}
[Fact]
public async Task Precanceled_ThrowsException()
{
var writer = new StringWriter();
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => writer.WriteAsync(Memory<char>.Empty, new CancellationToken(true)));
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => writer.WriteLineAsync(Memory<char>.Empty, new CancellationToken(true)));
}
}
}

View File

@@ -5,6 +5,7 @@
<RootNamespace>System.IO</RootNamespace>
<AssemblyName>System.IO.Tests</AssemblyName>
<ProjectGuid>{492EC54D-D2C4-4B3F-AC1F-646B3F7EBB02}</ProjectGuid>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
@@ -12,6 +13,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="BinaryReader\BinaryReaderTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="IndentedTextWriter.cs" />
<Compile Include="BinaryReader\BinaryReaderTests.cs" />
<Compile Include="MemoryStream\MemoryStream.GetBufferTests.cs" />
@@ -22,6 +24,7 @@
<Compile Include="StreamWriter\StreamWriter.StringCtorTests.cs" />
<Compile Include="Stream\Stream.APMMethodsTests.cs" />
<Compile Include="BinaryWriter\BinaryWriter.WriteByteCharTests.cs" />
<Compile Include="BinaryWriter\BinaryWriter.WriteByteCharTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="BinaryWriter\BinaryWriter.WriteTests.cs" />
<Compile Include="BinaryWriter\BinaryWriterTests.cs" />
<Compile Include="BufferedStream\BufferedStream.FlushTests.cs" />
@@ -32,6 +35,7 @@
<Compile Include="MemoryStream\MemoryStream.ConstructorTests.cs" />
<Compile Include="MemoryStream\MemoryStream.TryGetBufferTests.cs" />
<Compile Include="MemoryStream\MemoryStreamTests.cs" />
<Compile Include="MemoryStream\MemoryStreamTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="StreamReader\StreamReader.CtorTests.cs" />
<Compile Include="StreamReader\StreamReaderTests.cs" />
<Compile Include="StreamWriter\StreamWriter.BaseStream.cs" />
@@ -39,14 +43,21 @@
<Compile Include="StreamWriter\StreamWriter.CtorTests.cs" />
<Compile Include="StreamWriter\StreamWriter.FlushTests.cs" />
<Compile Include="StreamWriter\StreamWriter.WriteTests.cs" />
<Compile Include="Stream\Stream.ReadWriteSpan.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="Stream\Stream.NullTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="Stream\Stream.NullTests.cs" />
<Compile Include="Stream\Stream.AsyncTests.cs" />
<Compile Include="Stream\Stream.CopyToTests.cs" />
<Compile Include="Stream\Stream.Methods.cs" />
<Compile Include="Stream\Stream.TestLeaveOpen.cs" />
<Compile Include="Stream\Stream.TimeoutTests.cs" />
<Compile Include="StringReader\StringReaderTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="StringReader\StringReader.CtorTests.cs" />
<Compile Include="StringWriter\StringWriterTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="StringWriter\StringWriterTests.cs" />
<Compile Include="$(CommonTestPath)\System\Buffers\NativeOwnedMemory.cs" Condition="'$(TargetGroup)' == 'netcoreapp'">
<Link>Common\System\Buffers\NativeOwnedMemory.cs</Link>
</Compile>
<Compile Include="$(CommonTestPath)\System\IO\CallTrackingStream.cs">
<Link>Common\System\IO\CallTrackingStream.cs</Link>
</Compile>
@@ -56,6 +67,13 @@
<Compile Include="$(CommonTestPath)\System\IO\WrappedMemoryStream.cs">
<Link>Common\System\IO\WrappedMemoryStream.cs</Link>
</Compile>
<Compile Include="TestDataProvider\TestDataProvider.cs" />
<Compile Include="TextReader\CharArrayTextReader.cs" />
<Compile Include="TextReader\TextReaderTests.cs" />
<Compile Include="TextReader\TextReaderTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="TextWriter\CharArrayTextWriter.cs" />
<Compile Include="TextWriter\TextWriterTests.cs" />
<Compile Include="TextWriter\TextWriterTests.netcoreapp.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" />

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.IO.Tests
{
public static class TestDataProvider
{
private static readonly char[] s_charData;
private static readonly char[] s_smallData;
private static readonly char[] s_largeData;
public static object FirstObject { get; } = (object)1;
public static object SecondObject { get; } = (object)"[second object]";
public static object ThirdObject { get; } = (object)"<third object>";
public static object[] MultipleObjects { get; } = new object[] { FirstObject, SecondObject, ThirdObject };
public static string FormatStringOneObject { get; } = "Object is {0}";
public static string FormatStringTwoObjects { get; } = $"Object are '{0}', {SecondObject}";
public static string FormatStringThreeObjects { get; } = $"Objects are {0}, {SecondObject}, {ThirdObject}";
public static string FormatStringMultipleObjects { get; } = "Multiple Objects are: {0}, {1}, {2}";
static TestDataProvider()
{
s_charData = new char[]
{
char.MinValue,
char.MaxValue,
'\t',
' ',
'$',
'@',
'#',
'\0',
'\v',
'\'',
'\u3190',
'\uC3A0',
'A',
'5',
'\r',
'\uFE70',
'-',
';',
'\r',
'\n',
'T',
'3',
'\n',
'K',
'\u00E6'
};
s_smallData = "HELLO".ToCharArray();
var data = new List<char>();
for (int count = 0; count < 1000; ++count)
{
data.AddRange(s_smallData);
}
s_largeData = data.ToArray();
}
public static char[] CharData => s_charData;
public static char[] SmallData => s_smallData;
public static char[] LargeData => s_largeData;
}
}

View File

@@ -0,0 +1,37 @@
// 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.
namespace System.IO.Tests
{
public class CharArrayTextReader : TextReader
{
private readonly char[] _charBuffer;
private int _charPos = 0;
public bool EndOfStream => _charPos >= _charBuffer.Length;
public CharArrayTextReader(char[] data)
{
_charBuffer = data;
}
public override int Peek()
{
if (_charPos == _charBuffer.Length)
{
return -1;
}
return _charBuffer[_charPos];
}
public override int Read()
{
if (_charPos == _charBuffer.Length)
{
return -1;
}
return _charBuffer[_charPos++];
}
}
}

Some files were not shown because too many files have changed in this diff Show More