Bug 1628715 - Part 7bis: Add gtests for nsTArray::AppendElements. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D71062
This commit is contained in:
Simon Giesecke 2020-04-24 14:00:48 +00:00
parent ddcf8e7ab1
commit c80cf74d98

View File

@ -58,11 +58,12 @@ struct nsTArray_RelocationStrategy<TestTArray::Movable> {
namespace TestTArray {
constexpr int dummyArrayData[] = {4, 1, 2, 8};
static const nsTArray<int>& DummyArray() {
static nsTArray<int> sArray;
if (sArray.IsEmpty()) {
const int data[] = {4, 1, 2, 8};
sArray.AppendElements(data, ArrayLength(data));
sArray.AppendElements(dummyArrayData, ArrayLength(dummyArrayData));
}
return sArray;
}
@ -80,17 +81,151 @@ static const nsTArray<int>& FakeHugeArray() {
}
#endif
TEST(TArray, AppendElementsRvalue)
TEST(TArray, int_AppendElements_PlainArray)
{
nsTArray<int> array;
int* ptr = array.AppendElements(dummyArrayData, ArrayLength(dummyArrayData));
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ptr = array.AppendElements(dummyArrayData, ArrayLength(dummyArrayData));
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
}
TEST(TArray, int_AppendElements_PlainArray_Fallible)
{
nsTArray<int> array;
int* ptr = array.AppendElements(dummyArrayData, ArrayLength(dummyArrayData),
fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ptr = array.AppendElements(dummyArrayData, ArrayLength(dummyArrayData),
fallible);
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
}
TEST(TArray, int_AppendElements_TArray_Copy)
{
nsTArray<int> array;
const nsTArray<int> temp(DummyArray());
int* ptr = array.AppendElements(temp);
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_FALSE(temp.IsEmpty());
ptr = array.AppendElements(temp);
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
ASSERT_FALSE(temp.IsEmpty());
}
TEST(TArray, int_AppendElements_TArray_Copy_Fallible)
{
nsTArray<int> array;
const nsTArray<int> temp(DummyArray());
int* ptr = array.AppendElements(temp, fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_FALSE(temp.IsEmpty());
ptr = array.AppendElements(temp, fallible);
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
ASSERT_FALSE(temp.IsEmpty());
}
TEST(TArray, int_AppendElements_TArray_Rvalue)
{
nsTArray<int> array;
nsTArray<int> temp(DummyArray());
array.AppendElements(std::move(temp));
int* ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyArray();
array.AppendElements(std::move(temp));
ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
ASSERT_TRUE(temp.IsEmpty());
}
TEST(TArray, int_AppendElements_TArray_Rvalue_Fallible)
{
nsTArray<int> array;
nsTArray<int> temp(DummyArray());
int* ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyArray();
ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
ASSERT_TRUE(temp.IsEmpty());
}
TEST(TArray, int_AppendElements_FallibleArray_Rvalue)
{
nsTArray<int> array;
FallibleTArray<int> temp(DummyArray());
int* ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyArray();
ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
ASSERT_EQ(expected, array);
ASSERT_TRUE(temp.IsEmpty());
}
TEST(TArray, int_AppendElements_FallibleArray_Rvalue_Fallible)
{
nsTArray<int> array;
FallibleTArray<int> temp(DummyArray());
int* ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_EQ(DummyArray(), array);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyArray();
ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[DummyArray().Length()], ptr);
nsTArray<int> expected;
expected.AppendElements(DummyArray());
expected.AppendElements(DummyArray());
@ -115,7 +250,223 @@ TEST(TArray, AppendElementsSpan)
ASSERT_EQ(expected, array);
}
TEST(TArray, Assign)
TEST(TArray, int_AppendElement_NoElementArg)
{
nsTArray<int> array;
array.AppendElement();
ASSERT_EQ(1u, array.Length());
}
TEST(TArray, int_AppendElement_NoElementArg_Fallible)
{
nsTArray<int> array;
ASSERT_NE(nullptr, array.AppendElement(fallible));
ASSERT_EQ(1u, array.Length());
}
TEST(TArray, int_AppendElement_NoElementArg_Address)
{
nsTArray<int> array;
*array.AppendElement() = 42;
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(42, array[0]);
}
TEST(TArray, int_AppendElement_NoElementArg_Fallible_Address)
{
nsTArray<int> array;
*array.AppendElement(fallible) = 42;
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(42, array[0]);
}
TEST(TArray, int_AppendElement_ElementArg)
{
nsTArray<int> array;
array.AppendElement(42);
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(42, array[0]);
}
TEST(TArray, int_AppendElement_ElementArg_Fallible)
{
nsTArray<int> array;
ASSERT_NE(nullptr, array.AppendElement(42, fallible));
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(42, array[0]);
}
constexpr size_t dummyMovableArrayLength = 4;
uint32_t dummyMovableArrayDestructorCounter;
static nsTArray<Movable> DummyMovableArray() {
nsTArray<Movable> res;
res.SetLength(dummyMovableArrayLength);
for (size_t i = 0; i < dummyMovableArrayLength; ++i) {
res[i].mDestructionCounter = &dummyMovableArrayDestructorCounter;
}
return res;
}
TEST(TArray, Movable_AppendElements_TArray_Rvalue)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
nsTArray<Movable> temp(DummyMovableArray());
Movable* ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[0], ptr);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyMovableArray();
ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[dummyMovableArrayLength], ptr);
ASSERT_TRUE(temp.IsEmpty());
}
ASSERT_EQ(2 * dummyMovableArrayLength, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElements_TArray_Rvalue_Fallible)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
nsTArray<Movable> temp(DummyMovableArray());
Movable* ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyMovableArray();
ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[dummyMovableArrayLength], ptr);
ASSERT_TRUE(temp.IsEmpty());
}
ASSERT_EQ(2 * dummyMovableArrayLength, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElements_FallibleArray_Rvalue)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
FallibleTArray<Movable> temp(DummyMovableArray());
Movable* ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[0], ptr);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyMovableArray();
ptr = array.AppendElements(std::move(temp));
ASSERT_EQ(&array[dummyMovableArrayLength], ptr);
ASSERT_TRUE(temp.IsEmpty());
}
ASSERT_EQ(2 * dummyMovableArrayLength, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElements_FallibleArray_Rvalue_Fallible)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
FallibleTArray<Movable> temp(DummyMovableArray());
Movable* ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[0], ptr);
ASSERT_TRUE(temp.IsEmpty());
temp = DummyMovableArray();
ptr = array.AppendElements(std::move(temp), fallible);
ASSERT_EQ(&array[dummyMovableArrayLength], ptr);
ASSERT_TRUE(temp.IsEmpty());
}
ASSERT_EQ(2 * dummyMovableArrayLength, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElement_NoElementArg)
{
nsTArray<Movable> array;
array.AppendElement();
ASSERT_EQ(1u, array.Length());
}
TEST(TArray, Movable_AppendElement_NoElementArg_Fallible)
{
nsTArray<Movable> array;
ASSERT_NE(nullptr, array.AppendElement(fallible));
ASSERT_EQ(1u, array.Length());
}
TEST(TArray, Movable_AppendElement_NoElementArg_Address)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
array.AppendElement()->mDestructionCounter =
&dummyMovableArrayDestructorCounter;
ASSERT_EQ(1u, array.Length());
}
ASSERT_EQ(1u, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElement_NoElementArg_Fallible_Address)
{
dummyMovableArrayDestructorCounter = 0;
{
nsTArray<Movable> array;
array.AppendElement(fallible)->mDestructionCounter =
&dummyMovableArrayDestructorCounter;
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(&dummyMovableArrayDestructorCounter,
array[0].mDestructionCounter);
}
ASSERT_EQ(1u, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElement_ElementArg)
{
dummyMovableArrayDestructorCounter = 0;
Movable movable;
movable.mDestructionCounter = &dummyMovableArrayDestructorCounter;
{
nsTArray<Movable> array;
array.AppendElement(std::move(movable));
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(&dummyMovableArrayDestructorCounter,
array[0].mDestructionCounter);
}
ASSERT_EQ(1u, dummyMovableArrayDestructorCounter);
}
TEST(TArray, Movable_AppendElement_ElementArg_Fallible)
{
dummyMovableArrayDestructorCounter = 0;
Movable movable;
movable.mDestructionCounter = &dummyMovableArrayDestructorCounter;
{
nsTArray<Movable> array;
array.AppendElement(std::move(movable), fallible);
ASSERT_EQ(1u, array.Length());
ASSERT_EQ(&dummyMovableArrayDestructorCounter,
array[0].mDestructionCounter);
}
ASSERT_EQ(1u, dummyMovableArrayDestructorCounter);
}
TEST(TArray, int_Assign)
{
nsTArray<int> array;
array.Assign(DummyArray());
@ -134,7 +485,7 @@ TEST(TArray, Assign)
ASSERT_EQ(DummyArray(), array2);
}
TEST(TArray, AssignmentOperatorSelfAssignment)
TEST(TArray, int_AssignmentOperatorSelfAssignment)
{
nsTArray<int> array;
array = DummyArray();
@ -153,7 +504,7 @@ TEST(TArray, AssignmentOperatorSelfAssignment)
#endif
}
TEST(TArray, CopyOverlappingForwards)
TEST(TArray, Movable_CopyOverlappingForwards)
{
const size_t rangeLength = 8;
const size_t initialLength = 2 * rangeLength;
@ -181,7 +532,7 @@ TEST(TArray, CopyOverlappingForwards)
// The code to copy overlapping regions had a bug in that it wouldn't correctly
// destroy all over the source elements being copied.
TEST(TArray, CopyOverlappingBackwards)
TEST(TArray, Copyable_CopyOverlappingBackwards)
{
const size_t rangeLength = 8;
const size_t initialLength = 2 * rangeLength;