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.
5 #include "base/id_map.h"
7 #include "testing/gtest/include/gtest/gtest.h"
11 class IDMapTest
: public testing::Test
{
17 class DestructorCounter
{
19 explicit DestructorCounter(int* counter
) : counter_(counter
) {}
20 ~DestructorCounter() { ++(*counter_
); }
25 TEST_F(IDMapTest
, Basic
) {
26 IDMap
<TestObject
> map
;
27 EXPECT_TRUE(map
.IsEmpty());
28 EXPECT_EQ(0U, map
.size());
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
));
46 EXPECT_FALSE(map
.IsEmpty());
47 EXPECT_EQ(1U, map
.size());
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));
59 TEST_F(IDMapTest
, IteratorRemainsValidWhenRemovingCurrentElement
) {
60 IDMap
<TestObject
> map
;
71 IDMap
<TestObject
>::const_iterator
iter(&map
);
72 while (!iter
.IsAtEnd()) {
73 map
.Remove(iter
.GetCurrentKey());
77 // Test that while an iterator is still in scope, we get the map emptiness
78 // right (http://crbug.com/35571).
79 EXPECT_TRUE(map
.IsEmpty());
80 EXPECT_EQ(0U, map
.size());
83 EXPECT_TRUE(map
.IsEmpty());
84 EXPECT_EQ(0U, map
.size());
87 TEST_F(IDMapTest
, IteratorRemainsValidWhenRemovingOtherElements
) {
88 IDMap
<TestObject
> map
;
91 TestObject obj
[kCount
];
94 for (int i
= 0; i
< kCount
; i
++)
95 ids
[i
] = map
.Add(&obj
[i
]);
98 for (IDMap
<TestObject
>::const_iterator
iter(&map
);
99 !iter
.IsAtEnd(); iter
.Advance()) {
102 EXPECT_EQ(ids
[0], iter
.GetCurrentKey());
103 EXPECT_EQ(&obj
[0], iter
.GetCurrentValue());
107 EXPECT_EQ(ids
[2], iter
.GetCurrentKey());
108 EXPECT_EQ(&obj
[2], iter
.GetCurrentValue());
112 EXPECT_EQ(ids
[4], iter
.GetCurrentKey());
113 EXPECT_EQ(&obj
[4], iter
.GetCurrentValue());
117 FAIL() << "should not have that many elements";
125 TEST_F(IDMapTest
, OwningPointersDeletesThemOnRemove
) {
126 const int kCount
= 3;
128 int external_del_count
= 0;
129 DestructorCounter
* external_obj
[kCount
];
130 int map_external_ids
[kCount
];
132 int owned_del_count
= 0;
133 DestructorCounter
* owned_obj
[kCount
];
134 int map_owned_ids
[kCount
];
136 IDMap
<DestructorCounter
> map_external
;
137 IDMap
<DestructorCounter
, IDMapOwnPointer
> map_owned
;
139 for (int i
= 0; i
< kCount
; ++i
) {
140 external_obj
[i
] = new DestructorCounter(&external_del_count
);
141 map_external_ids
[i
] = map_external
.Add(external_obj
[i
]);
143 owned_obj
[i
] = new DestructorCounter(&owned_del_count
);
144 map_owned_ids
[i
] = map_owned
.Add(owned_obj
[i
]);
147 for (int i
= 0; i
< kCount
; ++i
) {
148 EXPECT_EQ(external_del_count
, 0);
149 EXPECT_EQ(owned_del_count
, i
);
151 map_external
.Remove(map_external_ids
[i
]);
152 map_owned
.Remove(map_owned_ids
[i
]);
155 for (int i
= 0; i
< kCount
; ++i
) {
156 delete external_obj
[i
];
159 EXPECT_EQ(external_del_count
, kCount
);
160 EXPECT_EQ(owned_del_count
, kCount
);
163 TEST_F(IDMapTest
, OwningPointersDeletesThemOnDestruct
) {
164 const int kCount
= 3;
166 int external_del_count
= 0;
167 DestructorCounter
* external_obj
[kCount
];
168 int map_external_ids
[kCount
];
170 int owned_del_count
= 0;
171 DestructorCounter
* owned_obj
[kCount
];
172 int map_owned_ids
[kCount
];
175 IDMap
<DestructorCounter
> map_external
;
176 IDMap
<DestructorCounter
, IDMapOwnPointer
> map_owned
;
178 for (int i
= 0; i
< kCount
; ++i
) {
179 external_obj
[i
] = new DestructorCounter(&external_del_count
);
180 map_external_ids
[i
] = map_external
.Add(external_obj
[i
]);
182 owned_obj
[i
] = new DestructorCounter(&owned_del_count
);
183 map_owned_ids
[i
] = map_owned
.Add(owned_obj
[i
]);
187 EXPECT_EQ(external_del_count
, 0);
189 for (int i
= 0; i
< kCount
; ++i
) {
190 delete external_obj
[i
];
193 EXPECT_EQ(external_del_count
, kCount
);
194 EXPECT_EQ(owned_del_count
, kCount
);