You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

555 lines
16 KiB

using System;
using NUnit.Framework;
using UnityEngine.Profiling;
namespace UnityEngine.Rendering.Tests
{
class DynamicArrayTests
{
DynamicArray<int> m_DynamicArray;
[SetUp]
public void Setup()
{
m_DynamicArray = new DynamicArray<int>();
}
[OneTimeTearDown]
public void CleanUp()
{
m_DynamicArray = null;
}
[Test]
public void TestContainElement()
{
m_DynamicArray.Add(2);
Assert.IsTrue(m_DynamicArray.Contains(2));
Assert.IsFalse(m_DynamicArray.Contains(55));
}
[Test]
public void TestAddElementCorrectSize()
{
Assert.AreEqual(0, m_DynamicArray.size);
m_DynamicArray.Add(2);
Assert.AreEqual(1, m_DynamicArray.size);
m_DynamicArray.Add(4);
Assert.AreEqual(2, m_DynamicArray.size);
}
[Test]
public void TestAddRangeCorrectElements()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
var otherArray = new DynamicArray<int>();
otherArray.Add(3);
otherArray.Add(4);
m_DynamicArray.AddRange(otherArray);
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(2, m_DynamicArray[1]);
Assert.AreEqual(3, m_DynamicArray[2]);
Assert.AreEqual(4, m_DynamicArray[3]);
Assert.AreEqual(4, m_DynamicArray.size);
}
[Test]
public void TestAddRangeOutOfSpaceKeepPreviousElements()
{
var smallDynamicArray = new DynamicArray<int>(2);
smallDynamicArray[0] = 1;
smallDynamicArray[1] = 2;
var otherArray = new DynamicArray<int>();
otherArray.Add(3);
otherArray.Add(4);
smallDynamicArray.AddRange(otherArray);
Assert.AreEqual(1, smallDynamicArray[0]);
Assert.AreEqual(2, smallDynamicArray[1]);
Assert.AreEqual(3, smallDynamicArray[2]);
Assert.AreEqual(4, smallDynamicArray[3]);
Assert.AreEqual(4, smallDynamicArray.size);
}
[Test]
public void TestRemoveElementCorrectSize()
{
m_DynamicArray.Add(2);
m_DynamicArray.Add(4);
Assert.AreEqual(2, m_DynamicArray.size);
m_DynamicArray.Remove(2);
Assert.AreEqual(1, m_DynamicArray.size);
m_DynamicArray.Remove(4);
Assert.AreEqual(0, m_DynamicArray.size);
}
[Test]
public void TestRemoveAtKeepOrder()
{
m_DynamicArray.Add(2);
m_DynamicArray.Add(4);
m_DynamicArray.Add(8);
Assert.AreEqual(3, m_DynamicArray.size);
m_DynamicArray.RemoveAt(1);
Assert.AreEqual(2, m_DynamicArray.size);
Assert.AreEqual(2, m_DynamicArray[0]);
Assert.AreEqual(8, m_DynamicArray[1]);
}
[Test]
public void TestRemoveInexistantElementReturnFalse()
{
m_DynamicArray.Add(2);
m_DynamicArray.Add(4);
Assert.IsFalse(m_DynamicArray.Remove(8));
Assert.AreEqual(2, m_DynamicArray.size);
}
[Test]
public void TestRemoveKeepOrder()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
m_DynamicArray.Add(3);
m_DynamicArray.Add(4);
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(2, m_DynamicArray[1]);
Assert.AreEqual(3, m_DynamicArray[2]);
Assert.AreEqual(4, m_DynamicArray[3]);
Assert.AreEqual(4, m_DynamicArray.size);
m_DynamicArray.Remove(2);
Assert.IsFalse(m_DynamicArray.Contains(2));
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(3, m_DynamicArray[1]);
Assert.AreEqual(4, m_DynamicArray[2]);
Assert.AreEqual(3, m_DynamicArray.size);
}
[Test]
public void TestRemoveRangeKeepOrder()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
m_DynamicArray.Add(3);
m_DynamicArray.Add(4);
m_DynamicArray.Add(5);
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(2, m_DynamicArray[1]);
Assert.AreEqual(3, m_DynamicArray[2]);
Assert.AreEqual(4, m_DynamicArray[3]);
Assert.AreEqual(5, m_DynamicArray[4]);
Assert.AreEqual(5, m_DynamicArray.size);
m_DynamicArray.RemoveRange(1, 2);
Assert.IsFalse(m_DynamicArray.Contains(2));
Assert.IsFalse(m_DynamicArray.Contains(3));
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(4, m_DynamicArray[1]);
Assert.AreEqual(5, m_DynamicArray[2]);
Assert.AreEqual(3, m_DynamicArray.size);
}
[Test]
public void TestInvalidAccessThrows()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
int dummy;
Assert.Throws<System.IndexOutOfRangeException>(() => dummy = m_DynamicArray[2]);
Assert.Throws<System.IndexOutOfRangeException>(() => dummy = m_DynamicArray[-1]);
}
[Test]
public void TestRemoveAtInvalidAccessThrows()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
Assert.Throws<System.IndexOutOfRangeException>(() => m_DynamicArray.RemoveAt(-1));
Assert.Throws<System.IndexOutOfRangeException>(() => m_DynamicArray.RemoveAt(2));
}
[Test]
public void TestRemoveRangeInvalidAccessThrows()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
Assert.Throws<System.ArgumentOutOfRangeException>(() => m_DynamicArray.RemoveRange(1, 2));
}
[Test]
public void TestRemoveRangeValidAccessDoesNotThrows()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
Assert.DoesNotThrow(() => m_DynamicArray.RemoveRange(1, 1));
}
[Test]
public void TestFindIndexFailReturnMinusOne()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
Assert.AreEqual(-1, m_DynamicArray.FindIndex(0, m_DynamicArray.size, (x) => x == 4));
}
[Test]
public void TestFindIndexSuccessReturnRightFirstIndex()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
m_DynamicArray.Add(3);
m_DynamicArray.Add(2);
Assert.AreEqual(1, m_DynamicArray.FindIndex(0, m_DynamicArray.size, (x) => x == 2));
}
[Test]
public void TestIndexOfReturnFirstValidIndex()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
m_DynamicArray.Add(3);
m_DynamicArray.Add(2);
Assert.AreEqual(1, m_DynamicArray.IndexOf(2));
}
[Test]
public void TestIndexOfRangeRespectCount()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(2);
m_DynamicArray.Add(3);
m_DynamicArray.Add(4);
Assert.AreEqual(-1, m_DynamicArray.IndexOf(4, 1, 2));
}
[Test]
public void TestIndexOfRangeReturnFirstValidIndex()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(4);
m_DynamicArray.Add(3);
m_DynamicArray.Add(4);
m_DynamicArray.Add(5);
Assert.AreEqual(1, m_DynamicArray.IndexOf(4, 1, 3));
}
[Test]
public void TestIndexOfWithStartingIndexFail()
{
m_DynamicArray.Add(1);
m_DynamicArray.Add(4);
m_DynamicArray.Add(3);
Assert.AreEqual(-1, m_DynamicArray.IndexOf(1, 1, 2));
}
[Test]
public void TestResizeIncreaseCapacity()
{
m_DynamicArray.Resize(256);
Assert.AreEqual(256, m_DynamicArray.capacity);
}
[Test]
public void TestReserveKeepsSize()
{
var size = m_DynamicArray.size;
m_DynamicArray.Reserve(256);
Assert.AreEqual(256, m_DynamicArray.capacity);
Assert.AreEqual(size, m_DynamicArray.size);
}
[Test]
public void TestResizeAndClear()
{
// Uses the capacity only allocator
m_DynamicArray = new DynamicArray<int>(64, false);
Assert.AreEqual(0, m_DynamicArray.size);
Assert.AreEqual(64, m_DynamicArray.capacity);
// First resize it to 32 elements
m_DynamicArray.Resize(32, false);
Assert.AreEqual(32, m_DynamicArray.size);
m_DynamicArray[31] = 0xFFFF;
// Resize it back to 0 elements
m_DynamicArray.Resize(0);
Assert.AreEqual(0, m_DynamicArray.size);
// Resize it back to 32 elements, the memory should not have been reallocated
// it also shouln't have been cleared (for peformance reasons)
m_DynamicArray.Resize(32);
Assert.AreEqual(32, m_DynamicArray.size);
Assert.AreEqual(0xFFFF, m_DynamicArray[31]);
// Resize it back to 0 elements
m_DynamicArray.Resize(0);
Assert.AreEqual(0, m_DynamicArray.size);
// Resize it back to 32 elements, the memory should not have been reallocated
// the memory should have been cleared, resize and clear was used
m_DynamicArray.ResizeAndClear(32);
Assert.AreEqual(32, m_DynamicArray.size);
Assert.AreEqual(0, m_DynamicArray[31]);
}
[Test]
public void TestDynamicString()
{
var ds = new DynamicString("Foo");
ds.Append("Bar");
ds.Append(new DynamicString("Baz"));
var s = ds.ToString();
Assert.AreEqual("FooBarBaz", s);
}
[Test]
public void TestAppendSelf()
{
var ds = new DynamicString("Foo");
ds.Append(ds);
var s = ds.ToString();
Assert.AreEqual("FooFoo", s);
}
[Test]
public void TestQuickSort()
{
m_DynamicArray.Add(8);
m_DynamicArray.Add(4);
m_DynamicArray.Add(3);
m_DynamicArray.Add(4);
m_DynamicArray.Add(5);
m_DynamicArray.Add(1);
m_DynamicArray.Add(12);
m_DynamicArray.QuickSort();
Assert.AreEqual(1, m_DynamicArray[0]);
Assert.AreEqual(3, m_DynamicArray[1]);
Assert.AreEqual(4, m_DynamicArray[2]);
Assert.AreEqual(4, m_DynamicArray[3]);
Assert.AreEqual(5, m_DynamicArray[4]);
Assert.AreEqual(8, m_DynamicArray[5]);
Assert.AreEqual(12, m_DynamicArray[6]);
}
[Test]
public void TestForEach_FullRange()
{
m_DynamicArray.Add(8);
m_DynamicArray.Add(4);
m_DynamicArray.Add(3);
m_DynamicArray.Add(6);
var sum = 0;
foreach (var i in m_DynamicArray)
{
sum += i;
}
Assert.AreEqual(21, sum);
// now check if we are _not_ iterating on empty array
sum = 0;
m_DynamicArray.Clear();
foreach (var i in m_DynamicArray)
{
sum += i;
}
Assert.AreEqual(0, sum);
}
[Test]
public void TestForEach_SubRange()
{
m_DynamicArray.Add(8);
m_DynamicArray.Add(4);
m_DynamicArray.Add(3);
m_DynamicArray.Add(6);
var sum = 0;
foreach (var i in m_DynamicArray.SubRange(1,2))
{
sum += i;
}
Assert.AreEqual(7, sum);
//remove item of array and test again
m_DynamicArray.RemoveAt(1);
sum = 0;
foreach (var i in m_DynamicArray.SubRange(1,2))
{
sum += i;
}
Assert.AreEqual(9, sum);
}
[Test]
public void GetEnumerators_ArgumentValidation()
{
Assert.Throws<ArgumentNullException>(() => {
var iterator = new DynamicArray<int>.Iterator(null);
});
Assert.Throws<ArgumentNullException>(() => {
var iterator = new DynamicArray<int>.RangeEnumerable.RangeIterator(null, 0,0);
});
m_DynamicArray.Add(12);
m_DynamicArray.Add(2);
Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(-5, 1); });
Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(17, 1); });
Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(0, 12); });
Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(1, 2); });
Assert.DoesNotThrow(() => { var iterator = m_DynamicArray.SubRange(1, 1); });
Assert.Throws<IndexOutOfRangeException>(() => { var iterator = m_DynamicArray.SubRange(2, 1); });
}
[Test]
public void Foreach_TestNoModificationsAllowed()
{
Assert.Throws<InvalidOperationException>(() =>
{
m_DynamicArray.Add(3);
m_DynamicArray.Add(3);
foreach (var i in m_DynamicArray)
{
m_DynamicArray.Remove(i);
}
});
Assert.Throws<InvalidOperationException>(() =>
{
m_DynamicArray.Add(3);
m_DynamicArray.Add(3);
foreach (var i in m_DynamicArray)
{
m_DynamicArray.Add(1);
}
});
Assert.Throws<InvalidOperationException>(() =>
{
m_DynamicArray.Add(8);
m_DynamicArray.Add(3);
foreach (var i in m_DynamicArray)
{
if (i == 3)
{
m_DynamicArray.Add(1);
m_DynamicArray.RemoveAt(0);
}
}
});
Assert.Throws<InvalidOperationException>(() =>
{
m_DynamicArray.Add(8);
m_DynamicArray.Add(3);
m_DynamicArray.Add(7);
foreach (var i in m_DynamicArray)
{
if (i == 3)
{
m_DynamicArray.QuickSort();
}
}
});
}
static Recorder gcAllocRecorder = Recorder.Get("GC.Alloc");
static int CountGCAllocs(Action action)
{
gcAllocRecorder.FilterToCurrentThread();
gcAllocRecorder.enabled = false;
gcAllocRecorder.enabled = true;
action();
gcAllocRecorder.enabled = false;
return gcAllocRecorder.sampleBlockCount;
}
static void ValidateNoGCAllocs(Action action)
{
// warmup
// this will catch static c'tors etc
CountGCAllocs(action);
// actual test
var count = CountGCAllocs(action);
if (count != 0)
throw new AssertionException($"Expected 0 GC allocations but there were {count}");
}
[Test]
public void Foreach_NoGC()
{
m_DynamicArray.Reserve(4);
m_DynamicArray.Add(12);
m_DynamicArray.Add(4);
m_DynamicArray.Add(8);
m_DynamicArray.Add(2);
var sum = 0;
ValidateNoGCAllocs(() =>
{
sum = 0;
foreach (var i in m_DynamicArray)
{
sum += i;
}
});
Assert.AreEqual(sum, 26);
ValidateNoGCAllocs(() =>
{
sum = 0;
foreach (var i in m_DynamicArray.SubRange(0, 2))
{
sum += i;
}
});
Assert.AreEqual(sum, 16);
}
}
}