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