A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using NUnit.Framework;
4using Unity.Collections;
5using Unity.Collections.Tests;
6using Unity.Jobs;
7using Assert = FastAssert;
8
9internal class MathTests : CollectionsTestCommonBase
10{
11 [Test]
12 public void Tests()
13 {
14 Assert.AreEqual(0, CollectionHelper.Log2Floor(1));
15 Assert.AreEqual(1, CollectionHelper.Log2Floor(2));
16 Assert.AreEqual(1, CollectionHelper.Log2Floor(3));
17 Assert.AreEqual(2, CollectionHelper.Log2Floor(4));
18
19 Assert.AreEqual(3, CollectionHelper.Log2Floor(15));
20 Assert.AreEqual(4, CollectionHelper.Log2Floor(16));
21 Assert.AreEqual(4, CollectionHelper.Log2Floor(19));
22
23 Assert.AreEqual(30, CollectionHelper.Log2Floor(int.MaxValue));
24 Assert.AreEqual(16, CollectionHelper.Log2Floor(1 << 16));
25
26 Assert.AreEqual(-1, CollectionHelper.Log2Floor(0));
27 }
28}
29
30internal class NativeArraySortTests : CollectionsTestCommonBase
31{
32 [Test]
33 public void SortNativeArray_RandomInts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
34 {
35 var random = new Unity.Mathematics.Random(1);
36 NativeArray<int> array = new NativeArray<int>(size, Allocator.Persistent);
37 Assert.IsTrue(array.IsCreated);
38
39 for (int i = 0; i < array.Length; i++)
40 {
41 array[i] = random.NextInt(int.MinValue, int.MaxValue);
42 }
43
44 array.Sort();
45
46 int min = int.MinValue;
47 foreach (var i in array)
48 {
49 Assert.LessOrEqual(min, i);
50 min = i;
51 }
52 array.Dispose();
53 }
54
55 [Test]
56 public void SortNativeArray_SortedInts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
57 {
58 NativeArray<int> array = new NativeArray<int>(size, Allocator.Persistent);
59 Assert.IsTrue(array.IsCreated);
60
61 for (int i = 0; i < array.Length; i++)
62 {
63 array[i] = i;
64 }
65
66 array.Sort();
67
68 int min = int.MinValue;
69 foreach (var i in array)
70 {
71 Assert.LessOrEqual(min, i);
72 min = i;
73 }
74 array.Dispose();
75 }
76
77 [Test]
78 public void SortNativeArray_RandomBytes_ReturnSorted([Values(0, 1, 10, 1000, 10000, 100000)] int size)
79 {
80 var random = new Unity.Mathematics.Random(1);
81 NativeArray<byte> array = new NativeArray<byte>(size, Allocator.Persistent);
82 Assert.IsTrue(array.IsCreated);
83
84 for (int i = 0; i < array.Length; i++)
85 {
86 array[i] = (byte)random.NextInt(byte.MinValue, byte.MinValue);
87 }
88
89 array.Sort();
90
91 int min = int.MinValue;
92 foreach (var i in array)
93 {
94 Assert.LessOrEqual(min, i);
95 min = i;
96 }
97 array.Dispose();
98 }
99
100 [Test]
101 public void SortNativeArray_RandomShorts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
102 {
103 var random = new Unity.Mathematics.Random(1);
104 NativeArray<short> array = new NativeArray<short>(size, Allocator.Persistent);
105 Assert.IsTrue(array.IsCreated);
106
107 for (int i = 0; i < array.Length; i++)
108 {
109 array[i] = (short)random.NextInt(short.MinValue, short.MaxValue);
110 }
111
112 array.Sort();
113
114 int min = int.MinValue;
115 foreach (var i in array)
116 {
117 Assert.LessOrEqual(min, i);
118 min = i;
119 }
120 array.Dispose();
121 }
122
123 [Test]
124 public void SortNativeArray_RandomFloats_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
125 {
126 var random = new Unity.Mathematics.Random(1);
127 NativeArray<float> array = new NativeArray<float>(size, Allocator.Persistent);
128 Assert.IsTrue(array.IsCreated);
129
130 for (int i = 0; i < array.Length; i++)
131 {
132 array[i] = (float)random.NextDouble();
133 }
134
135 array.Sort();
136
137 float min = float.MinValue;
138 foreach (var i in array)
139 {
140 Assert.LessOrEqual(min, i);
141 min = i;
142 }
143 array.Dispose();
144 }
145
146 struct ComparableType : IComparable<ComparableType>
147 {
148 public int value;
149 public int CompareTo(ComparableType other) => value.CompareTo(other.value);
150 }
151
152 [Test]
153 public void SortNativeArray_RandomComparableType_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
154 {
155 var random = new Unity.Mathematics.Random(1);
156 NativeArray<ComparableType> array = new NativeArray<ComparableType>(size, Allocator.Persistent);
157 Assert.IsTrue(array.IsCreated);
158
159 for (int i = 0; i < array.Length; i++)
160 {
161 array[i] = new ComparableType
162 {
163 value = random.NextInt(int.MinValue, int.MaxValue)
164 };
165 }
166
167 array.Sort();
168
169 int min = int.MinValue;
170 foreach (var i in array)
171 {
172 Assert.LessOrEqual(min, i.value);
173 min = i.value;
174 }
175 array.Dispose();
176 }
177
178 struct NonComparableType
179 {
180 public int value;
181 }
182
183 struct NonComparableTypeComparator : IComparer<NonComparableType>
184 {
185 public int Compare(NonComparableType lhs, NonComparableType rhs)
186 {
187 return lhs.value.CompareTo(rhs.value);
188 }
189 }
190
191 [Test]
192 public void SortNativeArray_RandomNonComparableType_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
193 {
194 var random = new Unity.Mathematics.Random(1);
195 NativeArray<NonComparableType> array = new NativeArray<NonComparableType>(size, Allocator.Persistent);
196 Assert.IsTrue(array.IsCreated);
197
198 for (int i = 0; i < array.Length; i++)
199 {
200 array[i] = new NonComparableType
201 {
202 value = random.NextInt(int.MinValue, int.MaxValue)
203 };
204 }
205
206 array.Sort(new NonComparableTypeComparator());
207
208 int min = int.MinValue;
209 foreach (var i in array)
210 {
211 Assert.LessOrEqual(min, i.value);
212 min = i.value;
213 }
214 array.Dispose();
215 }
216
217 [Test]
218 public void SortNativeSlice_ReturnSorted()
219 {
220 var random = new Unity.Mathematics.Random(1);
221 NativeArray<int> array = new NativeArray<int>(1000, Allocator.Persistent);
222 Assert.IsTrue(array.IsCreated);
223
224 for (int i = 0; i < array.Length; ++i)
225 {
226 array[i] = random.NextInt(int.MinValue, int.MaxValue);
227 }
228
229 var slice = new NativeSlice<int>(array, 200, 600);
230
231 slice.Sort();
232
233 int min = int.MinValue;
234 foreach (var i in slice)
235 {
236 Assert.LessOrEqual(min, i);
237 min = i;
238 }
239
240 array.Dispose();
241 }
242
243 [Test]
244 public void SortNativeSlice_DoesNotChangeArrayBeyondLimits()
245 {
246 var random = new Unity.Mathematics.Random(1);
247 NativeArray<int> array = new NativeArray<int>(1000, Allocator.Persistent);
248 Assert.IsTrue(array.IsCreated);
249
250 for (int i = 0; i < array.Length; ++i)
251 {
252 array[i] = random.NextInt(int.MinValue, int.MaxValue);
253 }
254 var backupArray = new NativeArray<int>(array.Length, Allocator.Persistent);
255 backupArray.CopyFrom(array);
256
257 var slice = new NativeSlice<int>(array, 200, 600);
258
259 slice.Sort();
260
261 for (var i = 0; i < 200; ++i)
262 {
263 Assert.AreEqual(backupArray[i], array[i]);
264 }
265
266 for (var i = 800; i < 1000; ++i)
267 {
268 Assert.AreEqual(backupArray[i], array[i]);
269 }
270
271 array.Dispose();
272 backupArray.Dispose();
273 }
274
275 [Test]
276 [TestRequiresDotsDebugOrCollectionChecks]
277 public void SortNativeSlice_WithCustomStride_ThrowsInvalidOperationException()
278 {
279 var random = new Unity.Mathematics.Random(1);
280 NativeArray<int> array = new NativeArray<int>(10, Allocator.Persistent);
281 for (int i = 0; i < array.Length; ++i)
282 {
283 array[i] = random.NextInt(int.MinValue, int.MaxValue);
284 }
285
286 var slice = new NativeSlice<int>(array, 2, 6);
287 var sliceWithCustomStride = slice.SliceWithStride<short>();
288
289 Assert.DoesNotThrow(() => slice.Sort());
290 Assert.Throws<InvalidOperationException>(() => sliceWithCustomStride.Sort());
291
292 array.Dispose();
293 }
294}
295
296
297internal class NativeSliceTests : CollectionsTestCommonBase
298{
299 [Test]
300 public void NativeSlice_CopyTo()
301 {
302 NativeArray<int> array = new NativeArray<int>(1000, Allocator.Persistent);
303
304 for (int i = 0; i < array.Length; ++i)
305 {
306 array[i] = i;
307 }
308
309 var copyToArray = new int[600];
310
311 for (int i = 0; i < copyToArray.Length; ++i)
312 {
313 copyToArray[i] = 0x12345678;
314 }
315
316 var slice = new NativeSlice<int>(array, 200, 600);
317 slice.CopyTo(copyToArray);
318
319 for (var i = 0; i < 600; ++i)
320 {
321 Assert.AreEqual(copyToArray[i], array[i + 200]);
322 }
323
324 array.Dispose();
325 }
326
327 [Test]
328 public void NativeSlice_CopyFrom()
329 {
330 NativeArray<int> array = new NativeArray<int>(1000, Allocator.Persistent);
331
332 for (int i = 0; i < array.Length; ++i)
333 {
334 array[i] = i;
335 }
336
337 var copyFromArray = new int[600];
338
339 for (int i = 0; i < copyFromArray.Length; ++i)
340 {
341 copyFromArray[i] = 0x12345678;
342 }
343
344 var slice = new NativeSlice<int>(array, 200, 600);
345 slice.CopyFrom(copyFromArray);
346
347 for (var i = 0; i < 600; ++i)
348 {
349 Assert.AreEqual(slice[i], 0x12345678);
350 }
351
352 array.Dispose();
353 }
354
355 [Test]
356 public void SortJobNativeArray_RandomInts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
357 {
358 var random = new Unity.Mathematics.Random(1);
359 NativeArray<int> array = new NativeArray<int>(size, Allocator.Persistent);
360 Assert.IsTrue(array.IsCreated);
361
362 for (int i = 0; i < array.Length; i++)
363 {
364 array[i] = random.NextInt(int.MinValue, int.MaxValue);
365 }
366
367 array.SortJob().Schedule().Complete();
368
369 int min = int.MinValue;
370 foreach (var i in array)
371 {
372 Assert.LessOrEqual(min, i);
373 min = i;
374 }
375
376 array.Dispose();
377 }
378
379 [Test]
380 public void SortJobNativeArray_SortedInts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
381 {
382 NativeArray<int> array = new NativeArray<int>(size, Allocator.Persistent);
383 Assert.IsTrue(array.IsCreated);
384
385 for (int i = 0; i < array.Length; i++)
386 {
387 array[i] = i;
388 }
389
390 array.SortJob().Schedule().Complete();
391
392 int min = int.MinValue;
393 foreach (var i in array)
394 {
395 Assert.LessOrEqual(min, i);
396 min = i;
397 }
398 array.Dispose();
399 }
400
401 [Test]
402 public void SortJobNativeArray_RandomBytes_ReturnSorted([Values(0, 1, 10, 1000, 10000, 100000)] int size)
403 {
404 var random = new Unity.Mathematics.Random(1);
405 NativeArray<byte> array = new NativeArray<byte>(size, Allocator.Persistent);
406 Assert.IsTrue(array.IsCreated);
407
408 for (int i = 0; i < array.Length; i++)
409 {
410 array[i] = (byte)random.NextInt(byte.MinValue, byte.MinValue);
411 }
412
413 array.SortJob().Schedule().Complete();
414
415 int min = int.MinValue;
416 foreach (var i in array)
417 {
418 Assert.LessOrEqual(min, i);
419 min = i;
420 }
421 array.Dispose();
422 }
423
424 struct DescendingComparer<T> : IComparer<T> where T : IComparable<T>
425 {
426 public int Compare(T x, T y) => y.CompareTo(x);
427 }
428
429 [Test]
430 public void SortJobNativeArray_RandomBytes_ReturnSorted_Descending([Values(0, 1, 10, 1000, 10000, 100000)] int size)
431 {
432 var random = new Unity.Mathematics.Random(1);
433 NativeArray<byte> array = new NativeArray<byte>(size, Allocator.Persistent);
434 Assert.IsTrue(array.IsCreated);
435
436 for (int i = 0; i < array.Length; i++)
437 {
438 array[i] = (byte)random.NextInt(byte.MinValue, byte.MinValue);
439 }
440
441 array.SortJob(new DescendingComparer<byte>()).Schedule().Complete();
442
443 int max = int.MaxValue;
444 foreach (var i in array)
445 {
446 Assert.GreaterOrEqual(max, i);
447 max = i;
448 }
449 array.Dispose();
450 }
451
452 [Test]
453 public void SortJobNativeArray_RandomShorts_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
454 {
455 var random = new Unity.Mathematics.Random(1);
456 NativeArray<short> array = new NativeArray<short>(size, Allocator.Persistent);
457 Assert.IsTrue(array.IsCreated);
458
459 for (int i = 0; i < array.Length; i++)
460 {
461 array[i] = (short)random.NextInt(short.MinValue, short.MaxValue);
462 }
463
464 array.SortJob().Schedule().Complete();
465
466 int min = int.MinValue;
467 foreach (var i in array)
468 {
469 Assert.LessOrEqual(min, i);
470 min = i;
471 }
472 array.Dispose();
473 }
474
475 [Test]
476 public void SortNativeArrayByJob_RandomShorts_ReturnSorted_Descending([Values(0, 1, 10, 1000, 10000)] int size)
477 {
478 var random = new Unity.Mathematics.Random(1);
479 NativeArray<short> array = new NativeArray<short>(size, Allocator.Persistent);
480 Assert.IsTrue(array.IsCreated);
481
482 for (int i = 0; i < array.Length; i++)
483 {
484 array[i] = (short)random.NextInt(short.MinValue, short.MaxValue);
485 }
486
487 array.SortJob(new DescendingComparer<short>()).Schedule().Complete();
488
489 int max = int.MaxValue;
490 foreach (var i in array)
491 {
492 Assert.GreaterOrEqual(max, i);
493 max = i;
494 }
495 array.Dispose();
496 }
497
498 [Test]
499 public void SortJobNativeArray_RandomFloats_ReturnSorted([Values(0, 1, 10, 1000, 10000)] int size)
500 {
501 var random = new Unity.Mathematics.Random(1);
502 NativeArray<float> array = new NativeArray<float>(size, Allocator.Persistent);
503 Assert.IsTrue(array.IsCreated);
504
505 for (int i = 0; i < array.Length; i++)
506 {
507 array[i] = (float)random.NextDouble();
508 }
509
510 array.SortJob().Schedule().Complete();
511
512 float min = float.MinValue;
513 foreach (var i in array)
514 {
515 Assert.LessOrEqual(min, i);
516 min = i;
517 }
518 array.Dispose();
519 }
520
521 [Test]
522 public void SortJobNativeArray_RandomFloats_ReturnSorted_Descending([Values(0, 1, 10, 1000, 10000)] int size)
523 {
524 var random = new Unity.Mathematics.Random(1);
525 NativeArray<float> array = new NativeArray<float>(size, Allocator.Persistent);
526 Assert.IsTrue(array.IsCreated);
527
528 for (int i = 0; i < array.Length; i++)
529 {
530 array[i] = (float)random.NextDouble();
531 }
532
533 array.SortJob(new DescendingComparer<float>()).Schedule().Complete();
534
535 float max = float.MaxValue;
536 foreach (var i in array)
537 {
538 Assert.GreaterOrEqual(max, i);
539 max = i;
540 }
541 array.Dispose();
542 }
543
544 struct FilterOdd : IJobFilter
545 {
546 public bool Execute(int index) => index % 2 == 0;
547 }
548
549 [Test]
550 public void SortJobNativeList_UseInPreviousJob()
551 {
552 var rng = new Unity.Mathematics.Random(123);
553 NativeList<int> indices = new NativeList<int>(10, Allocator.TempJob);
554 for (int i = 0; i < 10; i++)
555 {
556 indices.Add(rng.NextInt(100));
557 }
558
559 var handle = new FilterOdd().ScheduleFilter(indices);
560 var sortJob = indices.SortJobDefer(new DescendingComparer<int>());
561 handle = sortJob.Schedule(handle);
562
563 handle.Complete();
564
565 float max = float.MaxValue;
566 foreach (var i in indices)
567 {
568 Assert.IsTrue(0 == (i & 1));
569 Assert.GreaterOrEqual(max, i);
570 max = i;
571 }
572
573 indices.Dispose();
574 }
575}