Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: base/memory/scoped_vector_unittest.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/scoped_vector.h ('k') | base/memory/shared_memory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "base/memory/scoped_vector.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace {
13
14 // The LifeCycleObject notifies its Observer upon construction & destruction.
15 class LifeCycleObject {
16 public:
17 class Observer {
18 public:
19 virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
20 virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
21
22 protected:
23 virtual ~Observer() {}
24 };
25
26 ~LifeCycleObject() {
27 observer_->OnLifeCycleDestroy(this);
28 }
29
30 private:
31 friend class LifeCycleWatcher;
32
33 explicit LifeCycleObject(Observer* observer)
34 : observer_(observer) {
35 observer_->OnLifeCycleConstruct(this);
36 }
37
38 Observer* observer_;
39
40 DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
41 };
42
43 // The life cycle states we care about for the purposes of testing ScopedVector
44 // against objects.
45 enum LifeCycleState {
46 LC_INITIAL,
47 LC_CONSTRUCTED,
48 LC_DESTROYED,
49 };
50
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
59 // changes are:
60 // INITIAL -> CONSTRUCTED -> DESTROYED.
61 // Anything more complicated than that should start another test.
62 class LifeCycleWatcher : public LifeCycleObject::Observer {
63 public:
64 LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
65 ~LifeCycleWatcher() override {}
66
67 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
68 // LifeCycleWatcher.
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);
74 }
75
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;
84 }
85
86 LifeCycleState life_cycle_state() const { return life_cycle_state_; }
87
88 // Factory method for creating a new LifeCycleObject tied to this
89 // LifeCycleWatcher.
90 LifeCycleObject* NewLifeCycleObject() {
91 return new LifeCycleObject(this);
92 }
93
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();
97 }
98
99 private:
100 LifeCycleState life_cycle_state_;
101 scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
102
103 DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
104 };
105
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());
111 delete object;
112 EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
113 }
114
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());
125 }
126
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());
137 }
138
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());
149 }
150
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;
157
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]));
163
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]));
169
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]));
176 }
177
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()));
185
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]));
194 }
195
196 TEST(ScopedVectorTest, Scope) {
197 LifeCycleWatcher watcher;
198 EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
199 {
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()));
204 }
205 EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
206 }
207
208 TEST(ScopedVectorTest, MoveConstruct) {
209 LifeCycleWatcher watcher;
210 EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
211 {
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()));
216
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()));
221
222 EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
223 }
224 EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
225 }
226
227 TEST(ScopedVectorTest, MoveAssign) {
228 LifeCycleWatcher watcher;
229 EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
230 {
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()));
236
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()));
241
242 EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
243 }
244 EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
245 }
246
247 class DeleteCounter {
248 public:
249 explicit DeleteCounter(int* deletes)
250 : deletes_(deletes) {
251 }
252
253 ~DeleteCounter() {
254 (*deletes_)++;
255 }
256
257 void VoidMethod0() {}
258
259 private:
260 int* const deletes_;
261
262 DISALLOW_COPY_AND_ASSIGN(DeleteCounter);
263 };
264
265 template <typename T>
266 ScopedVector<T> PassThru(ScopedVector<T> scoper) {
267 return scoper.Pass();
268 }
269
270 TEST(ScopedVectorTest, Passed) {
271 int deletes = 0;
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);
280 result.clear();
281 EXPECT_EQ(1, deletes);
282 };
283
284 TEST(ScopedVectorTest, InsertRange) {
285 LifeCycleWatcher watchers[5];
286
287 std::vector<LifeCycleObject*> vec;
288 for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
289 ++it) {
290 EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
291 vec.push_back(it->NewLifeCycleObject());
292 EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
293 }
294 // Start scope for ScopedVector.
295 {
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);
299 ++it)
300 EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
301 }
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);
307 ++it)
308 EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
309 }
310
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);
316 {
317 ScopedVector<DeleteCounter> v;
318 v.push_back(elem.Pass());
319 EXPECT_EQ(0, delete_counter);
320 }
321 EXPECT_EQ(1, delete_counter);
322 }
323
324 } // namespace
OLDNEW
« no previous file with comments | « base/memory/scoped_vector.h ('k') | base/memory/shared_memory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698