Extract SIGPIPE ignoring code to a common place.
[chromium-blink-merge.git] / base / id_map_unittest.cc
blob80c4c66986ae7c0b8a3d9a63fa4c4e9790849b9f
1 // Copyright (c) 2011 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/id_map.h"
7 #include "testing/gtest/include/gtest/gtest.h"
9 namespace {
11 class IDMapTest : public testing::Test {
14 class TestObject {
17 class DestructorCounter {
18 public:
19 explicit DestructorCounter(int* counter) : counter_(counter) {}
20 ~DestructorCounter() { ++(*counter_); }
21 private:
22 int* counter_;
25 TEST_F(IDMapTest, Basic) {
26 IDMap<TestObject> map;
27 EXPECT_TRUE(map.IsEmpty());
28 EXPECT_EQ(0U, map.size());
30 TestObject obj1;
31 TestObject obj2;
33 int32 id1 = map.Add(&obj1);
34 EXPECT_FALSE(map.IsEmpty());
35 EXPECT_EQ(1U, map.size());
36 EXPECT_EQ(&obj1, map.Lookup(id1));
38 int32 id2 = map.Add(&obj2);
39 EXPECT_FALSE(map.IsEmpty());
40 EXPECT_EQ(2U, map.size());
42 EXPECT_EQ(&obj1, map.Lookup(id1));
43 EXPECT_EQ(&obj2, map.Lookup(id2));
45 map.Remove(id1);
46 EXPECT_FALSE(map.IsEmpty());
47 EXPECT_EQ(1U, map.size());
49 map.Remove(id2);
50 EXPECT_TRUE(map.IsEmpty());
51 EXPECT_EQ(0U, map.size());
53 map.AddWithID(&obj1, 1);
54 map.AddWithID(&obj2, 2);
55 EXPECT_EQ(&obj1, map.Lookup(1));
56 EXPECT_EQ(&obj2, map.Lookup(2));
58 EXPECT_EQ(0, map.iteration_depth());
61 TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) {
62 IDMap<TestObject> map;
64 TestObject obj1;
65 TestObject obj2;
66 TestObject obj3;
68 map.Add(&obj1);
69 map.Add(&obj2);
70 map.Add(&obj3);
73 IDMap<TestObject>::const_iterator iter(&map);
75 EXPECT_EQ(1, map.iteration_depth());
77 while (!iter.IsAtEnd()) {
78 map.Remove(iter.GetCurrentKey());
79 iter.Advance();
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());
88 EXPECT_TRUE(map.IsEmpty());
89 EXPECT_EQ(0U, map.size());
91 EXPECT_EQ(0, map.iteration_depth());
94 TEST_F(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) {
95 IDMap<TestObject> map;
97 const int kCount = 5;
98 TestObject obj[kCount];
99 int32 ids[kCount];
101 for (int i = 0; i < kCount; i++)
102 ids[i] = map.Add(&obj[i]);
104 int counter = 0;
105 for (IDMap<TestObject>::const_iterator iter(&map);
106 !iter.IsAtEnd(); iter.Advance()) {
107 EXPECT_EQ(1, map.iteration_depth());
109 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;
130 counter++;
133 EXPECT_EQ(0, map.iteration_depth());
136 TEST_F(IDMapTest, CopyIterator) {
137 IDMap<TestObject> map;
139 TestObject obj1;
140 TestObject obj2;
141 TestObject obj3;
143 map.Add(&obj1);
144 map.Add(&obj2);
145 map.Add(&obj3);
147 EXPECT_EQ(0, map.iteration_depth());
150 IDMap<TestObject>::const_iterator iter1(&map);
151 EXPECT_EQ(1, map.iteration_depth());
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());
159 // Make sure after destroying all iterators the map's iteration depth
160 // returns to initial state.
161 EXPECT_EQ(0, map.iteration_depth());
164 TEST_F(IDMapTest, AssignIterator) {
165 IDMap<TestObject> map;
167 TestObject obj1;
168 TestObject obj2;
169 TestObject obj3;
171 map.Add(&obj1);
172 map.Add(&obj2);
173 map.Add(&obj3);
175 EXPECT_EQ(0, map.iteration_depth());
178 IDMap<TestObject>::const_iterator iter1(&map);
179 EXPECT_EQ(1, map.iteration_depth());
181 IDMap<TestObject>::const_iterator iter2(&map);
182 EXPECT_EQ(2, map.iteration_depth());
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());
189 // Make sure after destroying all iterators the map's iteration depth
190 // returns to initial state.
191 EXPECT_EQ(0, map.iteration_depth());
194 TEST_F(IDMapTest, IteratorRemainsValidWhenClearing) {
195 IDMap<TestObject> map;
197 const int kCount = 5;
198 TestObject obj[kCount];
199 int32 ids[kCount];
201 for (int i = 0; i < kCount; i++)
202 ids[i] = map.Add(&obj[i]);
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;
223 counter++;
226 EXPECT_TRUE(map.IsEmpty());
227 EXPECT_EQ(0U, map.size());
230 TEST_F(IDMapTest, OwningPointersDeletesThemOnRemove) {
231 const int kCount = 3;
233 int external_del_count = 0;
234 DestructorCounter* external_obj[kCount];
235 int map_external_ids[kCount];
237 int owned_del_count = 0;
238 DestructorCounter* owned_obj[kCount];
239 int map_owned_ids[kCount];
241 IDMap<DestructorCounter> map_external;
242 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
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]);
248 owned_obj[i] = new DestructorCounter(&owned_del_count);
249 map_owned_ids[i] = map_owned.Add(owned_obj[i]);
252 for (int i = 0; i < kCount; ++i) {
253 EXPECT_EQ(external_del_count, 0);
254 EXPECT_EQ(owned_del_count, i);
256 map_external.Remove(map_external_ids[i]);
257 map_owned.Remove(map_owned_ids[i]);
260 for (int i = 0; i < kCount; ++i) {
261 delete external_obj[i];
264 EXPECT_EQ(external_del_count, kCount);
265 EXPECT_EQ(owned_del_count, kCount);
268 TEST_F(IDMapTest, OwningPointersDeletesThemOnClear) {
269 const int kCount = 3;
271 int external_del_count = 0;
272 DestructorCounter* external_obj[kCount];
274 int owned_del_count = 0;
275 DestructorCounter* owned_obj[kCount];
277 IDMap<DestructorCounter> map_external;
278 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
280 for (int i = 0; i < kCount; ++i) {
281 external_obj[i] = new DestructorCounter(&external_del_count);
282 map_external.Add(external_obj[i]);
284 owned_obj[i] = new DestructorCounter(&owned_del_count);
285 map_owned.Add(owned_obj[i]);
288 EXPECT_EQ(external_del_count, 0);
289 EXPECT_EQ(owned_del_count, 0);
291 map_external.Clear();
292 map_owned.Clear();
294 EXPECT_EQ(external_del_count, 0);
295 EXPECT_EQ(owned_del_count, kCount);
297 for (int i = 0; i < kCount; ++i) {
298 delete external_obj[i];
301 EXPECT_EQ(external_del_count, kCount);
302 EXPECT_EQ(owned_del_count, kCount);
305 TEST_F(IDMapTest, OwningPointersDeletesThemOnDestruct) {
306 const int kCount = 3;
308 int external_del_count = 0;
309 DestructorCounter* external_obj[kCount];
311 int owned_del_count = 0;
312 DestructorCounter* owned_obj[kCount];
315 IDMap<DestructorCounter> map_external;
316 IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
318 for (int i = 0; i < kCount; ++i) {
319 external_obj[i] = new DestructorCounter(&external_del_count);
320 map_external.Add(external_obj[i]);
322 owned_obj[i] = new DestructorCounter(&owned_del_count);
323 map_owned.Add(owned_obj[i]);
327 EXPECT_EQ(external_del_count, 0);
329 for (int i = 0; i < kCount; ++i) {
330 delete external_obj[i];
333 EXPECT_EQ(external_del_count, kCount);
334 EXPECT_EQ(owned_del_count, kCount);
337 } // namespace