Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
755 changes: 455 additions & 300 deletions src/System.Memory/src/System/SpanHelpers.T.cs

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/IndexOf.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,12 @@ public static void TestMultipleMatchIndexOf_String()
Assert.Equal(length - 2, idx);
}
}

[Theory]
[MemberData(nameof(TestHelpers.IndexOfNullData), MemberType = typeof(TestHelpers))]
public static void IndexOfNull_String(string[] spanInput, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).IndexOf((string)null));
}
}
}
21 changes: 21 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/IndexOfAny.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -962,5 +962,26 @@ public static void MakeSureNoChecksGoOutOfRangeIndexOfAny_ManyString()
Assert.Equal(-1, index);
}
}

[Theory]
[MemberData(nameof(TestHelpers.IndexOfAnyNullSequenceData), MemberType = typeof(TestHelpers))]
public static void IndexOfAnyNullSequence_String(string[] spanInput, string[] searchInput, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).IndexOfAny(searchInput));
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).IndexOfAny((ReadOnlySpan<string>)searchInput));

if (searchInput != null)
{
if (searchInput.Length >= 3)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).IndexOfAny(searchInput[0], searchInput[1], searchInput[2]));
}

if (searchInput.Length >= 2)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).IndexOfAny(searchInput[0], searchInput[1]));
}
}
}
}
}
7 changes: 7 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/IndexOfSequence.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,5 +230,12 @@ public static void IndexOfSequenceLengthOneValueJustPasttVeryEnd_String()
int index = span.IndexOf(value);
Assert.Equal(-1, index);
}

[Theory]
[MemberData(nameof(TestHelpers.IndexOfNullSequenceData), MemberType = typeof(TestHelpers))]
public static void IndexOfNullSequence_String(string[] source, string[] target, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(source).IndexOf(target));
}
}
}
7 changes: 7 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/LastIndexOf.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,12 @@ public static void TestMultipleMatchLastIndexOf_String()
Assert.Equal(length - 1, idx);
}
}

[Theory]
[MemberData(nameof(TestHelpers.LastIndexOfNullData), MemberType = typeof(TestHelpers))]
public static void LastIndexOfNull_String(string[] spanInput, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).LastIndexOf((string)null));
}
}
}
21 changes: 21 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/LastIndexOfAny.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -932,5 +932,26 @@ public static void MakeSureNoChecksGoOutOfRangeLastIndexOfAny_String_ManyByte()
Assert.Equal(-1, index);
}
}

[Theory]
[MemberData(nameof(TestHelpers.LastIndexOfAnyNullSequenceData), MemberType = typeof(TestHelpers))]
public static void LastIndexOfAnyNullSequence_String(string[] spanInput, string[] searchInput, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).LastIndexOfAny(searchInput));
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).LastIndexOfAny((ReadOnlySpan<string>)searchInput));

if (searchInput != null)
{
if (searchInput.Length >= 3)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).LastIndexOfAny(searchInput[0], searchInput[1], searchInput[2]));
}

if (searchInput.Length >= 2)
{
Assert.Equal(expected, new ReadOnlySpan<string>(spanInput).LastIndexOfAny(searchInput[0], searchInput[1]));
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -240,5 +240,12 @@ public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_String()
int index = span.LastIndexOf(value);
Assert.Equal(-1, index);
}

[Theory]
[MemberData(nameof(TestHelpers.LastIndexOfNullSequenceData), MemberType = typeof(TestHelpers))]
public static void LastIndexOfNullSequence_String(string[] source, string[] target, int expected)
{
Assert.Equal(expected, new ReadOnlySpan<string>(source).LastIndexOf(target));
}
}
}
9 changes: 9 additions & 0 deletions src/System.Memory/tests/ReadOnlySpan/SequenceEqual.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,14 @@ public static void MakeSureNoSequenceEqualChecksGoOutOfRange()
Assert.True(b);
}
}

[Theory]
[MemberData(nameof(TestHelpers.SequenceEqualNullData), MemberType = typeof(TestHelpers))]
public static void SequenceEqual_NullData_String(string[] firstInput, string[] secondInput, bool expected)
{
ReadOnlySpan<string> theStrings = firstInput;

Assert.Equal(expected, theStrings.SequenceEqual(secondInput));
}
}
}
9 changes: 9 additions & 0 deletions src/System.Memory/tests/Span/SequenceEqual.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ namespace System.SpanTests
{
public static partial class SpanTests
{
[Fact]
public static void NullReferenceSequenceEqual()
{
Span<string> first = new Span<string>(new string[] { "a", "b", null, null });
Span<string> second = new Span<string>(new string[] { "a", "b", null, null });
bool b = first.SequenceEqual(second);
Assert.True(b);
}

[Fact]
public static void ZeroLengthSequenceEqual()
{
Expand Down
130 changes: 130 additions & 0 deletions src/System.Memory/tests/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,5 +409,135 @@ public static Memory<T> DangerousCreateMemory<T>(object obj, int offset, int len
/// <summary>Creates a <see cref="ReadOnlyMemory{T}"/> with the specified values in its backing field.</summary>
public static ReadOnlyMemory<T> DangerousCreateReadOnlyMemory<T>(object obj, int offset, int length) =>
DangerousCreateMemory<T>(obj, offset, length);

public static TheoryData<string[], string[], bool> SequenceEqualNullData => new TheoryData<string[], string[], bool>()
{
{ new string[] { "1", null, "2" }, new string[] { "1", null, "2" } , true},
{ new string[] { "1", null, "2" }, new string[] { "1", "3", "2" } , false},
{ new string[] { "1", null, "2" }, new string[] { null, "3", "2" } , false},
{ new string[] { "1", null, "2" }, new string[] { null } , false},
{ new string[] { "1", null, "2" }, null , false},

{ new string[] { null, "2", "1" }, new string[] { null, "2" } , false},

{ null, new string[] { null }, false},
{ null, null , true},
{ null, new string[] { "1", "3", "2" } , false},
{ null, new string[] { "1", null, "2" } , false},

{ new string[] { "1", null, null }, new string[] { "1", null, null }, true},
{ new string[] { null, null, null }, new string[] { null, null, null }, true},
};

public static TheoryData<string[], int> IndexOfNullData => new TheoryData<string[], int>()
{
{ new string[] { "1", null, "2" }, 1},
{ new string[] { "1", "3", "2" }, -1},
{ null, -1},
{ new string[] { "1", null, null }, 1},
{ new string[] { null, null, null }, 0},
};

public static TheoryData<string[], string[], int> IndexOfNullSequenceData => new TheoryData<string[], string[], int>()
{
{ new string[] { "1", null, "2" }, new string[] { "1", null, "2" }, 0},
{ new string[] { "1", null, "2" }, new string[] { null }, 1},
{ new string[] { "1", null, "2" }, (string[])null, 0},

{ new string[] { "1", "3", "2" }, new string[] { "1", null, "2" }, -1},
{ new string[] { "1", "3", "2" }, new string[] { null }, -1},
{ new string[] { "1", "3", "2" }, (string[])null, 0},

{ null, new string[] { "1", null, "2" }, -1},

{ new string[] { "1", null, null }, new string[] { null, null, "2" }, -1},
{ new string[] { null, null, null }, new string[] { null, null }, 0},
};

public static TheoryData<string[], string[], int> IndexOfAnyNullSequenceData => new TheoryData<string[], string[], int>()
{
{ new string[] { "1", null, "2" }, new string[] { "1", null, "2" }, 0},
{ new string[] { "1", null, "2" }, new string[] { null, null }, 1},

{ new string[] { "1", null, "2" }, new string[] { "3", null }, 1},
{ new string[] { "1", null, "2" }, new string[] { "1", "2" }, 0},
{ new string[] { "1", null, "2" }, new string[] { "3", "4" }, -1},

{ new string[] { null, null, "2" }, new string[] { "3", null }, 0},
{ new string[] { null, null, "2" }, new string[] { null, "1" }, 0},
{ new string[] { null, null, "2" }, new string[] { null, "1" }, 0},

{ new string[] { "1", "3", "2" }, new string[] { "1", null, "2" }, 0},
{ new string[] { "1", "3", "2" }, new string[] { null, null }, -1},

{ new string[] { "1", "3", "2" }, new string[] { null, "1" }, 0},

{ null, new string[] { "1", null, "2" }, -1},

{ new string[] { "1", null, null }, new string[] { null, null, "2" }, 1},
{ new string[] { null, null, null }, new string[] { null, null }, 0},

{ new string[] { "1", "3", "2" }, null, 0},
{ new string[] { "1", null, "2" }, null, 0},
};

public static TheoryData<string[], int> LastIndexOfNullData => new TheoryData<string[], int>()
{
{ new string[] { "1", null, "2" }, 1},
{ new string[] { "1", "3", "2" }, -1},
{ null, -1},
{ new string[] { "1", null, null }, 2},
{ new string[] { null, null, null }, 2},
{ new string[] { null, null, "3" }, 1},
};

public static TheoryData<string[], string[], int> LastIndexOfNullSequenceData => new TheoryData<string[], string[], int>()
{
{ new string[] { "1", null, "2" }, new string[] { "1", null, "2" }, 0},
{ new string[] { "1", null, "2" }, new string[] { null }, 1},
{ new string[] { "1", null, "2" }, (string[])null, 0},

{ new string[] { "1", "3", "1" }, new string[] { "1", null, "2" }, -1},
{ new string[] { "1", "3", "1" }, new string[] { "1" }, 2},
{ new string[] { "1", "3", "1" }, null, 0},
{ new string[] { "1", "3", "1" }, (string[])null, 0},

{ null, new string[] { "1", null, "2" }, -1},

{ new string[] { "1", null, null }, new string[] { null, null, "2" }, -1},
{ new string[] { null, null, null }, new string[] { null, null }, 1},
};

public static TheoryData<string[], string[], int> LastIndexOfAnyNullSequenceData => new TheoryData<string[], string[], int>()
{
{ new string[] { "1", null, "2" }, new string[] { "1", null, "3" }, 1},
{ new string[] { "1", null, "2" }, new string[] { null, null }, 1},
{ new string[] { "1", null, "2" }, new string[] { "3", "4" }, -1},
{ new string[] { "1", null, "2" }, new string[] { "3", null }, 1},
{ new string[] { "1", null, "2" }, new string[] { "1", null }, 1},
{ new string[] { "1", null, "2" }, new string[] { null, null }, 1},
{ new string[] { "1", null, "2" }, new string[] { "1", "2" }, 2},
{ null, new string[] { "1", null, "2" }, -1},

{ new string[] { null, null, "2" }, new string[] { "3", null }, 1},
{ new string[] { null, null, "2" }, new string[] { null, "1" }, 1},
{ new string[] { null, null, "2" }, new string[] { null, "1" }, 1},

{ new string[] { "1", "3", "2" }, new string[] { null, "1" }, 0},
{ new string[] { "1", "3", "2" }, new string[] { "1", "2", null }, 2},
{ new string[] { "1", "3", "2" }, new string[] { "4", "5", null }, -1},
{ new string[] { "1", "3", "2" }, new string[] { null, null }, -1},
{ new string[] { "1", "3", "2" }, new string[] { null, null, null }, -1},
{ new string[] { "1", "3", "2" }, new string[] { null, null, null, null }, -1},
{ new string[] { "1", "3", "2" }, new string[] { null, null, null, null, null }, -1},

{ null, new string[] { null, "1" }, -1},

{ new string[] { "1", null, null }, new string[] { null, null, "2" }, 2},
{ new string[] { null, null, null }, new string[] { null, null }, 2},

{ new string[] { "1", null, "2" }, null, 0},
{ new string[] { "1", "3", "2" }, null, 0},
};
}
}