• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_ptr.h"
6 #include "base/memory/scoped_vector.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 
9 namespace {
10 
11 // The LifeCycleObject notifies its Observer upon construction & destruction.
12 class LifeCycleObject {
13  public:
14   class Observer {
15    public:
16     virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
17     virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
18 
19    protected:
~Observer()20     virtual ~Observer() {}
21   };
22 
LifeCycleObject(Observer * observer)23   explicit LifeCycleObject(Observer* observer)
24       : observer_(observer) {
25     observer_->OnLifeCycleConstruct(this);
26   }
27 
~LifeCycleObject()28   ~LifeCycleObject() {
29     observer_->OnLifeCycleDestroy(this);
30   }
31 
32  private:
33   Observer* observer_;
34 
35   DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
36 };
37 
38 // The life cycle states we care about for the purposes of testing ScopedVector
39 // against objects.
40 enum LifeCycleState {
41   LC_INITIAL,
42   LC_CONSTRUCTED,
43   LC_DESTROYED,
44 };
45 
46 // Because we wish to watch the life cycle of an object being constructed and
47 // destroyed, and further wish to test expectations against the state of that
48 // object, we cannot save state in that object itself. Instead, we use this
49 // pairing of the watcher, which observes the object and notifies of
50 // construction & destruction. Since we also may be testing assumptions about
51 // things not getting freed, this class also acts like a scoping object and
52 // deletes the |constructed_life_cycle_object_|, if any when the
53 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
54 // changes are:
55 //   INITIAL -> CONSTRUCTED -> DESTROYED.
56 // Anything more complicated than that should start another test.
57 class LifeCycleWatcher : public LifeCycleObject::Observer {
58  public:
LifeCycleWatcher()59   LifeCycleWatcher()
60       : life_cycle_state_(LC_INITIAL),
61         constructed_life_cycle_object_(NULL) {}
~LifeCycleWatcher()62   ~LifeCycleWatcher() {
63   }
64 
65   // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
66   // LifeCycleWatcher.
OnLifeCycleConstruct(LifeCycleObject * object)67   virtual void OnLifeCycleConstruct(LifeCycleObject* object) {
68     ASSERT_EQ(LC_INITIAL, life_cycle_state_);
69     ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
70     life_cycle_state_ = LC_CONSTRUCTED;
71     constructed_life_cycle_object_.reset(object);
72   }
73 
74   // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
75   // same one we saw constructed.
OnLifeCycleDestroy(LifeCycleObject * object)76   virtual void OnLifeCycleDestroy(LifeCycleObject* object) {
77     ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
78     LifeCycleObject* constructed_life_cycle_object =
79         constructed_life_cycle_object_.release();
80     ASSERT_EQ(constructed_life_cycle_object, object);
81     life_cycle_state_ = LC_DESTROYED;
82   }
83 
life_cycle_state() const84   LifeCycleState life_cycle_state() const { return life_cycle_state_; }
85 
86   // Factory method for creating a new LifeCycleObject tied to this
87   // LifeCycleWatcher.
NewLifeCycleObject()88   LifeCycleObject* NewLifeCycleObject() {
89     return new LifeCycleObject(this);
90   }
91 
92  private:
93   LifeCycleState life_cycle_state_;
94   scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
95 
96   DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
97 };
98 
TEST(ScopedVectorTest,LifeCycleWatcher)99 TEST(ScopedVectorTest, LifeCycleWatcher) {
100   LifeCycleWatcher watcher;
101   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
102   LifeCycleObject* object = watcher.NewLifeCycleObject();
103   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
104   delete object;
105   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
106 }
107 
TEST(ScopedVectorTest,Reset)108 TEST(ScopedVectorTest, Reset) {
109   LifeCycleWatcher watcher;
110   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
111   ScopedVector<LifeCycleObject> scoped_vector;
112   scoped_vector.push_back(watcher.NewLifeCycleObject());
113   EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
114   scoped_vector.reset();
115   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
116 }
117 
TEST(ScopedVectorTest,Scope)118 TEST(ScopedVectorTest, Scope) {
119   LifeCycleWatcher watcher;
120   EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
121   {
122     ScopedVector<LifeCycleObject> scoped_vector;
123     scoped_vector.push_back(watcher.NewLifeCycleObject());
124     EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
125   }
126   EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
127 }
128 
TEST(ScopedVectorTest,InsertRange)129 TEST(ScopedVectorTest, InsertRange) {
130   LifeCycleWatcher watchers[5];
131 
132   std::vector<LifeCycleObject*> vec;
133   for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
134       ++it) {
135     EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
136     vec.push_back(it->NewLifeCycleObject());
137     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
138   }
139   // Start scope for ScopedVector.
140   {
141     ScopedVector<LifeCycleObject> scoped_vector;
142     scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
143     for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
144         ++it)
145       EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
146   }
147   for(LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
148     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
149   for(LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
150     EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
151   for(LifeCycleWatcher* it = watchers + 3; it != watchers + arraysize(watchers);
152       ++it)
153     EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
154 }
155 
156 }  // namespace
157