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.
5 #include "base/prefs/pref_member.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 const char kBoolPref
[] = "bool";
18 const char kIntPref
[] = "int";
19 const char kDoublePref
[] = "double";
20 const char kStringPref
[] = "string";
21 const char kStringListPref
[] = "string_list";
23 void RegisterTestPrefs(PrefRegistrySimple
* registry
) {
24 registry
->RegisterBooleanPref(kBoolPref
, false);
25 registry
->RegisterIntegerPref(kIntPref
, 0);
26 registry
->RegisterDoublePref(kDoublePref
, 0.0);
27 registry
->RegisterStringPref(kStringPref
, "default");
28 registry
->RegisterListPref(kStringListPref
, new base::ListValue());
31 class GetPrefValueHelper
32 : public base::RefCountedThreadSafe
<GetPrefValueHelper
> {
34 GetPrefValueHelper() : value_(false), pref_thread_("pref thread") {
38 void Init(const std::string
& pref_name
, PrefService
* prefs
) {
39 pref_
.Init(pref_name
, prefs
);
40 pref_
.MoveToThread(pref_thread_
.message_loop_proxy());
48 base::WaitableEvent
event(true, false);
50 pref_thread_
.message_loop_proxy()->PostTask(
52 base::Bind(&GetPrefValueHelper::GetPrefValue
, this, &event
)));
56 // The thread must be stopped on the main thread. GetPrefValueHelper being
57 // ref-counted, the destructor can be called from any thread.
62 bool value() { return value_
; }
65 friend class base::RefCountedThreadSafe
<GetPrefValueHelper
>;
66 ~GetPrefValueHelper() {}
68 void GetPrefValue(base::WaitableEvent
* event
) {
69 value_
= pref_
.GetValue();
73 BooleanPrefMember pref_
;
76 base::Thread pref_thread_
; // The thread |pref_| runs on.
79 class PrefMemberTestClass
{
81 explicit PrefMemberTestClass(PrefService
* prefs
)
82 : observe_cnt_(0), prefs_(prefs
) {
83 str_
.Init(kStringPref
, prefs
,
84 base::Bind(&PrefMemberTestClass::OnPreferenceChanged
,
85 base::Unretained(this)));
88 void OnPreferenceChanged(const std::string
& pref_name
) {
89 EXPECT_EQ(pref_name
, kStringPref
);
90 EXPECT_EQ(str_
.GetValue(), prefs_
->GetString(kStringPref
));
94 StringPrefMember str_
;
101 } // anonymous namespace
103 TEST(PrefMemberTest
, BasicGetAndSet
) {
104 TestingPrefServiceSimple prefs
;
105 RegisterTestPrefs(prefs
.registry());
108 BooleanPrefMember boolean
;
109 boolean
.Init(kBoolPref
, &prefs
);
111 // Check the defaults
112 EXPECT_FALSE(prefs
.GetBoolean(kBoolPref
));
113 EXPECT_FALSE(boolean
.GetValue());
114 EXPECT_FALSE(*boolean
);
116 // Try changing through the member variable.
117 boolean
.SetValue(true);
118 EXPECT_TRUE(boolean
.GetValue());
119 EXPECT_TRUE(prefs
.GetBoolean(kBoolPref
));
120 EXPECT_TRUE(*boolean
);
122 // Try changing back through the pref.
123 prefs
.SetBoolean(kBoolPref
, false);
124 EXPECT_FALSE(prefs
.GetBoolean(kBoolPref
));
125 EXPECT_FALSE(boolean
.GetValue());
126 EXPECT_FALSE(*boolean
);
129 IntegerPrefMember integer
;
130 integer
.Init(kIntPref
, &prefs
);
132 // Check the defaults
133 EXPECT_EQ(0, prefs
.GetInteger(kIntPref
));
134 EXPECT_EQ(0, integer
.GetValue());
135 EXPECT_EQ(0, *integer
);
137 // Try changing through the member variable.
139 EXPECT_EQ(5, integer
.GetValue());
140 EXPECT_EQ(5, prefs
.GetInteger(kIntPref
));
141 EXPECT_EQ(5, *integer
);
143 // Try changing back through the pref.
144 prefs
.SetInteger(kIntPref
, 2);
145 EXPECT_EQ(2, prefs
.GetInteger(kIntPref
));
146 EXPECT_EQ(2, integer
.GetValue());
147 EXPECT_EQ(2, *integer
);
150 DoublePrefMember double_member
;
151 double_member
.Init(kDoublePref
, &prefs
);
153 // Check the defaults
154 EXPECT_EQ(0.0, prefs
.GetDouble(kDoublePref
));
155 EXPECT_EQ(0.0, double_member
.GetValue());
156 EXPECT_EQ(0.0, *double_member
);
158 // Try changing through the member variable.
159 double_member
.SetValue(1.0);
160 EXPECT_EQ(1.0, double_member
.GetValue());
161 EXPECT_EQ(1.0, prefs
.GetDouble(kDoublePref
));
162 EXPECT_EQ(1.0, *double_member
);
164 // Try changing back through the pref.
165 prefs
.SetDouble(kDoublePref
, 3.0);
166 EXPECT_EQ(3.0, prefs
.GetDouble(kDoublePref
));
167 EXPECT_EQ(3.0, double_member
.GetValue());
168 EXPECT_EQ(3.0, *double_member
);
171 StringPrefMember string
;
172 string
.Init(kStringPref
, &prefs
);
174 // Check the defaults
175 EXPECT_EQ("default", prefs
.GetString(kStringPref
));
176 EXPECT_EQ("default", string
.GetValue());
177 EXPECT_EQ("default", *string
);
179 // Try changing through the member variable.
180 string
.SetValue("foo");
181 EXPECT_EQ("foo", string
.GetValue());
182 EXPECT_EQ("foo", prefs
.GetString(kStringPref
));
183 EXPECT_EQ("foo", *string
);
185 // Try changing back through the pref.
186 prefs
.SetString(kStringPref
, "bar");
187 EXPECT_EQ("bar", prefs
.GetString(kStringPref
));
188 EXPECT_EQ("bar", string
.GetValue());
189 EXPECT_EQ("bar", *string
);
192 base::ListValue expected_list
;
193 std::vector
<std::string
> expected_vector
;
194 StringListPrefMember string_list
;
195 string_list
.Init(kStringListPref
, &prefs
);
197 // Check the defaults
198 EXPECT_TRUE(expected_list
.Equals(prefs
.GetList(kStringListPref
)));
199 EXPECT_EQ(expected_vector
, string_list
.GetValue());
200 EXPECT_EQ(expected_vector
, *string_list
);
202 // Try changing through the pref member.
203 expected_list
.AppendString("foo");
204 expected_vector
.push_back("foo");
205 string_list
.SetValue(expected_vector
);
207 EXPECT_TRUE(expected_list
.Equals(prefs
.GetList(kStringListPref
)));
208 EXPECT_EQ(expected_vector
, string_list
.GetValue());
209 EXPECT_EQ(expected_vector
, *string_list
);
211 // Try adding through the pref.
212 expected_list
.AppendString("bar");
213 expected_vector
.push_back("bar");
214 prefs
.Set(kStringListPref
, expected_list
);
216 EXPECT_TRUE(expected_list
.Equals(prefs
.GetList(kStringListPref
)));
217 EXPECT_EQ(expected_vector
, string_list
.GetValue());
218 EXPECT_EQ(expected_vector
, *string_list
);
220 // Try removing through the pref.
221 expected_list
.Remove(0, NULL
);
222 expected_vector
.erase(expected_vector
.begin());
223 prefs
.Set(kStringListPref
, expected_list
);
225 EXPECT_TRUE(expected_list
.Equals(prefs
.GetList(kStringListPref
)));
226 EXPECT_EQ(expected_vector
, string_list
.GetValue());
227 EXPECT_EQ(expected_vector
, *string_list
);
230 TEST(PrefMemberTest
, InvalidList
) {
231 // Set the vector to an initial good value.
232 std::vector
<std::string
> expected_vector
;
233 expected_vector
.push_back("foo");
235 // Try to add a valid list first.
236 base::ListValue list
;
237 list
.AppendString("foo");
238 std::vector
<std::string
> vector
;
239 EXPECT_TRUE(subtle::PrefMemberVectorStringUpdate(list
, &vector
));
240 EXPECT_EQ(expected_vector
, vector
);
242 // Now try to add an invalid list. |vector| should not be changed.
243 list
.AppendInteger(0);
244 EXPECT_FALSE(subtle::PrefMemberVectorStringUpdate(list
, &vector
));
245 EXPECT_EQ(expected_vector
, vector
);
248 TEST(PrefMemberTest
, TwoPrefs
) {
249 // Make sure two DoublePrefMembers stay in sync.
250 TestingPrefServiceSimple prefs
;
251 RegisterTestPrefs(prefs
.registry());
253 DoublePrefMember pref1
;
254 pref1
.Init(kDoublePref
, &prefs
);
255 DoublePrefMember pref2
;
256 pref2
.Init(kDoublePref
, &prefs
);
259 EXPECT_EQ(2.3, *pref2
);
262 EXPECT_EQ(3.5, *pref1
);
264 prefs
.SetDouble(kDoublePref
, 4.2);
265 EXPECT_EQ(4.2, *pref1
);
266 EXPECT_EQ(4.2, *pref2
);
269 TEST(PrefMemberTest
, Observer
) {
270 TestingPrefServiceSimple prefs
;
271 RegisterTestPrefs(prefs
.registry());
273 PrefMemberTestClass
test_obj(&prefs
);
274 EXPECT_EQ("default", *test_obj
.str_
);
276 // Calling SetValue should not fire the observer.
277 test_obj
.str_
.SetValue("hello");
278 EXPECT_EQ(0, test_obj
.observe_cnt_
);
279 EXPECT_EQ("hello", prefs
.GetString(kStringPref
));
281 // Changing the pref does fire the observer.
282 prefs
.SetString(kStringPref
, "world");
283 EXPECT_EQ(1, test_obj
.observe_cnt_
);
284 EXPECT_EQ("world", *(test_obj
.str_
));
286 // Not changing the value should not fire the observer.
287 prefs
.SetString(kStringPref
, "world");
288 EXPECT_EQ(1, test_obj
.observe_cnt_
);
289 EXPECT_EQ("world", *(test_obj
.str_
));
291 prefs
.SetString(kStringPref
, "hello");
292 EXPECT_EQ(2, test_obj
.observe_cnt_
);
293 EXPECT_EQ("hello", prefs
.GetString(kStringPref
));
296 TEST(PrefMemberTest
, NoInit
) {
297 // Make sure not calling Init on a PrefMember doesn't cause problems.
298 IntegerPrefMember pref
;
301 TEST(PrefMemberTest
, MoveToThread
) {
302 TestingPrefServiceSimple prefs
;
303 scoped_refptr
<GetPrefValueHelper
> helper(new GetPrefValueHelper());
304 RegisterTestPrefs(prefs
.registry());
305 helper
->Init(kBoolPref
, &prefs
);
307 helper
->FetchValue();
308 EXPECT_FALSE(helper
->value());
310 prefs
.SetBoolean(kBoolPref
, true);
312 helper
->FetchValue();
313 EXPECT_TRUE(helper
->value());
317 helper
->FetchValue();
318 EXPECT_TRUE(helper
->value());
320 helper
->StopThread();