Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Radchenko <radchenkosasha@gmail.com>2018-04-10 04:40:29 +0300
committerAhson Khan <ahkha@microsoft.com>2018-04-10 04:40:29 +0300
commitbd301664af514f39fc3b4b84c5eb257aae3c011b (patch)
tree7aff8af208dede19b716de5e1edda762add04736 /src
parent3ad8ce59dd3203f8a72febf5c5e56c742de49fad (diff)
Created tests for default and empty ReadOnlySequence (#28702)
* Created tests for default and empty ReadOnlySequence * using * Added comments * Renamed method ThrowArgumentValidationException to ThrowStartOrEndArgumentValidationException * Splitted tests for Empty and Default into separated files * Review issues * Added brackets
Diffstat (limited to 'src')
-rw-r--r--src/System.Memory/src/System/Buffers/ReadOnlySequence.cs33
-rw-r--r--src/System.Memory/src/System/Buffers/ReadOnlySequence_helpers.cs28
-rw-r--r--src/System.Memory/src/System/ThrowHelper.cs18
-rw-r--r--src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Common.cs159
-rw-r--r--src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Default.cs191
-rw-r--r--src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Empty.cs216
-rw-r--r--src/System.Memory/tests/System.Memory.Tests.csproj2
7 files changed, 548 insertions, 99 deletions
diff --git a/src/System.Memory/src/System/Buffers/ReadOnlySequence.cs b/src/System.Memory/src/System/Buffers/ReadOnlySequence.cs
index 58c1518d82..1184e2212b 100644
--- a/src/System.Memory/src/System/Buffers/ReadOnlySequence.cs
+++ b/src/System.Memory/src/System/Buffers/ReadOnlySequence.cs
@@ -68,8 +68,10 @@ namespace System.Buffers
private ReadOnlySequence(object startSegment, int startIndexAndFlags, object endSegment, int endIndexAndFlags)
{
// Used by SliceImpl to create new ReadOnlySequence
- Debug.Assert(startSegment != null);
- Debug.Assert(endSegment != null);
+
+ // startSegment and endSegment can be null for default ReadOnlySequence only
+ Debug.Assert( (startSegment != null && endSegment != null) ||
+ (startSegment == null && endSegment == null && startIndexAndFlags == 0 && endIndexAndFlags == 0) );
_sequenceStart = new SequencePosition(startSegment, startIndexAndFlags);
_sequenceEnd = new SequencePosition(endSegment, endIndexAndFlags);
@@ -160,6 +162,9 @@ namespace System.Buffers
/// <param name="length">The length of the slice</param>
public ReadOnlySequence<T> Slice(long start, long length)
{
+ if (start < 0 || length < 0)
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
+
SequencePosition begin = Seek(_sequenceStart, _sequenceEnd, start);
SequencePosition end = Seek(begin, _sequenceEnd, length);
return SliceImpl(begin, end);
@@ -172,6 +177,8 @@ namespace System.Buffers
/// <param name="end">The end (inclusive) of the slice</param>
public ReadOnlySequence<T> Slice(long start, SequencePosition end)
{
+ if (start < 0)
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
BoundsCheck(end, _sequenceEnd);
SequencePosition begin = Seek(_sequenceStart, end, start);
@@ -191,7 +198,10 @@ namespace System.Buffers
/// <param name="length">The length of the slice</param>
public ReadOnlySequence<T> Slice(SequencePosition start, long length)
{
- BoundsCheck(start, _sequenceEnd);
+ BoundsCheck(start, _sequenceEnd); // check start before length
+ if (length < 0)
+ // Passing value >= 0 means throw exception on length argument
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(0);
SequencePosition end = Seek(start, _sequenceEnd, length);
return SliceImpl(start, end);
@@ -204,6 +214,9 @@ namespace System.Buffers
/// <param name="length">The length of the slice</param>
public ReadOnlySequence<T> Slice(int start, int length)
{
+ if (start < 0 || length < 0)
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
+
SequencePosition begin = Seek(_sequenceStart, _sequenceEnd, start);
SequencePosition end = Seek(begin, _sequenceEnd, length);
return SliceImpl(begin, end);
@@ -216,6 +229,8 @@ namespace System.Buffers
/// <param name="end">The end (inclusive) of the slice</param>
public ReadOnlySequence<T> Slice(int start, SequencePosition end)
{
+ if (start < 0)
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
BoundsCheck(end, _sequenceEnd);
SequencePosition begin = Seek(_sequenceStart, end, start);
@@ -235,7 +250,10 @@ namespace System.Buffers
/// <param name="length">The length of the slice</param>
public ReadOnlySequence<T> Slice(SequencePosition start, int length)
{
- BoundsCheck(start, _sequenceEnd);
+ BoundsCheck(start, _sequenceEnd); // check start before length
+ if (length < 0)
+ // Passing value >= 0 means throw exception on length argument
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(0);
SequencePosition end = Seek(start, _sequenceEnd, length);
return SliceImpl(start, end);
@@ -271,10 +289,11 @@ namespace System.Buffers
/// <param name="start">The start index at which to begin this slice.</param>
public ReadOnlySequence<T> Slice(long start)
{
+ if (start < 0)
+ ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
+
if (start == 0)
- {
return this;
- }
SequencePosition begin = Seek(_sequenceStart, _sequenceEnd, start);
return SliceImpl(begin, _sequenceEnd);
@@ -330,7 +349,7 @@ namespace System.Buffers
public SequencePosition GetPosition(long offset, SequencePosition origin)
{
if (offset < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset);
+ ThrowHelper.ThrowArgumentOutOfRangeException_OffsetOutOfRange();
return Seek(origin, _sequenceEnd, offset);
}
diff --git a/src/System.Memory/src/System/Buffers/ReadOnlySequence_helpers.cs b/src/System.Memory/src/System/Buffers/ReadOnlySequence_helpers.cs
index f3f40bf838..b1c5569c65 100644
--- a/src/System.Memory/src/System/Buffers/ReadOnlySequence_helpers.cs
+++ b/src/System.Memory/src/System/Buffers/ReadOnlySequence_helpers.cs
@@ -142,10 +142,10 @@ namespace System.Buffers
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal SequencePosition Seek(in SequencePosition start, in SequencePosition end, int count) => Seek(start, end, (long)count);
+ internal SequencePosition Seek(in SequencePosition start, in SequencePosition end, int offset) => Seek(start, end, (long)offset);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal SequencePosition Seek(in SequencePosition start, in SequencePosition end, long count)
+ internal SequencePosition Seek(in SequencePosition start, in SequencePosition end, long offset)
{
GetTypeAndIndices(start.GetInteger(), end.GetInteger(), out SequenceType type, out int startIndex, out int endIndex);
@@ -160,48 +160,48 @@ namespace System.Buffers
int currentLength = startSegment.Memory.Length - startIndex;
// Position in start segment, defer to single segment seek
- if (currentLength > count)
+ if (currentLength > offset)
goto IsSingleSegment;
// End of segment. Move to start of next.
- return SeekMultiSegment(startSegment.Next, startIndex, endObject, endIndex, count - currentLength);
+ return SeekMultiSegment(startSegment.Next, endObject, endIndex, offset - currentLength);
}
Debug.Assert(startObject == endObject);
- if (endIndex - startIndex < count)
- ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange();
+ if (endIndex - startIndex < offset)
+ ThrowHelper.ThrowArgumentOutOfRangeException_OffsetOutOfRange();
// Single segment Seek
IsSingleSegment:
- return new SequencePosition(startObject, startIndex + (int)count);
+ return new SequencePosition(startObject, startIndex + (int)offset);
}
[MethodImpl(MethodImplOptions.NoInlining)]
- private static SequencePosition SeekMultiSegment(ReadOnlySequenceSegment<T> currentSegment, int startIndex, object endObject, int endPosition, long count)
+ private static SequencePosition SeekMultiSegment(ReadOnlySequenceSegment<T> currentSegment, object endObject, int endPosition, long offset)
{
Debug.Assert(currentSegment != null);
- Debug.Assert(count >= 0);
+ Debug.Assert(offset >= 0);
while (currentSegment != null && currentSegment != endObject)
{
int memoryLength = currentSegment.Memory.Length;
// Fully contained in this segment
- if (memoryLength > count)
+ if (memoryLength > offset)
goto FoundSegment;
// Move to next
- count -= memoryLength;
+ offset -= memoryLength;
currentSegment = currentSegment.Next;
}
// Hit the end of the segments but didn't reach the count
- if (currentSegment == null || (currentSegment == endObject && endPosition < count))
- ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange();
+ if (currentSegment == null || (currentSegment == endObject && endPosition < offset))
+ ThrowHelper.ThrowArgumentOutOfRangeException_OffsetOutOfRange();
FoundSegment:
- return new SequencePosition(currentSegment, (int)count);
+ return new SequencePosition(currentSegment, (int)offset);
}
private static void CheckEndReachable(object startSegment, object endSegment)
diff --git a/src/System.Memory/src/System/ThrowHelper.cs b/src/System.Memory/src/System/ThrowHelper.cs
index f72d712f35..5a854a49b3 100644
--- a/src/System.Memory/src/System/ThrowHelper.cs
+++ b/src/System.Memory/src/System/ThrowHelper.cs
@@ -80,9 +80,9 @@ namespace System
[MethodImpl(MethodImplOptions.NoInlining)]
private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange() { return new ArgumentOutOfRangeException("position"); }
- internal static void ThrowArgumentOutOfRangeException_CountOutOfRange() { throw CreateArgumentOutOfRangeException_CountOutOfRange(); }
+ internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange() { throw CreateArgumentOutOfRangeException_OffsetOutOfRange(); }
[MethodImpl(MethodImplOptions.NoInlining)]
- private static Exception CreateArgumentOutOfRangeException_CountOutOfRange() { return new ArgumentOutOfRangeException("count"); }
+ private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange() { return new ArgumentOutOfRangeException(nameof(ExceptionArgument.offset)); }
internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer() { throw CreateObjectDisposedException_ArrayMemoryPoolBuffer(); }
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -151,6 +151,20 @@ namespace System
else
return CreateArgumentOutOfRangeException(ExceptionArgument.length);
}
+
+ //
+ // ReadOnlySequence Slice validation Throws coalesced to enable inlining of the Slice
+ //
+ public static void ThrowStartOrEndArgumentValidationException(long start)
+ => throw CreateStartOrEndArgumentValidationException(start);
+
+ private static Exception CreateStartOrEndArgumentValidationException(long start)
+ {
+ if (start < 0)
+ return CreateArgumentOutOfRangeException(ExceptionArgument.start);
+ return CreateArgumentOutOfRangeException(ExceptionArgument.length);
+ }
+
}
//
diff --git a/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Common.cs b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Common.cs
index 25cb2da0af..7cfa2d1c18 100644
--- a/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Common.cs
+++ b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Common.cs
@@ -5,7 +5,6 @@
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
-using System.MemoryTests;
using System.Text;
using Xunit;
@@ -13,6 +12,8 @@ namespace System.Memory.Tests
{
public class CommonReadOnlySequenceTests
{
+ #region Position
+
[Fact]
public void SegmentStartIsConsideredInBoundsCheck()
{
@@ -103,6 +104,10 @@ namespace System.Memory.Tests
Assert.Equal(200, seq.Length);
}
+ #endregion
+
+ #region First
+
[Fact]
public void CanGetFirst()
{
@@ -141,6 +146,10 @@ namespace System.Memory.Tests
Assert.Equal(0, buffer.First.Length);
}
+ #endregion
+
+ #region EmptySegments
+
[Fact]
public void SeekSkipsEmptySegments()
{
@@ -183,6 +192,62 @@ namespace System.Memory.Tests
}
[Fact]
+ public void SeekEmptySkipDoesNotCrossPastEnd()
+ {
+ var bufferSegment1 = new BufferSegment<byte>(new byte[100]);
+ BufferSegment<byte> bufferSegment2 = bufferSegment1.Append(new byte[0]);
+ BufferSegment<byte> bufferSegment3 = bufferSegment2.Append(new byte[0]);
+ BufferSegment<byte> bufferSegment4 = bufferSegment3.Append(new byte[100]);
+
+ var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
+
+ SequencePosition c1 = buffer.GetPosition(100);
+
+ Assert.Equal(0, c1.GetInteger());
+ Assert.Equal(bufferSegment2, c1.GetObject());
+
+ c1 = buffer.GetPosition(100, buffer.Start);
+
+ Assert.Equal(0, c1.GetInteger());
+ Assert.Equal(bufferSegment2, c1.GetObject());
+
+ // Go out of bounds for segment
+ Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(150, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(250, buffer.Start));
+ }
+
+ [Fact]
+ public void SeekEmptySkipDoesNotCrossPastEndWithExtraChainedBlocks()
+ {
+ var bufferSegment1 = new BufferSegment<byte>(new byte[100]);
+ BufferSegment<byte> bufferSegment2 = bufferSegment1.Append(new byte[0]);
+ BufferSegment<byte> bufferSegment3 = bufferSegment2.Append(new byte[0]);
+ BufferSegment<byte> bufferSegment4 = bufferSegment3.Append(new byte[100]);
+ BufferSegment<byte> bufferSegment5 = bufferSegment4.Append(new byte[0]);
+ BufferSegment<byte> bufferSegment6 = bufferSegment5.Append(new byte[100]);
+
+ var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
+
+ SequencePosition c1 = buffer.GetPosition(100);
+
+ Assert.Equal(0, c1.GetInteger());
+ Assert.Equal(bufferSegment2, c1.GetObject());
+
+ c1 = buffer.GetPosition(100, buffer.Start);
+
+ Assert.Equal(0, c1.GetInteger());
+ Assert.Equal(bufferSegment2, c1.GetObject());
+
+ // Go out of bounds for segment
+ Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(150, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(250, buffer.Start));
+ }
+
+ #endregion
+
+ #region TryGet
+
+ [Fact]
public void TryGetStopsAtEnd()
{
var bufferSegment1 = new BufferSegment<byte>(new byte[100]);
@@ -211,8 +276,8 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment1, 100);
- var start = buffer.Start;
- Assert.True(buffer.TryGet(ref start, out var memory));
+ SequencePosition start = buffer.Start;
+ Assert.True(buffer.TryGet(ref start, out ReadOnlyMemory<byte> memory));
Assert.Equal(100, memory.Length);
Assert.False(buffer.TryGet(ref start, out memory));
}
@@ -225,8 +290,8 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
- var start = buffer.Start;
- Assert.True(buffer.TryGet(ref start, out var memory));
+ SequencePosition start = buffer.Start;
+ Assert.True(buffer.TryGet(ref start, out ReadOnlyMemory<byte> memory));
Assert.Equal(100, memory.Length);
Assert.True(buffer.TryGet(ref start, out memory));
Assert.Equal(0, memory.Length);
@@ -241,14 +306,18 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
- var start = buffer.Start;
- Assert.True(buffer.TryGet(ref start, out var memory));
+ SequencePosition start = buffer.Start;
+ Assert.True(buffer.TryGet(ref start, out ReadOnlyMemory<byte> memory));
Assert.Equal(100, memory.Length);
Assert.True(buffer.TryGet(ref start, out memory));
Assert.Equal(0, memory.Length);
Assert.False(buffer.TryGet(ref start, out memory));
}
+ #endregion
+
+ #region Enumerable
+
[Fact]
public void EnumerableStopsAtEndWhenEndIsLastByteOfFull()
{
@@ -258,7 +327,7 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment1, 100);
List<int> sizes = new List<int>();
- foreach (var memory in buffer)
+ foreach (ReadOnlyMemory<byte> memory in buffer)
{
sizes.Add(memory.Length);
}
@@ -276,7 +345,7 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
List<int> sizes = new List<int>();
- foreach (var memory in buffer)
+ foreach (ReadOnlyMemory<byte> memory in buffer)
{
sizes.Add(memory.Length);
}
@@ -294,7 +363,7 @@ namespace System.Memory.Tests
var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
List<int> sizes = new List<int>();
- foreach (var memory in buffer)
+ foreach (ReadOnlyMemory<byte> memory in buffer)
{
sizes.Add(memory.Length);
}
@@ -303,73 +372,9 @@ namespace System.Memory.Tests
Assert.Equal(new[] { 100, 0 }, sizes);
}
- [Fact]
- public void SeekEmptySkipDoesNotCrossPastEnd()
- {
- var bufferSegment1 = new BufferSegment<byte>(new byte[100]);
- BufferSegment<byte> bufferSegment2 = bufferSegment1.Append(new byte[0]);
- BufferSegment<byte> bufferSegment3 = bufferSegment2.Append(new byte[0]);
- BufferSegment<byte> bufferSegment4 = bufferSegment3.Append(new byte[100]);
+ #endregion
- var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
-
- SequencePosition c1 = buffer.GetPosition(100);
-
- Assert.Equal(0, c1.GetInteger());
- Assert.Equal(bufferSegment2, c1.GetObject());
-
- c1 = buffer.GetPosition(100, buffer.Start);
-
- Assert.Equal(0, c1.GetInteger());
- Assert.Equal(bufferSegment2, c1.GetObject());
-
- // Go out of bounds for segment
- Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(150, buffer.Start));
- Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(250, buffer.Start));
- }
-
- [Fact]
- public void SeekEmptySkipDoesNotCrossPastEndWithExtraChainedBlocks()
- {
- var bufferSegment1 = new BufferSegment<byte>(new byte[100]);
- BufferSegment<byte> bufferSegment2 = bufferSegment1.Append(new byte[0]);
- BufferSegment<byte> bufferSegment3 = bufferSegment2.Append(new byte[0]);
- BufferSegment<byte> bufferSegment4 = bufferSegment3.Append(new byte[100]);
- BufferSegment<byte> bufferSegment5 = bufferSegment4.Append(new byte[0]);
- BufferSegment<byte> bufferSegment6 = bufferSegment5.Append(new byte[100]);
-
- var buffer = new ReadOnlySequence<byte>(bufferSegment1, 0, bufferSegment2, 0);
-
- SequencePosition c1 = buffer.GetPosition(100);
-
- Assert.Equal(0, c1.GetInteger());
- Assert.Equal(bufferSegment2, c1.GetObject());
-
- c1 = buffer.GetPosition(100, buffer.Start);
-
- Assert.Equal(0, c1.GetInteger());
- Assert.Equal(bufferSegment2, c1.GetObject());
-
- // Go out of bounds for segment
- Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(150, buffer.Start));
- Assert.Throws<ArgumentOutOfRangeException>(() => c1 = buffer.GetPosition(250, buffer.Start));
- }
-
- [Fact]
- public void Create_WorksWithArray()
- {
- var buffer = new ReadOnlySequence<byte>(new byte[] { 1, 2, 3, 4, 5 });
- Assert.Equal(buffer.ToArray(), new byte[] { 1, 2, 3, 4, 5 });
- }
-
- [Fact]
- public void Empty_ReturnsLengthZeroBuffer()
- {
- var buffer = ReadOnlySequence<byte>.Empty;
- Assert.Equal(0, buffer.Length);
- Assert.Equal(true, buffer.IsSingleSegment);
- Assert.Equal(0, buffer.First.Length);
- }
+ #region Constructor
[Fact]
public void Ctor_Array_Offset()
@@ -418,6 +423,8 @@ namespace System.Memory.Tests
Assert.Throws<ArgumentNullException>(() => new ReadOnlySequence<byte>(segment, 5, null, 0));
}
+ #endregion
+
[Fact]
public void HelloWorldAcrossTwoBlocks()
{
diff --git a/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Default.cs b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Default.cs
new file mode 100644
index 0000000000..b2d5ddc892
--- /dev/null
+++ b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Default.cs
@@ -0,0 +1,191 @@
+// 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 Xunit;
+
+namespace System.Memory.Tests
+{
+ public class ReadOnlySequenceTestsDefault
+ {
+ #region Constructor
+
+ [Fact]
+ public void Default_Constructor()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Equal(default, buffer.Start);
+ Assert.Equal(default, buffer.End);
+ Assert.True(buffer.IsEmpty);
+ Assert.True(buffer.IsSingleSegment);
+ Assert.Equal(0, buffer.Length);
+ Assert.True(buffer.First.IsEmpty);
+ Assert.Equal($"System.Buffers.ReadOnlySequence<{typeof(byte).Name}>[0]", buffer.ToString());
+ }
+
+ #endregion
+
+ #region GetPosition
+
+ [Fact]
+ public void Default_GetPosition()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ SequencePosition position = default;
+
+ Assert.Equal(position, buffer.GetPosition(0));
+ Assert.Equal(position, buffer.GetPosition(0, buffer.Start));
+ Assert.Equal(position, buffer.GetPosition(0, buffer.End));
+ }
+
+ [Fact]
+ public void Default_GetPositionPositive()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1, buffer.End));
+ }
+
+ [Fact]
+ public void Default_GetPositionNegative()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1, buffer.End));
+ }
+
+ #endregion
+
+ #region Slice
+
+ [Fact]
+ public void Default_Slice()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Equal(buffer, buffer.Slice(0, 0));
+ Assert.Equal(buffer, buffer.Slice(0, buffer.End));
+ Assert.Equal(buffer, buffer.Slice(0));
+ Assert.Equal(buffer, buffer.Slice(0L, 0L));
+ Assert.Equal(buffer, buffer.Slice(0L, buffer.End));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, 0));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, 0L));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, buffer.End));
+ }
+
+ [Fact]
+ public void Default_SlicePositiveStart()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, buffer.End));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1L, 0L));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1L, buffer.End));
+ }
+
+ [Fact]
+ public void Default_SliceNegativeStart()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, buffer.End));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, 0L));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, -1L));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, buffer.End));
+ }
+
+ [Fact]
+ public void Default_SlicePositiveLength()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(0, 1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(0L, 1L));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(buffer.Start, 1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(buffer.Start, 1L));
+ }
+
+ [Fact]
+ public void Default_SliceNegativeLength()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(0, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(0L, -1L));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(buffer.Start, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(buffer.Start, -1L));
+ }
+
+ #endregion
+
+ #region Enumerator
+
+ [Fact]
+ public void Default_Enumerator()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ ReadOnlySequence<byte>.Enumerator enumerator = buffer.GetEnumerator();
+ {
+ Assert.Equal(default, enumerator.Current);
+ Assert.False(enumerator.MoveNext());
+ }
+ enumerator = new ReadOnlySequence<byte>.Enumerator(default);
+ {
+ Assert.Equal(default, enumerator.Current);
+ Assert.False(enumerator.MoveNext());
+ }
+ }
+
+ #endregion
+
+ #region TryGet
+
+ [Fact]
+ public void Default_TryGet()
+ {
+ ReadOnlySequence<byte> buffer = default;
+ ReadOnlyMemory<byte> memory;
+
+ SequencePosition c1 = buffer.Start;
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ c1 = buffer.End;
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Empty.cs b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Empty.cs
new file mode 100644
index 0000000000..164c9727dc
--- /dev/null
+++ b/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceTests.Empty.cs
@@ -0,0 +1,216 @@
+// 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 Xunit;
+
+namespace System.Memory.Tests
+{
+ public class ReadOnlySequenceTestsEmpty
+ {
+ #region Constructor
+
+ [Fact]
+ public void Empty_Constructor()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Equal(buffer.Start.GetObject(), buffer.End.GetObject());
+ Assert.Equal(0, buffer.Start.GetInteger() & int.MaxValue);
+ Assert.Equal(0, buffer.End.GetInteger() & int.MaxValue);
+ Assert.True(buffer.IsEmpty);
+ Assert.True(buffer.IsSingleSegment);
+ Assert.Equal(0, buffer.Length);
+ Assert.True(buffer.First.IsEmpty);
+ Assert.Equal($"System.Buffers.ReadOnlySequence<{typeof(byte).Name}>[0]", buffer.ToString());
+ }
+
+ #endregion
+
+ #region GetPosition
+
+ [Fact]
+ public void Empty_GetPosition()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ SequencePosition position = new SequencePosition(buffer.Start.GetObject(), 0);
+
+ Assert.Equal(position, buffer.GetPosition(0));
+ Assert.Equal(position, buffer.GetPosition(0, buffer.Start));
+ Assert.Equal(position, buffer.GetPosition(0, buffer.End));
+ }
+
+ [Fact]
+ public void Empty_GetPositionPositive()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(1, buffer.End));
+ }
+
+ [Fact]
+ public void Empty_GetPositionNegative()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1, buffer.Start));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.GetPosition(-1, buffer.End));
+ }
+
+ #endregion
+
+ #region Slice
+
+ [Fact]
+ public void Empty_Slice()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Equal(buffer, buffer.Slice(0, 0));
+ Assert.Equal(buffer, buffer.Slice(0, buffer.End));
+ Assert.Equal(buffer, buffer.Slice(0));
+ Assert.Equal(buffer, buffer.Slice(0L, 0L));
+ Assert.Equal(buffer, buffer.Slice(0L, buffer.End));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, 0));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, 0L));
+ Assert.Equal(buffer, buffer.Slice(buffer.Start, buffer.End));
+ }
+
+ [Fact]
+ public void Empty_SlicePositiveStart()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1, buffer.End));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1L, 0L));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(1L, buffer.End));
+ }
+
+ [Fact]
+ public void Empty_SliceNegativeStart()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1, buffer.End));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, 0L));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, -1L));
+ Assert.Throws<ArgumentOutOfRangeException>("start", () => buffer.Slice(-1L, buffer.End));
+ }
+
+ [Fact]
+ public void Empty_SlicePositiveLength()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(0, 1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(0L, 1L));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(buffer.Start, 1));
+ Assert.Throws<ArgumentOutOfRangeException>("offset", () => buffer.Slice(buffer.Start, 1L));
+ }
+
+ [Fact]
+ public void Empty_SliceNegativeLength()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(0, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(0L, -1L));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(buffer.Start, -1));
+ Assert.Throws<ArgumentOutOfRangeException>("length", () => buffer.Slice(buffer.Start, -1L));
+ }
+
+ #endregion
+
+ #region Enumerator
+
+ [Fact]
+ public void Empty_Enumerator()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ ReadOnlySequence<byte>.Enumerator enumerator = buffer.GetEnumerator();
+ {
+ Assert.Equal(default, enumerator.Current);
+ Assert.True(enumerator.MoveNext());
+ ReadOnlyMemory<byte> memory = enumerator.Current;
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(enumerator.MoveNext());
+ }
+ enumerator = new ReadOnlySequence<byte>.Enumerator(buffer);
+ {
+ Assert.Equal(default, enumerator.Current);
+ Assert.True(enumerator.MoveNext());
+ ReadOnlyMemory<byte> memory = enumerator.Current;
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(enumerator.MoveNext());
+ }
+ }
+
+ #endregion
+
+ #region TryGet
+
+ [Fact]
+ public void Empty_TryGet()
+ {
+ ReadOnlySequence<byte> buffer = ReadOnlySequence<byte>.Empty;
+ ReadOnlyMemory<byte> memory;
+
+ SequencePosition c1 = buffer.Start;
+ Assert.True(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(buffer.Start, c1);
+ Assert.True(memory.IsEmpty);
+
+ Assert.True(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ c1 = buffer.End;
+ Assert.True(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(buffer.End, c1);
+ Assert.True(memory.IsEmpty);
+
+ Assert.True(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, false));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+
+ Assert.False(buffer.TryGet(ref c1, out memory, true));
+ Assert.Equal(null, c1.GetObject());
+ Assert.True(memory.IsEmpty);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/System.Memory/tests/System.Memory.Tests.csproj b/src/System.Memory/tests/System.Memory.Tests.csproj
index fa92304b23..d9bbbf699e 100644
--- a/src/System.Memory/tests/System.Memory.Tests.csproj
+++ b/src/System.Memory/tests/System.Memory.Tests.csproj
@@ -20,6 +20,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AllocationHelper.cs" />
+ <Compile Include="ReadOnlyBuffer\ReadOnlySequenceTests.Default.cs" />
+ <Compile Include="ReadOnlyBuffer\ReadOnlySequenceTests.Empty.cs" />
<Compile Include="TInt.cs" />
<Compile Include="TestException.cs" />
<Compile Include="TestHelpers.cs" />