Skip to content

Commit 14f40e2

Browse files
committed
Improved unit test coverage for RefEnumerable<T>
1 parent 296e916 commit 14f40e2

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed

UnitTests/UnitTests.HighPerformance.Shared/Extensions/Test_ArrayExtensions.2D.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ public void Test_ArrayExtensions_2D_GetRow_Rectangle()
181181

182182
CollectionAssert.AreEqual(array.GetRow(1).ToArray(), new[] { 5, 6, 7, 8 });
183183

184+
// Test an empty array
185+
Assert.AreSame(new int[1, 0].GetRow(0).ToArray(), Array.Empty<int>());
186+
184187
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.GetRow(-1));
185188

186189
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.GetRow(20));
@@ -254,6 +257,7 @@ public void Test_ArrayExtensions_2D_GetRowOrColumn_Helpers()
254257
Assert.ThrowsException<ArgumentException>(() => array.GetColumn(0).CopyTo(default(Span<int>)));
255258

256259
Assert.IsTrue(array.GetRow(2).TryCopyTo(copy));
260+
Assert.IsFalse(array.GetRow(0).TryCopyTo(default(Span<int>)));
257261

258262
result = new[] { 9, 10, 42, 12 };
259263

@@ -321,6 +325,7 @@ public void Test_ArrayExtensions_2D_ReadOnlyGetRowOrColumn_Helpers()
321325
Assert.ThrowsException<ArgumentException>(() => ((ReadOnlySpan2D<int>)array).GetColumn(0).CopyTo(default(Span<int>)));
322326

323327
Assert.IsTrue(span2D.GetRow(2).TryCopyTo(copy));
328+
Assert.IsFalse(span2D.GetRow(2).TryCopyTo(default(Span<int>)));
324329

325330
result = new[] { 9, 10, 11, 12 };
326331

@@ -353,6 +358,62 @@ public void Test_ArrayExtensions_2D_GetColumn_Rectangle()
353358
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.GetColumn(20));
354359
}
355360

361+
[TestCategory("ArrayExtensions")]
362+
[TestMethod]
363+
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1312", Justification = "Dummy loop variable")]
364+
[SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1501", Justification = "Empty test loop")]
365+
public void Test_ArrayExtensions_2D_RefEnumerable_Misc()
366+
{
367+
int[,] array1 =
368+
{
369+
{ 1, 2, 3, 4 },
370+
{ 5, 6, 7, 8 },
371+
{ 9, 10, 11, 12 },
372+
{ 13, 14, 15, 16 }
373+
};
374+
375+
int[,] array2 = new int[4, 4];
376+
377+
// Copy to enumerable with source step == 1, destination step == 1
378+
array1.GetRow(0).CopyTo(array2.GetRow(0));
379+
380+
// Copy enumerable with source step == 1, destination step != 1
381+
array1.GetRow(1).CopyTo(array2.GetColumn(1));
382+
383+
// Copy enumerable with source step != 1, destination step == 1
384+
array1.GetColumn(2).CopyTo(array2.GetRow(2));
385+
386+
// Copy enumerable with source step != 1, destination step != 1
387+
array1.GetColumn(3).CopyTo(array2.GetColumn(3));
388+
389+
int[,] result =
390+
{
391+
{ 1, 5, 3, 4 },
392+
{ 0, 6, 0, 8 },
393+
{ 3, 7, 11, 12 },
394+
{ 0, 8, 0, 16 }
395+
};
396+
397+
CollectionAssert.AreEqual(array2, result);
398+
399+
// Test a valid and an invalid TryCopyTo call with the RefEnumerable<T> overload
400+
bool shouldBeTrue = array1.GetRow(0).TryCopyTo(array2.GetColumn(0));
401+
bool shouldBeFalse = array1.GetRow(0).TryCopyTo(default(RefEnumerable<int>));
402+
403+
result = new[,]
404+
{
405+
{ 1, 5, 3, 4 },
406+
{ 2, 6, 0, 8 },
407+
{ 3, 7, 11, 12 },
408+
{ 4, 8, 0, 16 }
409+
};
410+
411+
CollectionAssert.AreEqual(array2, result);
412+
413+
Assert.IsTrue(shouldBeTrue);
414+
Assert.IsFalse(shouldBeFalse);
415+
}
416+
356417
[TestCategory("ArrayExtensions")]
357418
[TestMethod]
358419
public void Test_ArrayExtensions_2D_GetColumn_Empty()

UnitTests/UnitTests.HighPerformance.Shared/Extensions/Test_ReadOnlySpanExtensions.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,5 +267,35 @@ public void Test_ReadOnlySpanExtensions_Tokenize_CommaWithMissingValues()
267267

268268
CollectionAssert.AreEqual(result, tokens);
269269
}
270+
271+
[TestCategory("ReadOnlySpanExtensions")]
272+
[TestMethod]
273+
public void Test_ReadOnlySpanExtensions_CopyTo_RefEnumerable()
274+
{
275+
int[,] array1 = new int[4, 5];
276+
277+
ReadOnlySpan<int> values = new[] { 10, 20, 30, 40, 50 };
278+
279+
// Copy a span to a target row and column with valid lengths
280+
values.CopyTo(array1.GetRow(0));
281+
values.Slice(0, 4).CopyTo(array1.GetColumn(1));
282+
283+
// Try to copy to a valid row and an invalid column (too short for the source span)
284+
bool shouldBeTrue = values.TryCopyTo(array1.GetRow(2));
285+
bool shouldBeFalse = values.TryCopyTo(array1.GetColumn(1));
286+
287+
Assert.IsTrue(shouldBeTrue);
288+
Assert.IsFalse(shouldBeFalse);
289+
290+
int[,] result =
291+
{
292+
{ 10, 10, 30, 40, 50 },
293+
{ 0, 20, 0, 0, 0 },
294+
{ 10, 20, 30, 40, 50 },
295+
{ 0, 40, 0, 0, 0 }
296+
};
297+
298+
CollectionAssert.AreEqual(array1, result);
299+
}
270300
}
271301
}

UnitTests/UnitTests.HighPerformance.Shared/Extensions/Test_SpanExtensions.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,35 @@ public void Test_SpanExtensions_Enumerate_Empty()
168168
Assert.Fail("Empty source sequence");
169169
}
170170
}
171+
172+
[TestCategory("SpanExtensions")]
173+
[TestMethod]
174+
public void Test_SpanExtensions_CopyTo_RefEnumerable()
175+
{
176+
int[,] array1 = new int[4, 5];
177+
178+
int[] values = { 10, 20, 30, 40, 50 };
179+
180+
// Copy a span to a target row and column with valid lengths
181+
values.AsSpan().CopyTo(array1.GetRow(0));
182+
values.AsSpan(0, 4).CopyTo(array1.GetColumn(1));
183+
184+
// Try to copy to a valid row and an invalid column (too short for the source span)
185+
bool shouldBeTrue = values.AsSpan().TryCopyTo(array1.GetRow(2));
186+
bool shouldBeFalse = values.AsSpan().TryCopyTo(array1.GetColumn(1));
187+
188+
Assert.IsTrue(shouldBeTrue);
189+
Assert.IsFalse(shouldBeFalse);
190+
191+
int[,] result =
192+
{
193+
{ 10, 10, 30, 40, 50 },
194+
{ 0, 20, 0, 0, 0 },
195+
{ 10, 20, 30, 40, 50 },
196+
{ 0, 40, 0, 0, 0 }
197+
};
198+
199+
CollectionAssert.AreEqual(array1, result);
200+
}
171201
}
172202
}

UnitTests/UnitTests.HighPerformance.Shared/Memory/Test_ReadOnlySpan2D{T}.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics.CodeAnalysis;
77
using System.Runtime.CompilerServices;
88
using Microsoft.Toolkit.HighPerformance.Enumerables;
9+
using Microsoft.Toolkit.HighPerformance.Extensions;
910
using Microsoft.Toolkit.HighPerformance.Memory;
1011
using Microsoft.VisualStudio.TestTools.UnitTesting;
1112

@@ -692,6 +693,8 @@ public void Test_ReadOnlySpan2DT_GetRow()
692693

693694
CollectionAssert.AreEqual(enumerable.ToArray(), expected);
694695

696+
Assert.AreSame(default(ReadOnlyRefEnumerable<int>).ToArray(), Array.Empty<int>());
697+
695698
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).GetRow(-1));
696699
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).GetRow(2));
697700
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).GetRow(1000));
@@ -832,5 +835,83 @@ public void Test_ReadOnlySpan2DT_GetEnumerator_Empty()
832835

833836
Assert.IsFalse(enumerator.MoveNext());
834837
}
838+
839+
[TestCategory("ReadOnlySpan2DT")]
840+
[TestMethod]
841+
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1312", Justification = "Dummy loop variable")]
842+
[SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1501", Justification = "Empty test loop")]
843+
public void Test_ReadOnlySpan2DT_ReadOnlyRefEnumerable_Misc()
844+
{
845+
int[,] array1 =
846+
{
847+
{ 1, 2, 3, 4 },
848+
{ 5, 6, 7, 8 },
849+
{ 9, 10, 11, 12 },
850+
{ 13, 14, 15, 16 }
851+
};
852+
853+
ReadOnlySpan2D<int> span1 = array1;
854+
855+
int[,] array2 = new int[4, 4];
856+
857+
// Copy to enumerable with source step == 1, destination step == 1
858+
span1.GetRow(0).CopyTo(array2.GetRow(0));
859+
860+
// Copy enumerable with source step == 1, destination step != 1
861+
span1.GetRow(1).CopyTo(array2.GetColumn(1));
862+
863+
// Copy enumerable with source step != 1, destination step == 1
864+
span1.GetColumn(2).CopyTo(array2.GetRow(2));
865+
866+
// Copy enumerable with source step != 1, destination step != 1
867+
span1.GetColumn(3).CopyTo(array2.GetColumn(3));
868+
869+
int[,] result =
870+
{
871+
{ 1, 5, 3, 4 },
872+
{ 0, 6, 0, 8 },
873+
{ 3, 7, 11, 12 },
874+
{ 0, 8, 0, 16 }
875+
};
876+
877+
CollectionAssert.AreEqual(array2, result);
878+
879+
// Test a valid and an invalid TryCopyTo call with the RefEnumerable<T> overload
880+
bool shouldBeTrue = span1.GetRow(0).TryCopyTo(array2.GetColumn(0));
881+
bool shouldBeFalse = span1.GetRow(0).TryCopyTo(default(RefEnumerable<int>));
882+
883+
result = new[,]
884+
{
885+
{ 1, 5, 3, 4 },
886+
{ 2, 6, 0, 8 },
887+
{ 3, 7, 11, 12 },
888+
{ 4, 8, 0, 16 }
889+
};
890+
891+
CollectionAssert.AreEqual(array2, result);
892+
893+
Assert.IsTrue(shouldBeTrue);
894+
Assert.IsFalse(shouldBeFalse);
895+
}
896+
897+
[TestCategory("ReadOnlySpan2DT")]
898+
[TestMethod]
899+
public void Test_ReadOnlySpan2DT_ReadOnlyRefEnumerable_Cast()
900+
{
901+
int[,] array1 =
902+
{
903+
{ 1, 2, 3, 4 },
904+
{ 5, 6, 7, 8 },
905+
{ 9, 10, 11, 12 },
906+
{ 13, 14, 15, 16 }
907+
};
908+
909+
int[] result = { 5, 6, 7, 8 };
910+
911+
// Cast a RefEnumerable<T> to a readonly one and verify the contents
912+
int[] row = ((ReadOnlyRefEnumerable<int>)array1.GetRow(1)).ToArray();
913+
914+
CollectionAssert.AreEqual(result, row);
915+
}
835916
}
836917
}

0 commit comments

Comments
 (0)