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