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 bool destroyed
= false;
151 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>, std::greater
<int>> scoped_map
;
152 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
153 scoped_map
.insert(1, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
155 auto it
= scoped_map
.begin();
156 EXPECT_EQ(1, it
->first
);
158 EXPECT_EQ(0, it
->first
);
161 TEST(ScopedPtrMapTest
, Scope
) {
162 bool destroyed
= false;
164 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
165 scoped_map
.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed
)));
166 EXPECT_FALSE(destroyed
);
168 EXPECT_TRUE(destroyed
);
171 TEST(ScopedPtrMapTest
, MoveConstruct
) {
172 bool destroyed
= false;
174 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
175 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
176 scoped_map
.insert(0, make_scoped_ptr(elem
));
177 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
178 EXPECT_FALSE(destroyed
);
179 EXPECT_FALSE(scoped_map
.empty());
181 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map_copy(
183 EXPECT_TRUE(scoped_map
.empty());
184 EXPECT_FALSE(scoped_map_copy
.empty());
185 EXPECT_EQ(elem
, scoped_map_copy
.find(0)->second
);
186 EXPECT_FALSE(destroyed
);
188 EXPECT_TRUE(destroyed
);
191 TEST(ScopedPtrMapTest
, MoveAssign
) {
192 bool destroyed
= false;
194 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
195 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
196 scoped_map
.insert(0, make_scoped_ptr(elem
));
197 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
198 EXPECT_FALSE(destroyed
);
199 EXPECT_FALSE(scoped_map
.empty());
201 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map_assign
;
202 scoped_map_assign
= scoped_map
.Pass();
203 EXPECT_TRUE(scoped_map
.empty());
204 EXPECT_FALSE(scoped_map_assign
.empty());
205 EXPECT_EQ(elem
, scoped_map_assign
.find(0)->second
);
206 EXPECT_FALSE(destroyed
);
208 EXPECT_TRUE(destroyed
);
211 template <typename Key
, typename ScopedPtr
>
212 ScopedPtrMap
<Key
, ScopedPtr
> PassThru(ScopedPtrMap
<Key
, ScopedPtr
> scoper
) {
216 TEST(ScopedPtrMapTest
, Passed
) {
217 bool destroyed
= false;
218 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> scoped_map
;
219 ScopedDestroyer
* elem
= new ScopedDestroyer(&destroyed
);
220 scoped_map
.insert(0, make_scoped_ptr(elem
));
221 EXPECT_EQ(elem
, scoped_map
.find(0)->second
);
222 EXPECT_FALSE(destroyed
);
224 base::Callback
<ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>>(void)>
225 callback
= base::Bind(&PassThru
<int, scoped_ptr
<ScopedDestroyer
>>,
226 base::Passed(&scoped_map
));
227 EXPECT_TRUE(scoped_map
.empty());
228 EXPECT_FALSE(destroyed
);
230 ScopedPtrMap
<int, scoped_ptr
<ScopedDestroyer
>> result
= callback
.Run();
231 EXPECT_TRUE(scoped_map
.empty());
232 EXPECT_EQ(elem
, result
.find(0)->second
);
233 EXPECT_FALSE(destroyed
);
236 EXPECT_TRUE(destroyed
);