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 virtual ~LifeCycleWatcher() {}
67 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
69 virtual 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 virtual 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
, Clear
) {
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
.clear();
123 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
124 EXPECT_TRUE(scoped_vector
.empty());
127 TEST(ScopedVectorTest
, WeakClear
) {
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
.weak_clear();
135 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
136 EXPECT_TRUE(scoped_vector
.empty());
139 TEST(ScopedVectorTest
, ResizeShrink
) {
140 LifeCycleWatcher first_watcher
;
141 EXPECT_EQ(LC_INITIAL
, first_watcher
.life_cycle_state());
142 LifeCycleWatcher second_watcher
;
143 EXPECT_EQ(LC_INITIAL
, second_watcher
.life_cycle_state());
144 ScopedVector
<LifeCycleObject
> scoped_vector
;
146 scoped_vector
.push_back(first_watcher
.NewLifeCycleObject());
147 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
148 EXPECT_EQ(LC_INITIAL
, second_watcher
.life_cycle_state());
149 EXPECT_TRUE(first_watcher
.IsWatching(scoped_vector
[0]));
150 EXPECT_FALSE(second_watcher
.IsWatching(scoped_vector
[0]));
152 scoped_vector
.push_back(second_watcher
.NewLifeCycleObject());
153 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
154 EXPECT_EQ(LC_CONSTRUCTED
, second_watcher
.life_cycle_state());
155 EXPECT_FALSE(first_watcher
.IsWatching(scoped_vector
[1]));
156 EXPECT_TRUE(second_watcher
.IsWatching(scoped_vector
[1]));
158 // Test that shrinking a vector deletes elements in the disappearing range.
159 scoped_vector
.resize(1);
160 EXPECT_EQ(LC_CONSTRUCTED
, first_watcher
.life_cycle_state());
161 EXPECT_EQ(LC_DESTROYED
, second_watcher
.life_cycle_state());
162 EXPECT_EQ(1u, scoped_vector
.size());
163 EXPECT_TRUE(first_watcher
.IsWatching(scoped_vector
[0]));
166 TEST(ScopedVectorTest
, ResizeGrow
) {
167 LifeCycleWatcher watcher
;
168 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
169 ScopedVector
<LifeCycleObject
> scoped_vector
;
170 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
171 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
172 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
174 scoped_vector
.resize(5);
175 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
176 ASSERT_EQ(5u, scoped_vector
.size());
177 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
[0]));
178 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[1]));
179 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[2]));
180 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[3]));
181 EXPECT_FALSE(watcher
.IsWatching(scoped_vector
[4]));
184 TEST(ScopedVectorTest
, Scope
) {
185 LifeCycleWatcher watcher
;
186 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
188 ScopedVector
<LifeCycleObject
> scoped_vector
;
189 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
190 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
191 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
193 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
196 TEST(ScopedVectorTest
, MoveConstruct
) {
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_FALSE(scoped_vector
.empty());
203 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
205 ScopedVector
<LifeCycleObject
> scoped_vector_copy(scoped_vector
.Pass());
206 EXPECT_TRUE(scoped_vector
.empty());
207 EXPECT_FALSE(scoped_vector_copy
.empty());
208 EXPECT_TRUE(watcher
.IsWatching(scoped_vector_copy
.back()));
210 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
212 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
215 TEST(ScopedVectorTest
, MoveAssign
) {
216 LifeCycleWatcher watcher
;
217 EXPECT_EQ(LC_INITIAL
, watcher
.life_cycle_state());
219 ScopedVector
<LifeCycleObject
> scoped_vector
;
220 scoped_vector
.push_back(watcher
.NewLifeCycleObject());
221 ScopedVector
<LifeCycleObject
> scoped_vector_assign
;
222 EXPECT_FALSE(scoped_vector
.empty());
223 EXPECT_TRUE(watcher
.IsWatching(scoped_vector
.back()));
225 scoped_vector_assign
= scoped_vector
.Pass();
226 EXPECT_TRUE(scoped_vector
.empty());
227 EXPECT_FALSE(scoped_vector_assign
.empty());
228 EXPECT_TRUE(watcher
.IsWatching(scoped_vector_assign
.back()));
230 EXPECT_EQ(LC_CONSTRUCTED
, watcher
.life_cycle_state());
232 EXPECT_EQ(LC_DESTROYED
, watcher
.life_cycle_state());
235 class DeleteCounter
{
237 explicit DeleteCounter(int* deletes
)
238 : deletes_(deletes
) {
245 void VoidMethod0() {}
250 DISALLOW_COPY_AND_ASSIGN(DeleteCounter
);
253 template <typename T
>
254 ScopedVector
<T
> PassThru(ScopedVector
<T
> scoper
) {
255 return scoper
.Pass();
258 TEST(ScopedVectorTest
, Passed
) {
260 ScopedVector
<DeleteCounter
> deleter_vector
;
261 deleter_vector
.push_back(new DeleteCounter(&deletes
));
262 EXPECT_EQ(0, deletes
);
263 base::Callback
<ScopedVector
<DeleteCounter
>(void)> callback
=
264 base::Bind(&PassThru
<DeleteCounter
>, base::Passed(&deleter_vector
));
265 EXPECT_EQ(0, deletes
);
266 ScopedVector
<DeleteCounter
> result
= callback
.Run();
267 EXPECT_EQ(0, deletes
);
269 EXPECT_EQ(1, deletes
);
272 TEST(ScopedVectorTest
, InsertRange
) {
273 LifeCycleWatcher watchers
[5];
275 std::vector
<LifeCycleObject
*> vec
;
276 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ arraysize(watchers
);
278 EXPECT_EQ(LC_INITIAL
, it
->life_cycle_state());
279 vec
.push_back(it
->NewLifeCycleObject());
280 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
282 // Start scope for ScopedVector.
284 ScopedVector
<LifeCycleObject
> scoped_vector
;
285 scoped_vector
.insert(scoped_vector
.end(), vec
.begin() + 1, vec
.begin() + 3);
286 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ arraysize(watchers
);
288 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
290 for(LifeCycleWatcher
* it
= watchers
; it
!= watchers
+ 1; ++it
)
291 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());
292 for(LifeCycleWatcher
* it
= watchers
+ 1; it
!= watchers
+ 3; ++it
)
293 EXPECT_EQ(LC_DESTROYED
, it
->life_cycle_state());
294 for(LifeCycleWatcher
* it
= watchers
+ 3; it
!= watchers
+ arraysize(watchers
);
296 EXPECT_EQ(LC_CONSTRUCTED
, it
->life_cycle_state());