pref_notifier_impl_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. #include <stddef.h>
  5. #include "base/bind.h"
  6. #include "base/callback.h"
  7. #include "components/prefs/mock_pref_change_callback.h"
  8. #include "components/prefs/pref_notifier_impl.h"
  9. #include "components/prefs/pref_observer.h"
  10. #include "components/prefs/pref_registry_simple.h"
  11. #include "components/prefs/pref_service.h"
  12. #include "components/prefs/pref_value_store.h"
  13. #include "components/prefs/testing_pref_service.h"
  14. #include "testing/gmock/include/gmock/gmock.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. using testing::_;
  17. using testing::Field;
  18. using testing::Invoke;
  19. using testing::Mock;
  20. using testing::Truly;
  21. namespace {
  22. const char kChangedPref[] = "changed_pref";
  23. const char kUnchangedPref[] = "unchanged_pref";
  24. class MockPrefInitObserver {
  25. public:
  26. MOCK_METHOD1(OnInitializationCompleted, void(bool));
  27. };
  28. // This is an unmodified PrefNotifierImpl, except we make
  29. // OnPreferenceChanged public for tests.
  30. class TestingPrefNotifierImpl : public PrefNotifierImpl {
  31. public:
  32. explicit TestingPrefNotifierImpl(PrefService* service)
  33. : PrefNotifierImpl(service) {
  34. }
  35. // Make public for tests.
  36. using PrefNotifierImpl::OnPreferenceChanged;
  37. };
  38. // Mock PrefNotifier that allows tracking of observers and notifications.
  39. class MockPrefNotifier : public PrefNotifierImpl {
  40. public:
  41. explicit MockPrefNotifier(PrefService* pref_service)
  42. : PrefNotifierImpl(pref_service) {}
  43. ~MockPrefNotifier() override {}
  44. MOCK_METHOD1(FireObservers, void(const std::string& path));
  45. size_t CountObserver(const std::string& path, PrefObserver* obs) {
  46. auto observer_iterator = pref_observers()->find(path);
  47. if (observer_iterator == pref_observers()->end())
  48. return false;
  49. size_t count = 0;
  50. for (auto& existing_obs : *observer_iterator->second) {
  51. if (&existing_obs == obs)
  52. count++;
  53. }
  54. return count;
  55. }
  56. // Make public for tests below.
  57. using PrefNotifierImpl::OnPreferenceChanged;
  58. using PrefNotifierImpl::OnInitializationCompleted;
  59. };
  60. class PrefObserverMock : public PrefObserver {
  61. public:
  62. PrefObserverMock() {}
  63. virtual ~PrefObserverMock() {}
  64. MOCK_METHOD2(OnPreferenceChanged, void(PrefService*, const std::string&));
  65. };
  66. // Test fixture class.
  67. class PrefNotifierTest : public testing::Test {
  68. protected:
  69. void SetUp() override {
  70. pref_service_.registry()->RegisterBooleanPref(kChangedPref, true);
  71. pref_service_.registry()->RegisterBooleanPref(kUnchangedPref, true);
  72. }
  73. TestingPrefServiceSimple pref_service_;
  74. PrefObserverMock obs1_;
  75. PrefObserverMock obs2_;
  76. };
  77. TEST_F(PrefNotifierTest, OnPreferenceChanged) {
  78. MockPrefNotifier notifier(&pref_service_);
  79. EXPECT_CALL(notifier, FireObservers(kChangedPref)).Times(1);
  80. notifier.OnPreferenceChanged(kChangedPref);
  81. }
  82. TEST_F(PrefNotifierTest, OnInitializationCompleted) {
  83. MockPrefNotifier notifier(&pref_service_);
  84. MockPrefInitObserver observer;
  85. notifier.AddInitObserver(
  86. base::BindOnce(&MockPrefInitObserver::OnInitializationCompleted,
  87. base::Unretained(&observer)));
  88. EXPECT_CALL(observer, OnInitializationCompleted(true));
  89. notifier.OnInitializationCompleted(true);
  90. }
  91. TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) {
  92. const char pref_name[] = "homepage";
  93. const char pref_name2[] = "proxy";
  94. MockPrefNotifier notifier(&pref_service_);
  95. notifier.AddPrefObserver(pref_name, &obs1_);
  96. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
  97. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
  98. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  99. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  100. // Re-adding the same observer for the same pref doesn't change anything.
  101. // Skip this in debug mode, since it hits a DCHECK and death tests aren't
  102. // thread-safe.
  103. #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
  104. notifier.AddPrefObserver(pref_name, &obs1_);
  105. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
  106. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
  107. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  108. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  109. #endif
  110. // Ensure that we can add the same observer to a different pref.
  111. notifier.AddPrefObserver(pref_name2, &obs1_);
  112. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
  113. ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
  114. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  115. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  116. // Ensure that we can add another observer to the same pref.
  117. notifier.AddPrefObserver(pref_name, &obs2_);
  118. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
  119. ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
  120. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
  121. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  122. // Ensure that we can remove all observers, and that removing a non-existent
  123. // observer is harmless.
  124. notifier.RemovePrefObserver(pref_name, &obs1_);
  125. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
  126. ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
  127. ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
  128. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  129. notifier.RemovePrefObserver(pref_name, &obs2_);
  130. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
  131. ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
  132. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  133. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  134. notifier.RemovePrefObserver(pref_name, &obs1_);
  135. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
  136. ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
  137. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  138. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  139. notifier.RemovePrefObserver(pref_name2, &obs1_);
  140. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
  141. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
  142. ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
  143. ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
  144. }
  145. TEST_F(PrefNotifierTest, FireObservers) {
  146. TestingPrefNotifierImpl notifier(&pref_service_);
  147. notifier.AddPrefObserver(kChangedPref, &obs1_);
  148. notifier.AddPrefObserver(kUnchangedPref, &obs1_);
  149. EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
  150. EXPECT_CALL(obs2_, OnPreferenceChanged(_, _)).Times(0);
  151. notifier.OnPreferenceChanged(kChangedPref);
  152. Mock::VerifyAndClearExpectations(&obs1_);
  153. Mock::VerifyAndClearExpectations(&obs2_);
  154. notifier.AddPrefObserver(kChangedPref, &obs2_);
  155. notifier.AddPrefObserver(kUnchangedPref, &obs2_);
  156. EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
  157. EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
  158. notifier.OnPreferenceChanged(kChangedPref);
  159. Mock::VerifyAndClearExpectations(&obs1_);
  160. Mock::VerifyAndClearExpectations(&obs2_);
  161. // Make sure removing an observer from one pref doesn't affect anything else.
  162. notifier.RemovePrefObserver(kChangedPref, &obs1_);
  163. EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
  164. EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
  165. notifier.OnPreferenceChanged(kChangedPref);
  166. Mock::VerifyAndClearExpectations(&obs1_);
  167. Mock::VerifyAndClearExpectations(&obs2_);
  168. // Make sure removing an observer entirely doesn't affect anything else.
  169. notifier.RemovePrefObserver(kUnchangedPref, &obs1_);
  170. EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
  171. EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
  172. notifier.OnPreferenceChanged(kChangedPref);
  173. Mock::VerifyAndClearExpectations(&obs1_);
  174. Mock::VerifyAndClearExpectations(&obs2_);
  175. notifier.RemovePrefObserver(kChangedPref, &obs2_);
  176. notifier.RemovePrefObserver(kUnchangedPref, &obs2_);
  177. }
  178. } // namespace