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/observer_list.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 & deletion. We | |
| 12 // only really need one observer, but use the standard ObserverList pattern. | |
|
James Hawkins
2011/03/21 01:45:06
Why?
Sheridan Rawlins
2011/03/21 05:20:17
I was exploring use of ObserverList and thought it
| |
| 13 class LifeCycleObject { | |
| 14 public: | |
| 15 class Observer { | |
| 16 public: | |
|
James Hawkins
2011/03/21 01:45:06
protected:
virtual ~Observer() {}
Sheridan Rawlins
2011/03/21 05:20:17
You know, I was going to do that, but I saw anothe
| |
| 17 virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0; | |
| 18 virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0; | |
| 19 }; | |
| 20 | |
| 21 explicit LifeCycleObject(Observer* observer) { | |
| 22 observer_list_.AddObserver(observer); | |
| 23 FOR_EACH_OBSERVER(Observer, observer_list_, OnLifeCycleConstruct(this)); | |
| 24 } | |
| 25 ~LifeCycleObject() { | |
| 26 FOR_EACH_OBSERVER(Observer, observer_list_, OnLifeCycleDestroy(this)); | |
| 27 } | |
| 28 | |
| 29 private: | |
| 30 ObserverList<Observer> observer_list_; | |
| 31 | |
| 32 DISALLOW_COPY_AND_ASSIGN(LifeCycleObject); | |
| 33 }; | |
| 34 | |
| 35 // The life cycle states we care about for the purposes of testing Scoped | |
| 36 // Vector against objects. | |
| 37 enum LifeCycleState { | |
| 38 LC_INITIAL, | |
| 39 LC_CONSTRUCTED, | |
| 40 LC_DESTROYED, | |
| 41 }; | |
| 42 | |
| 43 // Because we wish to watch the life cycle of an object being constructed and | |
| 44 // destoyed, and further wish to test expectations against the state of that | |
|
James Hawkins
2011/03/21 01:45:06
s/destoyed/destroyed/
Sheridan Rawlins
2011/03/21 05:20:17
Done.
| |
| 45 // object, we cannot save state in that object itself. Instead, we use this | |
| 46 // pairing of the watcher which observes the object, which notifies of | |
|
James Hawkins
2011/03/21 01:45:06
s/object, which/object then/ ?
Sheridan Rawlins
2011/03/21 05:20:17
Done.
| |
| 47 // construction & destruction. | |
| 48 // Since we also may be testing things which don't get freed, this class also | |
| 49 // acts like a scoping object and deletes the |constructed_life_cycle_object_|, | |
| 50 // if any when the LifeCycleWatcher is destroyed. | |
| 51 // To keep this simple, the only expected state changes are | |
| 52 // INITIAL -> CONSTRUCTED -> DESTROYED. | |
| 53 // Anything more complicated than that should start another test. | |
| 54 class LifeCycleWatcher : public LifeCycleObject::Observer { | |
| 55 public: | |
| 56 LifeCycleWatcher() | |
| 57 : life_cycle_state_(LC_INITIAL), | |
| 58 constructed_life_cycle_object_(NULL) {} | |
| 59 ~LifeCycleWatcher() { | |
| 60 if (constructed_life_cycle_object_) | |
| 61 delete constructed_life_cycle_object_; | |
| 62 } | |
| 63 | |
| 64 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this | |
| 65 // LifeCycleWatcher. | |
| 66 virtual void OnLifeCycleConstruct(LifeCycleObject* object) { | |
| 67 ASSERT_EQ(LC_INITIAL, life_cycle_state_); | |
| 68 ASSERT_EQ(NULL, constructed_life_cycle_object_); | |
| 69 life_cycle_state_ = LC_CONSTRUCTED; | |
| 70 constructed_life_cycle_object_ = object; | |
| 71 } | |
| 72 | |
| 73 // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the | |
| 74 // same one we saw constructed. | |
| 75 virtual void OnLifeCycleDestroy (LifeCycleObject* object) { | |
|
James Hawkins
2011/03/21 01:45:06
Remove space before opening parenthesis.
Sheridan Rawlins
2011/03/21 05:20:17
Done.
| |
| 76 ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_); | |
| 77 ASSERT_EQ(constructed_life_cycle_object_, object); | |
| 78 life_cycle_state_ = LC_DESTROYED; | |
| 79 constructed_life_cycle_object_ = NULL; | |
| 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 LifeCycleObject* constructed_life_cycle_object_; | |
|
James Hawkins
2011/03/21 01:45:06
scoped_ptr
Sheridan Rawlins
2011/03/21 05:20:17
Done.
| |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher); | |
| 95 }; | |
| 96 | |
| 97 } // namespace | |
|
James Hawkins
2011/03/21 01:45:06
Wrap the rest of the file in the anonymous namespa
Sheridan Rawlins
2011/03/21 05:20:17
Man, I really copy/pasted some mediocrity from sco
| |
| 98 | |
| 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 | |
| 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 | |
| 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 | |
| 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 } | |
| OLD | NEW |