|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | + |
| 4 | +using System; |
| 5 | +using nanoFramework.TestFramework; |
| 6 | + |
| 7 | +namespace NFUnitTestTypes |
| 8 | +{ |
| 9 | + [TestClass] |
| 10 | + public class UnitTestsReadOnlySpanByte |
| 11 | + { |
| 12 | + //[TestMethod] |
| 13 | + //public void EmptySpanTests() |
| 14 | + //{ |
| 15 | + // // Empty span using default constructor |
| 16 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(); |
| 17 | + |
| 18 | + // Assert.AreEqual(0, span.Length, "Empty ReadOnlySpan should have length of 0"); |
| 19 | + // Assert.IsTrue(span.IsEmpty, "Empty ReadOnlySpan should be IsEmpty"); |
| 20 | + |
| 21 | + // // Empty span from null array |
| 22 | + // span = new ReadOnlySpan<byte>(null); |
| 23 | + |
| 24 | + // Assert.AreEqual(0, span.Length, "ReadOnlySpan from null should have length of 0"); |
| 25 | + // Assert.IsTrue(span.IsEmpty, "ReadOnlySpan from null should be IsEmpty"); |
| 26 | + |
| 27 | + // // Empty span using Empty property |
| 28 | + // span = ReadOnlySpan<byte>.Empty; |
| 29 | + |
| 30 | + // Assert.AreEqual(0, span.Length, "Empty ReadOnlySpan should have length of 0"); |
| 31 | + // Assert.IsTrue(span.IsEmpty, "Empty ReadOnlySpan should be IsEmpty"); |
| 32 | + //} |
| 33 | + |
| 34 | + //[TestMethod] |
| 35 | + //public void RaisingExceptionsOfAllKindsTests() |
| 36 | + //{ |
| 37 | + // // Should raise an exception on creation |
| 38 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => { ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(null, 1, 2); }, "ArgumentOutOfRangeException when array is null, start is 1 and length is 2"); |
| 39 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => { ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[1], 1, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 1 and length is 2"); |
| 40 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => { ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[1], 0, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 0 and length is 2"); |
| 41 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => { ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[1], 2, 0); }, "ArgumentOutOfRangeException when array is new byte[1], start is 2 and length is 0"); |
| 42 | + |
| 43 | + // // Exception on index access |
| 44 | + // byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 45 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 46 | + // { |
| 47 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 48 | + // _ = span[span.Length]; |
| 49 | + // }); |
| 50 | + |
| 51 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 52 | + // { |
| 53 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 54 | + // _ = span[-1]; |
| 55 | + // }); |
| 56 | + |
| 57 | + // // Slicing arguments |
| 58 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 59 | + // { |
| 60 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 61 | + // _ = span.Slice(span.Length + 1); |
| 62 | + // }); |
| 63 | + |
| 64 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 65 | + // { |
| 66 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 67 | + // _ = span.Slice(1, span.Length); |
| 68 | + // }); |
| 69 | + |
| 70 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 71 | + // { |
| 72 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 73 | + // _ = span.Slice(-1, span.Length); |
| 74 | + // }); |
| 75 | + |
| 76 | + // Assert.ThrowsException(typeof(ArgumentOutOfRangeException), () => |
| 77 | + // { |
| 78 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 79 | + // _ = span.Slice(1, -1); |
| 80 | + // }); |
| 81 | + //} |
| 82 | + |
| 83 | + [TestMethod] |
| 84 | + public void ToArrayTest() |
| 85 | + { |
| 86 | + byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 87 | + |
| 88 | + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 89 | + |
| 90 | + byte[] toArray = span.ToArray(); |
| 91 | + |
| 92 | + CollectionAssert.AreEqual(array, toArray, "Original array and ReadOnlySpan.ToArray should be the same"); |
| 93 | + } |
| 94 | + |
| 95 | + [TestMethod] |
| 96 | + public void ConstructorsOfAllKindsTests() |
| 97 | + { |
| 98 | + // Empty span using default constructor |
| 99 | + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(); |
| 100 | + |
| 101 | + Assert.AreEqual(span.Length, 0, "Empty ReadOnlySpan should have length of 0"); |
| 102 | + Assert.IsTrue(span.IsEmpty, "Empty ReadOnlySpan should be IsEmpty"); |
| 103 | + |
| 104 | + // Empty span from null with zero start and length |
| 105 | + span = new ReadOnlySpan<byte>(null, 0, 0); |
| 106 | + |
| 107 | + Assert.AreEqual(span.Length, 0, "Empty ReadOnlySpan should have length of 0"); |
| 108 | + Assert.IsTrue(span.IsEmpty, "Empty ReadOnlySpan should be IsEmpty"); |
| 109 | + |
| 110 | + //// Empty span using Empty property |
| 111 | + //span = ReadOnlySpan<byte>.Empty; |
| 112 | + |
| 113 | + //Assert.AreEqual(span.Length, 0, "Empty ReadOnlySpan should have length of 0"); |
| 114 | + //Assert.IsTrue(span.IsEmpty, "Empty ReadOnlySpan should be IsEmpty"); |
| 115 | + |
| 116 | + // ReadOnlySpan from normal array |
| 117 | + byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 118 | + span = new ReadOnlySpan<byte>(array); |
| 119 | + |
| 120 | + Assert.AreEqual(span.Length, array.Length, $"ReadOnlySpan should have length of the array it takes: {array.Length}"); |
| 121 | + Assert.IsFalse(span.IsEmpty, "ReadOnlySpan should NOT be IsEmpty"); |
| 122 | + |
| 123 | + // ReadOnlySpan from normal array with different start and length |
| 124 | + span = new ReadOnlySpan<byte>(array, 2, 8); |
| 125 | + |
| 126 | + Assert.AreEqual(span.Length, 8, $"ReadOnlySpan should have length of 8"); |
| 127 | + Assert.IsFalse(span.IsEmpty, "ReadOnlySpan should NOT be IsEmpty"); |
| 128 | + } |
| 129 | + |
| 130 | + //[TestMethod] |
| 131 | + //public void SliceTests() |
| 132 | + //{ |
| 133 | + // // ReadOnlySpan from normal array |
| 134 | + // byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 135 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 136 | + |
| 137 | + // // Slice 2 elements and check |
| 138 | + // ReadOnlySpan<byte> sliced = span.Slice(0, 2); |
| 139 | + |
| 140 | + // Assert.AreEqual(sliced.Length, 2, "Sliced span length must be 2"); |
| 141 | + // Assert.AreEqual(sliced[0], (byte)0x00, "Sliced first element must be value 0"); |
| 142 | + // Assert.AreEqual(sliced[1], (byte)0x01, "Sliced second element must be value 1"); |
| 143 | + |
| 144 | + // // Slice 4 elements starting at index 2 and check |
| 145 | + // sliced = span.Slice(2, 4); |
| 146 | + |
| 147 | + // Assert.AreEqual(sliced.Length, 4, "Sliced span length must be 4"); |
| 148 | + // Assert.AreEqual(sliced[0], (byte)0x02, "Sliced first element must be value 2"); |
| 149 | + // Assert.AreEqual(sliced[1], (byte)0x03, "Sliced second element must be value 3"); |
| 150 | + // Assert.AreEqual(sliced[2], (byte)0x04, "Sliced third element must be value 4"); |
| 151 | + // Assert.AreEqual(sliced[3], (byte)0x05, "Sliced fourth element must be value 5"); |
| 152 | + |
| 153 | + // // Slice starting at element 4 and check |
| 154 | + // sliced = span.Slice(4); |
| 155 | + |
| 156 | + // Assert.AreEqual(sliced.Length, 12, "Sliced span length must be 12"); |
| 157 | + |
| 158 | + // for (int i = 0; i < sliced.Length; i++) |
| 159 | + // { |
| 160 | + // Assert.AreEqual(sliced[i], span[i + 4], "ReadOnlySpan value should be the same as from the original span"); |
| 161 | + // } |
| 162 | + |
| 163 | + // // Slice of slice |
| 164 | + // ReadOnlySpan<byte> secondSliced = sliced.Slice(2, 4); |
| 165 | + |
| 166 | + // Assert.AreEqual(secondSliced.Length, 4, "Sliced span length must be 4"); |
| 167 | + |
| 168 | + // for (int i = 0; i < secondSliced.Length; i++) |
| 169 | + // { |
| 170 | + // Assert.AreEqual(secondSliced[i], sliced[i + 2], "ReadOnlySpan value should be the same as from the original span"); |
| 171 | + // } |
| 172 | + |
| 173 | + // // Should be an empty one |
| 174 | + // ReadOnlySpan<byte> empty = span.Slice(span.Length); |
| 175 | + |
| 176 | + // Assert.AreEqual(empty.Length, 0, "Slicing all the span should result in an empty span"); |
| 177 | + // Assert.IsTrue(empty.IsEmpty, "Empty span should be empty"); |
| 178 | + //} |
| 179 | + |
| 180 | + //[TestMethod] |
| 181 | + //public void GetElementsTests() |
| 182 | + //{ |
| 183 | + // // ReadOnlySpan from normal array |
| 184 | + // byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 185 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 186 | + // for (int i = 0; i < span.Length; i++) |
| 187 | + // { |
| 188 | + // Assert.AreEqual(span[i], array[i], "ReadOnlySpan value should be the same as from the original array"); |
| 189 | + // } |
| 190 | + |
| 191 | + // // Partial span |
| 192 | + // span = new ReadOnlySpan<byte>(array, 2, 8); |
| 193 | + // for (int i = 0; i < span.Length; i++) |
| 194 | + // { |
| 195 | + // Assert.AreEqual(span[i], array[i + 2], "ReadOnlySpan value should be the same as from the original array"); |
| 196 | + // } |
| 197 | + //} |
| 198 | + |
| 199 | + //[TestMethod] |
| 200 | + //public void StackAllocReadOnlySpanTests() |
| 201 | + //{ |
| 202 | + // // Create a ReadOnlySpan from stack-allocated memory |
| 203 | + // ReadOnlySpan<byte> span = stackalloc byte[16]; |
| 204 | + |
| 205 | + // Assert.AreEqual(16, span.Length, "Stack-allocated ReadOnlySpan should have length of 16"); |
| 206 | + // Assert.IsFalse(span.IsEmpty, "Stack-allocated ReadOnlySpan should NOT be IsEmpty"); |
| 207 | + |
| 208 | + // // Verify all elements are initialized to zero |
| 209 | + // for (int i = 0; i < span.Length; i++) |
| 210 | + // { |
| 211 | + // Assert.AreEqual((byte)0, span[i], "Stack-allocated ReadOnlySpan elements should be initialized to 0"); |
| 212 | + // } |
| 213 | + //} |
| 214 | + |
| 215 | + //[TestMethod] |
| 216 | + //public void StackAllocReadOnlySpanWithInitializerTests() |
| 217 | + //{ |
| 218 | + // // Create a ReadOnlySpan from stack-allocated memory with initializer |
| 219 | + // ReadOnlySpan<byte> span = stackalloc byte[8] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; |
| 220 | + |
| 221 | + // Assert.AreEqual(8, span.Length, "Stack-allocated ReadOnlySpan with initializer should have length of 8"); |
| 222 | + // Assert.IsFalse(span.IsEmpty, "Stack-allocated ReadOnlySpan should NOT be IsEmpty"); |
| 223 | + |
| 224 | + // // Verify the initialized values |
| 225 | + // for (int i = 0; i < span.Length; i++) |
| 226 | + // { |
| 227 | + // Assert.AreEqual((byte)(i + 1), span[i], $"Stack-allocated ReadOnlySpan element at index {i} should be {i + 1}"); |
| 228 | + // } |
| 229 | + //} |
| 230 | + |
| 231 | + //[TestMethod] |
| 232 | + //public void StackAllocReadOnlySpanSliceTests() |
| 233 | + //{ |
| 234 | + // // Create a ReadOnlySpan from stack-allocated memory |
| 235 | + // ReadOnlySpan<byte> span = stackalloc byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 236 | + |
| 237 | + // // Slice the stack-allocated span |
| 238 | + // ReadOnlySpan<byte> sliced = span.Slice(4, 8); |
| 239 | + |
| 240 | + // Assert.AreEqual(8, sliced.Length, "Sliced stack-allocated ReadOnlySpan should have length of 8"); |
| 241 | + |
| 242 | + // for (int i = 0; i < sliced.Length; i++) |
| 243 | + // { |
| 244 | + // Assert.AreEqual((byte)(i + 4), sliced[i], $"Sliced element at index {i} should be {i + 4}"); |
| 245 | + // } |
| 246 | + //} |
| 247 | + |
| 248 | + [TestMethod] |
| 249 | + public void StackAllocReadOnlySpanToArrayTests() |
| 250 | + { |
| 251 | + // Create a ReadOnlySpan from stack-allocated memory |
| 252 | + ReadOnlySpan<byte> span = stackalloc byte[6] { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; |
| 253 | + |
| 254 | + // Convert to array |
| 255 | + byte[] array = span.ToArray(); |
| 256 | + |
| 257 | + Assert.AreEqual(6, array.Length, "ToArray should create an array with the same length"); |
| 258 | + |
| 259 | + byte[] expected = new byte[] { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; |
| 260 | + CollectionAssert.AreEqual(expected, array, "Stack-allocated ReadOnlySpan ToArray should match expected values"); |
| 261 | + } |
| 262 | + |
| 263 | + [TestMethod] |
| 264 | + public void StackAllocEmptyReadOnlySpanTests() |
| 265 | + { |
| 266 | + // Create an empty stack-allocated ReadOnlySpan |
| 267 | + ReadOnlySpan<byte> span = stackalloc byte[0]; |
| 268 | + |
| 269 | + Assert.AreEqual(0, span.Length, "Empty stack-allocated ReadOnlySpan should have length of 0"); |
| 270 | + Assert.IsTrue(span.IsEmpty, "Empty stack-allocated ReadOnlySpan should be IsEmpty"); |
| 271 | + } |
| 272 | + |
| 273 | + //[TestMethod] |
| 274 | + //public void ImplicitConversionFromArrayTests() |
| 275 | + //{ |
| 276 | + // // Test implicit conversion from array to ReadOnlySpan |
| 277 | + // byte[] array = new byte[8] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80 }; |
| 278 | + |
| 279 | + // ReadOnlySpan<byte> span = array; // Implicit conversion |
| 280 | + |
| 281 | + // Assert.AreEqual(array.Length, span.Length, "Implicitly converted ReadOnlySpan should have same length as array"); |
| 282 | + |
| 283 | + // for (int i = 0; i < array.Length; i++) |
| 284 | + // { |
| 285 | + // Assert.AreEqual(array[i], span[i], $"Element at index {i} should match"); |
| 286 | + // } |
| 287 | + //} |
| 288 | + |
| 289 | + //[TestMethod] |
| 290 | + //public void EqualityOperatorTests() |
| 291 | + //{ |
| 292 | + // byte[] array1 = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; |
| 293 | + // byte[] array2 = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; |
| 294 | + // byte[] array3 = new byte[4] { 0x01, 0x02, 0x03, 0x05 }; |
| 295 | + |
| 296 | + // ReadOnlySpan<byte> span1 = new ReadOnlySpan<byte>(array1); |
| 297 | + // ReadOnlySpan<byte> span2 = new ReadOnlySpan<byte>(array2); |
| 298 | + // ReadOnlySpan<byte> span3 = new ReadOnlySpan<byte>(array3); |
| 299 | + |
| 300 | + // // Test equality with same content |
| 301 | + // Assert.IsTrue(span1 == span2, "ReadOnlySpans with same content should be equal"); |
| 302 | + |
| 303 | + // // Test inequality with different content |
| 304 | + // Assert.IsTrue(span1 != span3, "ReadOnlySpans with different content should not be equal"); |
| 305 | + // Assert.IsFalse(span1 == span3, "ReadOnlySpans with different content should not be equal"); |
| 306 | + |
| 307 | + // // Test empty spans |
| 308 | + // ReadOnlySpan<byte> empty1 = new ReadOnlySpan<byte>(); |
| 309 | + // ReadOnlySpan<byte> empty2 = new ReadOnlySpan<byte>(); |
| 310 | + |
| 311 | + // Assert.IsTrue(empty1 == empty2, "Empty ReadOnlySpans should be equal"); |
| 312 | + //} |
| 313 | + |
| 314 | + //[TestMethod] |
| 315 | + //public void ReadOnlyBehaviorTests() |
| 316 | + //{ |
| 317 | + // // Verify that ReadOnlySpan protects the underlying data from modification through the span |
| 318 | + // byte[] array = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; |
| 319 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array); |
| 320 | + |
| 321 | + // // We can read values |
| 322 | + // Assert.AreEqual((byte)0x01, span[0], "Should be able to read from ReadOnlySpan"); |
| 323 | + |
| 324 | + // // The following would not compile (which is the desired behavior): |
| 325 | + // // span[0] = 0xFF; // Error: Cannot assign to a readonly ref return |
| 326 | + |
| 327 | + // // But we can still modify the underlying array directly |
| 328 | + // array[0] = 0xFF; |
| 329 | + // Assert.AreEqual((byte)0xFF, span[0], "Modifying underlying array should be visible through ReadOnlySpan"); |
| 330 | + //} |
| 331 | + |
| 332 | + //[TestMethod] |
| 333 | + //public void PartialSpanTests() |
| 334 | + //{ |
| 335 | + // byte[] array = new byte[16] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
| 336 | + |
| 337 | + // // Create ReadOnlySpan that covers middle portion of array |
| 338 | + // ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(array, 4, 8); |
| 339 | + |
| 340 | + // Assert.AreEqual(8, span.Length, "Partial ReadOnlySpan should have correct length"); |
| 341 | + // Assert.AreEqual((byte)0x04, span[0], "First element should be from start index"); |
| 342 | + // Assert.AreEqual((byte)0x0B, span[7], "Last element should be at start + length - 1"); |
| 343 | + |
| 344 | + // // Verify all elements in the partial span |
| 345 | + // for (int i = 0; i < span.Length; i++) |
| 346 | + // { |
| 347 | + // Assert.AreEqual(array[i + 4], span[i], $"Element at index {i} should match array element at {i + 4}"); |
| 348 | + // } |
| 349 | + //} |
| 350 | + } |
| 351 | +} |
0 commit comments