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