A game about forced loneliness, made by TACStudios
1using System;
2using NUnit.Framework;
3using UnityEngine.Profiling;
4
5namespace UnityEngine.Rendering.Tests
6{
7 class DynamicArrayTests
8 {
9 DynamicArray<int> m_DynamicArray;
10
11 [SetUp]
12 public void Setup()
13 {
14 m_DynamicArray = new DynamicArray<int>();
15 }
16
17 [OneTimeTearDown]
18 public void CleanUp()
19 {
20 m_DynamicArray = null;
21 }
22
23 [Test]
24 public void TestContainElement()
25 {
26 m_DynamicArray.Add(2);
27
28 Assert.IsTrue(m_DynamicArray.Contains(2));
29 Assert.IsFalse(m_DynamicArray.Contains(55));
30 }
31
32 [Test]
33 public void TestAddElementCorrectSize()
34 {
35 Assert.AreEqual(0, m_DynamicArray.size);
36 m_DynamicArray.Add(2);
37 Assert.AreEqual(1, m_DynamicArray.size);
38 m_DynamicArray.Add(4);
39 Assert.AreEqual(2, m_DynamicArray.size);
40 }
41
42 [Test]
43 public void TestAddRangeCorrectElements()
44 {
45 m_DynamicArray.Add(1);
46 m_DynamicArray.Add(2);
47
48 var otherArray = new DynamicArray<int>();
49 otherArray.Add(3);
50 otherArray.Add(4);
51
52 m_DynamicArray.AddRange(otherArray);
53
54 Assert.AreEqual(1, m_DynamicArray[0]);
55 Assert.AreEqual(2, m_DynamicArray[1]);
56 Assert.AreEqual(3, m_DynamicArray[2]);
57 Assert.AreEqual(4, m_DynamicArray[3]);
58 Assert.AreEqual(4, m_DynamicArray.size);
59 }
60
61 [Test]
62 public void TestAddRangeOutOfSpaceKeepPreviousElements()
63 {
64 var smallDynamicArray = new DynamicArray<int>(2);
65 smallDynamicArray[0] = 1;
66 smallDynamicArray[1] = 2;
67
68 var otherArray = new DynamicArray<int>();
69 otherArray.Add(3);
70 otherArray.Add(4);
71
72 smallDynamicArray.AddRange(otherArray);
73
74 Assert.AreEqual(1, smallDynamicArray[0]);
75 Assert.AreEqual(2, smallDynamicArray[1]);
76 Assert.AreEqual(3, smallDynamicArray[2]);
77 Assert.AreEqual(4, smallDynamicArray[3]);
78 Assert.AreEqual(4, smallDynamicArray.size);
79 }
80
81 [Test]
82 public void TestRemoveElementCorrectSize()
83 {
84 m_DynamicArray.Add(2);
85 m_DynamicArray.Add(4);
86
87 Assert.AreEqual(2, m_DynamicArray.size);
88
89 m_DynamicArray.Remove(2);
90
91 Assert.AreEqual(1, m_DynamicArray.size);
92
93 m_DynamicArray.Remove(4);
94
95 Assert.AreEqual(0, m_DynamicArray.size);
96 }
97
98 [Test]
99 public void TestRemoveAtKeepOrder()
100 {
101 m_DynamicArray.Add(2);
102 m_DynamicArray.Add(4);
103 m_DynamicArray.Add(8);
104
105 Assert.AreEqual(3, m_DynamicArray.size);
106
107 m_DynamicArray.RemoveAt(1);
108
109 Assert.AreEqual(2, m_DynamicArray.size);
110 Assert.AreEqual(2, m_DynamicArray[0]);
111 Assert.AreEqual(8, m_DynamicArray[1]);
112 }
113
114 [Test]
115 public void TestRemoveInexistantElementReturnFalse()
116 {
117 m_DynamicArray.Add(2);
118 m_DynamicArray.Add(4);
119
120 Assert.IsFalse(m_DynamicArray.Remove(8));
121 Assert.AreEqual(2, m_DynamicArray.size);
122 }
123
124 [Test]
125 public void TestRemoveKeepOrder()
126 {
127 m_DynamicArray.Add(1);
128 m_DynamicArray.Add(2);
129 m_DynamicArray.Add(3);
130 m_DynamicArray.Add(4);
131
132 Assert.AreEqual(1, m_DynamicArray[0]);
133 Assert.AreEqual(2, m_DynamicArray[1]);
134 Assert.AreEqual(3, m_DynamicArray[2]);
135 Assert.AreEqual(4, m_DynamicArray[3]);
136 Assert.AreEqual(4, m_DynamicArray.size);
137
138 m_DynamicArray.Remove(2);
139 Assert.IsFalse(m_DynamicArray.Contains(2));
140 Assert.AreEqual(1, m_DynamicArray[0]);
141 Assert.AreEqual(3, m_DynamicArray[1]);
142 Assert.AreEqual(4, m_DynamicArray[2]);
143 Assert.AreEqual(3, m_DynamicArray.size);
144 }
145
146 [Test]
147 public void TestRemoveRangeKeepOrder()
148 {
149 m_DynamicArray.Add(1);
150 m_DynamicArray.Add(2);
151 m_DynamicArray.Add(3);
152 m_DynamicArray.Add(4);
153 m_DynamicArray.Add(5);
154
155 Assert.AreEqual(1, m_DynamicArray[0]);
156 Assert.AreEqual(2, m_DynamicArray[1]);
157 Assert.AreEqual(3, m_DynamicArray[2]);
158 Assert.AreEqual(4, m_DynamicArray[3]);
159 Assert.AreEqual(5, m_DynamicArray[4]);
160 Assert.AreEqual(5, m_DynamicArray.size);
161
162 m_DynamicArray.RemoveRange(1, 2);
163 Assert.IsFalse(m_DynamicArray.Contains(2));
164 Assert.IsFalse(m_DynamicArray.Contains(3));
165 Assert.AreEqual(1, m_DynamicArray[0]);
166 Assert.AreEqual(4, m_DynamicArray[1]);
167 Assert.AreEqual(5, m_DynamicArray[2]);
168 Assert.AreEqual(3, m_DynamicArray.size);
169 }
170
171 [Test]
172 public void TestInvalidAccessThrows()
173 {
174 m_DynamicArray.Add(1);
175 m_DynamicArray.Add(2);
176
177 int dummy;
178 Assert.Throws<System.IndexOutOfRangeException>(() => dummy = m_DynamicArray[2]);
179 Assert.Throws<System.IndexOutOfRangeException>(() => dummy = m_DynamicArray[-1]);
180 }
181
182 [Test]
183 public void TestRemoveAtInvalidAccessThrows()
184 {
185 m_DynamicArray.Add(1);
186 m_DynamicArray.Add(2);
187
188 Assert.Throws<System.IndexOutOfRangeException>(() => m_DynamicArray.RemoveAt(-1));
189 Assert.Throws<System.IndexOutOfRangeException>(() => m_DynamicArray.RemoveAt(2));
190 }
191
192 [Test]
193 public void TestRemoveRangeInvalidAccessThrows()
194 {
195 m_DynamicArray.Add(1);
196 m_DynamicArray.Add(2);
197
198 Assert.Throws<System.ArgumentOutOfRangeException>(() => m_DynamicArray.RemoveRange(1, 2));
199 }
200
201 [Test]
202 public void TestRemoveRangeValidAccessDoesNotThrows()
203 {
204 m_DynamicArray.Add(1);
205 m_DynamicArray.Add(2);
206
207 Assert.DoesNotThrow(() => m_DynamicArray.RemoveRange(1, 1));
208 }
209
210 [Test]
211 public void TestFindIndexFailReturnMinusOne()
212 {
213 m_DynamicArray.Add(1);
214 m_DynamicArray.Add(2);
215
216 Assert.AreEqual(-1, m_DynamicArray.FindIndex(0, m_DynamicArray.size, (x) => x == 4));
217 }
218
219 [Test]
220 public void TestFindIndexSuccessReturnRightFirstIndex()
221 {
222 m_DynamicArray.Add(1);
223 m_DynamicArray.Add(2);
224 m_DynamicArray.Add(3);
225 m_DynamicArray.Add(2);
226
227 Assert.AreEqual(1, m_DynamicArray.FindIndex(0, m_DynamicArray.size, (x) => x == 2));
228 }
229
230 [Test]
231 public void TestIndexOfReturnFirstValidIndex()
232 {
233 m_DynamicArray.Add(1);
234 m_DynamicArray.Add(2);
235 m_DynamicArray.Add(3);
236 m_DynamicArray.Add(2);
237
238 Assert.AreEqual(1, m_DynamicArray.IndexOf(2));
239 }
240
241 [Test]
242 public void TestIndexOfRangeRespectCount()
243 {
244 m_DynamicArray.Add(1);
245 m_DynamicArray.Add(2);
246 m_DynamicArray.Add(3);
247 m_DynamicArray.Add(4);
248
249 Assert.AreEqual(-1, m_DynamicArray.IndexOf(4, 1, 2));
250 }
251
252 [Test]
253 public void TestIndexOfRangeReturnFirstValidIndex()
254 {
255 m_DynamicArray.Add(1);
256 m_DynamicArray.Add(4);
257 m_DynamicArray.Add(3);
258 m_DynamicArray.Add(4);
259 m_DynamicArray.Add(5);
260
261 Assert.AreEqual(1, m_DynamicArray.IndexOf(4, 1, 3));
262 }
263
264 [Test]
265 public void TestIndexOfWithStartingIndexFail()
266 {
267 m_DynamicArray.Add(1);
268 m_DynamicArray.Add(4);
269 m_DynamicArray.Add(3);
270
271 Assert.AreEqual(-1, m_DynamicArray.IndexOf(1, 1, 2));
272 }
273
274 [Test]
275 public void TestResizeIncreaseCapacity()
276 {
277 m_DynamicArray.Resize(256);
278
279 Assert.AreEqual(256, m_DynamicArray.capacity);
280 }
281
282 [Test]
283 public void TestReserveKeepsSize()
284 {
285 var size = m_DynamicArray.size;
286 m_DynamicArray.Reserve(256);
287
288 Assert.AreEqual(256, m_DynamicArray.capacity);
289 Assert.AreEqual(size, m_DynamicArray.size);
290 }
291
292 [Test]
293 public void TestResizeAndClear()
294 {
295 // Uses the capacity only allocator
296 m_DynamicArray = new DynamicArray<int>(64, false);
297
298 Assert.AreEqual(0, m_DynamicArray.size);
299 Assert.AreEqual(64, m_DynamicArray.capacity);
300
301 // First resize it to 32 elements
302 m_DynamicArray.Resize(32, false);
303 Assert.AreEqual(32, m_DynamicArray.size);
304 m_DynamicArray[31] = 0xFFFF;
305
306 // Resize it back to 0 elements
307 m_DynamicArray.Resize(0);
308 Assert.AreEqual(0, m_DynamicArray.size);
309
310 // Resize it back to 32 elements, the memory should not have been reallocated
311 // it also shouln't have been cleared (for peformance reasons)
312 m_DynamicArray.Resize(32);
313 Assert.AreEqual(32, m_DynamicArray.size);
314 Assert.AreEqual(0xFFFF, m_DynamicArray[31]);
315
316 // Resize it back to 0 elements
317 m_DynamicArray.Resize(0);
318 Assert.AreEqual(0, m_DynamicArray.size);
319
320 // Resize it back to 32 elements, the memory should not have been reallocated
321 // the memory should have been cleared, resize and clear was used
322 m_DynamicArray.ResizeAndClear(32);
323 Assert.AreEqual(32, m_DynamicArray.size);
324 Assert.AreEqual(0, m_DynamicArray[31]);
325 }
326
327 [Test]
328 public void TestDynamicString()
329 {
330 var ds = new DynamicString("Foo");
331
332 ds.Append("Bar");
333 ds.Append(new DynamicString("Baz"));
334
335 var s = ds.ToString();
336 Assert.AreEqual("FooBarBaz", s);
337 }
338
339 [Test]
340 public void TestAppendSelf()
341 {
342 var ds = new DynamicString("Foo");
343
344 ds.Append(ds);
345
346 var s = ds.ToString();
347 Assert.AreEqual("FooFoo", s);
348 }
349
350 [Test]
351 public void TestQuickSort()
352 {
353 m_DynamicArray.Add(8);
354 m_DynamicArray.Add(4);
355 m_DynamicArray.Add(3);
356 m_DynamicArray.Add(4);
357 m_DynamicArray.Add(5);
358 m_DynamicArray.Add(1);
359 m_DynamicArray.Add(12);
360
361 m_DynamicArray.QuickSort();
362
363 Assert.AreEqual(1, m_DynamicArray[0]);
364 Assert.AreEqual(3, m_DynamicArray[1]);
365 Assert.AreEqual(4, m_DynamicArray[2]);
366 Assert.AreEqual(4, m_DynamicArray[3]);
367 Assert.AreEqual(5, m_DynamicArray[4]);
368 Assert.AreEqual(8, m_DynamicArray[5]);
369 Assert.AreEqual(12, m_DynamicArray[6]);
370 }
371
372 [Test]
373 public void TestForEach_FullRange()
374 {
375 m_DynamicArray.Add(8);
376 m_DynamicArray.Add(4);
377 m_DynamicArray.Add(3);
378 m_DynamicArray.Add(6);
379
380 var sum = 0;
381 foreach (var i in m_DynamicArray)
382 {
383 sum += i;
384 }
385 Assert.AreEqual(21, sum);
386
387 // now check if we are _not_ iterating on empty array
388 sum = 0;
389 m_DynamicArray.Clear();
390 foreach (var i in m_DynamicArray)
391 {
392 sum += i;
393 }
394 Assert.AreEqual(0, sum);
395 }
396 [Test]
397 public void TestForEach_SubRange()
398 {
399 m_DynamicArray.Add(8);
400 m_DynamicArray.Add(4);
401 m_DynamicArray.Add(3);
402 m_DynamicArray.Add(6);
403
404 var sum = 0;
405 foreach (var i in m_DynamicArray.SubRange(1,2))
406 {
407 sum += i;
408 }
409
410 Assert.AreEqual(7, sum);
411
412 //remove item of array and test again
413 m_DynamicArray.RemoveAt(1);
414 sum = 0;
415 foreach (var i in m_DynamicArray.SubRange(1,2))
416 {
417 sum += i;
418 }
419 Assert.AreEqual(9, sum);
420 }
421
422 [Test]
423 public void GetEnumerators_ArgumentValidation()
424 {
425 Assert.Throws<ArgumentNullException>(() => {
426 var iterator = new DynamicArray<int>.Iterator(null);
427 });
428
429 Assert.Throws<ArgumentNullException>(() => {
430 var iterator = new DynamicArray<int>.RangeEnumerable.RangeIterator(null, 0,0);
431 });
432
433 m_DynamicArray.Add(12);
434 m_DynamicArray.Add(2);
435
436 Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(-5, 1); });
437 Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(17, 1); });
438 Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(0, 12); });
439 Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(1, 2); });
440 Assert.DoesNotThrow(() => { var iterator = m_DynamicArray.SubRange(1, 1); });
441 Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(2, 1); });
442 }
443
444 [Test]
445 public void Foreach_TestNoModificationsAllowed()
446 {
447 Assert.Throws<InvalidOperationException>(() =>
448 {
449 m_DynamicArray.Add(3);
450 m_DynamicArray.Add(3);
451
452 foreach (var i in m_DynamicArray)
453 {
454 m_DynamicArray.Remove(i);
455 }
456 });
457
458 Assert.Throws<InvalidOperationException>(() =>
459 {
460 m_DynamicArray.Add(3);
461 m_DynamicArray.Add(3);
462
463 foreach (var i in m_DynamicArray)
464 {
465 m_DynamicArray.Add(1);
466 }
467 });
468
469 Assert.Throws<InvalidOperationException>(() =>
470 {
471 m_DynamicArray.Add(8);
472 m_DynamicArray.Add(3);
473
474 foreach (var i in m_DynamicArray)
475 {
476 if (i == 3)
477 {
478 m_DynamicArray.Add(1);
479 m_DynamicArray.RemoveAt(0);
480 }
481 }
482 });
483
484 Assert.Throws<InvalidOperationException>(() =>
485 {
486 m_DynamicArray.Add(8);
487 m_DynamicArray.Add(3);
488 m_DynamicArray.Add(7);
489
490 foreach (var i in m_DynamicArray)
491 {
492 if (i == 3)
493 {
494 m_DynamicArray.QuickSort();
495 }
496 }
497 });
498 }
499
500 static Recorder gcAllocRecorder = Recorder.Get("GC.Alloc");
501 static int CountGCAllocs(Action action)
502 {
503 gcAllocRecorder.FilterToCurrentThread();
504 gcAllocRecorder.enabled = false;
505 gcAllocRecorder.enabled = true;
506
507 action();
508
509 gcAllocRecorder.enabled = false;
510 return gcAllocRecorder.sampleBlockCount;
511 }
512 static void ValidateNoGCAllocs(Action action)
513 {
514 // warmup
515 // this will catch static c'tors etc
516 CountGCAllocs(action);
517
518 // actual test
519 var count = CountGCAllocs(action);
520 if (count != 0)
521 throw new AssertionException($"Expected 0 GC allocations but there were {count}");
522 }
523
524 [Test]
525 public void Foreach_NoGC()
526 {
527 m_DynamicArray.Reserve(4);
528 m_DynamicArray.Add(12);
529 m_DynamicArray.Add(4);
530 m_DynamicArray.Add(8);
531 m_DynamicArray.Add(2);
532
533 var sum = 0;
534 ValidateNoGCAllocs(() =>
535 {
536 sum = 0;
537 foreach (var i in m_DynamicArray)
538 {
539 sum += i;
540 }
541 });
542 Assert.AreEqual(sum, 26);
543
544 ValidateNoGCAllocs(() =>
545 {
546 sum = 0;
547 foreach (var i in m_DynamicArray.SubRange(0, 2))
548 {
549 sum += i;
550 }
551 });
552 Assert.AreEqual(sum, 16);
553 }
554 }
555}