blob: c05d8278b8b81db7c871e845fbecb47d9ebd541a [file] [log] [blame]
James Kuszmaul97f750d2019-01-20 20:08:03 -08001#include "aos/containers/priority_queue.h"
2
3#include "gtest/gtest.h"
4
5namespace aos {
6namespace testing {
7
8// Effectively copies the implementation of ::std::less just to demonstrate how
9// things work.
10class ExampleCompare {
11 public:
12 constexpr bool operator()(const int &lhs, const int &rhs) const {
13 return lhs < rhs;
14 }
15};
16
17class PriorityQueueTest : public ::testing::Test {
18 public:
19 PriorityQueueTest() {}
20 protected:
21 PriorityQueue<int, 10, ExampleCompare> queue_;
22};
23
24TEST_F(PriorityQueueTest, DefaultIsEmpty) {
25 ASSERT_EQ(0u, queue_.size());
26 ASSERT_TRUE(queue_.empty());
27 ASSERT_FALSE(queue_.full());
28}
29
30TEST_F(PriorityQueueTest, CanAddData) {
31 auto it = queue_.PushFromBottom(5);
32 ASSERT_EQ(1u, queue_.size());
33 ASSERT_FALSE(queue_.empty());
34 ASSERT_FALSE(queue_.full());
35 EXPECT_EQ(5, *it);
36 EXPECT_EQ(5, queue_.get(0));
37 EXPECT_EQ(5, queue_.top());
38 EXPECT_EQ(queue_.begin(), it);
39 // Also check pre/post-fix increment/decrement operators
40 EXPECT_EQ(queue_.end(), ++it);
41 EXPECT_EQ(queue_.begin(), --it);
42 EXPECT_EQ(queue_.begin(), it++);
43 EXPECT_EQ(queue_.end(), it--);
44 EXPECT_EQ(queue_.begin(), it);
45}
46
47TEST_F(PriorityQueueTest, PriorityInsertion) {
48 queue_.PushFromBottom(10);
49 queue_.PushFromBottom(20);
50 queue_.PushFromBottom(15);
51 auto it = queue_.PushFromBottom(11);
52 ASSERT_EQ(4u, queue_.size());
53 ASSERT_FALSE(queue_.full());
54 ::std::vector<int> reverse_expected{20, 15, 11};
James Kuszmaul4b04eaf2019-02-10 17:13:25 -080055 EXPECT_EQ(10, *queue_.begin());
James Kuszmaul97f750d2019-01-20 20:08:03 -080056 for (; it != queue_.end(); ++it) {
57 EXPECT_EQ(reverse_expected.back(), *it);
58 reverse_expected.pop_back();
59 }
60 ASSERT_TRUE(reverse_expected.empty());
61}
62
James Kuszmaul4b04eaf2019-02-10 17:13:25 -080063// Tests that the clear() method works properly.
64TEST_F(PriorityQueueTest, ClearQueue) {
65 queue_.PushFromBottom(10);
66 queue_.PushFromBottom(20);
67 queue_.PushFromBottom(15);
68 queue_.PushFromBottom(11);
69 ASSERT_EQ(4u, queue_.size());
70 ASSERT_FALSE(queue_.full());
71 queue_.clear();
72 ASSERT_TRUE(queue_.empty());
73 ASSERT_EQ(0u, queue_.size());
74
75 queue_.PushFromBottom(1);
76 queue_.PushFromBottom(3);
77 queue_.PushFromBottom(2);
78 ASSERT_EQ(3u, queue_.size());
79 ::std::vector<int> reverse_expected{3, 2, 1};
80 for (const int val : queue_) {
81 EXPECT_EQ(reverse_expected.back(), val);
82 reverse_expected.pop_back();
83 }
84 ASSERT_TRUE(reverse_expected.empty());
85}
86
James Kuszmaul97f750d2019-01-20 20:08:03 -080087TEST_F(PriorityQueueTest, FullBufferInsertTop) {
88 for (int ii = 0; ii < 10; ++ii) {
89 queue_.PushFromBottom(ii);
90 }
91 ASSERT_EQ(10u, queue_.size());
92 ASSERT_TRUE(queue_.full());
93 // Check adding value at top.
94 queue_.PushFromBottom(100);
95 ASSERT_EQ(10u, queue_.size());
96 ASSERT_TRUE(queue_.full());
97 ::std::vector<int> reverse_expected{100, 9, 8, 7, 6, 5, 4, 3, 2, 1};
98 EXPECT_EQ(100, queue_.top());
99 for (int val : queue_) {
100 EXPECT_EQ(reverse_expected.back(), val);
101 reverse_expected.pop_back();
102 }
103 ASSERT_TRUE(reverse_expected.empty());
104}
105
106TEST_F(PriorityQueueTest, FullBufferInsertMiddle) {
107 for (int ii = 9; ii >= 0; --ii) {
108 queue_.PushFromBottom(ii);
109 }
110 // Check adding value in the middle.
111 queue_.PushFromBottom(5);
112
113 ::std::vector<int> reverse_expected{9, 8, 7, 6, 5, 5, 4, 3, 2, 1};
114 EXPECT_EQ(9, queue_.top());
115 for (int val : queue_) {
116 EXPECT_EQ(reverse_expected.back(), val);
117 reverse_expected.pop_back();
118 }
119 ASSERT_TRUE(reverse_expected.empty());
120}
121
122TEST_F(PriorityQueueTest, FullBufferInsertBelowBottom) {
123 for (int ii = 9; ii >= 0; --ii) {
124 queue_.PushFromBottom(ii);
125 }
126 // Check adding value at the bottom where it will be dropped.
127 queue_.PushFromBottom(-1);
128
129 ::std::vector<int> reverse_expected{9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
130 EXPECT_EQ(9, queue_.top());
131 for (int val : queue_) {
132 EXPECT_EQ(reverse_expected.back(), val);
133 reverse_expected.pop_back();
134 }
135 ASSERT_TRUE(reverse_expected.empty());
136}
137
138TEST_F(PriorityQueueTest, FullBufferInsertBottom) {
139 for (int ii = 18; ii >= 0; ii -= 2) {
140 queue_.PushFromBottom(ii);
141 }
142 ASSERT_TRUE(queue_.full());
143 // Check adding value at the bottom where it displaces the bottom value.
144 queue_.PushFromBottom(1);
145
146 ::std::vector<int> reverse_expected{18, 16, 14, 12, 10, 8, 6, 4, 2, 1};
147 EXPECT_EQ(18, queue_.top());
148 for (int val : queue_) {
149 EXPECT_EQ(reverse_expected.back(), val);
150 reverse_expected.pop_back();
151 }
152 ASSERT_TRUE(reverse_expected.empty());
153}
154
155// Check that operator-> works as expected on the iterator.
156struct TestStruct {
157 int a;
158 friend bool operator<(const TestStruct &lhs, const TestStruct &rhs) {
159 return lhs.a < rhs.a;
160 }
161};
162TEST(PriorirtyQueueTest, MemberAccess) {
163 PriorityQueue<TestStruct, 10, ::std::less<TestStruct>> q;
164 auto it = q.PushFromBottom({11});
165 EXPECT_EQ(11, it->a);
166}
167
168} // namespace testing
169} // namespace aos