Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / system_wrappers / source / scoped_vector_unittest.cc
1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 // Borrowed from Chromium's src/base/memory/scoped_vector_unittest.cc
12
13 #include "webrtc/system_wrappers/interface/scoped_vector.h"
14
15 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace webrtc {
19 namespace {
20
21 // The LifeCycleObject notifies its Observer upon construction & destruction.
22 class LifeCycleObject {
23  public:
24   class Observer {
25    public:
26     virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
27     virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
28
29    protected:
30     virtual ~Observer() {}
31   };
32
33   ~LifeCycleObject() {
34     observer_->OnLifeCycleDestroy(this);
35   }
36
37  private:
38   friend class LifeCycleWatcher;
39
40   explicit LifeCycleObject(Observer* observer)
41       : observer_(observer) {
42     observer_->OnLifeCycleConstruct(this);
43   }
44
45   Observer* observer_;
46
47   DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
48 };
49
50 // The life cycle states we care about for the purposes of testing ScopedVector
51 // against objects.
52 enum LifeCycleState {
53   LC_INITIAL,
54   LC_CONSTRUCTED,
55   LC_DESTROYED,
56 };
57
58 // Because we wish to watch the life cycle of an object being constructed and
59 // destroyed, and further wish to test expectations against the state of that
60 // object, we cannot save state in that object itself. Instead, we use this
61 // pairing of the watcher, which observes the object and notifies of
62 // construction & destruction. Since we also may be testing assumptions about
63 // things not getting freed, this class also acts like a scoping object and
64 // deletes the |constructed_life_cycle_object_|, if any when the
65 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
66 // changes are:
67 //   INITIAL -> CONSTRUCTED -> DESTROYED.
68 // Anything more complicated than that should start another test.
69 class LifeCycleWatcher : public LifeCycleObject::Observer {
70  public:
71   LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
72   virtual ~LifeCycleWatcher() {}
73
74   // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
75   // LifeCycleWatcher.
76   virtual void OnLifeCycleConstruct(LifeCycleObject* object) OVERRIDE {
77     ASSERT_EQ(LC_INITIAL, life_cycle_state_);
78     ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
79     life_cycle_state_ = LC_CONSTRUCTED;
80     constructed_life_cycle_object_.reset(object);
81   }
82
83   // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
84   // same one we saw constructed.
85   virtual void OnLifeCycleDestroy(LifeCycleObject* object) OVERRIDE {
86     ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
87     LifeCycleObject* constructed_life_cycle_object =
88         constructed_life_cycle_object_.release();
89     ASSERT_EQ(constructed_life_cycle_object, object);
90     life_cycle_state_ = LC_DESTROYED;
91   }
92
93   LifeCycleState life_cycle_state() const { return life_cycle_state_; }
94
95   // Factory method for creating a new LifeCycleObject tied to this
96   // LifeCycleWatcher.
97   LifeCycleObject* NewLifeCycleObject() {
98     return new LifeCycleObject(this);
99   }
100
101   // Returns true iff |object| is the same object that this watcher is tracking.
102   bool IsWatching(LifeCycleObject* object) const {
103     return object == constructed_life_cycle_object_.get();
104   }
105
106  private:
107   LifeCycleState life_cycle_state_;
108   scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
109
110   DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
111 };
112
113 TEST(ScopedVectorTest, LifeCycleWatcher) {
114   LifeCycleWatcher watcher;
115   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
116   LifeCycleObject* object = watcher.NewLifeCycleObject();
117   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
118   delete object;
119   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
120 }
121
122 TEST(ScopedVectorTest, PopBack) {
123   LifeCycleWatcher watcher;
124   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
125   ScopedVector<LifeCycleObject> scoped_vector;
126   scoped_vector.push_back(watcher.NewLifeCycleObject());
127   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
128   EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
129   scoped_vector.pop_back();
130   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
131   EXPECT_TRUE(scoped_vector.empty());
132 }
133
134 TEST(ScopedVectorTest, Clear) {
135   LifeCycleWatcher watcher;
136   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
137   ScopedVector<LifeCycleObject> scoped_vector;
138   scoped_vector.push_back(watcher.NewLifeCycleObject());
139   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
140   EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
141   scoped_vector.clear();
142   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
143   EXPECT_TRUE(scoped_vector.empty());
144 }
145
146 TEST(ScopedVectorTest, WeakClear) {
147   LifeCycleWatcher watcher;
148   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
149   ScopedVector<LifeCycleObject> scoped_vector;
150   scoped_vector.push_back(watcher.NewLifeCycleObject());
151   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
152   EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
153   scoped_vector.weak_clear();
154   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
155   EXPECT_TRUE(scoped_vector.empty());
156 }
157
158 TEST(ScopedVectorTest, ResizeShrink) {
159   LifeCycleWatcher first_watcher;
160   EXPECT_EQ(LC_INITIAL, first_watcher.life_cycle_state());
161   LifeCycleWatcher second_watcher;
162   EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
163   ScopedVector<LifeCycleObject> scoped_vector;
164
165   scoped_vector.push_back(first_watcher.NewLifeCycleObject());
166   EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
167   EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
168   EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
169   EXPECT_FALSE(second_watcher.IsWatching(scoped_vector[0]));
170
171   scoped_vector.push_back(second_watcher.NewLifeCycleObject());
172   EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
173   EXPECT_EQ(LC_CONSTRUCTED, second_watcher.life_cycle_state());
174   EXPECT_FALSE(first_watcher.IsWatching(scoped_vector[1]));
175   EXPECT_TRUE(second_watcher.IsWatching(scoped_vector[1]));
176
177   // Test that shrinking a vector deletes elements in the disappearing range.
178   scoped_vector.resize(1);
179   EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
180   EXPECT_EQ(LC_DESTROYED, second_watcher.life_cycle_state());
181   EXPECT_EQ(1u, scoped_vector.size());
182   EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
183 }
184
185 TEST(ScopedVectorTest, ResizeGrow) {
186   LifeCycleWatcher watcher;
187   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()));
192
193   scoped_vector.resize(5);
194   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
195   ASSERT_EQ(5u, scoped_vector.size());
196   EXPECT_TRUE(watcher.IsWatching(scoped_vector[0]));
197   EXPECT_FALSE(watcher.IsWatching(scoped_vector[1]));
198   EXPECT_FALSE(watcher.IsWatching(scoped_vector[2]));
199   EXPECT_FALSE(watcher.IsWatching(scoped_vector[3]));
200   EXPECT_FALSE(watcher.IsWatching(scoped_vector[4]));
201 }
202
203 TEST(ScopedVectorTest, Scope) {
204   LifeCycleWatcher watcher;
205   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
206   {
207     ScopedVector<LifeCycleObject> scoped_vector;
208     scoped_vector.push_back(watcher.NewLifeCycleObject());
209     EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
210     EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
211   }
212   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
213 }
214
215 TEST(ScopedVectorTest, MoveConstruct) {
216   LifeCycleWatcher watcher;
217   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
218   {
219     ScopedVector<LifeCycleObject> scoped_vector;
220     scoped_vector.push_back(watcher.NewLifeCycleObject());
221     EXPECT_FALSE(scoped_vector.empty());
222     EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
223
224     ScopedVector<LifeCycleObject> scoped_vector_copy(scoped_vector.Pass());
225     EXPECT_TRUE(scoped_vector.empty());
226     EXPECT_FALSE(scoped_vector_copy.empty());
227     EXPECT_TRUE(watcher.IsWatching(scoped_vector_copy.back()));
228
229     EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
230   }
231   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
232 }
233
234 TEST(ScopedVectorTest, MoveAssign) {
235   LifeCycleWatcher watcher;
236   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
237   {
238     ScopedVector<LifeCycleObject> scoped_vector;
239     scoped_vector.push_back(watcher.NewLifeCycleObject());
240     ScopedVector<LifeCycleObject> scoped_vector_assign;
241     EXPECT_FALSE(scoped_vector.empty());
242     EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
243
244     scoped_vector_assign = scoped_vector.Pass();
245     EXPECT_TRUE(scoped_vector.empty());
246     EXPECT_FALSE(scoped_vector_assign.empty());
247     EXPECT_TRUE(watcher.IsWatching(scoped_vector_assign.back()));
248
249     EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
250   }
251   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
252 }
253
254 class DeleteCounter {
255  public:
256   explicit DeleteCounter(int* deletes)
257       : deletes_(deletes) {
258   }
259
260   ~DeleteCounter() {
261     (*deletes_)++;
262   }
263
264   void VoidMethod0() {}
265
266  private:
267   int* const deletes_;
268
269   DISALLOW_COPY_AND_ASSIGN(DeleteCounter);
270 };
271
272 // This class is used in place of Chromium's base::Callback.
273 template <typename T>
274 class PassThru  {
275  public:
276   explicit PassThru(ScopedVector<T> scoper) : scoper_(scoper.Pass()) {}
277
278   ScopedVector<T> Run() {
279     return scoper_.Pass();
280   }
281
282  private:
283   ScopedVector<T> scoper_;
284 };
285
286 TEST(ScopedVectorTest, Passed) {
287   int deletes = 0;
288   ScopedVector<DeleteCounter> deleter_vector;
289   deleter_vector.push_back(new DeleteCounter(&deletes));
290   EXPECT_EQ(0, deletes);
291   PassThru<DeleteCounter> pass_thru(deleter_vector.Pass());
292   EXPECT_EQ(0, deletes);
293   ScopedVector<DeleteCounter> result = pass_thru.Run();
294   EXPECT_EQ(0, deletes);
295   result.clear();
296   EXPECT_EQ(1, deletes);
297 };
298
299 TEST(ScopedVectorTest, InsertRange) {
300   LifeCycleWatcher watchers[5];
301   size_t watchers_size = sizeof(watchers) / sizeof(*watchers);
302
303   std::vector<LifeCycleObject*> vec;
304   for (LifeCycleWatcher* it = watchers; it != watchers + watchers_size;
305        ++it) {
306     EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
307     vec.push_back(it->NewLifeCycleObject());
308     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
309   }
310   // Start scope for ScopedVector.
311   {
312     ScopedVector<LifeCycleObject> scoped_vector;
313     scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
314     for (LifeCycleWatcher* it = watchers; it != watchers + watchers_size;
315          ++it)
316       EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
317   }
318   for (LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
319     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
320   for (LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
321     EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
322   for (LifeCycleWatcher* it = watchers + 3; it != watchers + watchers_size;
323       ++it)
324     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
325 }
326
327 }  // namespace
328 }  // namespace webrtc