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