blob: cb45a0f29711d9ca691e1a079955ed91e2cc8e04 [file] [log] [blame]
danzhc3be2d42019-04-25 07:47:41 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Tests SimpleLinkedHashMap.
6
7#include "net/third_party/quiche/src/common/simple_linked_hash_map.h"
8
9#include <memory>
10#include <utility>
11
danzhc3be2d42019-04-25 07:47:41 -070012#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
13
14using testing::Pair;
15using testing::Pointee;
16using testing::UnorderedElementsAre;
17
18namespace quiche {
19namespace test {
20
21// Tests that move constructor works.
22TEST(LinkedHashMapTest, Move) {
23 // Use unique_ptr as an example of a non-copyable type.
24 SimpleLinkedHashMap<int, std::unique_ptr<int>> m;
bnc9676f692019-11-05 07:40:24 -080025 m[2] = std::make_unique<int>(12);
26 m[3] = std::make_unique<int>(13);
danzhc3be2d42019-04-25 07:47:41 -070027 SimpleLinkedHashMap<int, std::unique_ptr<int>> n = std::move(m);
28 EXPECT_THAT(n,
29 UnorderedElementsAre(Pair(2, Pointee(12)), Pair(3, Pointee(13))));
30}
31
32TEST(LinkedHashMapTest, CanEmplaceMoveOnly) {
33 SimpleLinkedHashMap<int, std::unique_ptr<int>> m;
34 struct Data {
35 int k, v;
36 };
37 const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
38 for (const auto& kv : data) {
39 m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
40 std::make_tuple(new int{kv.v}));
41 }
42 EXPECT_TRUE(m.contains(2));
43 auto found = m.find(2);
44 ASSERT_TRUE(found != m.end());
45 EXPECT_EQ(234, *found->second);
46}
47
48struct NoCopy {
49 explicit NoCopy(int x) : x(x) {}
50 NoCopy(const NoCopy&) = delete;
51 NoCopy& operator=(const NoCopy&) = delete;
52 NoCopy(NoCopy&&) = delete;
53 NoCopy& operator=(NoCopy&&) = delete;
54 int x;
55};
56
57TEST(LinkedHashMapTest, CanEmplaceNoMoveNoCopy) {
58 SimpleLinkedHashMap<int, NoCopy> m;
59 struct Data {
60 int k, v;
61 };
62 const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
63 for (const auto& kv : data) {
64 m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
65 std::make_tuple(kv.v));
66 }
67 EXPECT_TRUE(m.contains(2));
68 auto found = m.find(2);
69 ASSERT_TRUE(found != m.end());
70 EXPECT_EQ(234, found->second.x);
71}
72
73TEST(LinkedHashMapTest, ConstKeys) {
74 SimpleLinkedHashMap<int, int> m;
75 m.insert(std::make_pair(1, 2));
76 // Test that keys are const in iteration.
77 std::pair<int, int>& p = *m.begin();
78 EXPECT_EQ(1, p.first);
79}
80
81// Tests that iteration from begin() to end() works
82TEST(LinkedHashMapTest, Iteration) {
83 SimpleLinkedHashMap<int, int> m;
84 EXPECT_TRUE(m.begin() == m.end());
85
86 m.insert(std::make_pair(2, 12));
87 m.insert(std::make_pair(1, 11));
88 m.insert(std::make_pair(3, 13));
89
90 SimpleLinkedHashMap<int, int>::iterator i = m.begin();
91 ASSERT_TRUE(m.begin() == i);
92 ASSERT_TRUE(m.end() != i);
93 EXPECT_EQ(2, i->first);
94 EXPECT_EQ(12, i->second);
95
96 ++i;
97 ASSERT_TRUE(m.end() != i);
98 EXPECT_EQ(1, i->first);
99 EXPECT_EQ(11, i->second);
100
101 ++i;
102 ASSERT_TRUE(m.end() != i);
103 EXPECT_EQ(3, i->first);
104 EXPECT_EQ(13, i->second);
105
106 ++i; // Should be the end of the line.
107 ASSERT_TRUE(m.end() == i);
108}
109
110// Tests that reverse iteration from rbegin() to rend() works
111TEST(LinkedHashMapTest, ReverseIteration) {
112 SimpleLinkedHashMap<int, int> m;
113 EXPECT_TRUE(m.rbegin() == m.rend());
114
115 m.insert(std::make_pair(2, 12));
116 m.insert(std::make_pair(1, 11));
117 m.insert(std::make_pair(3, 13));
118
119 SimpleLinkedHashMap<int, int>::reverse_iterator i = m.rbegin();
120 ASSERT_TRUE(m.rbegin() == i);
121 ASSERT_TRUE(m.rend() != i);
122 EXPECT_EQ(3, i->first);
123 EXPECT_EQ(13, i->second);
124
125 ++i;
126 ASSERT_TRUE(m.rend() != i);
127 EXPECT_EQ(1, i->first);
128 EXPECT_EQ(11, i->second);
129
130 ++i;
131 ASSERT_TRUE(m.rend() != i);
132 EXPECT_EQ(2, i->first);
133 EXPECT_EQ(12, i->second);
134
135 ++i; // Should be the end of the line.
136 ASSERT_TRUE(m.rend() == i);
137}
138
139// Tests that clear() works
140TEST(LinkedHashMapTest, Clear) {
141 SimpleLinkedHashMap<int, int> m;
142 m.insert(std::make_pair(2, 12));
143 m.insert(std::make_pair(1, 11));
144 m.insert(std::make_pair(3, 13));
145
146 ASSERT_EQ(3u, m.size());
147
148 m.clear();
149
150 EXPECT_EQ(0u, m.size());
151
152 m.clear(); // Make sure we can call it on an empty map.
153
154 EXPECT_EQ(0u, m.size());
155}
156
157// Tests that size() works.
158TEST(LinkedHashMapTest, Size) {
159 SimpleLinkedHashMap<int, int> m;
160 EXPECT_EQ(0u, m.size());
161 m.insert(std::make_pair(2, 12));
162 EXPECT_EQ(1u, m.size());
163 m.insert(std::make_pair(1, 11));
164 EXPECT_EQ(2u, m.size());
165 m.insert(std::make_pair(3, 13));
166 EXPECT_EQ(3u, m.size());
167 m.clear();
168 EXPECT_EQ(0u, m.size());
169}
170
171// Tests empty()
172TEST(LinkedHashMapTest, Empty) {
173 SimpleLinkedHashMap<int, int> m;
174 ASSERT_TRUE(m.empty());
175 m.insert(std::make_pair(2, 12));
176 ASSERT_FALSE(m.empty());
177 m.clear();
178 ASSERT_TRUE(m.empty());
179}
180
181TEST(LinkedHashMapTest, Erase) {
182 SimpleLinkedHashMap<int, int> m;
183 ASSERT_EQ(0u, m.size());
danzh892f1f42019-04-26 08:57:56 -0700184 EXPECT_EQ(0u, m.erase(2)); // Nothing to erase yet
danzhc3be2d42019-04-25 07:47:41 -0700185
186 m.insert(std::make_pair(2, 12));
187 ASSERT_EQ(1u, m.size());
danzh892f1f42019-04-26 08:57:56 -0700188 EXPECT_EQ(1u, m.erase(2));
danzhc3be2d42019-04-25 07:47:41 -0700189 EXPECT_EQ(0u, m.size());
190
danzh892f1f42019-04-26 08:57:56 -0700191 EXPECT_EQ(0u, m.erase(2)); // Make sure nothing bad happens if we repeat.
danzhc3be2d42019-04-25 07:47:41 -0700192 EXPECT_EQ(0u, m.size());
193}
194
195TEST(LinkedHashMapTest, Erase2) {
196 SimpleLinkedHashMap<int, int> m;
197 ASSERT_EQ(0u, m.size());
danzh892f1f42019-04-26 08:57:56 -0700198 EXPECT_EQ(0u, m.erase(2)); // Nothing to erase yet
danzhc3be2d42019-04-25 07:47:41 -0700199
200 m.insert(std::make_pair(2, 12));
201 m.insert(std::make_pair(1, 11));
202 m.insert(std::make_pair(3, 13));
203 m.insert(std::make_pair(4, 14));
204 ASSERT_EQ(4u, m.size());
205
206 // Erase middle two
danzh892f1f42019-04-26 08:57:56 -0700207 EXPECT_EQ(1u, m.erase(1));
208 EXPECT_EQ(1u, m.erase(3));
danzhc3be2d42019-04-25 07:47:41 -0700209
210 EXPECT_EQ(2u, m.size());
211
212 // Make sure we can still iterate over everything that's left.
213 SimpleLinkedHashMap<int, int>::iterator it = m.begin();
214 ASSERT_TRUE(it != m.end());
215 EXPECT_EQ(12, it->second);
216 ++it;
217 ASSERT_TRUE(it != m.end());
218 EXPECT_EQ(14, it->second);
219 ++it;
220 ASSERT_TRUE(it == m.end());
221
danzh892f1f42019-04-26 08:57:56 -0700222 EXPECT_EQ(0u, m.erase(1)); // Make sure nothing bad happens if we repeat.
danzhc3be2d42019-04-25 07:47:41 -0700223 ASSERT_EQ(2u, m.size());
224
danzh892f1f42019-04-26 08:57:56 -0700225 EXPECT_EQ(1u, m.erase(2));
226 EXPECT_EQ(1u, m.erase(4));
danzhc3be2d42019-04-25 07:47:41 -0700227 ASSERT_EQ(0u, m.size());
228
danzh892f1f42019-04-26 08:57:56 -0700229 EXPECT_EQ(0u, m.erase(1)); // Make sure nothing bad happens if we repeat.
danzhc3be2d42019-04-25 07:47:41 -0700230 ASSERT_EQ(0u, m.size());
231}
232
233// Test that erase(iter,iter) and erase(iter) compile and work.
234TEST(LinkedHashMapTest, Erase3) {
235 SimpleLinkedHashMap<int, int> m;
236
237 m.insert(std::make_pair(1, 11));
238 m.insert(std::make_pair(2, 12));
239 m.insert(std::make_pair(3, 13));
240 m.insert(std::make_pair(4, 14));
241
242 // Erase middle two
243 SimpleLinkedHashMap<int, int>::iterator it2 = m.find(2);
244 SimpleLinkedHashMap<int, int>::iterator it4 = m.find(4);
245 EXPECT_EQ(m.erase(it2, it4), m.find(4));
danzh178723f2019-04-29 09:43:18 -0700246 EXPECT_EQ(2u, m.size());
danzhc3be2d42019-04-25 07:47:41 -0700247
248 // Make sure we can still iterate over everything that's left.
249 SimpleLinkedHashMap<int, int>::iterator it = m.begin();
250 ASSERT_TRUE(it != m.end());
251 EXPECT_EQ(11, it->second);
252 ++it;
253 ASSERT_TRUE(it != m.end());
254 EXPECT_EQ(14, it->second);
255 ++it;
256 ASSERT_TRUE(it == m.end());
257
258 // Erase first one using an iterator.
259 EXPECT_EQ(m.erase(m.begin()), m.find(4));
260
261 // Only the last element should be left.
262 it = m.begin();
263 ASSERT_TRUE(it != m.end());
264 EXPECT_EQ(14, it->second);
265 ++it;
266 ASSERT_TRUE(it == m.end());
267}
268
269TEST(LinkedHashMapTest, Insertion) {
270 SimpleLinkedHashMap<int, int> m;
271 ASSERT_EQ(0u, m.size());
272 std::pair<SimpleLinkedHashMap<int, int>::iterator, bool> result;
273
274 result = m.insert(std::make_pair(2, 12));
275 ASSERT_EQ(1u, m.size());
276 EXPECT_TRUE(result.second);
277 EXPECT_EQ(2, result.first->first);
278 EXPECT_EQ(12, result.first->second);
279
280 result = m.insert(std::make_pair(1, 11));
281 ASSERT_EQ(2u, m.size());
282 EXPECT_TRUE(result.second);
283 EXPECT_EQ(1, result.first->first);
284 EXPECT_EQ(11, result.first->second);
285
286 result = m.insert(std::make_pair(3, 13));
287 SimpleLinkedHashMap<int, int>::iterator result_iterator = result.first;
288 ASSERT_EQ(3u, m.size());
289 EXPECT_TRUE(result.second);
290 EXPECT_EQ(3, result.first->first);
291 EXPECT_EQ(13, result.first->second);
292
293 result = m.insert(std::make_pair(3, 13));
294 EXPECT_EQ(3u, m.size());
295 EXPECT_FALSE(result.second) << "No insertion should have occurred.";
296 EXPECT_TRUE(result_iterator == result.first)
297 << "Duplicate insertion should have given us the original iterator.";
298}
299
300static std::pair<int, int> Pair(int i, int j) {
301 return {i, j};
302}
303
304// Test front accessors.
305TEST(LinkedHashMapTest, Front) {
306 SimpleLinkedHashMap<int, int> m;
307
308 m.insert(std::make_pair(2, 12));
309 m.insert(std::make_pair(1, 11));
310 m.insert(std::make_pair(3, 13));
311
312 EXPECT_EQ(3u, m.size());
313 EXPECT_EQ(Pair(2, 12), m.front());
314 m.pop_front();
315 EXPECT_EQ(2u, m.size());
316 EXPECT_EQ(Pair(1, 11), m.front());
317 m.pop_front();
318 EXPECT_EQ(1u, m.size());
319 EXPECT_EQ(Pair(3, 13), m.front());
320 m.pop_front();
321 EXPECT_TRUE(m.empty());
322}
323
324TEST(LinkedHashMapTest, Find) {
325 SimpleLinkedHashMap<int, int> m;
326
327 EXPECT_TRUE(m.end() == m.find(1))
328 << "We shouldn't find anything in an empty map.";
329
330 m.insert(std::make_pair(2, 12));
331 EXPECT_TRUE(m.end() == m.find(1))
332 << "We shouldn't find an element that doesn't exist in the map.";
333
334 std::pair<SimpleLinkedHashMap<int, int>::iterator, bool> result =
335 m.insert(std::make_pair(1, 11));
336 ASSERT_TRUE(result.second);
337 ASSERT_TRUE(m.end() != result.first);
338 EXPECT_TRUE(result.first == m.find(1))
339 << "We should have found an element we know exists in the map.";
340 EXPECT_EQ(11, result.first->second);
341
342 // Check that a follow-up insertion doesn't affect our original
343 m.insert(std::make_pair(3, 13));
344 SimpleLinkedHashMap<int, int>::iterator it = m.find(1);
345 ASSERT_TRUE(m.end() != it);
346 EXPECT_EQ(11, it->second);
347
348 m.clear();
349 EXPECT_TRUE(m.end() == m.find(1))
350 << "We shouldn't find anything in a map that we've cleared.";
351}
352
353TEST(LinkedHashMapTest, Contains) {
354 SimpleLinkedHashMap<int, int> m;
355
356 EXPECT_FALSE(m.contains(1)) << "An empty map shouldn't contain anything.";
357
358 m.insert(std::make_pair(2, 12));
359 EXPECT_FALSE(m.contains(1))
360 << "The map shouldn't contain an element that doesn't exist.";
361
362 m.insert(std::make_pair(1, 11));
363 EXPECT_TRUE(m.contains(1))
364 << "The map should contain an element that we know exists.";
365
366 m.clear();
367 EXPECT_FALSE(m.contains(1))
368 << "A map that we've cleared shouldn't contain anything.";
369}
370
371TEST(LinkedHashMapTest, Swap) {
372 SimpleLinkedHashMap<int, int> m1;
373 SimpleLinkedHashMap<int, int> m2;
374 m1.insert(std::make_pair(1, 1));
375 m1.insert(std::make_pair(2, 2));
376 m2.insert(std::make_pair(3, 3));
377 ASSERT_EQ(2u, m1.size());
378 ASSERT_EQ(1u, m2.size());
379 m1.swap(m2);
380 ASSERT_EQ(1u, m1.size());
381 ASSERT_EQ(2u, m2.size());
382}
383
384TEST(LinkedHashMapTest, CustomHashAndEquality) {
385 struct CustomIntHash {
386 size_t operator()(int x) const { return x; }
387 };
388 SimpleLinkedHashMap<int, int, CustomIntHash> m;
389 m.insert(std::make_pair(1, 1));
390 EXPECT_TRUE(m.contains(1));
391 EXPECT_EQ(1, m[1]);
392}
393
394} // namespace test
395} // namespace quiche