1 // Copyright (c) 2009 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 #include "base/id_map.h" 6 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace { 10 11 class IDMapTest : public testing::Test { 12 }; 13 14 class TestObject { 15 }; 16 17 class DestructorCounter { 18 public: 19 explicit DestructorCounter(int* counter) : counter_(counter) {} 20 ~DestructorCounter() { ++(*counter_); } 21 private: 22 int* counter_; 23 }; 24 25 TEST_F(IDMapTest, Basic) { 26 IDMap<TestObject> map; 27 EXPECT_TRUE(map.IsEmpty()); 28 EXPECT_EQ(0U, map.size()); 29 30 TestObject obj1; 31 TestObject obj2; 32 33 int32 id1 = map.Add(&obj1); 34 EXPECT_FALSE(map.IsEmpty()); 35 EXPECT_EQ(1U, map.size()); 36 EXPECT_EQ(&obj1, map.Lookup(id1)); 37 38 int32 id2 = map.Add(&obj2); 39 EXPECT_FALSE(map.IsEmpty()); 40 EXPECT_EQ(2U, map.size()); 41 42 EXPECT_EQ(&obj1, map.Lookup(id1)); 43 EXPECT_EQ(&obj2, map.Lookup(id2)); 44 45 map.Remove(id1); 46 EXPECT_FALSE(map.IsEmpty()); 47 EXPECT_EQ(1U, map.size()); 48 49 map.Remove(id2); 50 EXPECT_TRUE(map.IsEmpty()); 51 EXPECT_EQ(0U, map.size()); 52 53 map.AddWithID(&obj1, 1); 54 map.AddWithID(&obj2, 2); 55 EXPECT_EQ(&obj1, map.Lookup(1)); 56 EXPECT_EQ(&obj2, map.Lookup(2)); 57 } 58 59 TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) { 60 IDMap<TestObject> map; 61 62 TestObject obj1; 63 TestObject obj2; 64 TestObject obj3; 65 66 map.Add(&obj1); 67 map.Add(&obj2); 68 map.Add(&obj3); 69 70 for (IDMap<TestObject>::const_iterator iter(&map); 71 !iter.IsAtEnd(); iter.Advance()) { 72 map.Remove(iter.GetCurrentKey()); 73 } 74 } 75 76 TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) { 77 IDMap<TestObject> map; 78 79 const int kCount = 5; 80 TestObject obj[kCount]; 81 int32 ids[kCount]; 82 83 for (int i = 0; i < kCount; i++) 84 ids[i] = map.Add(&obj[i]); 85 86 int counter = 0; 87 for (IDMap<TestObject>::const_iterator iter(&map); 88 !iter.IsAtEnd(); iter.Advance()) { 89 switch (counter) { 90 case 0: 91 EXPECT_EQ(ids[0], iter.GetCurrentKey()); 92 EXPECT_EQ(&obj[0], iter.GetCurrentValue()); 93 map.Remove(ids[1]); 94 break; 95 case 1: 96 EXPECT_EQ(ids[2], iter.GetCurrentKey()); 97 EXPECT_EQ(&obj[2], iter.GetCurrentValue()); 98 map.Remove(ids[3]); 99 break; 100 case 2: 101 EXPECT_EQ(ids[4], iter.GetCurrentKey()); 102 EXPECT_EQ(&obj[4], iter.GetCurrentValue()); 103 map.Remove(ids[0]); 104 break; 105 default: 106 FAIL() << "should not have that many elements"; 107 break; 108 } 109 110 counter++; 111 } 112 } 113 114 TEST_F(IDMapTest, OwningPointersDeletesThemOnRemove) { 115 const int kCount = 3; 116 117 int external_del_count = 0; 118 DestructorCounter* external_obj[kCount]; 119 int map_external_ids[kCount]; 120 121 int owned_del_count = 0; 122 DestructorCounter* owned_obj[kCount]; 123 int map_owned_ids[kCount]; 124 125 IDMap<DestructorCounter> map_external; 126 IDMap<DestructorCounter, IDMapOwnPointer> map_owned; 127 128 for (int i = 0; i < kCount; ++i) { 129 external_obj[i] = new DestructorCounter(&external_del_count); 130 map_external_ids[i] = map_external.Add(external_obj[i]); 131 132 owned_obj[i] = new DestructorCounter(&owned_del_count); 133 map_owned_ids[i] = map_owned.Add(owned_obj[i]); 134 } 135 136 for (int i = 0; i < kCount; ++i) { 137 EXPECT_EQ(external_del_count, 0); 138 EXPECT_EQ(owned_del_count, i); 139 140 map_external.Remove(map_external_ids[i]); 141 map_owned.Remove(map_owned_ids[i]); 142 } 143 144 for (int i = 0; i < kCount; ++i) { 145 delete external_obj[i]; 146 } 147 148 EXPECT_EQ(external_del_count, kCount); 149 EXPECT_EQ(owned_del_count, kCount); 150 } 151 152 TEST_F(IDMapTest, OwningPointersDeletesThemOnDestruct) { 153 const int kCount = 3; 154 155 int external_del_count = 0; 156 DestructorCounter* external_obj[kCount]; 157 int map_external_ids[kCount]; 158 159 int owned_del_count = 0; 160 DestructorCounter* owned_obj[kCount]; 161 int map_owned_ids[kCount]; 162 163 { 164 IDMap<DestructorCounter> map_external; 165 IDMap<DestructorCounter, IDMapOwnPointer> map_owned; 166 167 for (int i = 0; i < kCount; ++i) { 168 external_obj[i] = new DestructorCounter(&external_del_count); 169 map_external_ids[i] = map_external.Add(external_obj[i]); 170 171 owned_obj[i] = new DestructorCounter(&owned_del_count); 172 map_owned_ids[i] = map_owned.Add(owned_obj[i]); 173 } 174 } 175 176 EXPECT_EQ(external_del_count, 0); 177 178 for (int i = 0; i < kCount; ++i) { 179 delete external_obj[i]; 180 } 181 182 EXPECT_EQ(external_del_count, kCount); 183 EXPECT_EQ(owned_del_count, kCount); 184 } 185 186 } // namespace 187