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