pref_member_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 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 "chrome/browser/prefs/pref_member.h"
6
7#include "base/message_loop.h"
8#include "chrome/browser/prefs/pref_value_store.h"
9#include "chrome/common/notification_details.h"
10#include "chrome/common/notification_source.h"
11#include "chrome/common/notification_type.h"
12#include "chrome/test/testing_pref_service.h"
13#include "content/browser/browser_thread.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace {
17
18const char kBoolPref[] = "bool";
19const char kIntPref[] = "int";
20const char kDoublePref[] = "double";
21const char kStringPref[] = "string";
22
23void RegisterTestPrefs(PrefService* prefs) {
24  prefs->RegisterBooleanPref(kBoolPref, false);
25  prefs->RegisterIntegerPref(kIntPref, 0);
26  prefs->RegisterDoublePref(kDoublePref, 0.0);
27  prefs->RegisterStringPref(kStringPref, "default");
28}
29
30class GetPrefValueCallback
31    : public base::RefCountedThreadSafe<GetPrefValueCallback> {
32 public:
33  GetPrefValueCallback() : value_(false) {}
34
35  void Init(const char* pref_name, PrefService* prefs) {
36    pref_.Init(pref_name, prefs, NULL);
37    pref_.MoveToThread(BrowserThread::IO);
38  }
39
40  bool FetchValue() {
41    if (!BrowserThread::PostTask(
42        BrowserThread::IO, FROM_HERE,
43        NewRunnableMethod(this,
44                          &GetPrefValueCallback::GetPrefValueOnIOThread))) {
45      return false;
46    }
47    MessageLoop::current()->Run();
48    return true;
49  }
50
51  bool value() { return value_; }
52
53 private:
54  friend class base::RefCountedThreadSafe<GetPrefValueCallback>;
55  ~GetPrefValueCallback() {}
56
57  void GetPrefValueOnIOThread() {
58    value_ = pref_.GetValue();
59    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
60                            new MessageLoop::QuitTask());
61  }
62
63  BooleanPrefMember pref_;
64  bool value_;
65};
66
67class PrefMemberTestClass : public NotificationObserver {
68 public:
69  explicit PrefMemberTestClass(PrefService* prefs)
70      : observe_cnt_(0), prefs_(prefs) {
71    str_.Init(kStringPref, prefs, this);
72  }
73
74  virtual void Observe(NotificationType type,
75                       const NotificationSource& source,
76                       const NotificationDetails& details) {
77    DCHECK(NotificationType::PREF_CHANGED == type);
78    PrefService* prefs_in = Source<PrefService>(source).ptr();
79    EXPECT_EQ(prefs_in, prefs_);
80    std::string* pref_name_in = Details<std::string>(details).ptr();
81    EXPECT_EQ(*pref_name_in, kStringPref);
82    EXPECT_EQ(str_.GetValue(), prefs_->GetString(kStringPref));
83    ++observe_cnt_;
84  }
85
86  StringPrefMember str_;
87  int observe_cnt_;
88
89 private:
90  PrefService* prefs_;
91};
92
93}  // anonymous namespace
94
95TEST(PrefMemberTest, BasicGetAndSet) {
96  TestingPrefService prefs;
97  RegisterTestPrefs(&prefs);
98
99  // Test bool
100  BooleanPrefMember boolean;
101  boolean.Init(kBoolPref, &prefs, NULL);
102
103  // Check the defaults
104  EXPECT_FALSE(prefs.GetBoolean(kBoolPref));
105  EXPECT_FALSE(boolean.GetValue());
106  EXPECT_FALSE(*boolean);
107
108  // Try changing through the member variable.
109  boolean.SetValue(true);
110  EXPECT_TRUE(boolean.GetValue());
111  EXPECT_TRUE(prefs.GetBoolean(kBoolPref));
112  EXPECT_TRUE(*boolean);
113
114  // Try changing back through the pref.
115  prefs.SetBoolean(kBoolPref, false);
116  EXPECT_FALSE(prefs.GetBoolean(kBoolPref));
117  EXPECT_FALSE(boolean.GetValue());
118  EXPECT_FALSE(*boolean);
119
120  // Test int
121  IntegerPrefMember integer;
122  integer.Init(kIntPref, &prefs, NULL);
123
124  // Check the defaults
125  EXPECT_EQ(0, prefs.GetInteger(kIntPref));
126  EXPECT_EQ(0, integer.GetValue());
127  EXPECT_EQ(0, *integer);
128
129  // Try changing through the member variable.
130  integer.SetValue(5);
131  EXPECT_EQ(5, integer.GetValue());
132  EXPECT_EQ(5, prefs.GetInteger(kIntPref));
133  EXPECT_EQ(5, *integer);
134
135  // Try changing back through the pref.
136  prefs.SetInteger(kIntPref, 2);
137  EXPECT_EQ(2, prefs.GetInteger(kIntPref));
138  EXPECT_EQ(2, integer.GetValue());
139  EXPECT_EQ(2, *integer);
140
141  // Test double
142  DoublePrefMember double_member;
143  double_member.Init(kDoublePref, &prefs, NULL);
144
145  // Check the defaults
146  EXPECT_EQ(0.0, prefs.GetDouble(kDoublePref));
147  EXPECT_EQ(0.0, double_member.GetValue());
148  EXPECT_EQ(0.0, *double_member);
149
150  // Try changing through the member variable.
151  double_member.SetValue(1.0);
152  EXPECT_EQ(1.0, double_member.GetValue());
153  EXPECT_EQ(1.0, prefs.GetDouble(kDoublePref));
154  EXPECT_EQ(1.0, *double_member);
155
156  // Try changing back through the pref.
157  prefs.SetDouble(kDoublePref, 3.0);
158  EXPECT_EQ(3.0, prefs.GetDouble(kDoublePref));
159  EXPECT_EQ(3.0, double_member.GetValue());
160  EXPECT_EQ(3.0, *double_member);
161
162  // Test string
163  StringPrefMember string;
164  string.Init(kStringPref, &prefs, NULL);
165
166  // Check the defaults
167  EXPECT_EQ("default", prefs.GetString(kStringPref));
168  EXPECT_EQ("default", string.GetValue());
169  EXPECT_EQ("default", *string);
170
171  // Try changing through the member variable.
172  string.SetValue("foo");
173  EXPECT_EQ("foo", string.GetValue());
174  EXPECT_EQ("foo", prefs.GetString(kStringPref));
175  EXPECT_EQ("foo", *string);
176
177  // Try changing back through the pref.
178  prefs.SetString(kStringPref, "bar");
179  EXPECT_EQ("bar", prefs.GetString(kStringPref));
180  EXPECT_EQ("bar", string.GetValue());
181  EXPECT_EQ("bar", *string);
182}
183
184TEST(PrefMemberTest, TwoPrefs) {
185  // Make sure two DoublePrefMembers stay in sync.
186  TestingPrefService prefs;
187  RegisterTestPrefs(&prefs);
188
189  DoublePrefMember pref1;
190  pref1.Init(kDoublePref, &prefs, NULL);
191  DoublePrefMember pref2;
192  pref2.Init(kDoublePref, &prefs, NULL);
193
194  pref1.SetValue(2.3);
195  EXPECT_EQ(2.3, *pref2);
196
197  pref2.SetValue(3.5);
198  EXPECT_EQ(3.5, *pref1);
199
200  prefs.SetDouble(kDoublePref, 4.2);
201  EXPECT_EQ(4.2, *pref1);
202  EXPECT_EQ(4.2, *pref2);
203}
204
205TEST(PrefMemberTest, Observer) {
206  TestingPrefService prefs;
207  RegisterTestPrefs(&prefs);
208
209  PrefMemberTestClass test_obj(&prefs);
210  EXPECT_EQ("default", *test_obj.str_);
211
212  // Calling SetValue should not fire the observer.
213  test_obj.str_.SetValue("hello");
214  EXPECT_EQ(0, test_obj.observe_cnt_);
215  EXPECT_EQ("hello", prefs.GetString(kStringPref));
216
217  // Changing the pref does fire the observer.
218  prefs.SetString(kStringPref, "world");
219  EXPECT_EQ(1, test_obj.observe_cnt_);
220  EXPECT_EQ("world", *(test_obj.str_));
221
222  // Not changing the value should not fire the observer.
223  prefs.SetString(kStringPref, "world");
224  EXPECT_EQ(1, test_obj.observe_cnt_);
225  EXPECT_EQ("world", *(test_obj.str_));
226
227  prefs.SetString(kStringPref, "hello");
228  EXPECT_EQ(2, test_obj.observe_cnt_);
229  EXPECT_EQ("hello", prefs.GetString(kStringPref));
230}
231
232TEST(PrefMemberTest, NoInit) {
233  // Make sure not calling Init on a PrefMember doesn't cause problems.
234  IntegerPrefMember pref;
235}
236
237// Flakily triggers an assertion, http://crbug.com/74386.
238TEST(PrefMemberTest, DISABLED_MoveToThread) {
239  MessageLoop message_loop;
240  BrowserThread ui_thread(BrowserThread::UI, &message_loop);
241  BrowserThread io_thread(BrowserThread::IO);
242  ASSERT_TRUE(io_thread.Start());
243  TestingPrefService prefs;
244  RegisterTestPrefs(&prefs);
245  scoped_refptr<GetPrefValueCallback> callback =
246      make_scoped_refptr(new GetPrefValueCallback());
247  callback->Init(kBoolPref, &prefs);
248
249  ASSERT_TRUE(callback->FetchValue());
250  EXPECT_FALSE(callback->value());
251
252  prefs.SetBoolean(kBoolPref, true);
253
254  ASSERT_TRUE(callback->FetchValue());
255  EXPECT_TRUE(callback->value());
256}
257