blob: 2c459903a004b0edd8baaea656871581d24d3b81 [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};
55 EXPECT_EQ(20, queue_.top());
56 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
63TEST_F(PriorityQueueTest, FullBufferInsertTop) {
64 for (int ii = 0; ii < 10; ++ii) {
65 queue_.PushFromBottom(ii);
66 }
67 ASSERT_EQ(10u, queue_.size());
68 ASSERT_TRUE(queue_.full());
69 // Check adding value at top.
70 queue_.PushFromBottom(100);
71 ASSERT_EQ(10u, queue_.size());
72 ASSERT_TRUE(queue_.full());
73 ::std::vector<int> reverse_expected{100, 9, 8, 7, 6, 5, 4, 3, 2, 1};
74 EXPECT_EQ(100, queue_.top());
75 for (int val : queue_) {
76 EXPECT_EQ(reverse_expected.back(), val);
77 reverse_expected.pop_back();
78 }
79 ASSERT_TRUE(reverse_expected.empty());
80}
81
82TEST_F(PriorityQueueTest, FullBufferInsertMiddle) {
83 for (int ii = 9; ii >= 0; --ii) {
84 queue_.PushFromBottom(ii);
85 }
86 // Check adding value in the middle.
87 queue_.PushFromBottom(5);
88
89 ::std::vector<int> reverse_expected{9, 8, 7, 6, 5, 5, 4, 3, 2, 1};
90 EXPECT_EQ(9, queue_.top());
91 for (int val : queue_) {
92 EXPECT_EQ(reverse_expected.back(), val);
93 reverse_expected.pop_back();
94 }
95 ASSERT_TRUE(reverse_expected.empty());
96}
97
98TEST_F(PriorityQueueTest, FullBufferInsertBelowBottom) {
99 for (int ii = 9; ii >= 0; --ii) {
100 queue_.PushFromBottom(ii);
101 }
102 // Check adding value at the bottom where it will be dropped.
103 queue_.PushFromBottom(-1);
104
105 ::std::vector<int> reverse_expected{9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
106 EXPECT_EQ(9, queue_.top());
107 for (int val : queue_) {
108 EXPECT_EQ(reverse_expected.back(), val);
109 reverse_expected.pop_back();
110 }
111 ASSERT_TRUE(reverse_expected.empty());
112}
113
114TEST_F(PriorityQueueTest, FullBufferInsertBottom) {
115 for (int ii = 18; ii >= 0; ii -= 2) {
116 queue_.PushFromBottom(ii);
117 }
118 ASSERT_TRUE(queue_.full());
119 // Check adding value at the bottom where it displaces the bottom value.
120 queue_.PushFromBottom(1);
121
122 ::std::vector<int> reverse_expected{18, 16, 14, 12, 10, 8, 6, 4, 2, 1};
123 EXPECT_EQ(18, queue_.top());
124 for (int val : queue_) {
125 EXPECT_EQ(reverse_expected.back(), val);
126 reverse_expected.pop_back();
127 }
128 ASSERT_TRUE(reverse_expected.empty());
129}
130
131// Check that operator-> works as expected on the iterator.
132struct TestStruct {
133 int a;
134 friend bool operator<(const TestStruct &lhs, const TestStruct &rhs) {
135 return lhs.a < rhs.a;
136 }
137};
138TEST(PriorirtyQueueTest, MemberAccess) {
139 PriorityQueue<TestStruct, 10, ::std::less<TestStruct>> q;
140 auto it = q.PushFromBottom({11});
141 EXPECT_EQ(11, it->a);
142}
143
144} // namespace testing
145} // namespace aos