blob: 80c4c66986ae7c0b8a3d9a63fa4c4e9790849b9f [file] [log] [blame]
[email protected]9f7785d2011-06-25 04:33:181// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]9de09f82009-08-17 20:13:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]925d5d602009-08-19 14:56:385#include "base/id_map.h"
[email protected]9de09f82009-08-17 20:13:536
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace {
10
11class IDMapTest : public testing::Test {
12};
13
14class TestObject {
15};
16
[email protected]9e7e0e02010-01-25 23:25:1617class DestructorCounter {
18 public:
19 explicit DestructorCounter(int* counter) : counter_(counter) {}
20 ~DestructorCounter() { ++(*counter_); }
21 private:
22 int* counter_;
23};
24
[email protected]9de09f82009-08-17 20:13:5325TEST_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));
[email protected]0c8b8942012-10-27 01:03:0157
58 EXPECT_EQ(0, map.iteration_depth());
[email protected]9de09f82009-08-17 20:13:5359}
60
61TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) {
62 IDMap<TestObject> map;
63
64 TestObject obj1;
65 TestObject obj2;
66 TestObject obj3;
67
68 map.Add(&obj1);
69 map.Add(&obj2);
70 map.Add(&obj3);
71
[email protected]2de069e2010-02-16 09:15:3872 {
73 IDMap<TestObject>::const_iterator iter(&map);
[email protected]0c8b8942012-10-27 01:03:0174
75 EXPECT_EQ(1, map.iteration_depth());
76
[email protected]2de069e2010-02-16 09:15:3877 while (!iter.IsAtEnd()) {
78 map.Remove(iter.GetCurrentKey());
79 iter.Advance();
80 }
81
82 // Test that while an iterator is still in scope, we get the map emptiness
83 // right (http://crbug.com/35571).
84 EXPECT_TRUE(map.IsEmpty());
85 EXPECT_EQ(0U, map.size());
[email protected]9de09f82009-08-17 20:13:5386 }
[email protected]2de069e2010-02-16 09:15:3887
88 EXPECT_TRUE(map.IsEmpty());
89 EXPECT_EQ(0U, map.size());
[email protected]0c8b8942012-10-27 01:03:0190
91 EXPECT_EQ(0, map.iteration_depth());
[email protected]9de09f82009-08-17 20:13:5392}
93
94TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) {
95 IDMap<TestObject> map;
96
97 const int kCount = 5;
98 TestObject obj[kCount];
99 int32 ids[kCount];
100
101 for (int i = 0; i < kCount; i++)
102 ids[i] = map.Add(&obj[i]);
103
104 int counter = 0;
105 for (IDMap<TestObject>::const_iterator iter(&map);
106 !iter.IsAtEnd(); iter.Advance()) {
[email protected]0c8b8942012-10-27 01:03:01107 EXPECT_EQ(1, map.iteration_depth());
108
[email protected]9de09f82009-08-17 20:13:53109 switch (counter) {
110 case 0:
111 EXPECT_EQ(ids[0], iter.GetCurrentKey());
112 EXPECT_EQ(&obj[0], iter.GetCurrentValue());
113 map.Remove(ids[1]);
114 break;
115 case 1:
116 EXPECT_EQ(ids[2], iter.GetCurrentKey());
117 EXPECT_EQ(&obj[2], iter.GetCurrentValue());
118 map.Remove(ids[3]);
119 break;
120 case 2:
121 EXPECT_EQ(ids[4], iter.GetCurrentKey());
122 EXPECT_EQ(&obj[4], iter.GetCurrentValue());
123 map.Remove(ids[0]);
124 break;
125 default:
126 FAIL() << "should not have that many elements";
127 break;
128 }
129
130 counter++;
131 }
[email protected]0c8b8942012-10-27 01:03:01132
133 EXPECT_EQ(0, map.iteration_depth());
134}
135
136TEST_F(IDMapTest, CopyIterator) {
137 IDMap<TestObject> map;
138
139 TestObject obj1;
140 TestObject obj2;
141 TestObject obj3;
142
143 map.Add(&obj1);
144 map.Add(&obj2);
145 map.Add(&obj3);
146
147 EXPECT_EQ(0, map.iteration_depth());
148
149 {
150 IDMap<TestObject>::const_iterator iter1(&map);
151 EXPECT_EQ(1, map.iteration_depth());
152
153 // Make sure that copying the iterator correctly increments
154 // map's iteration depth.
155 IDMap<TestObject>::const_iterator iter2(iter1);
156 EXPECT_EQ(2, map.iteration_depth());
157 }
158
159 // Make sure after destroying all iterators the map's iteration depth
160 // returns to initial state.
161 EXPECT_EQ(0, map.iteration_depth());
162}
163
164TEST_F(IDMapTest, AssignIterator) {
165 IDMap<TestObject> map;
166
167 TestObject obj1;
168 TestObject obj2;
169 TestObject obj3;
170
171 map.Add(&obj1);
172 map.Add(&obj2);
173 map.Add(&obj3);
174
175 EXPECT_EQ(0, map.iteration_depth());
176
177 {
178 IDMap<TestObject>::const_iterator iter1(&map);
179 EXPECT_EQ(1, map.iteration_depth());
180
181 IDMap<TestObject>::const_iterator iter2(&map);
182 EXPECT_EQ(2, map.iteration_depth());
183
184 // Make sure that assigning the iterator correctly updates
185 // map's iteration depth (-1 for destruction, +1 for assignment).
186 EXPECT_EQ(2, map.iteration_depth());
187 }
188
189 // Make sure after destroying all iterators the map's iteration depth
190 // returns to initial state.
191 EXPECT_EQ(0, map.iteration_depth());
[email protected]9de09f82009-08-17 20:13:53192}
193
[email protected]fea0b9612012-10-29 21:36:22194TEST_F(IDMapTest, IteratorRemainsValidWhenClearing) {
195 IDMap<TestObject> map;
196
197 const int kCount = 5;
198 TestObject obj[kCount];
199 int32 ids[kCount];
200
201 for (int i = 0; i < kCount; i++)
202 ids[i] = map.Add(&obj[i]);
203
204 int counter = 0;
205 for (IDMap<TestObject>::const_iterator iter(&map);
206 !iter.IsAtEnd(); iter.Advance()) {
207 switch (counter) {
208 case 0:
209 EXPECT_EQ(ids[0], iter.GetCurrentKey());
210 EXPECT_EQ(&obj[0], iter.GetCurrentValue());
211 break;
212 case 1:
213 EXPECT_EQ(ids[1], iter.GetCurrentKey());
214 EXPECT_EQ(&obj[1], iter.GetCurrentValue());
215 map.Clear();
216 EXPECT_TRUE(map.IsEmpty());
217 EXPECT_EQ(0U, map.size());
218 break;
219 default:
220 FAIL() << "should not have that many elements";
221 break;
222 }
223 counter++;
224 }
225
226 EXPECT_TRUE(map.IsEmpty());
227 EXPECT_EQ(0U, map.size());
228}
229
[email protected]9e7e0e02010-01-25 23:25:16230TEST_F(IDMapTest, OwningPointersDeletesThemOnRemove) {
231 const int kCount = 3;
232
233 int external_del_count = 0;
234 DestructorCounter* external_obj[kCount];
235 int map_external_ids[kCount];
236
237 int owned_del_count = 0;
238 DestructorCounter* owned_obj[kCount];
239 int map_owned_ids[kCount];
240
241 IDMap<DestructorCounter> map_external;
242 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
243
244 for (int i = 0; i < kCount; ++i) {
245 external_obj[i] = new DestructorCounter(&external_del_count);
246 map_external_ids[i] = map_external.Add(external_obj[i]);
247
248 owned_obj[i] = new DestructorCounter(&owned_del_count);
249 map_owned_ids[i] = map_owned.Add(owned_obj[i]);
250 }
251
252 for (int i = 0; i < kCount; ++i) {
253 EXPECT_EQ(external_del_count, 0);
254 EXPECT_EQ(owned_del_count, i);
255
256 map_external.Remove(map_external_ids[i]);
257 map_owned.Remove(map_owned_ids[i]);
258 }
259
260 for (int i = 0; i < kCount; ++i) {
261 delete external_obj[i];
262 }
263
264 EXPECT_EQ(external_del_count, kCount);
265 EXPECT_EQ(owned_del_count, kCount);
266}
267
[email protected]fea0b9612012-10-29 21:36:22268TEST_F(IDMapTest, OwningPointersDeletesThemOnClear) {
269 const int kCount = 3;
270
271 int external_del_count = 0;
272 DestructorCounter* external_obj[kCount];
273
274 int owned_del_count = 0;
275 DestructorCounter* owned_obj[kCount];
276
277 IDMap<DestructorCounter> map_external;
278 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
279
280 for (int i = 0; i < kCount; ++i) {
281 external_obj[i] = new DestructorCounter(&external_del_count);
282 map_external.Add(external_obj[i]);
283
284 owned_obj[i] = new DestructorCounter(&owned_del_count);
285 map_owned.Add(owned_obj[i]);
286 }
287
288 EXPECT_EQ(external_del_count, 0);
289 EXPECT_EQ(owned_del_count, 0);
290
291 map_external.Clear();
292 map_owned.Clear();
293
294 EXPECT_EQ(external_del_count, 0);
295 EXPECT_EQ(owned_del_count, kCount);
296
297 for (int i = 0; i < kCount; ++i) {
298 delete external_obj[i];
299 }
300
301 EXPECT_EQ(external_del_count, kCount);
302 EXPECT_EQ(owned_del_count, kCount);
303}
304
[email protected]9e7e0e02010-01-25 23:25:16305TEST_F(IDMapTest, OwningPointersDeletesThemOnDestruct) {
306 const int kCount = 3;
307
308 int external_del_count = 0;
309 DestructorCounter* external_obj[kCount];
[email protected]9e7e0e02010-01-25 23:25:16310
311 int owned_del_count = 0;
312 DestructorCounter* owned_obj[kCount];
[email protected]9e7e0e02010-01-25 23:25:16313
314 {
315 IDMap<DestructorCounter> map_external;
316 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
317
318 for (int i = 0; i < kCount; ++i) {
319 external_obj[i] = new DestructorCounter(&external_del_count);
[email protected]9f7785d2011-06-25 04:33:18320 map_external.Add(external_obj[i]);
[email protected]9e7e0e02010-01-25 23:25:16321
322 owned_obj[i] = new DestructorCounter(&owned_del_count);
[email protected]9f7785d2011-06-25 04:33:18323 map_owned.Add(owned_obj[i]);
[email protected]9e7e0e02010-01-25 23:25:16324 }
325 }
326
327 EXPECT_EQ(external_del_count, 0);
328
329 for (int i = 0; i < kCount; ++i) {
330 delete external_obj[i];
331 }
332
333 EXPECT_EQ(external_del_count, kCount);
334 EXPECT_EQ(owned_del_count, kCount);
335}
336
[email protected]9de09f82009-08-17 20:13:53337} // namespace