| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "gtest/gtest.h" |
| |
| #include "chre/util/fixed_size_vector.h" |
| |
| using chre::FixedSizeVector; |
| |
| namespace { |
| constexpr int kMaxTestCapacity = 10; |
| int destructor_count[kMaxTestCapacity]; |
| |
| class Foo { |
| public: |
| ~Foo() { |
| if (mValue >= 0) { |
| destructor_count[mValue]++; |
| } |
| }; |
| void setValue(int value) { |
| mValue = value; |
| } |
| |
| private: |
| int mValue = -1; |
| }; |
| } // namespace |
| |
| TEST(FixedSizeVector, EmptyWithCapacityWithDefault) { |
| FixedSizeVector<int, 8> testVector; |
| ASSERT_NE(testVector.data(), nullptr); |
| ASSERT_EQ(testVector.size(), 0); |
| ASSERT_EQ(testVector.capacity(), 8); |
| ASSERT_TRUE(testVector.empty()); |
| ASSERT_FALSE(testVector.full()); |
| } |
| |
| TEST(FixedSizeVector, PushBackOneAndRead) { |
| FixedSizeVector<int, 8> testVector; |
| testVector.push_back(0x1337); |
| ASSERT_NE(testVector.data(), nullptr); |
| ASSERT_EQ(testVector.size(), 1); |
| ASSERT_EQ(testVector.capacity(), 8); |
| ASSERT_FALSE(testVector.empty()); |
| ASSERT_FALSE(testVector.full()); |
| ASSERT_EQ(testVector[0], 0x1337); |
| } |
| |
| TEST(FixedSizeVector, PushBackUntilFullAndRead) { |
| FixedSizeVector<int, 4> testVector; |
| testVector.push_back(1000); |
| testVector.push_back(2000); |
| testVector.push_back(3000); |
| testVector.push_back(4000); |
| |
| ASSERT_NE(testVector.data(), nullptr); |
| ASSERT_TRUE(testVector.full()); |
| ASSERT_FALSE(testVector.empty()); |
| ASSERT_EQ(testVector.size(), 4); |
| ASSERT_EQ(testVector[0], 1000); |
| ASSERT_EQ(testVector[1], 2000); |
| ASSERT_EQ(testVector[2], 3000); |
| ASSERT_EQ(testVector[3], 4000); |
| |
| ASSERT_EQ(testVector.data()[0], 1000); |
| ASSERT_EQ(testVector.data()[1], 2000); |
| ASSERT_EQ(testVector.data()[2], 3000); |
| ASSERT_EQ(testVector.data()[3], 4000); |
| } |
| |
| TEST(FixedSizeVector, PushBackAndErase) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0x1337); |
| vector.push_back(0xcafe); |
| vector.push_back(0xbeef); |
| vector.push_back(0xface); |
| |
| vector.erase(1); |
| ASSERT_EQ(vector[0], 0x1337); |
| ASSERT_EQ(vector.data()[0], 0x1337); |
| ASSERT_EQ(vector[1], 0xbeef); |
| ASSERT_EQ(vector.data()[1], 0xbeef); |
| ASSERT_EQ(vector[2], 0xface); |
| ASSERT_EQ(vector.data()[2], 0xface); |
| ASSERT_EQ(vector.size(), 3); |
| } |
| |
| TEST(FixedSizeVector, PushBackAndPopBack) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0x1337); |
| vector.push_back(0xcafe); |
| vector.push_back(0xbeef); |
| vector.push_back(0xface); |
| |
| ASSERT_EQ(vector.size(), 4); |
| ASSERT_EQ(vector.back(), 0xface); |
| vector.pop_back(); |
| ASSERT_EQ(vector.size(), 3); |
| ASSERT_EQ(vector.back(), 0xbeef); |
| vector.pop_back(); |
| ASSERT_EQ(vector.size(), 2); |
| ASSERT_EQ(vector.back(), 0xcafe); |
| vector.pop_back(); |
| ASSERT_EQ(vector.size(), 1); |
| ASSERT_EQ(vector.back(), 0x1337); |
| vector.pop_back(); |
| ASSERT_EQ(vector.size(), 0); |
| } |
| |
| TEST(FixedSizeVector, EraseDestructorCalled) { |
| FixedSizeVector<Foo, 4> vector; |
| for (size_t i = 0; i < 4; ++i) { |
| vector.push_back(Foo()); |
| vector[i].setValue(i); |
| } |
| |
| // last item before erase is '3'. |
| vector.erase(1); |
| EXPECT_EQ(0, destructor_count[0]); |
| EXPECT_EQ(0, destructor_count[1]); |
| EXPECT_EQ(0, destructor_count[2]); |
| EXPECT_EQ(1, destructor_count[3]); |
| |
| // last item before erase is still '3'. |
| vector.erase(2); |
| EXPECT_EQ(0, destructor_count[0]); |
| EXPECT_EQ(0, destructor_count[1]); |
| EXPECT_EQ(0, destructor_count[2]); |
| EXPECT_EQ(2, destructor_count[3]); |
| |
| // last item before erase is now '2'. |
| vector.erase(0); |
| EXPECT_EQ(0, destructor_count[0]); |
| EXPECT_EQ(0, destructor_count[1]); |
| EXPECT_EQ(1, destructor_count[2]); |
| EXPECT_EQ(2, destructor_count[3]); |
| } |
| |
| TEST(FixedSizeVectorDeathTest, SwapWithInvalidIndex) { |
| FixedSizeVector<int, 4> vector; |
| vector.push_back(0x1337); |
| vector.push_back(0xcafe); |
| EXPECT_DEATH(vector.swap(0, 2), ""); |
| } |
| |
| TEST(FixedSizeVectorDeathTest, SwapWithInvalidIndices) { |
| FixedSizeVector<int, 4> vector; |
| vector.push_back(0x1337); |
| vector.push_back(0xcafe); |
| EXPECT_DEATH(vector.swap(2, 3), ""); |
| } |
| |
| TEST(FixedSizeVector, Swap) { |
| FixedSizeVector<int, 4> vector; |
| vector.push_back(0x1337); |
| vector.push_back(0xcafe); |
| |
| vector.swap(0, 1); |
| EXPECT_EQ(vector[0], 0xcafe); |
| EXPECT_EQ(vector[1], 0x1337); |
| } |
| |
| TEST(FixedSizeVector, ResizeLarger) { |
| FixedSizeVector<int, 4> vector; |
| vector.resize(4); |
| EXPECT_EQ(vector.size(), 4); |
| } |
| |
| TEST(FixedSizeVector, ResizeSmaller) { |
| destructor_count[0] = 0; |
| |
| FixedSizeVector<Foo, 4> vector; |
| for (size_t i = 0; i < 3; i++) { |
| vector.push_back(Foo()); |
| vector[i].setValue(0); |
| } |
| |
| EXPECT_EQ(vector.size(), 3); |
| EXPECT_EQ(destructor_count[0], 0); |
| vector.resize(2); |
| EXPECT_EQ(vector.size(), 2); |
| EXPECT_EQ(destructor_count[0], 1); |
| } |
| |
| TEST(FixedSizeVector, Iterator) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| |
| size_t index = 0; |
| for (FixedSizeVector<int, 8>::iterator it = vector.begin(); |
| it != vector.end(); ++it) { |
| EXPECT_EQ(vector[index++], *it); |
| } |
| |
| FixedSizeVector<int, 8>::iterator it = vector.begin() + vector.size() - 1; |
| EXPECT_EQ(vector[vector.size() - 1], *it); |
| |
| it = vector.begin() + vector.size(); |
| EXPECT_TRUE(it == vector.end()); |
| } |
| |
| TEST(FixedSizeVector, ConstIterator) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| |
| size_t index = 0; |
| for (FixedSizeVector<int, 8>::const_iterator cit = vector.cbegin(); |
| cit != vector.cend(); ++cit) { |
| EXPECT_EQ(vector[index++], *cit); |
| } |
| |
| FixedSizeVector<int, 8>::const_iterator cit = |
| vector.cbegin() + vector.size() - 1; |
| EXPECT_EQ(vector[vector.size() - 1], *cit); |
| |
| cit = vector.cbegin() + vector.size(); |
| EXPECT_TRUE(cit == vector.cend()); |
| } |
| |
| TEST(FixedSizeVector, IteratorAndPushBack) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| |
| FixedSizeVector<int, 8>::iterator it_b = vector.begin(); |
| FixedSizeVector<int, 8>::iterator it_e = vector.end(); |
| |
| vector.push_back(3); |
| |
| size_t index = 0; |
| while (it_b != it_e) { |
| EXPECT_EQ(vector[index++], *it_b++); |
| } |
| } |
| |
| TEST(FixedSizeVector, IteratorAndEmplaceBack) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| |
| FixedSizeVector<int, 8>::iterator it_b = vector.begin(); |
| FixedSizeVector<int, 8>::iterator it_e = vector.end(); |
| |
| vector.emplace_back(3); |
| |
| size_t index = 0; |
| while (it_b != it_e) { |
| EXPECT_EQ(vector[index++], *it_b++); |
| } |
| } |
| |
| TEST(FixedSizeVector, IteratorAndErase) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| |
| FixedSizeVector<int, 8>::iterator it_b = vector.begin(); |
| |
| vector.erase(2); |
| |
| size_t index = 0; |
| while (index < 2) { |
| EXPECT_EQ(vector[index++], *it_b++); |
| } |
| } |
| |
| TEST(FixedSizeVector, IteratorAndSwap) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| vector.push_back(3); |
| |
| FixedSizeVector<int, 8>::iterator it_b = vector.begin(); |
| |
| vector.swap(1, 3); |
| |
| size_t index = 0; |
| while (index < 4) { |
| if (index != 1 && index != 3) { |
| EXPECT_EQ(vector[index], *it_b); |
| } |
| index++; |
| it_b++; |
| } |
| } |
| |
| TEST(FixedSizeVector, IteratorAndResize) { |
| FixedSizeVector<int, 8> vector; |
| vector.push_back(0); |
| vector.push_back(1); |
| vector.push_back(2); |
| vector.push_back(3); |
| |
| FixedSizeVector<int, 8>::iterator it_b = vector.begin(); |
| |
| vector.resize(2); |
| |
| size_t index = 0; |
| while (index < 2) { |
| EXPECT_EQ(vector[index++], *it_b++); |
| } |
| } |