1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include "chre/util/fixed_size_vector.h"
20 
21 using chre::FixedSizeVector;
22 
23 namespace {
24 constexpr int kMaxTestCapacity = 10;
25 int destructor_count[kMaxTestCapacity];
26 
27 class Foo {
28  public:
~Foo()29   ~Foo() {
30     if (mValue >= 0) {
31       destructor_count[mValue]++;
32     }
33   };
setValue(int value)34   void setValue(int value) {
35     mValue = value;
36   }
37 
38  private:
39   int mValue = -1;
40 };
41 }  // namespace
42 
TEST(FixedSizeVector,EmptyWithCapacityWithDefault)43 TEST(FixedSizeVector, EmptyWithCapacityWithDefault) {
44   FixedSizeVector<int, 8> testVector;
45   ASSERT_NE(testVector.data(), nullptr);
46   ASSERT_EQ(testVector.size(), 0);
47   ASSERT_EQ(testVector.capacity(), 8);
48   ASSERT_TRUE(testVector.empty());
49   ASSERT_FALSE(testVector.full());
50 }
51 
TEST(FixedSizeVector,PushBackOneAndRead)52 TEST(FixedSizeVector, PushBackOneAndRead) {
53   FixedSizeVector<int, 8> testVector;
54   testVector.push_back(0x1337);
55   ASSERT_NE(testVector.data(), nullptr);
56   ASSERT_EQ(testVector.size(), 1);
57   ASSERT_EQ(testVector.capacity(), 8);
58   ASSERT_FALSE(testVector.empty());
59   ASSERT_FALSE(testVector.full());
60   ASSERT_EQ(testVector[0], 0x1337);
61 }
62 
TEST(FixedSizeVector,PushBackUntilFullAndRead)63 TEST(FixedSizeVector, PushBackUntilFullAndRead) {
64   FixedSizeVector<int, 4> testVector;
65   testVector.push_back(1000);
66   testVector.push_back(2000);
67   testVector.push_back(3000);
68   testVector.push_back(4000);
69 
70   ASSERT_NE(testVector.data(), nullptr);
71   ASSERT_TRUE(testVector.full());
72   ASSERT_FALSE(testVector.empty());
73   ASSERT_EQ(testVector.size(), 4);
74   ASSERT_EQ(testVector[0], 1000);
75   ASSERT_EQ(testVector[1], 2000);
76   ASSERT_EQ(testVector[2], 3000);
77   ASSERT_EQ(testVector[3], 4000);
78 
79   ASSERT_EQ(testVector.data()[0], 1000);
80   ASSERT_EQ(testVector.data()[1], 2000);
81   ASSERT_EQ(testVector.data()[2], 3000);
82   ASSERT_EQ(testVector.data()[3], 4000);
83 }
84 
TEST(FixedSizeVector,PushBackAndErase)85 TEST(FixedSizeVector, PushBackAndErase) {
86   FixedSizeVector<int, 8> vector;
87   vector.push_back(0x1337);
88   vector.push_back(0xcafe);
89   vector.push_back(0xbeef);
90   vector.push_back(0xface);
91 
92   vector.erase(1);
93   ASSERT_EQ(vector[0], 0x1337);
94   ASSERT_EQ(vector.data()[0], 0x1337);
95   ASSERT_EQ(vector[1], 0xbeef);
96   ASSERT_EQ(vector.data()[1], 0xbeef);
97   ASSERT_EQ(vector[2], 0xface);
98   ASSERT_EQ(vector.data()[2], 0xface);
99   ASSERT_EQ(vector.size(), 3);
100 }
101 
TEST(FixedSizeVector,PushBackAndPopBack)102 TEST(FixedSizeVector, PushBackAndPopBack) {
103   FixedSizeVector<int, 8> vector;
104   vector.push_back(0x1337);
105   vector.push_back(0xcafe);
106   vector.push_back(0xbeef);
107   vector.push_back(0xface);
108 
109   ASSERT_EQ(vector.size(), 4);
110   ASSERT_EQ(vector.back(), 0xface);
111   vector.pop_back();
112   ASSERT_EQ(vector.size(), 3);
113   ASSERT_EQ(vector.back(), 0xbeef);
114   vector.pop_back();
115   ASSERT_EQ(vector.size(), 2);
116   ASSERT_EQ(vector.back(), 0xcafe);
117   vector.pop_back();
118   ASSERT_EQ(vector.size(), 1);
119   ASSERT_EQ(vector.back(), 0x1337);
120   vector.pop_back();
121   ASSERT_EQ(vector.size(), 0);
122 }
123 
TEST(FixedSizeVector,EraseDestructorCalled)124 TEST(FixedSizeVector, EraseDestructorCalled) {
125   FixedSizeVector<Foo, 4> vector;
126   for (size_t i = 0; i < 4; ++i) {
127     vector.push_back(Foo());
128     vector[i].setValue(i);
129   }
130 
131   // last item before erase is '3'.
132   vector.erase(1);
133   EXPECT_EQ(0, destructor_count[0]);
134   EXPECT_EQ(0, destructor_count[1]);
135   EXPECT_EQ(0, destructor_count[2]);
136   EXPECT_EQ(1, destructor_count[3]);
137 
138   // last item before erase is still '3'.
139   vector.erase(2);
140   EXPECT_EQ(0, destructor_count[0]);
141   EXPECT_EQ(0, destructor_count[1]);
142   EXPECT_EQ(0, destructor_count[2]);
143   EXPECT_EQ(2, destructor_count[3]);
144 
145   // last item before erase is now '2'.
146   vector.erase(0);
147   EXPECT_EQ(0, destructor_count[0]);
148   EXPECT_EQ(0, destructor_count[1]);
149   EXPECT_EQ(1, destructor_count[2]);
150   EXPECT_EQ(2, destructor_count[3]);
151 }
152 
TEST(FixedSizeVectorDeathTest,SwapWithInvalidIndex)153 TEST(FixedSizeVectorDeathTest, SwapWithInvalidIndex) {
154   FixedSizeVector<int, 4> vector;
155   vector.push_back(0x1337);
156   vector.push_back(0xcafe);
157   EXPECT_DEATH(vector.swap(0, 2), "");
158 }
159 
TEST(FixedSizeVectorDeathTest,SwapWithInvalidIndices)160 TEST(FixedSizeVectorDeathTest, SwapWithInvalidIndices) {
161   FixedSizeVector<int, 4> vector;
162   vector.push_back(0x1337);
163   vector.push_back(0xcafe);
164   EXPECT_DEATH(vector.swap(2, 3), "");
165 }
166 
TEST(FixedSizeVector,Swap)167 TEST(FixedSizeVector, Swap) {
168   FixedSizeVector<int, 4> vector;
169   vector.push_back(0x1337);
170   vector.push_back(0xcafe);
171 
172   vector.swap(0, 1);
173   EXPECT_EQ(vector[0], 0xcafe);
174   EXPECT_EQ(vector[1], 0x1337);
175 }
176 
TEST(FixedSizeVector,ResizeLarger)177 TEST(FixedSizeVector, ResizeLarger) {
178   FixedSizeVector<int, 4> vector;
179   vector.resize(4);
180   EXPECT_EQ(vector.size(), 4);
181 }
182 
TEST(FixedSizeVector,ResizeSmaller)183 TEST(FixedSizeVector, ResizeSmaller) {
184   destructor_count[0] = 0;
185 
186   FixedSizeVector<Foo, 4> vector;
187   for (size_t i = 0; i < 3; i++) {
188     vector.push_back(Foo());
189     vector[i].setValue(0);
190   }
191 
192   EXPECT_EQ(vector.size(), 3);
193   EXPECT_EQ(destructor_count[0], 0);
194   vector.resize(2);
195   EXPECT_EQ(vector.size(), 2);
196   EXPECT_EQ(destructor_count[0], 1);
197 }
198 
TEST(FixedSizeVector,Iterator)199 TEST(FixedSizeVector, Iterator) {
200   FixedSizeVector<int, 8> vector;
201   vector.push_back(0);
202   vector.push_back(1);
203   vector.push_back(2);
204 
205   size_t index = 0;
206   for (FixedSizeVector<int, 8>::iterator it = vector.begin();
207        it != vector.end(); ++it) {
208     EXPECT_EQ(vector[index++], *it);
209   }
210 
211   FixedSizeVector<int, 8>::iterator it = vector.begin() + vector.size() - 1;
212   EXPECT_EQ(vector[vector.size() - 1], *it);
213 
214   it = vector.begin() + vector.size();
215   EXPECT_TRUE(it == vector.end());
216 }
217 
TEST(FixedSizeVector,ConstIterator)218 TEST(FixedSizeVector, ConstIterator) {
219   FixedSizeVector<int, 8> vector;
220   vector.push_back(0);
221   vector.push_back(1);
222   vector.push_back(2);
223 
224   size_t index = 0;
225   for (FixedSizeVector<int, 8>::const_iterator cit = vector.cbegin();
226        cit != vector.cend(); ++cit) {
227     EXPECT_EQ(vector[index++], *cit);
228   }
229 
230   FixedSizeVector<int, 8>::const_iterator cit =
231       vector.cbegin() + vector.size() - 1;
232   EXPECT_EQ(vector[vector.size() - 1], *cit);
233 
234   cit = vector.cbegin() + vector.size();
235   EXPECT_TRUE(cit == vector.cend());
236 }
237 
TEST(FixedSizeVector,IteratorAndPushBack)238 TEST(FixedSizeVector, IteratorAndPushBack) {
239   FixedSizeVector<int, 8> vector;
240   vector.push_back(0);
241   vector.push_back(1);
242   vector.push_back(2);
243 
244   FixedSizeVector<int, 8>::iterator it_b = vector.begin();
245   FixedSizeVector<int, 8>::iterator it_e = vector.end();
246 
247   vector.push_back(3);
248 
249   size_t index = 0;
250   while (it_b != it_e) {
251     EXPECT_EQ(vector[index++], *it_b++);
252   }
253 }
254 
TEST(FixedSizeVector,IteratorAndEmplaceBack)255 TEST(FixedSizeVector, IteratorAndEmplaceBack) {
256   FixedSizeVector<int, 8> vector;
257   vector.push_back(0);
258   vector.push_back(1);
259   vector.push_back(2);
260 
261   FixedSizeVector<int, 8>::iterator it_b = vector.begin();
262   FixedSizeVector<int, 8>::iterator it_e = vector.end();
263 
264   vector.emplace_back(3);
265 
266   size_t index = 0;
267   while (it_b != it_e) {
268     EXPECT_EQ(vector[index++], *it_b++);
269   }
270 }
271 
TEST(FixedSizeVector,IteratorAndErase)272 TEST(FixedSizeVector, IteratorAndErase) {
273   FixedSizeVector<int, 8> vector;
274   vector.push_back(0);
275   vector.push_back(1);
276   vector.push_back(2);
277 
278   FixedSizeVector<int, 8>::iterator it_b = vector.begin();
279 
280   vector.erase(2);
281 
282   size_t index = 0;
283   while (index < 2) {
284     EXPECT_EQ(vector[index++], *it_b++);
285   }
286 }
287 
TEST(FixedSizeVector,IteratorAndSwap)288 TEST(FixedSizeVector, IteratorAndSwap) {
289   FixedSizeVector<int, 8> vector;
290   vector.push_back(0);
291   vector.push_back(1);
292   vector.push_back(2);
293   vector.push_back(3);
294 
295   FixedSizeVector<int, 8>::iterator it_b = vector.begin();
296 
297   vector.swap(1, 3);
298 
299   size_t index = 0;
300   while (index < 4) {
301     if (index != 1 && index != 3) {
302       EXPECT_EQ(vector[index], *it_b);
303     }
304     index++;
305     it_b++;
306   }
307 }
308 
TEST(FixedSizeVector,IteratorAndResize)309 TEST(FixedSizeVector, IteratorAndResize) {
310   FixedSizeVector<int, 8> vector;
311   vector.push_back(0);
312   vector.push_back(1);
313   vector.push_back(2);
314   vector.push_back(3);
315 
316   FixedSizeVector<int, 8>::iterator it_b = vector.begin();
317 
318   vector.resize(2);
319 
320   size_t index = 0;
321   while (index < 2) {
322     EXPECT_EQ(vector[index++], *it_b++);
323   }
324 }
325