1#include "gtest/gtest.h"
2#include "chre/util/array_queue.h"
3
4using chre::ArrayQueue;
5
6namespace {
7constexpr int kMaxTestCapacity = 10;
8int destructor_count[kMaxTestCapacity];
9int constructor_count;
10
11class DummyElement {
12 public:
13  DummyElement() {
14    constructor_count++;
15  };
16  DummyElement(int i) {
17    val_ = i;
18    constructor_count++;
19  };
20  ~DummyElement() {
21    if (val_ >= 0 && val_ < kMaxTestCapacity) {
22      destructor_count[val_]++;
23    }
24  };
25  void setValue(int i) {
26    val_ = i;
27  }
28
29 private:
30  int val_ = kMaxTestCapacity - 1;
31};
32}
33
34TEST(ArrayQueueTest, IsEmptyInitially) {
35  ArrayQueue<int, 4> q;
36  EXPECT_TRUE(q.empty());
37  EXPECT_EQ(0, q.size());
38}
39
40TEST(ArrayQueueTest, SimplePushPop) {
41  ArrayQueue<int, 3> q;
42  EXPECT_TRUE(q.push(1));
43  EXPECT_TRUE(q.push(2));
44  q.pop();
45  EXPECT_TRUE(q.push(3));
46}
47
48TEST(ArrayQueueTest, TestSize) {
49  ArrayQueue<int, 2> q;
50  q.push(1);
51  EXPECT_EQ(1, q.size());
52  q.push(2);
53  EXPECT_EQ(2, q.size());
54  q.pop();
55  EXPECT_EQ(1, q.size());
56  q.pop();
57}
58
59TEST(ArrayQueueTest, TestEmpty) {
60  ArrayQueue<int, 2> q;
61  q.push(1);
62  EXPECT_FALSE(q.empty());
63  q.push(2);
64  EXPECT_FALSE(q.empty());
65  q.pop();
66  EXPECT_FALSE(q.empty());
67  q.pop();
68  EXPECT_TRUE(q.empty());
69}
70
71TEST(ArrayQueueTest, PopWhenEmpty) {
72  ArrayQueue<int, 4> q;
73  q.pop();
74  EXPECT_EQ(0, q.size());
75}
76
77TEST(ArrayQueueTest, PushWhenFull) {
78  ArrayQueue<int, 2> q;
79  q.push(1);
80  q.push(2);
81  EXPECT_FALSE(q.push(3));
82}
83
84TEST(ArrayQueueDeathTest, FrontWhenEmpty) {
85  ArrayQueue<int, 4> q;
86  EXPECT_DEATH(q.front(), "");
87}
88
89TEST(ArrayQueueTest, TestFront) {
90  ArrayQueue<int, 3> q;
91  q.push(1);
92  EXPECT_EQ(1, q.front());
93  q.pop();
94  q.push(2);
95  EXPECT_EQ(2, q.front());
96}
97
98TEST(ArrayQueueDeathTest, InvalidSubscript) {
99  ArrayQueue<int, 2> q;
100  EXPECT_DEATH(q[0], "");
101 }
102
103TEST(ArrayQueueTest, Subscript) {
104  ArrayQueue<int, 2> q;
105  q.push(1);
106  q.push(2);
107  EXPECT_EQ(1, q[0]);
108  EXPECT_EQ(2, q[1]);
109  q.pop();
110  EXPECT_EQ(2, q[0]);
111}
112
113TEST(ArrayQueueTest, RemoveWithInvalidIndex) {
114  ArrayQueue<int, 3> q;
115  EXPECT_FALSE(q.remove(0));
116}
117
118TEST(ArrayQueueTest, RemoveWithIndex) {
119  ArrayQueue<int, 3> q;
120  q.push(1);
121  q.push(2);
122  q.remove(0);
123  EXPECT_EQ(2, q.front());
124  EXPECT_EQ(1, q.size());
125  q.push(3);
126  q.remove(1);
127  EXPECT_EQ(2, q.front());
128  EXPECT_EQ(1, q.size());
129}
130
131TEST(ArrayQueueTest, DestructorCalledOnPop) {
132  for (size_t i = 0; i < kMaxTestCapacity; ++i) {
133    destructor_count[i] = 0;
134  }
135
136  ArrayQueue<DummyElement, 3> q;
137  DummyElement e;
138  q.push(e);
139  q.push(e);
140
141  q.front().setValue(0);
142  q.pop();
143  EXPECT_EQ(1, destructor_count[0]);
144
145  q.front().setValue(1);
146  q.pop();
147  EXPECT_EQ(1, destructor_count[1]);
148}
149
150TEST(ArrayQueueTest, ElementsDestructedWhenQueueDestructed) {
151  for (size_t i = 0; i < kMaxTestCapacity; ++i) {
152    destructor_count[i] = 0;
153  }
154
155  // Put q and e in the scope so their destructor will be called going
156  // out of scope.
157  { ArrayQueue<DummyElement, 4> q;
158    DummyElement e;
159
160    for (size_t i = 0; i < 3; ++i) {
161      q.push(e);
162      q[i].setValue(i);
163    }
164
165    q.~ArrayQueue();
166
167    for (size_t i = 0; i < 3; ++i) {
168      EXPECT_EQ(1, destructor_count[i]);
169    }
170  }
171
172  // Check destructor count.
173  for (size_t i = 0; i < 3; ++i) {
174    EXPECT_EQ(1, destructor_count[i]);
175  }
176  EXPECT_EQ(0, destructor_count[3]);
177  EXPECT_EQ(1, destructor_count[kMaxTestCapacity - 1]);
178}
179
180TEST(ArrayQueueTest, EmplaceTest) {
181  constructor_count = 0;
182  ArrayQueue<DummyElement, 2> q;
183
184  EXPECT_TRUE(q.emplace(0));
185  EXPECT_EQ(1, constructor_count);
186  EXPECT_EQ(1, q.size());
187
188  EXPECT_TRUE(q.emplace(1));
189  EXPECT_EQ(2, constructor_count);
190  EXPECT_EQ(2, q.size());
191
192  EXPECT_FALSE(q.emplace(2));
193  EXPECT_EQ(2, constructor_count);
194  EXPECT_EQ(2, q.size());
195}
196
197TEST(ArrayQueueTest, EmptyQueueIterator) {
198  ArrayQueue<int, 4> q;
199
200  ArrayQueue<int, 4>::iterator it = q.begin();
201  EXPECT_TRUE(it == q.end());
202  EXPECT_FALSE(it != q.end());
203}
204
205TEST(ArrayQueueTest, SimpleIterator) {
206  ArrayQueue<int, 4> q;
207  for (size_t i = 0; i < 3; ++i) {
208    q.push(i);
209  }
210
211  size_t index = 0;
212  for (ArrayQueue<int, 4>::iterator it = q.begin(); it != q.end(); ++it) {
213    EXPECT_EQ(q[index++], *it);
214  }
215
216  index = 0;
217  ArrayQueue<int, 4>::iterator it = q.begin();
218  while (it != q.end()) {
219    EXPECT_EQ(q[index++], *it++);
220  }
221
222  for (size_t i = 0; i < 3; ++i) {
223    q.pop();
224    q.push(i + 3);
225  }
226
227  index = 0;
228  it = q.begin();
229  while (it != q.end()) {
230    EXPECT_EQ(q[index++], *it++);
231  }
232}
233
234TEST(ArrayQueueTest, IteratorAndPush) {
235  ArrayQueue<int, 4> q;
236  for (size_t i = 0; i < 2; ++i) {
237    q.push(i);
238  }
239
240  ArrayQueue<int, 4>::iterator it_b = q.begin();
241  ArrayQueue<int, 4>::iterator it_e = q.end();
242  q.push(3);
243
244  size_t index = 0;
245  while (it_b != it_e) {
246    EXPECT_EQ(q[index++], *it_b++);
247  }
248}
249
250TEST(ArrayQueueTest, IteratorAndPop) {
251  ArrayQueue<int, 4> q;
252  for (size_t i = 0; i < 3; ++i) {
253    q.push(i);
254  }
255
256  ArrayQueue<int, 4>::iterator it_b = q.begin();
257  q.pop();
258  it_b++;
259
260  for (size_t i = 0; i < 2; ++i) {
261    EXPECT_EQ(q[i], *it_b++);
262  }
263}
264
265TEST(ArrayQueueTest, IteratorAndRemove) {
266  ArrayQueue<int, 4> q;
267  for (size_t i = 0; i < 2; ++i) {
268    q.push(i);
269  }
270
271  ArrayQueue<int, 4>::iterator it_b = q.begin();
272  q.remove(1);
273
274  EXPECT_EQ(q[0], *it_b);
275}
276
277TEST(ArrayQueueTest, IteratorAndEmplace) {
278  ArrayQueue<int, 4> q;
279  for (size_t i = 0; i < 2; ++i) {
280    q.push(i);
281  }
282
283  ArrayQueue<int, 4>::iterator it_b = q.begin();
284  ArrayQueue<int, 4>::iterator it_e = q.end();
285  q.emplace(3);
286
287  size_t index = 0;
288  while (it_b != it_e) {
289    EXPECT_EQ(q[index++], *it_b++);
290  }
291}
292
293TEST(ArrayQueueTest, SimpleConstIterator) {
294  ArrayQueue<int, 4> q;
295  for (size_t i = 0; i < 3; ++i) {
296    q.push(i);
297  }
298
299  size_t index = 0;
300  for (ArrayQueue<int, 4>::const_iterator cit = q.cbegin();
301       cit != q.cend(); ++cit) {
302    EXPECT_EQ(q[index++], *cit);
303  }
304
305  index = 0;
306  ArrayQueue<int, 4>::const_iterator cit = q.cbegin();
307  while (cit != q.cend()) {
308    EXPECT_EQ(q[index++], *cit++);
309  }
310
311  for (size_t i = 0; i < 3; ++i) {
312    q.pop();
313    q.push(i + 3);
314  }
315
316  index = 0;
317  cit = q.cbegin();
318  while (cit != q.cend()) {
319    EXPECT_EQ(q[index++], *cit++);
320  }
321}
322
323TEST(ArrayQueueTest, Full) {
324  ArrayQueue<size_t, 4> q;
325  for (size_t i = 0; i < 4; i++) {
326    EXPECT_FALSE(q.full());
327    q.push(i);
328  }
329
330  EXPECT_TRUE(q.full());
331}
332