Simple Cache: a few tests for rare corner cases with CRC check missing.
[chromium-blink-merge.git] / base / containers / small_map_unittest.cc
blobc90a3030041bdb8358b49dddb637b83b1214034e
1 // Copyright (c) 2012 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.
5 #include "base/containers/small_map.h"
7 #include <stddef.h>
9 #include <algorithm>
10 #include <functional>
11 #include <map>
13 #include "base/logging.h"
14 #include "base/hash_tables.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace base {
19 TEST(SmallMap, General) {
20 SmallMap<hash_map<int, int> > m;
22 EXPECT_TRUE(m.empty());
24 m[0] = 5;
26 EXPECT_FALSE(m.empty());
27 EXPECT_EQ(m.size(), 1u);
29 m[9] = 2;
31 EXPECT_FALSE(m.empty());
32 EXPECT_EQ(m.size(), 2u);
34 EXPECT_EQ(m[9], 2);
35 EXPECT_EQ(m[0], 5);
36 EXPECT_FALSE(m.UsingFullMap());
38 SmallMap<hash_map<int, int> >::iterator iter(m.begin());
39 ASSERT_TRUE(iter != m.end());
40 EXPECT_EQ(iter->first, 0);
41 EXPECT_EQ(iter->second, 5);
42 ++iter;
43 ASSERT_TRUE(iter != m.end());
44 EXPECT_EQ((*iter).first, 9);
45 EXPECT_EQ((*iter).second, 2);
46 ++iter;
47 EXPECT_TRUE(iter == m.end());
49 m[8] = 23;
50 m[1234] = 90;
51 m[-5] = 6;
53 EXPECT_EQ(m[ 9], 2);
54 EXPECT_EQ(m[ 0], 5);
55 EXPECT_EQ(m[1234], 90);
56 EXPECT_EQ(m[ 8], 23);
57 EXPECT_EQ(m[ -5], 6);
58 EXPECT_EQ(m.size(), 5u);
59 EXPECT_FALSE(m.empty());
60 EXPECT_TRUE(m.UsingFullMap());
62 iter = m.begin();
63 for (int i = 0; i < 5; i++) {
64 EXPECT_TRUE(iter != m.end());
65 ++iter;
67 EXPECT_TRUE(iter == m.end());
69 const SmallMap<hash_map<int, int> >& ref = m;
70 EXPECT_TRUE(ref.find(1234) != m.end());
71 EXPECT_TRUE(ref.find(5678) == m.end());
74 TEST(SmallMap, PostFixIteratorIncrement) {
75 SmallMap<hash_map<int, int> > m;
76 m[0] = 5;
77 m[2] = 3;
80 SmallMap<hash_map<int, int> >::iterator iter(m.begin());
81 SmallMap<hash_map<int, int> >::iterator last(iter++);
82 ++last;
83 EXPECT_TRUE(last == iter);
87 SmallMap<hash_map<int, int> >::const_iterator iter(m.begin());
88 SmallMap<hash_map<int, int> >::const_iterator last(iter++);
89 ++last;
90 EXPECT_TRUE(last == iter);
94 // Based on the General testcase.
95 TEST(SmallMap, CopyConstructor) {
96 SmallMap<hash_map<int, int> > src;
99 SmallMap<hash_map<int, int> > m(src);
100 EXPECT_TRUE(m.empty());
103 src[0] = 5;
106 SmallMap<hash_map<int, int> > m(src);
107 EXPECT_FALSE(m.empty());
108 EXPECT_EQ(m.size(), 1u);
111 src[9] = 2;
114 SmallMap<hash_map<int, int> > m(src);
115 EXPECT_FALSE(m.empty());
116 EXPECT_EQ(m.size(), 2u);
118 EXPECT_EQ(m[9], 2);
119 EXPECT_EQ(m[0], 5);
120 EXPECT_FALSE(m.UsingFullMap());
123 src[8] = 23;
124 src[1234] = 90;
125 src[-5] = 6;
128 SmallMap<hash_map<int, int> > m(src);
129 EXPECT_EQ(m[ 9], 2);
130 EXPECT_EQ(m[ 0], 5);
131 EXPECT_EQ(m[1234], 90);
132 EXPECT_EQ(m[ 8], 23);
133 EXPECT_EQ(m[ -5], 6);
134 EXPECT_EQ(m.size(), 5u);
135 EXPECT_FALSE(m.empty());
136 EXPECT_TRUE(m.UsingFullMap());
140 template<class inner>
141 static void SmallMapToMap(SmallMap<inner> const& src, inner* dest) {
142 typename SmallMap<inner>::const_iterator it;
143 for (it = src.begin(); it != src.end(); ++it) {
144 dest->insert(std::make_pair(it->first, it->second));
148 template<class inner>
149 static bool SmallMapEqual(SmallMap<inner> const& a,
150 SmallMap<inner> const& b) {
151 inner ia, ib;
152 SmallMapToMap(a, &ia);
153 SmallMapToMap(b, &ib);
155 // On most systems we can use operator== here, but under some lesser STL
156 // implementations it doesn't seem to work. So we manually compare.
157 if (ia.size() != ib.size())
158 return false;
159 for (typename inner::iterator ia_it = ia.begin(), ib_it = ib.begin();
160 ia_it != ia.end(); ++ia_it, ++ib_it) {
161 if (*ia_it != *ib_it)
162 return false;
164 return true;
167 TEST(SmallMap, AssignmentOperator) {
168 SmallMap<hash_map<int, int> > src_small;
169 SmallMap<hash_map<int, int> > src_large;
171 src_small[1] = 20;
172 src_small[2] = 21;
173 src_small[3] = 22;
174 EXPECT_FALSE(src_small.UsingFullMap());
176 src_large[1] = 20;
177 src_large[2] = 21;
178 src_large[3] = 22;
179 src_large[5] = 23;
180 src_large[6] = 24;
181 src_large[7] = 25;
182 EXPECT_TRUE(src_large.UsingFullMap());
184 // Assignments to empty.
185 SmallMap<hash_map<int, int> > dest_small;
186 dest_small = src_small;
187 EXPECT_TRUE(SmallMapEqual(dest_small, src_small));
188 EXPECT_EQ(dest_small.UsingFullMap(),
189 src_small.UsingFullMap());
191 SmallMap<hash_map<int, int> > dest_large;
192 dest_large = src_large;
193 EXPECT_TRUE(SmallMapEqual(dest_large, src_large));
194 EXPECT_EQ(dest_large.UsingFullMap(),
195 src_large.UsingFullMap());
197 // Assignments which assign from full to small, and vice versa.
198 dest_small = src_large;
199 EXPECT_TRUE(SmallMapEqual(dest_small, src_large));
200 EXPECT_EQ(dest_small.UsingFullMap(),
201 src_large.UsingFullMap());
203 dest_large = src_small;
204 EXPECT_TRUE(SmallMapEqual(dest_large, src_small));
205 EXPECT_EQ(dest_large.UsingFullMap(),
206 src_small.UsingFullMap());
208 // Double check that SmallMapEqual works:
209 dest_large[42] = 666;
210 EXPECT_FALSE(SmallMapEqual(dest_large, src_small));
213 TEST(SmallMap, Insert) {
214 SmallMap<hash_map<int, int> > sm;
216 // loop through the transition from small map to map.
217 for (int i = 1; i <= 10; ++i) {
218 VLOG(1) << "Iteration " << i;
219 // insert an element
220 std::pair<SmallMap<hash_map<int, int> >::iterator,
221 bool> ret;
222 ret = sm.insert(std::make_pair(i, 100*i));
223 EXPECT_TRUE(ret.second);
224 EXPECT_TRUE(ret.first == sm.find(i));
225 EXPECT_EQ(ret.first->first, i);
226 EXPECT_EQ(ret.first->second, 100*i);
228 // try to insert it again with different value, fails, but we still get an
229 // iterator back with the original value.
230 ret = sm.insert(std::make_pair(i, -i));
231 EXPECT_FALSE(ret.second);
232 EXPECT_TRUE(ret.first == sm.find(i));
233 EXPECT_EQ(ret.first->first, i);
234 EXPECT_EQ(ret.first->second, 100*i);
236 // check the state of the map.
237 for (int j = 1; j <= i; ++j) {
238 SmallMap<hash_map<int, int> >::iterator it = sm.find(j);
239 EXPECT_TRUE(it != sm.end());
240 EXPECT_EQ(it->first, j);
241 EXPECT_EQ(it->second, j * 100);
243 EXPECT_EQ(sm.size(), static_cast<size_t>(i));
244 EXPECT_FALSE(sm.empty());
248 TEST(SmallMap, InsertRange) {
249 // loop through the transition from small map to map.
250 for (int elements = 0; elements <= 10; ++elements) {
251 VLOG(1) << "Elements " << elements;
252 hash_map<int, int> normal_map;
253 for (int i = 1; i <= elements; ++i) {
254 normal_map.insert(std::make_pair(i, 100*i));
257 SmallMap<hash_map<int, int> > sm;
258 sm.insert(normal_map.begin(), normal_map.end());
259 EXPECT_EQ(normal_map.size(), sm.size());
260 for (int i = 1; i <= elements; ++i) {
261 VLOG(1) << "Iteration " << i;
262 EXPECT_TRUE(sm.find(i) != sm.end());
263 EXPECT_EQ(sm.find(i)->first, i);
264 EXPECT_EQ(sm.find(i)->second, 100*i);
269 TEST(SmallMap, Erase) {
270 SmallMap<hash_map<std::string, int> > m;
271 SmallMap<hash_map<std::string, int> >::iterator iter;
273 m["monday"] = 1;
274 m["tuesday"] = 2;
275 m["wednesday"] = 3;
277 EXPECT_EQ(m["monday" ], 1);
278 EXPECT_EQ(m["tuesday" ], 2);
279 EXPECT_EQ(m["wednesday"], 3);
280 EXPECT_EQ(m.count("tuesday"), 1u);
281 EXPECT_FALSE(m.UsingFullMap());
283 iter = m.begin();
284 ASSERT_TRUE(iter != m.end());
285 EXPECT_EQ(iter->first, "monday");
286 EXPECT_EQ(iter->second, 1);
287 ++iter;
288 ASSERT_TRUE(iter != m.end());
289 EXPECT_EQ(iter->first, "tuesday");
290 EXPECT_EQ(iter->second, 2);
291 ++iter;
292 ASSERT_TRUE(iter != m.end());
293 EXPECT_EQ(iter->first, "wednesday");
294 EXPECT_EQ(iter->second, 3);
295 ++iter;
296 EXPECT_TRUE(iter == m.end());
298 EXPECT_EQ(m.erase("tuesday"), 1u);
300 EXPECT_EQ(m["monday" ], 1);
301 EXPECT_EQ(m["wednesday"], 3);
302 EXPECT_EQ(m.count("tuesday"), 0u);
303 EXPECT_EQ(m.erase("tuesday"), 0u);
305 iter = m.begin();
306 ASSERT_TRUE(iter != m.end());
307 EXPECT_EQ(iter->first, "monday");
308 EXPECT_EQ(iter->second, 1);
309 ++iter;
310 ASSERT_TRUE(iter != m.end());
311 EXPECT_EQ(iter->first, "wednesday");
312 EXPECT_EQ(iter->second, 3);
313 ++iter;
314 EXPECT_TRUE(iter == m.end());
316 m["thursday"] = 4;
317 m["friday"] = 5;
318 EXPECT_EQ(m.size(), 4u);
319 EXPECT_FALSE(m.empty());
320 EXPECT_FALSE(m.UsingFullMap());
322 m["saturday"] = 6;
323 EXPECT_TRUE(m.UsingFullMap());
325 EXPECT_EQ(m.count("friday"), 1u);
326 EXPECT_EQ(m.erase("friday"), 1u);
327 EXPECT_TRUE(m.UsingFullMap());
328 EXPECT_EQ(m.count("friday"), 0u);
329 EXPECT_EQ(m.erase("friday"), 0u);
331 EXPECT_EQ(m.size(), 4u);
332 EXPECT_FALSE(m.empty());
333 EXPECT_EQ(m.erase("monday"), 1u);
334 EXPECT_EQ(m.size(), 3u);
335 EXPECT_FALSE(m.empty());
337 m.clear();
338 EXPECT_FALSE(m.UsingFullMap());
339 EXPECT_EQ(m.size(), 0u);
340 EXPECT_TRUE(m.empty());
343 TEST(SmallMap, NonHashMap) {
344 SmallMap<std::map<int, int>, 4, std::equal_to<int> > m;
345 EXPECT_TRUE(m.empty());
347 m[9] = 2;
348 m[0] = 5;
350 EXPECT_EQ(m[9], 2);
351 EXPECT_EQ(m[0], 5);
352 EXPECT_EQ(m.size(), 2u);
353 EXPECT_FALSE(m.empty());
354 EXPECT_FALSE(m.UsingFullMap());
356 SmallMap<std::map<int, int>, 4, std::equal_to<int> >::iterator iter(
357 m.begin());
358 ASSERT_TRUE(iter != m.end());
359 EXPECT_EQ(iter->first, 9);
360 EXPECT_EQ(iter->second, 2);
361 ++iter;
362 ASSERT_TRUE(iter != m.end());
363 EXPECT_EQ(iter->first, 0);
364 EXPECT_EQ(iter->second, 5);
365 ++iter;
366 EXPECT_TRUE(iter == m.end());
367 --iter;
368 ASSERT_TRUE(iter != m.end());
369 EXPECT_EQ(iter->first, 0);
370 EXPECT_EQ(iter->second, 5);
372 m[8] = 23;
373 m[1234] = 90;
374 m[-5] = 6;
376 EXPECT_EQ(m[ 9], 2);
377 EXPECT_EQ(m[ 0], 5);
378 EXPECT_EQ(m[1234], 90);
379 EXPECT_EQ(m[ 8], 23);
380 EXPECT_EQ(m[ -5], 6);
381 EXPECT_EQ(m.size(), 5u);
382 EXPECT_FALSE(m.empty());
383 EXPECT_TRUE(m.UsingFullMap());
385 iter = m.begin();
386 ASSERT_TRUE(iter != m.end());
387 EXPECT_EQ(iter->first, -5);
388 EXPECT_EQ(iter->second, 6);
389 ++iter;
390 ASSERT_TRUE(iter != m.end());
391 EXPECT_EQ(iter->first, 0);
392 EXPECT_EQ(iter->second, 5);
393 ++iter;
394 ASSERT_TRUE(iter != m.end());
395 EXPECT_EQ(iter->first, 8);
396 EXPECT_EQ(iter->second, 23);
397 ++iter;
398 ASSERT_TRUE(iter != m.end());
399 EXPECT_EQ(iter->first, 9);
400 EXPECT_EQ(iter->second, 2);
401 ++iter;
402 ASSERT_TRUE(iter != m.end());
403 EXPECT_EQ(iter->first, 1234);
404 EXPECT_EQ(iter->second, 90);
405 ++iter;
406 EXPECT_TRUE(iter == m.end());
407 --iter;
408 ASSERT_TRUE(iter != m.end());
409 EXPECT_EQ(iter->first, 1234);
410 EXPECT_EQ(iter->second, 90);
413 TEST(SmallMap, DefaultEqualKeyWorks) {
414 // If these tests compile, they pass. The EXPECT calls are only there to avoid
415 // unused variable warnings.
416 SmallMap<hash_map<int, int> > hm;
417 EXPECT_EQ(0u, hm.size());
418 SmallMap<std::map<int, int> > m;
419 EXPECT_EQ(0u, m.size());
422 namespace {
424 class hash_map_add_item : public hash_map<int, int> {
425 public:
426 hash_map_add_item() : hash_map<int, int>() {}
427 explicit hash_map_add_item(const std::pair<int, int>& item)
428 : hash_map<int, int>() {
429 insert(item);
433 void InitMap(ManualConstructor<hash_map_add_item>* map_ctor) {
434 map_ctor->Init(std::make_pair(0, 0));
437 class hash_map_add_item_initializer {
438 public:
439 explicit hash_map_add_item_initializer(int item_to_add)
440 : item_(item_to_add) {}
441 hash_map_add_item_initializer()
442 : item_(0) {}
443 void operator()(ManualConstructor<hash_map_add_item>* map_ctor) const {
444 map_ctor->Init(std::make_pair(item_, item_));
447 int item_;
450 } // anonymous namespace
452 TEST(SmallMap, SubclassInitializationWithFunctionPointer) {
453 SmallMap<hash_map_add_item, 4, std::equal_to<int>,
454 void (&)(ManualConstructor<hash_map_add_item>*)> m(InitMap);
456 EXPECT_TRUE(m.empty());
458 m[1] = 1;
459 m[2] = 2;
460 m[3] = 3;
461 m[4] = 4;
463 EXPECT_EQ(4u, m.size());
464 EXPECT_EQ(0u, m.count(0));
466 m[5] = 5;
467 EXPECT_EQ(6u, m.size());
468 // Our function adds an extra item when we convert to a map.
469 EXPECT_EQ(1u, m.count(0));
472 TEST(SmallMap, SubclassInitializationWithFunctionObject) {
473 SmallMap<hash_map_add_item, 4, std::equal_to<int>,
474 hash_map_add_item_initializer> m(hash_map_add_item_initializer(-1));
476 EXPECT_TRUE(m.empty());
478 m[1] = 1;
479 m[2] = 2;
480 m[3] = 3;
481 m[4] = 4;
483 EXPECT_EQ(4u, m.size());
484 EXPECT_EQ(0u, m.count(-1));
486 m[5] = 5;
487 EXPECT_EQ(6u, m.size());
488 // Our functor adds an extra item when we convert to a map.
489 EXPECT_EQ(1u, m.count(-1));
492 } // namespace base