scoped_vector_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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. #include "butil/memory/scoped_vector.h"
  5. #include "butil/memory/scoped_ptr.h"
  6. #include <gtest/gtest.h>
  7. namespace {
  8. // The LifeCycleObject notifies its Observer upon construction & destruction.
  9. class LifeCycleObject {
  10. public:
  11. class Observer {
  12. public:
  13. virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
  14. virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
  15. protected:
  16. virtual ~Observer() {}
  17. };
  18. ~LifeCycleObject() {
  19. observer_->OnLifeCycleDestroy(this);
  20. }
  21. private:
  22. friend class LifeCycleWatcher;
  23. explicit LifeCycleObject(Observer* observer)
  24. : observer_(observer) {
  25. observer_->OnLifeCycleConstruct(this);
  26. }
  27. Observer* observer_;
  28. DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
  29. };
  30. // The life cycle states we care about for the purposes of testing ScopedVector
  31. // against objects.
  32. enum LifeCycleState {
  33. LC_INITIAL,
  34. LC_CONSTRUCTED,
  35. LC_DESTROYED,
  36. };
  37. // Because we wish to watch the life cycle of an object being constructed and
  38. // destroyed, and further wish to test expectations against the state of that
  39. // object, we cannot save state in that object itself. Instead, we use this
  40. // pairing of the watcher, which observes the object and notifies of
  41. // construction & destruction. Since we also may be testing assumptions about
  42. // things not getting freed, this class also acts like a scoping object and
  43. // deletes the |constructed_life_cycle_object_|, if any when the
  44. // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
  45. // changes are:
  46. // INITIAL -> CONSTRUCTED -> DESTROYED.
  47. // Anything more complicated than that should start another test.
  48. class LifeCycleWatcher : public LifeCycleObject::Observer {
  49. public:
  50. LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
  51. virtual ~LifeCycleWatcher() {}
  52. // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
  53. // LifeCycleWatcher.
  54. virtual void OnLifeCycleConstruct(LifeCycleObject* object) OVERRIDE {
  55. ASSERT_EQ(LC_INITIAL, life_cycle_state_);
  56. ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
  57. life_cycle_state_ = LC_CONSTRUCTED;
  58. constructed_life_cycle_object_.reset(object);
  59. }
  60. // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
  61. // same one we saw constructed.
  62. virtual void OnLifeCycleDestroy(LifeCycleObject* object) OVERRIDE {
  63. ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
  64. LifeCycleObject* constructed_life_cycle_object =
  65. constructed_life_cycle_object_.release();
  66. ASSERT_EQ(constructed_life_cycle_object, object);
  67. life_cycle_state_ = LC_DESTROYED;
  68. }
  69. LifeCycleState life_cycle_state() const { return life_cycle_state_; }
  70. // Factory method for creating a new LifeCycleObject tied to this
  71. // LifeCycleWatcher.
  72. LifeCycleObject* NewLifeCycleObject() {
  73. return new LifeCycleObject(this);
  74. }
  75. // Returns true iff |object| is the same object that this watcher is tracking.
  76. bool IsWatching(LifeCycleObject* object) const {
  77. return object == constructed_life_cycle_object_.get();
  78. }
  79. private:
  80. LifeCycleState life_cycle_state_;
  81. scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
  82. DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
  83. };
  84. TEST(ScopedVectorTest, LifeCycleWatcher) {
  85. LifeCycleWatcher watcher;
  86. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  87. LifeCycleObject* object = watcher.NewLifeCycleObject();
  88. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  89. delete object;
  90. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  91. }
  92. TEST(ScopedVectorTest, PopBack) {
  93. LifeCycleWatcher watcher;
  94. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  95. butil::ScopedVector<LifeCycleObject> scoped_vector;
  96. scoped_vector.push_back(watcher.NewLifeCycleObject());
  97. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  98. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  99. scoped_vector.pop_back();
  100. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  101. EXPECT_TRUE(scoped_vector.empty());
  102. }
  103. TEST(ScopedVectorTest, Clear) {
  104. LifeCycleWatcher watcher;
  105. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  106. butil::ScopedVector<LifeCycleObject> scoped_vector;
  107. scoped_vector.push_back(watcher.NewLifeCycleObject());
  108. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  109. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  110. scoped_vector.clear();
  111. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  112. EXPECT_TRUE(scoped_vector.empty());
  113. }
  114. TEST(ScopedVectorTest, WeakClear) {
  115. LifeCycleWatcher watcher;
  116. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  117. butil::ScopedVector<LifeCycleObject> scoped_vector;
  118. scoped_vector.push_back(watcher.NewLifeCycleObject());
  119. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  120. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  121. scoped_vector.weak_clear();
  122. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  123. EXPECT_TRUE(scoped_vector.empty());
  124. }
  125. TEST(ScopedVectorTest, ResizeShrink) {
  126. LifeCycleWatcher first_watcher;
  127. EXPECT_EQ(LC_INITIAL, first_watcher.life_cycle_state());
  128. LifeCycleWatcher second_watcher;
  129. EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
  130. butil::ScopedVector<LifeCycleObject> scoped_vector;
  131. scoped_vector.push_back(first_watcher.NewLifeCycleObject());
  132. EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
  133. EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
  134. EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
  135. EXPECT_FALSE(second_watcher.IsWatching(scoped_vector[0]));
  136. scoped_vector.push_back(second_watcher.NewLifeCycleObject());
  137. EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
  138. EXPECT_EQ(LC_CONSTRUCTED, second_watcher.life_cycle_state());
  139. EXPECT_FALSE(first_watcher.IsWatching(scoped_vector[1]));
  140. EXPECT_TRUE(second_watcher.IsWatching(scoped_vector[1]));
  141. // Test that shrinking a vector deletes elements in the disappearing range.
  142. scoped_vector.resize(1);
  143. EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
  144. EXPECT_EQ(LC_DESTROYED, second_watcher.life_cycle_state());
  145. EXPECT_EQ(1u, scoped_vector.size());
  146. EXPECT_TRUE(first_watcher.IsWatching(scoped_vector[0]));
  147. }
  148. TEST(ScopedVectorTest, ResizeGrow) {
  149. LifeCycleWatcher watcher;
  150. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  151. butil::ScopedVector<LifeCycleObject> scoped_vector;
  152. scoped_vector.push_back(watcher.NewLifeCycleObject());
  153. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  154. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  155. scoped_vector.resize(5);
  156. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  157. ASSERT_EQ(5u, scoped_vector.size());
  158. EXPECT_TRUE(watcher.IsWatching(scoped_vector[0]));
  159. EXPECT_FALSE(watcher.IsWatching(scoped_vector[1]));
  160. EXPECT_FALSE(watcher.IsWatching(scoped_vector[2]));
  161. EXPECT_FALSE(watcher.IsWatching(scoped_vector[3]));
  162. EXPECT_FALSE(watcher.IsWatching(scoped_vector[4]));
  163. }
  164. TEST(ScopedVectorTest, Scope) {
  165. LifeCycleWatcher watcher;
  166. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  167. {
  168. butil::ScopedVector<LifeCycleObject> scoped_vector;
  169. scoped_vector.push_back(watcher.NewLifeCycleObject());
  170. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  171. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  172. }
  173. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  174. }
  175. TEST(ScopedVectorTest, Scope2) {
  176. LifeCycleWatcher watcher;
  177. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  178. {
  179. butil::ScopedVector<LifeCycleObject> scoped_vector{ watcher.NewLifeCycleObject() };
  180. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  181. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  182. }
  183. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  184. }
  185. TEST(ScopedVectorTest, MoveConstruct) {
  186. LifeCycleWatcher watcher;
  187. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  188. {
  189. butil::ScopedVector<LifeCycleObject> scoped_vector;
  190. scoped_vector.push_back(watcher.NewLifeCycleObject());
  191. EXPECT_FALSE(scoped_vector.empty());
  192. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  193. butil::ScopedVector<LifeCycleObject> scoped_vector_copy(scoped_vector.Pass());
  194. EXPECT_TRUE(scoped_vector.empty());
  195. EXPECT_FALSE(scoped_vector_copy.empty());
  196. EXPECT_TRUE(watcher.IsWatching(scoped_vector_copy.back()));
  197. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  198. }
  199. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  200. }
  201. TEST(ScopedVectorTest, MoveAssign) {
  202. LifeCycleWatcher watcher;
  203. EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
  204. {
  205. butil::ScopedVector<LifeCycleObject> scoped_vector;
  206. scoped_vector.push_back(watcher.NewLifeCycleObject());
  207. butil::ScopedVector<LifeCycleObject> scoped_vector_assign;
  208. EXPECT_FALSE(scoped_vector.empty());
  209. EXPECT_TRUE(watcher.IsWatching(scoped_vector.back()));
  210. scoped_vector_assign = scoped_vector.Pass();
  211. EXPECT_TRUE(scoped_vector.empty());
  212. EXPECT_FALSE(scoped_vector_assign.empty());
  213. EXPECT_TRUE(watcher.IsWatching(scoped_vector_assign.back()));
  214. EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
  215. }
  216. EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
  217. }
  218. class DeleteCounter {
  219. public:
  220. explicit DeleteCounter(int* deletes)
  221. : deletes_(deletes) {
  222. }
  223. ~DeleteCounter() {
  224. (*deletes_)++;
  225. }
  226. void VoidMethod0() {}
  227. private:
  228. int* const deletes_;
  229. DISALLOW_COPY_AND_ASSIGN(DeleteCounter);
  230. };
  231. template <typename T>
  232. butil::ScopedVector<T> PassThru(butil::ScopedVector<T> scoper) {
  233. return scoper.Pass();
  234. }
  235. TEST(ScopedVectorTest, Passed) {
  236. int deletes = 0;
  237. butil::ScopedVector<DeleteCounter> deleter_vector;
  238. deleter_vector.push_back(new DeleteCounter(&deletes));
  239. EXPECT_EQ(0, deletes);
  240. EXPECT_EQ(0, deletes);
  241. butil::ScopedVector<DeleteCounter> result = deleter_vector.Pass();
  242. EXPECT_EQ(0, deletes);
  243. result.clear();
  244. EXPECT_EQ(1, deletes);
  245. };
  246. TEST(ScopedVectorTest, InsertRange) {
  247. LifeCycleWatcher watchers[5];
  248. std::vector<LifeCycleObject*> vec;
  249. for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
  250. ++it) {
  251. EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
  252. vec.push_back(it->NewLifeCycleObject());
  253. EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
  254. }
  255. // Start scope for ScopedVector.
  256. {
  257. butil::ScopedVector<LifeCycleObject> scoped_vector;
  258. scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
  259. for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
  260. ++it)
  261. EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
  262. }
  263. for(LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
  264. EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
  265. for(LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
  266. EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
  267. for(LifeCycleWatcher* it = watchers + 3; it != watchers + arraysize(watchers);
  268. ++it)
  269. EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
  270. }
  271. } // namespace