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