1 // Copyright (c) 2012 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/memory/scoped_vector.h"
8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 // The LifeCycleObject notifies its Observer upon construction & destruction.
15 class LifeCycleObject
{
19 virtual void OnLifeCycleConstruct(LifeCycleObject
* o
) = 0;
20 virtual void OnLifeCycleDestroy(LifeCycleObject
* o
) = 0;
23 virtual ~Observer() {}
27 observer_
->OnLifeCycleDestroy(this);
31 friend class LifeCycleWatcher
;
33 explicit LifeCycleObject(Observer
* observer
)
34 : observer_(observer
) {
35 observer_
->OnLifeCycleConstruct(this);
40 DISALLOW_COPY_AND_ASSIGN(LifeCycleObject
);
43 // The life cycle states we care about for the purposes of testing ScopedVector
51 // Because we wish to watch the life cycle of an object being constructed and
52 // destroyed, and further wish to test expectations against the state of that
53 // object, we cannot save state in that object itself. Instead, we use this
54 // pairing of the watcher, which observes the object and notifies of
55 // construction & destruction. Since we also may be testing assumptions about
56 // things not getting freed, this class also acts like a scoping object and
57 // deletes the |constructed_life_cycle_object_|, if any when the
58 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
60 // INITIAL -> CONSTRUCTED -> DESTROYED.
61 // Anything more complicated than that should start another test.
62 class LifeCycleWatcher
: public LifeCycleObject::Observer
{
64 LifeCycleWatcher() : life_cycle_state_(LC_INITIAL
) {}
65 ~LifeCycleWatcher() override
{}
67 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
69 void OnLifeCycleConstruct(LifeCycleObject
* object
) override
{
70 ASSERT_EQ(LC_INITIAL
, life_cycle_state_
);
71 ASSERT_EQ(NULL
, constructed_life_cycle_object_
.get());
72 life_cycle_state_
= LC_CONSTRUCTED
;
73 constructed_life_cycle_object_
.reset(object
);
76 // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
77 // same one we saw constructed.
78 void OnLifeCycleDestroy(LifeCycleObject
* object
) override
{
79 ASSERT_EQ(LC_CONSTRUCTED
, life_cycle_state_
);
80 LifeCycleObject
* constructed_life_cycle_object
=
81 constructed_life_cycle_object_
.release();
82 ASSERT_EQ(constructed_life_cycle_object
, object
);
83 life_cycle_state_
= LC_DESTROYED
;
86 LifeCycleState
life_cycle_state() const { return life_cycle_state_
; }
88 // Factory method for creating a new LifeCycleObject tied to this
90 LifeCycleObject
* NewLifeCycleObject() {
91 return new LifeCycleObject(this);
94 // Returns true iff |object| is the same object that this watcher is tracking.
95 bool IsWatching(LifeCycleObject
* object
) const {
96 return object
== constructed_life_cycle_object_
.get();
100 LifeCycleState life_cycle_state_
;
101 scoped_ptr
<LifeCycleObject
> constructed_life_cycle_object_
;
103 DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher
);
106 TEST(ScopedVectorTest
, LifeCycleWatcher
) {
107 LifeCycleWatcher watcher
;
108 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
109 LifeCycleObject
* object
= watcher
.NewLifeCycleObject();
110 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
112 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
115 TEST(ScopedVectorTest
, PopBack
) {
116 LifeCycleWatcher watcher
;
117 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
118 ScopedVector
<LifeCycleObject
> scoped_vector
;
119 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
120 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
121 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
122 scoped_vector
.pop_back();
123 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
124 EXPECT_TRUE(scoped_vector
.empty());
127 TEST(ScopedVectorTest
, Clear
) {
128 LifeCycleWatcher watcher
;
129 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
130 ScopedVector
<LifeCycleObject
> scoped_vector
;
131 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
132 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
133 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
134 scoped_vector
.clear();
135 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
136 EXPECT_TRUE(scoped_vector
.empty());
139 TEST(ScopedVectorTest
, WeakClear
) {
140 LifeCycleWatcher watcher
;
141 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
142 ScopedVector
<LifeCycleObject
> scoped_vector
;
143 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
144 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
145 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
146 scoped_vector
.weak_clear();
147 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
148 EXPECT_TRUE(scoped_vector
.empty());
151 TEST(ScopedVectorTest
, ResizeShrink
) {
152 LifeCycleWatcher first_watcher
;
153 EXPECT_EQ(LC_INITIAL
, first_watcher
.life_cycle_state());
154 LifeCycleWatcher second_watcher
;
155 EXPECT_EQ(LC_INITIAL
, second_watcher
.life_cycle_state());
156 ScopedVector
<LifeCycleObject
> scoped_vector
;
158 scoped_vector
.push_back(first_watcher
.NewLifeCycleObject());
159 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
160 EXPECT_EQ(LC_INITIAL
, second_watcher
.life_cycle_state());
161 EXPECT_TRUE(first_watcher
.IsWatching(scoped_vector
[0]));
162 EXPECT_FALSE(second_watcher
.IsWatching(scoped_vector
[0]));
164 scoped_vector
.push_back(second_watcher
.NewLifeCycleObject());
165 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
166 EXPECT_EQ(LC_CONSTRUCTED
, second_watcher
.life_cycle_state());
167 EXPECT_FALSE(first_watcher
.IsWatching(scoped_vector
[1]));
168 EXPECT_TRUE(second_watcher
.IsWatching(scoped_vector
[1]));
170 // Test that shrinking a vector deletes elements in the disappearing range.
171 scoped_vector
.resize(1);
172 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
173 EXPECT_EQ(LC_DESTROYED
, second_watcher
.life_cycle_state());
174 EXPECT_EQ(1u, scoped_vector
.size());
175 EXPECT_TRUE(first_watcher
.IsWatching(scoped_vector
[0]));
178 TEST(ScopedVectorTest
, ResizeGrow
) {
179 LifeCycleWatcher watcher
;
180 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
181 ScopedVector
<LifeCycleObject
> scoped_vector
;
182 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
183 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
184 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
186 scoped_vector
.resize(5);
187 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
188 ASSERT_EQ(5u, scoped_vector
.size());
189 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
[0]));
190 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[1]));
191 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[2]));
192 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[3]));
193 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[4]));
196 TEST(ScopedVectorTest
, Scope
) {
197 LifeCycleWatcher watcher
;
198 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
200 ScopedVector
<LifeCycleObject
> scoped_vector
;
201 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
202 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
203 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
205 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
208 TEST(ScopedVectorTest
, MoveConstruct
) {
209 LifeCycleWatcher watcher
;
210 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
212 ScopedVector
<LifeCycleObject
> scoped_vector
;
213 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
214 EXPECT_FALSE(scoped_vector
.empty());
215 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
217 ScopedVector
<LifeCycleObject
> scoped_vector_copy(scoped_vector
.Pass());
218 EXPECT_TRUE(scoped_vector
.empty());
219 EXPECT_FALSE(scoped_vector_copy
.empty());
220 EXPECT_TRUE(watcher
.IsWatching(scoped_vector_copy
.back()));
222 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
224 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
227 TEST(ScopedVectorTest
, MoveAssign
) {
228 LifeCycleWatcher watcher
;
229 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
231 ScopedVector
<LifeCycleObject
> scoped_vector
;
232 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
233 ScopedVector
<LifeCycleObject
> scoped_vector_assign
;
234 EXPECT_FALSE(scoped_vector
.empty());
235 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
237 scoped_vector_assign
= scoped_vector
.Pass();
238 EXPECT_TRUE(scoped_vector
.empty());
239 EXPECT_FALSE(scoped_vector_assign
.empty());
240 EXPECT_TRUE(watcher
.IsWatching(scoped_vector_assign
.back()));
242 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
244 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
247 class DeleteCounter
{
249 explicit DeleteCounter(int* deletes
)
250 : deletes_(deletes
) {
257 void VoidMethod0() {}
262 DISALLOW_COPY_AND_ASSIGN(DeleteCounter
);
265 template <typename T
>
266 ScopedVector
<T
> PassThru(ScopedVector
<T
> scoper
) {
267 return scoper
.Pass();
270 TEST(ScopedVectorTest
, Passed
) {
272 ScopedVector
<DeleteCounter
> deleter_vector
;
273 deleter_vector
.push_back(new DeleteCounter(&deletes
));
274 EXPECT_EQ(0, deletes
);
275 base::Callback
<ScopedVector
<DeleteCounter
>(void)> callback
=
276 base::Bind(&PassThru
<DeleteCounter
>, base::Passed(&deleter_vector
));
277 EXPECT_EQ(0, deletes
);
278 ScopedVector
<DeleteCounter
> result
= callback
.Run();
279 EXPECT_EQ(0, deletes
);
281 EXPECT_EQ(1, deletes
);
284 TEST(ScopedVectorTest
, InsertRange
) {
285 LifeCycleWatcher watchers
[5];
287 std::vector
<LifeCycleObject
*> vec
;
288 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ arraysize(watchers
);
290 EXPECT_EQ(LC_INITIAL
, it
->life_cycle_state());
291 vec
.push_back(it
->NewLifeCycleObject());
292 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
294 // Start scope for ScopedVector.
296 ScopedVector
<LifeCycleObject
> scoped_vector
;
297 scoped_vector
.insert(scoped_vector
.end(), vec
.begin() + 1, vec
.begin() + 3);
298 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ arraysize(watchers
);
300 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
302 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ 1; ++it
)
303 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
304 for(LifeCycleWatcher
* it
= watchers
+ 1; it
!= watchers
+ 3; ++it
)
305 EXPECT_EQ(LC_DESTROYED
, it
->life_cycle_state());
306 for(LifeCycleWatcher
* it
= watchers
+ 3; it
!= watchers
+ arraysize(watchers
);
308 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
311 // Assertions for push_back(scoped_ptr).
312 TEST(ScopedVectorTest
, PushBackScopedPtr
) {
313 int delete_counter
= 0;
314 scoped_ptr
<DeleteCounter
> elem(new DeleteCounter(&delete_counter
));
315 EXPECT_EQ(0, delete_counter
);
317 ScopedVector
<DeleteCounter
> v
;
318 v
.push_back(elem
.Pass());
319 EXPECT_EQ(0, delete_counter
);
321 EXPECT_EQ(1, delete_counter
);