1 // Copyright 2015 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/scoped_ptr_map.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "testing/gtest/include/gtest/gtest.h"
19 // A ScopedDestroyer sets a Boolean to true upon destruction.
20 class ScopedDestroyer
{
22 ScopedDestroyer(bool* destroyed
) : destroyed_(destroyed
) {
26 ~ScopedDestroyer() { *destroyed_
= true; }
32 TEST(ScopedPtrMapTest
, Insert
) {
33 bool destroyed1
= false;
34 bool destroyed2
= false;
36 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
39 ScopedDestroyer
* elem1
= new ScopedDestroyer(&destroyed1
);
40 EXPECT_FALSE(destroyed1
);
41 EXPECT_TRUE(scoped_map
.insert(0, make_scoped_ptr(elem1
)).second
);
42 EXPECT_EQ(elem1
, scoped_map
.find(0)->second
);
43 EXPECT_FALSE(destroyed1
);
45 // Insert to existing key.
46 ScopedDestroyer
* elem2
= new ScopedDestroyer(&destroyed2
);
47 EXPECT_FALSE(destroyed2
);
48 EXPECT_FALSE(scoped_map
.insert(0, make_scoped_ptr(elem2
)).second
);
49 EXPECT_EQ(elem1
, scoped_map
.find(0)->second
);
51 EXPECT_FALSE(destroyed1
);
52 EXPECT_TRUE(destroyed2
);
54 EXPECT_TRUE(destroyed1
);
57 TEST(ScopedPtrMapTest
, Set
) {
58 bool destroyed1
= false;
59 bool destroyed2
= false;
61 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
64 ScopedDestroyer
* elem1
= new ScopedDestroyer(&destroyed1
);
65 EXPECT_FALSE(destroyed1
);
66 scoped_map
.set(0, make_scoped_ptr(elem1
));
67 EXPECT_EQ(elem1
, scoped_map
.find(0)->second
);
68 EXPECT_FALSE(destroyed1
);
70 // Set to replace an existing key.
71 ScopedDestroyer
* elem2
= new ScopedDestroyer(&destroyed2
);
72 EXPECT_FALSE(destroyed2
);
73 scoped_map
.set(0, make_scoped_ptr(elem2
));
74 EXPECT_EQ(elem2
, scoped_map
.find(0)->second
);
76 EXPECT_TRUE(destroyed1
);
77 EXPECT_FALSE(destroyed2
);
79 EXPECT_TRUE(destroyed1
);
80 EXPECT_TRUE(destroyed2
);
83 TEST(ScopedPtrMapTest
, EraseIterator
) {
84 bool destroyed
= false;
85 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
86 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
87 EXPECT_FALSE(destroyed
);
88 scoped_map
.erase(scoped_map
.find(0));
89 EXPECT_TRUE(destroyed
);
90 EXPECT_TRUE(scoped_map
.empty());
93 TEST(ScopedPtrMapTest
, EraseKey
) {
94 bool destroyed
= false;
95 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
96 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
97 EXPECT_FALSE(destroyed
);
98 EXPECT_EQ(1u, scoped_map
.erase(0));
99 EXPECT_TRUE(destroyed
);
100 EXPECT_TRUE(scoped_map
.empty());
102 // Test erase of a non-existent key.
103 EXPECT_EQ(0u, scoped_map
.erase(7));
106 TEST(ScopedPtrMapTest
, EraseRange
) {
107 bool destroyed1
= false;
108 bool destroyed2
= false;
109 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
111 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed1
)));
112 EXPECT_FALSE(destroyed1
);
114 scoped_map
.insert(1, make_scoped_ptr(new ScopedDestroyer(&destroyed2
)));
115 EXPECT_FALSE(destroyed2
);
117 scoped_map
.erase(scoped_map
.find(0), scoped_map
.end());
118 EXPECT_TRUE(destroyed1
);
119 EXPECT_TRUE(destroyed2
);
120 EXPECT_TRUE(scoped_map
.empty());
123 TEST(ScopedPtrMapTest
, TakeAndErase
) {
124 bool destroyed
= false;
125 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
126 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
127 scoped_map
.insert(0, make_scoped_ptr(elem
));
128 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
129 EXPECT_FALSE(destroyed
);
130 scoped_ptr
<ScopedDestroyer
> object
= scoped_map
.take_and_erase(0);
131 EXPECT_EQ(elem
, object
.get());
132 EXPECT_FALSE(destroyed
);
133 EXPECT_TRUE(scoped_map
.empty());
135 EXPECT_TRUE(destroyed
);
138 TEST(ScopedPtrMapTest
, Clear
) {
139 bool destroyed
= false;
140 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
141 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
142 EXPECT_FALSE(destroyed
);
144 EXPECT_TRUE(destroyed
);
145 EXPECT_TRUE(scoped_map
.empty());
148 TEST(ScopedPtrMapTest
, Compare
) {
149 // Construct a ScopedPtrMap with a custom comparison function.
150 ScopedPtrMap
<int, scoped_ptr
<int>, std::greater
<int>> scoped_map1
;
151 scoped_map1
.insert(0, make_scoped_ptr(new int(0)));
152 scoped_map1
.insert(1, make_scoped_ptr(new int(0)));
154 auto it
= scoped_map1
.begin();
155 EXPECT_EQ(1, it
->first
);
157 EXPECT_EQ(0, it
->first
);
159 // Test the move constructor.
160 ScopedPtrMap
<int, scoped_ptr
<int>, std::greater
<int>> scoped_map2(
162 EXPECT_EQ(2u, scoped_map2
.size());
163 EXPECT_TRUE(scoped_map1
.empty());
165 // Test move assignment.
166 scoped_map1
= scoped_map2
.Pass();
167 EXPECT_EQ(2u, scoped_map1
.size());
168 EXPECT_TRUE(scoped_map2
.empty());
171 scoped_map2
.swap(scoped_map1
);
172 EXPECT_EQ(2u, scoped_map2
.size());
173 EXPECT_TRUE(scoped_map1
.empty());
176 TEST(ScopedPtrMapTest
, Scope
) {
177 bool destroyed
= false;
179 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
180 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
181 EXPECT_FALSE(destroyed
);
183 EXPECT_TRUE(destroyed
);
186 TEST(ScopedPtrMapTest
, MoveConstruct
) {
187 bool destroyed
= false;
189 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
190 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
191 scoped_map
.insert(0, make_scoped_ptr(elem
));
192 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
193 EXPECT_FALSE(destroyed
);
194 EXPECT_FALSE(scoped_map
.empty());
196 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map_copy(
198 EXPECT_TRUE(scoped_map
.empty());
199 EXPECT_FALSE(scoped_map_copy
.empty());
200 EXPECT_EQ(elem
, scoped_map_copy
.find(0)->second
);
201 EXPECT_FALSE(destroyed
);
203 EXPECT_TRUE(destroyed
);
206 TEST(ScopedPtrMapTest
, MoveAssign
) {
207 bool destroyed
= false;
209 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
210 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
211 scoped_map
.insert(0, make_scoped_ptr(elem
));
212 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
213 EXPECT_FALSE(destroyed
);
214 EXPECT_FALSE(scoped_map
.empty());
216 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map_assign
;
217 scoped_map_assign
= scoped_map
.Pass();
218 EXPECT_TRUE(scoped_map
.empty());
219 EXPECT_FALSE(scoped_map_assign
.empty());
220 EXPECT_EQ(elem
, scoped_map_assign
.find(0)->second
);
221 EXPECT_FALSE(destroyed
);
223 EXPECT_TRUE(destroyed
);
226 template <typename Key
, typename ScopedPtr
>
227 ScopedPtrMap
<Key
, ScopedPtr
> PassThru(ScopedPtrMap
<Key
, ScopedPtr
> scoper
) {
231 TEST(ScopedPtrMapTest
, Passed
) {
232 bool destroyed
= false;
233 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
234 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
235 scoped_map
.insert(0, make_scoped_ptr(elem
));
236 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
237 EXPECT_FALSE(destroyed
);
239 base::Callback
<ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>>(void)>
240 callback
= base::Bind(&PassThru
<int, scoped_ptr
<ScopedDestroyer
>>,
241 base::Passed(&scoped_map
));
242 EXPECT_TRUE(scoped_map
.empty());
243 EXPECT_FALSE(destroyed
);
245 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> result
= callback
.Run();
246 EXPECT_TRUE(scoped_map
.empty());
247 EXPECT_EQ(elem
, result
.find(0)->second
);
248 EXPECT_FALSE(destroyed
);
251 EXPECT_TRUE(destroyed
);