• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "chre/util/array_queue.h"
2 #include "gtest/gtest.h"
3 
4 #include <algorithm>
5 #include <type_traits>
6 #include <vector>
7 
8 using chre::ArrayQueue;
9 using chre::ArrayQueueExt;
10 
11 namespace {
12 constexpr int kMaxTestCapacity = 10;
13 int destructor_count[kMaxTestCapacity];
14 int constructor_count;
15 int total_destructor_count;
16 
17 class FakeElement {
18  public:
FakeElement()19   FakeElement() {
20     constructor_count++;
21   };
FakeElement(int i)22   FakeElement(int i) {
23     val_ = i;
24     constructor_count++;
25   };
~FakeElement()26   ~FakeElement() {
27     total_destructor_count++;
28     if (val_ >= 0 && val_ < kMaxTestCapacity) {
29       destructor_count[val_]++;
30     }
31   };
setValue(int i)32   void setValue(int i) {
33     val_ = i;
34   }
35 
36  private:
37   int val_ = kMaxTestCapacity - 1;
38 };
39 }  // namespace
40 
TEST(ArrayQueueTest,IsEmptyInitially)41 TEST(ArrayQueueTest, IsEmptyInitially) {
42   ArrayQueue<int, 4> q;
43   EXPECT_TRUE(q.empty());
44   EXPECT_EQ(0, q.size());
45 }
46 
TEST(ArrayQueueTest,SimplePushPop)47 TEST(ArrayQueueTest, SimplePushPop) {
48   ArrayQueue<int, 3> q;
49   EXPECT_TRUE(q.push(1));
50   EXPECT_TRUE(q.push(2));
51   q.pop();
52   EXPECT_TRUE(q.push(3));
53 }
54 
TEST(ArrayQueueTest,SimplePushPopBackPush)55 TEST(ArrayQueueTest, SimplePushPopBackPush) {
56   ArrayQueue<int, 3> q;
57   EXPECT_TRUE(q.push(0));
58   EXPECT_TRUE(q.push(1));
59   EXPECT_TRUE(q.push(2));
60   q.pop_back();
61   EXPECT_EQ(2, q.size());
62   EXPECT_EQ(0, q[0]);
63   EXPECT_EQ(1, q[1]);
64 
65   EXPECT_TRUE(q.push(3));
66   EXPECT_EQ(3, q.size());
67   EXPECT_EQ(0, q[0]);
68   EXPECT_EQ(1, q[1]);
69   EXPECT_EQ(3, q[2]);
70 
71   q.pop_back();
72   q.pop_back();
73   q.pop_back();
74 
75   EXPECT_EQ(0, q.size());
76   EXPECT_TRUE(q.push(4));
77   EXPECT_TRUE(q.push(5));
78   EXPECT_TRUE(q.push(6));
79   EXPECT_EQ(3, q.size());
80   EXPECT_EQ(4, q[0]);
81   EXPECT_EQ(5, q[1]);
82   EXPECT_EQ(6, q[2]);
83 
84   q.pop();
85 
86   EXPECT_TRUE(q.push(7));
87   EXPECT_EQ(5, q[0]);
88   EXPECT_EQ(6, q[1]);
89   EXPECT_EQ(7, q[2]);
90 }
91 
TEST(ArrayQueueTest,TestSize)92 TEST(ArrayQueueTest, TestSize) {
93   ArrayQueue<int, 2> q;
94   q.push(1);
95   EXPECT_EQ(1, q.size());
96   q.push(2);
97   EXPECT_EQ(2, q.size());
98   q.pop();
99   EXPECT_EQ(1, q.size());
100   q.pop();
101 }
102 
TEST(ArrayQueueTest,TestEmpty)103 TEST(ArrayQueueTest, TestEmpty) {
104   ArrayQueue<int, 2> q;
105   q.push(1);
106   EXPECT_FALSE(q.empty());
107   q.push(2);
108   EXPECT_FALSE(q.empty());
109   q.pop();
110   EXPECT_FALSE(q.empty());
111   q.pop();
112   EXPECT_TRUE(q.empty());
113 }
114 
TEST(ArrayQueueTest,KickPushWhenNotFull)115 TEST(ArrayQueueTest, KickPushWhenNotFull) {
116   ArrayQueue<int, 2> q;
117   q.kick_push(1);
118   EXPECT_EQ(1, q.size());
119   EXPECT_EQ(1, q[0]);
120   q.kick_push(2);
121   EXPECT_EQ(2, q.size());
122   EXPECT_EQ(2, q[1]);
123 }
124 
TEST(ArrayQueueTest,KickPushWhenFull)125 TEST(ArrayQueueTest, KickPushWhenFull) {
126   ArrayQueue<int, 2> q;
127   q.kick_push(1);
128   q.push(2);
129   EXPECT_EQ(2, q.size());
130   q.kick_push(3);
131   EXPECT_EQ(2, q.size());
132   EXPECT_EQ(2, q[0]);
133   EXPECT_EQ(3, q[1]);
134 }
135 
TEST(ArrayQueueTest,PopWhenEmpty)136 TEST(ArrayQueueTest, PopWhenEmpty) {
137   ArrayQueue<int, 4> q;
138   q.pop();
139   EXPECT_EQ(0, q.size());
140 }
141 
TEST(ArrayQueueTest,PopBackWhenEmpty)142 TEST(ArrayQueueTest, PopBackWhenEmpty) {
143   ArrayQueue<int, 4> q;
144   q.pop_back();
145   EXPECT_EQ(0, q.size());
146 }
147 
TEST(ArrayQueueTest,PushWhenFull)148 TEST(ArrayQueueTest, PushWhenFull) {
149   ArrayQueue<int, 2> q;
150   q.push(1);
151   q.push(2);
152   EXPECT_FALSE(q.push(3));
153 }
154 
TEST(ArrayQueueDeathTest,FrontWhenEmpty)155 TEST(ArrayQueueDeathTest, FrontWhenEmpty) {
156   ArrayQueue<int, 4> q;
157   EXPECT_DEATH(q.front(), "");
158 }
159 
TEST(ArrayQueueDeathTest,BackWhenEmpty)160 TEST(ArrayQueueDeathTest, BackWhenEmpty) {
161   ArrayQueue<int, 4> q;
162   EXPECT_DEATH(q.back(), "");
163 }
164 
TEST(ArrayQueueTest,TestFront)165 TEST(ArrayQueueTest, TestFront) {
166   ArrayQueue<int, 3> q;
167   q.push(1);
168   EXPECT_EQ(1, q.front());
169   q.pop();
170   q.push(2);
171   EXPECT_EQ(2, q.front());
172   q.push(3);
173   EXPECT_EQ(2, q.front());
174 }
175 
TEST(ArrayQueueTest,TestBack)176 TEST(ArrayQueueTest, TestBack) {
177   ArrayQueue<int, 3> q;
178   q.push(1);
179   EXPECT_EQ(1, q.back());
180   q.pop();
181   q.push(2);
182   EXPECT_EQ(2, q.back());
183   q.push(3);
184   EXPECT_EQ(3, q.back());
185 }
186 
TEST(ArrayQueueDeathTest,InvalidSubscript)187 TEST(ArrayQueueDeathTest, InvalidSubscript) {
188   ArrayQueue<int, 2> q;
189   EXPECT_DEATH(q[0], "");
190 }
191 
TEST(ArrayQueueTest,Subscript)192 TEST(ArrayQueueTest, Subscript) {
193   ArrayQueue<int, 2> q;
194   q.push(1);
195   q.push(2);
196   EXPECT_EQ(1, q[0]);
197   EXPECT_EQ(2, q[1]);
198   q.pop();
199   EXPECT_EQ(2, q[0]);
200 }
201 
TEST(ArrayQueueTest,RemoveWithInvalidIndex)202 TEST(ArrayQueueTest, RemoveWithInvalidIndex) {
203   ArrayQueue<int, 3> q;
204   EXPECT_FALSE(q.remove(0));
205 }
206 
TEST(ArrayQueueTest,RemoveWithIndex)207 TEST(ArrayQueueTest, RemoveWithIndex) {
208   ArrayQueue<int, 3> q;
209   q.push(1);
210   q.push(2);
211   q.remove(0);
212   EXPECT_EQ(2, q.front());
213   EXPECT_EQ(1, q.size());
214   q.push(3);
215   q.remove(1);
216   EXPECT_EQ(2, q.front());
217   EXPECT_EQ(1, q.size());
218 }
219 
TEST(ArrayQueueTest,DestructorCalledOnPop)220 TEST(ArrayQueueTest, DestructorCalledOnPop) {
221   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
222     destructor_count[i] = 0;
223   }
224 
225   ArrayQueue<FakeElement, 3> q;
226   FakeElement e;
227   q.push(e);
228   q.push(e);
229 
230   q.front().setValue(0);
231   q.pop();
232   EXPECT_EQ(1, destructor_count[0]);
233 
234   q.front().setValue(1);
235   q.pop();
236   EXPECT_EQ(1, destructor_count[1]);
237 }
238 
TEST(ArrayQueueTest,ElementsDestructedWhenQueueDestructed)239 TEST(ArrayQueueTest, ElementsDestructedWhenQueueDestructed) {
240   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
241     destructor_count[i] = 0;
242   }
243 
244   // Put q and e in the scope so their destructor will be called going
245   // out of scope.
246   {
247     ArrayQueue<FakeElement, 4> q;
248     FakeElement e;
249 
250     for (size_t i = 0; i < 3; ++i) {
251       q.push(e);
252       q[i].setValue(i);
253     }
254 
255     q.~ArrayQueue();
256 
257     for (size_t i = 0; i < 3; ++i) {
258       EXPECT_EQ(1, destructor_count[i]);
259     }
260   }
261 
262   // Check destructor count.
263   for (size_t i = 0; i < 3; ++i) {
264     EXPECT_EQ(1, destructor_count[i]);
265   }
266   EXPECT_EQ(0, destructor_count[3]);
267   EXPECT_EQ(1, destructor_count[kMaxTestCapacity - 1]);
268 }
269 
TEST(ArrayQueueTest,EmplaceTest)270 TEST(ArrayQueueTest, EmplaceTest) {
271   constructor_count = 0;
272   ArrayQueue<FakeElement, 2> q;
273 
274   EXPECT_TRUE(q.emplace(0));
275   EXPECT_EQ(1, constructor_count);
276   EXPECT_EQ(1, q.size());
277 
278   EXPECT_TRUE(q.emplace(1));
279   EXPECT_EQ(2, constructor_count);
280   EXPECT_EQ(2, q.size());
281 
282   EXPECT_FALSE(q.emplace(2));
283   EXPECT_EQ(2, constructor_count);
284   EXPECT_EQ(2, q.size());
285 }
286 
TEST(ArrayQueueTest,EmptyQueueIterator)287 TEST(ArrayQueueTest, EmptyQueueIterator) {
288   ArrayQueue<int, 4> q;
289 
290   ArrayQueue<int, 4>::iterator it = q.begin();
291   EXPECT_TRUE(it == q.end());
292   EXPECT_FALSE(it != q.end());
293 }
294 
TEST(ArrayQueueTest,SimpleIterator)295 TEST(ArrayQueueTest, SimpleIterator) {
296   ArrayQueue<int, 4> q;
297   for (size_t i = 0; i < 3; ++i) {
298     q.push(i);
299   }
300   EXPECT_NE(q.begin(), q.end());
301 
302   size_t index = 0;
303   for (ArrayQueue<int, 4>::iterator it = q.begin(); it != q.end(); ++it) {
304     EXPECT_EQ(q[index++], *it);
305   }
306   index = 0;
307   for (ArrayQueue<int, 4>::iterator it = q.begin(); it != q.end(); it++) {
308     EXPECT_EQ(q[index++], *it);
309   }
310 
311   index = 0;
312   ArrayQueue<int, 4>::iterator it = q.begin();
313   while (it != q.end()) {
314     EXPECT_EQ(q[index++], *it++);
315   }
316 
317   for (size_t i = 0; i < 3; ++i) {
318     q.pop();
319     q.push(i + 3);
320   }
321 
322   index = 0;
323   it = q.begin();
324   while (it != q.end()) {
325     EXPECT_EQ(q[index++], *it++);
326   }
327 
328   // Iterator concept checks: default constructible, copy assignable, copy
329   // constructible
330   ArrayQueue<int, 4>::iterator it2;
331   it2 = it;
332   EXPECT_EQ(it, it2);
333 
334   ArrayQueue<int, 4>::iterator it3(it);
335   EXPECT_EQ(it, it3);
336 }
337 
TEST(ArrayQueueTest,IteratorSwap)338 TEST(ArrayQueueTest, IteratorSwap) {
339   ArrayQueue<int, 2> q;
340   q.push(1);
341   q.push(2);
342 
343   auto it1 = q.begin(), it2 = q.end();
344   std::swap(it1, it2);
345   EXPECT_EQ(it1, q.end());
346   EXPECT_EQ(it2, q.begin());
347 }
348 
TEST(ArrayQueueTest,IteratorAndPush)349 TEST(ArrayQueueTest, IteratorAndPush) {
350   ArrayQueue<int, 4> q;
351   for (size_t i = 0; i < 2; ++i) {
352     q.push(i);
353   }
354 
355   ArrayQueue<int, 4>::iterator it_b = q.begin();
356   ArrayQueue<int, 4>::iterator it_e = q.end();
357   q.push(3);
358 
359   size_t index = 0;
360   while (it_b != it_e) {
361     EXPECT_EQ(q[index++], *it_b++);
362   }
363 }
364 
TEST(ArrayQueueTest,IteratorAndPop)365 TEST(ArrayQueueTest, IteratorAndPop) {
366   ArrayQueue<int, 4> q;
367   for (size_t i = 0; i < 3; ++i) {
368     q.push(i);
369   }
370 
371   ArrayQueue<int, 4>::iterator it_b = q.begin();
372   q.pop();
373   it_b++;
374 
375   for (size_t i = 0; i < 2; ++i) {
376     EXPECT_EQ(q[i], *it_b++);
377   }
378 }
379 
TEST(ArrayQueueTest,IteratorAndRemove)380 TEST(ArrayQueueTest, IteratorAndRemove) {
381   ArrayQueue<int, 4> q;
382   for (size_t i = 0; i < 2; ++i) {
383     q.push(i);
384   }
385 
386   ArrayQueue<int, 4>::iterator it_b = q.begin();
387   q.remove(1);
388 
389   EXPECT_EQ(q[0], *it_b);
390 }
391 
TEST(ArrayQueueTest,IteratorAndEmplace)392 TEST(ArrayQueueTest, IteratorAndEmplace) {
393   ArrayQueue<int, 4> q;
394   for (size_t i = 0; i < 2; ++i) {
395     q.push(i);
396   }
397 
398   ArrayQueue<int, 4>::iterator it_b = q.begin();
399   ArrayQueue<int, 4>::iterator it_e = q.end();
400   q.emplace(3);
401 
402   size_t index = 0;
403   while (it_b != it_e) {
404     EXPECT_EQ(q[index++], *it_b++);
405   }
406 }
407 
TEST(ArrayQueueTest,SimpleConstIterator)408 TEST(ArrayQueueTest, SimpleConstIterator) {
409   ArrayQueue<int, 4> q;
410   for (size_t i = 0; i < 3; ++i) {
411     q.push(i);
412   }
413 
414   size_t index = 0;
415   for (ArrayQueue<int, 4>::const_iterator cit = q.cbegin(); cit != q.cend();
416        ++cit) {
417     EXPECT_EQ(q[index++], *cit);
418   }
419 
420   index = 0;
421   ArrayQueue<int, 4>::const_iterator cit = q.cbegin();
422   while (cit != q.cend()) {
423     EXPECT_EQ(q[index++], *cit++);
424   }
425 
426   for (size_t i = 0; i < 3; ++i) {
427     q.pop();
428     q.push(i + 3);
429   }
430 
431   index = 0;
432   cit = q.cbegin();
433   while (cit != q.cend()) {
434     EXPECT_EQ(q[index++], *cit++);
435   }
436 }
437 
TEST(ArrayQueueTest,Full)438 TEST(ArrayQueueTest, Full) {
439   ArrayQueue<size_t, 4> q;
440   for (size_t i = 0; i < 4; i++) {
441     EXPECT_FALSE(q.full());
442     q.push(i);
443   }
444 
445   EXPECT_TRUE(q.full());
446 }
447 
TEST(ArrayQueueTest,ArrayCopy)448 TEST(ArrayQueueTest, ArrayCopy) {
449   constexpr size_t kSize = 8;
450   ArrayQueue<size_t, kSize> q;
451   std::vector<size_t> v;
452   v.resize(kSize);
453 
454   for (size_t i = 0; i < kSize; i++) {
455     q.push(i);
456 
457     v.assign(kSize, 0xdeadbeef);
458     std::copy(q.begin(), q.end(), v.begin());
459 
460     for (size_t j = 0; j < i; j++) {
461       EXPECT_EQ(q[j], v[j]);
462       EXPECT_EQ(*std::next(q.begin(), j), v[j]);
463     }
464   }
465 }
466 
TEST(ArrayQueueTest,IteratorTraits)467 TEST(ArrayQueueTest, IteratorTraits) {
468   ArrayQueue<int, 2> q;
469   q.push(1234);
470   q.push(5678);
471 
472   using traits = std::iterator_traits<decltype(q)::iterator>;
473   typename traits::difference_type diff = std::distance(q.begin(), q.end());
474   EXPECT_EQ(diff, q.size());
475 
476   typename traits::value_type v = *q.begin();
477   EXPECT_EQ(v, q[0]);
478 
479   typename traits::reference r = *q.begin();
480   r = 999;
481   EXPECT_EQ(r, q[0]);
482 
483   typename traits::pointer p = &r;
484   EXPECT_EQ(*p, q[0]);
485 
486   // Note: if the implementation is upgraded to another category like random
487   // access, then this static assert should be updated. It exists primarily to
488   // confirm that we are declaring an iterator_category
489   static_assert(
490       std::is_same<traits::iterator_category, std::forward_iterator_tag>::value,
491       "ArrayQueueIterator should be a forward iterator");
492 }
493 
TEST(ArrayQueueTest,ArrayClear)494 TEST(ArrayQueueTest, ArrayClear) {
495   ArrayQueue<size_t, 4> q;
496 
497   q.clear();
498   EXPECT_TRUE(q.empty());
499 
500   for (size_t i = 0; i < 4; i++) {
501     q.push(i);
502   }
503 
504   q.clear();
505   EXPECT_TRUE(q.empty());
506 
507   // Make sure that insertion/access still work after a clear.
508   for (size_t i = 0; i < 4; i++) {
509     q.push(i);
510   }
511   for (size_t i = 0; i < 4; i++) {
512     EXPECT_EQ(q[i], i);
513   }
514 }
515 
TEST(ArrayQueueTest,ElementsDestructedArrayClear)516 TEST(ArrayQueueTest, ElementsDestructedArrayClear) {
517   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
518     destructor_count[i] = 0;
519   }
520   total_destructor_count = 0;
521 
522   ArrayQueue<FakeElement, 4> q;
523   for (size_t i = 0; i < 3; ++i) {
524     q.emplace(i);
525   }
526 
527   q.clear();
528 
529   for (size_t i = 0; i < 3; ++i) {
530     EXPECT_EQ(1, destructor_count[i]);
531   }
532   EXPECT_EQ(3, total_destructor_count);
533 }
534 
TEST(ArrayQueueExtTest,BasicTest)535 TEST(ArrayQueueExtTest, BasicTest) {
536   constexpr size_t kNumElements = 32;
537   int32_t array[kNumElements];
538   ArrayQueueExt<int32_t> q(array, kNumElements);
539 
540   ASSERT_EQ(q.data(), array);
541   EXPECT_EQ(q.capacity(), kNumElements);
542 
543   for (int i = 0; i < kNumElements; i++) {
544     q.push(i);
545   }
546 
547   for (int i = 0; i < kNumElements; i++) {
548     EXPECT_EQ(array[i], q[i]);
549   }
550 }
551