1
0

observer_list_unittest.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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/observer_list.h"
  5. #include <vector>
  6. #include "butil/compiler_specific.h"
  7. #include "butil/memory/weak_ptr.h"
  8. #include "butil/threading/platform_thread.h"
  9. #include <gtest/gtest.h>
  10. namespace butil {
  11. namespace {
  12. class Foo {
  13. public:
  14. virtual void Observe(int x) = 0;
  15. virtual ~Foo() {}
  16. };
  17. class Adder : public Foo {
  18. public:
  19. explicit Adder(int scaler) : total(0), scaler_(scaler) {}
  20. virtual void Observe(int x) OVERRIDE {
  21. total += x * scaler_;
  22. }
  23. virtual ~Adder() {}
  24. int total;
  25. private:
  26. int scaler_;
  27. };
  28. class Disrupter : public Foo {
  29. public:
  30. Disrupter(ObserverList<Foo>* list, Foo* doomed)
  31. : list_(list),
  32. doomed_(doomed) {
  33. }
  34. virtual ~Disrupter() {}
  35. virtual void Observe(int x) OVERRIDE {
  36. list_->RemoveObserver(doomed_);
  37. }
  38. private:
  39. ObserverList<Foo>* list_;
  40. Foo* doomed_;
  41. };
  42. template <typename ObserverListType>
  43. class AddInObserve : public Foo {
  44. public:
  45. explicit AddInObserve(ObserverListType* observer_list)
  46. : added(false),
  47. observer_list(observer_list),
  48. adder(1) {
  49. }
  50. virtual void Observe(int x) OVERRIDE {
  51. if (!added) {
  52. added = true;
  53. observer_list->AddObserver(&adder);
  54. }
  55. }
  56. bool added;
  57. ObserverListType* observer_list;
  58. Adder adder;
  59. };
  60. TEST(ObserverListTest, BasicTest) {
  61. ObserverList<Foo> observer_list;
  62. Adder a(1), b(-1), c(1), d(-1), e(-1);
  63. Disrupter evil(&observer_list, &c);
  64. observer_list.AddObserver(&a);
  65. observer_list.AddObserver(&b);
  66. FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
  67. observer_list.AddObserver(&evil);
  68. observer_list.AddObserver(&c);
  69. observer_list.AddObserver(&d);
  70. // Removing an observer not in the list should do nothing.
  71. observer_list.RemoveObserver(&e);
  72. FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
  73. EXPECT_EQ(20, a.total);
  74. EXPECT_EQ(-20, b.total);
  75. EXPECT_EQ(0, c.total);
  76. EXPECT_EQ(-10, d.total);
  77. EXPECT_EQ(0, e.total);
  78. }
  79. TEST(ObserverListTest, Existing) {
  80. ObserverList<Foo> observer_list(ObserverList<Foo>::NOTIFY_EXISTING_ONLY);
  81. Adder a(1);
  82. AddInObserve<ObserverList<Foo> > b(&observer_list);
  83. observer_list.AddObserver(&a);
  84. observer_list.AddObserver(&b);
  85. FOR_EACH_OBSERVER(Foo, observer_list, Observe(1));
  86. EXPECT_TRUE(b.added);
  87. // B's adder should not have been notified because it was added during
  88. // notification.
  89. EXPECT_EQ(0, b.adder.total);
  90. // Notify again to make sure b's adder is notified.
  91. FOR_EACH_OBSERVER(Foo, observer_list, Observe(1));
  92. EXPECT_EQ(1, b.adder.total);
  93. }
  94. class AddInClearObserve : public Foo {
  95. public:
  96. explicit AddInClearObserve(ObserverList<Foo>* list)
  97. : list_(list), added_(false), adder_(1) {}
  98. virtual void Observe(int /* x */) OVERRIDE {
  99. list_->Clear();
  100. list_->AddObserver(&adder_);
  101. added_ = true;
  102. }
  103. bool added() const { return added_; }
  104. const Adder& adder() const { return adder_; }
  105. private:
  106. ObserverList<Foo>* const list_;
  107. bool added_;
  108. Adder adder_;
  109. };
  110. TEST(ObserverListTest, ClearNotifyAll) {
  111. ObserverList<Foo> observer_list;
  112. AddInClearObserve a(&observer_list);
  113. observer_list.AddObserver(&a);
  114. FOR_EACH_OBSERVER(Foo, observer_list, Observe(1));
  115. EXPECT_TRUE(a.added());
  116. EXPECT_EQ(1, a.adder().total)
  117. << "Adder should observe once and have sum of 1.";
  118. }
  119. TEST(ObserverListTest, ClearNotifyExistingOnly) {
  120. ObserverList<Foo> observer_list(ObserverList<Foo>::NOTIFY_EXISTING_ONLY);
  121. AddInClearObserve a(&observer_list);
  122. observer_list.AddObserver(&a);
  123. FOR_EACH_OBSERVER(Foo, observer_list, Observe(1));
  124. EXPECT_TRUE(a.added());
  125. EXPECT_EQ(0, a.adder().total)
  126. << "Adder should not observe, so sum should still be 0.";
  127. }
  128. class ListDestructor : public Foo {
  129. public:
  130. explicit ListDestructor(ObserverList<Foo>* list) : list_(list) {}
  131. virtual ~ListDestructor() {}
  132. virtual void Observe(int x) OVERRIDE {
  133. delete list_;
  134. }
  135. private:
  136. ObserverList<Foo>* list_;
  137. };
  138. TEST(ObserverListTest, IteratorOutlivesList) {
  139. ObserverList<Foo>* observer_list = new ObserverList<Foo>;
  140. ListDestructor a(observer_list);
  141. observer_list->AddObserver(&a);
  142. FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0));
  143. // If this test fails, there'll be Valgrind errors when this function goes out
  144. // of scope.
  145. }
  146. } // namespace
  147. } // namespace butil