scoped_multi_source_observation_unittest.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // Copyright 2020 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 "base/scoped_multi_source_observation.h"
  5. #include "base/containers/contains.h"
  6. #include "base/ranges/algorithm.h"
  7. #include "base/test/gtest_util.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace base {
  10. namespace {
  11. class TestSourceObserver {};
  12. class TestSource {
  13. public:
  14. void AddObserver(TestSourceObserver* observer);
  15. void RemoveObserver(TestSourceObserver* observer);
  16. bool HasObserver(TestSourceObserver* observer) const;
  17. size_t num_observers() const { return observers_.size(); }
  18. private:
  19. std::vector<TestSourceObserver*> observers_;
  20. };
  21. void TestSource::AddObserver(TestSourceObserver* observer) {
  22. observers_.push_back(observer);
  23. }
  24. void TestSource::RemoveObserver(TestSourceObserver* observer) {
  25. auto it = base::ranges::find(observers_, observer);
  26. ASSERT_TRUE(it != observers_.end());
  27. observers_.erase(it);
  28. }
  29. bool TestSource::HasObserver(TestSourceObserver* observer) const {
  30. return base::Contains(observers_, observer);
  31. }
  32. using TestScopedMultiSourceObservation =
  33. ScopedMultiSourceObservation<TestSource, TestSourceObserver>;
  34. class ScopedMultiSourceObservationTest : public testing::Test {
  35. public:
  36. TestSource* s1() { return &s1_; }
  37. TestSource* s2() { return &s2_; }
  38. TestSourceObserver* o1() { return &o1_; }
  39. private:
  40. TestSource s1_;
  41. TestSource s2_;
  42. TestSourceObserver o1_;
  43. };
  44. } // namespace
  45. TEST_F(ScopedMultiSourceObservationTest, RemovesSourcesOnDestruction) {
  46. {
  47. TestScopedMultiSourceObservation obs(o1());
  48. EXPECT_EQ(0u, s1()->num_observers());
  49. EXPECT_FALSE(s1()->HasObserver(o1()));
  50. obs.AddObservation(s1());
  51. EXPECT_EQ(1u, s1()->num_observers());
  52. EXPECT_TRUE(s1()->HasObserver(o1()));
  53. obs.AddObservation(s2());
  54. EXPECT_EQ(1u, s2()->num_observers());
  55. EXPECT_TRUE(s2()->HasObserver(o1()));
  56. }
  57. // Test that all observations are removed when it goes out of scope.
  58. EXPECT_EQ(0u, s1()->num_observers());
  59. EXPECT_EQ(0u, s2()->num_observers());
  60. }
  61. TEST_F(ScopedMultiSourceObservationTest, RemoveObservation) {
  62. TestScopedMultiSourceObservation obs(o1());
  63. EXPECT_EQ(0u, s1()->num_observers());
  64. EXPECT_FALSE(s1()->HasObserver(o1()));
  65. EXPECT_EQ(0u, s2()->num_observers());
  66. EXPECT_FALSE(s2()->HasObserver(o1()));
  67. obs.AddObservation(s1());
  68. EXPECT_EQ(1u, s1()->num_observers());
  69. EXPECT_TRUE(s1()->HasObserver(o1()));
  70. obs.AddObservation(s2());
  71. EXPECT_EQ(1u, s2()->num_observers());
  72. EXPECT_TRUE(s2()->HasObserver(o1()));
  73. obs.RemoveObservation(s1());
  74. EXPECT_EQ(0u, s1()->num_observers());
  75. EXPECT_FALSE(s1()->HasObserver(o1()));
  76. EXPECT_EQ(1u, s2()->num_observers());
  77. EXPECT_TRUE(s2()->HasObserver(o1()));
  78. obs.RemoveObservation(s2());
  79. EXPECT_EQ(0u, s1()->num_observers());
  80. EXPECT_FALSE(s1()->HasObserver(o1()));
  81. EXPECT_EQ(0u, s2()->num_observers());
  82. EXPECT_FALSE(s2()->HasObserver(o1()));
  83. }
  84. TEST_F(ScopedMultiSourceObservationTest, RemoveAllObservations) {
  85. TestScopedMultiSourceObservation obs(o1());
  86. EXPECT_EQ(0u, s1()->num_observers());
  87. EXPECT_FALSE(s1()->HasObserver(o1()));
  88. EXPECT_EQ(0u, s2()->num_observers());
  89. EXPECT_FALSE(s2()->HasObserver(o1()));
  90. obs.AddObservation(s1());
  91. obs.AddObservation(s2());
  92. EXPECT_EQ(1u, s1()->num_observers());
  93. EXPECT_TRUE(s1()->HasObserver(o1()));
  94. EXPECT_EQ(1u, s2()->num_observers());
  95. EXPECT_TRUE(s2()->HasObserver(o1()));
  96. obs.RemoveAllObservations();
  97. EXPECT_EQ(0u, s1()->num_observers());
  98. EXPECT_FALSE(s1()->HasObserver(o1()));
  99. EXPECT_EQ(0u, s2()->num_observers());
  100. EXPECT_FALSE(s2()->HasObserver(o1()));
  101. }
  102. TEST_F(ScopedMultiSourceObservationTest, IsObservingSource) {
  103. TestScopedMultiSourceObservation obs(o1());
  104. EXPECT_FALSE(obs.IsObservingSource(s1()));
  105. EXPECT_FALSE(obs.IsObservingSource(s2()));
  106. obs.AddObservation(s1());
  107. EXPECT_TRUE(obs.IsObservingSource(s1()));
  108. EXPECT_FALSE(obs.IsObservingSource(s2()));
  109. obs.AddObservation(s2());
  110. EXPECT_TRUE(obs.IsObservingSource(s1()));
  111. EXPECT_TRUE(obs.IsObservingSource(s2()));
  112. obs.RemoveObservation(s1());
  113. EXPECT_FALSE(obs.IsObservingSource(s1()));
  114. EXPECT_TRUE(obs.IsObservingSource(s2()));
  115. }
  116. TEST_F(ScopedMultiSourceObservationTest, IsObservingAnySource) {
  117. TestScopedMultiSourceObservation obs(o1());
  118. EXPECT_FALSE(obs.IsObservingAnySource());
  119. obs.AddObservation(s1());
  120. EXPECT_TRUE(obs.IsObservingAnySource());
  121. obs.AddObservation(s2());
  122. EXPECT_TRUE(obs.IsObservingAnySource());
  123. obs.RemoveAllObservations();
  124. EXPECT_FALSE(obs.IsObservingAnySource());
  125. }
  126. TEST_F(ScopedMultiSourceObservationTest, GetSourcesCount) {
  127. TestScopedMultiSourceObservation obs(o1());
  128. EXPECT_EQ(0u, obs.GetSourcesCount());
  129. obs.AddObservation(s1());
  130. EXPECT_EQ(1u, obs.GetSourcesCount());
  131. obs.AddObservation(s2());
  132. EXPECT_EQ(2u, obs.GetSourcesCount());
  133. obs.RemoveAllObservations();
  134. EXPECT_EQ(0u, obs.GetSourcesCount());
  135. }
  136. namespace {
  137. // A test source with oddly named Add/Remove functions.
  138. class TestSourceWithNonDefaultNames {
  139. public:
  140. void AddFoo(TestSourceObserver* observer) { impl_.AddObserver(observer); }
  141. void RemoveFoo(TestSourceObserver* observer) {
  142. impl_.RemoveObserver(observer);
  143. }
  144. const TestSource& impl() const { return impl_; }
  145. private:
  146. TestSource impl_;
  147. };
  148. using TestScopedMultiSourceObservationWithNonDefaultNames =
  149. ScopedMultiSourceObservation<TestSourceWithNonDefaultNames,
  150. TestSourceObserver,
  151. &TestSourceWithNonDefaultNames::AddFoo,
  152. &TestSourceWithNonDefaultNames::RemoveFoo>;
  153. } // namespace
  154. TEST_F(ScopedMultiSourceObservationTest, NonDefaultNames) {
  155. TestSourceWithNonDefaultNames nds1;
  156. EXPECT_EQ(0u, nds1.impl().num_observers());
  157. {
  158. TestScopedMultiSourceObservationWithNonDefaultNames obs(o1());
  159. obs.AddObservation(&nds1);
  160. EXPECT_EQ(1u, nds1.impl().num_observers());
  161. EXPECT_TRUE(nds1.impl().HasObserver(o1()));
  162. }
  163. EXPECT_EQ(0u, nds1.impl().num_observers());
  164. }
  165. } // namespace base