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