pref_service_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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 <string> 6 7#include "app/test/data/resource.h" 8#include "base/scoped_ptr.h" 9#include "base/values.h" 10#include "chrome/browser/prefs/dummy_pref_store.h" 11#include "chrome/browser/prefs/pref_change_registrar.h" 12#include "chrome/browser/prefs/pref_value_store.h" 13#include "chrome/common/chrome_paths.h" 14#include "chrome/common/notification_observer_mock.h" 15#include "chrome/common/notification_service.h" 16#include "chrome/common/notification_type.h" 17#include "chrome/common/pref_names.h" 18#include "chrome/test/testing_pref_service.h" 19#include "testing/gmock/include/gmock/gmock.h" 20#include "testing/gtest/include/gtest/gtest.h" 21 22using testing::_; 23using testing::Mock; 24using testing::Pointee; 25using testing::Property; 26 27class TestPrefObserver : public NotificationObserver { 28 public: 29 TestPrefObserver(const PrefService* prefs, 30 const std::string& pref_name, 31 const std::string& new_pref_value) 32 : observer_fired_(false), 33 prefs_(prefs), 34 pref_name_(pref_name), 35 new_pref_value_(new_pref_value) { 36 } 37 virtual ~TestPrefObserver() {} 38 39 virtual void Observe(NotificationType type, 40 const NotificationSource& source, 41 const NotificationDetails& details) { 42 EXPECT_EQ(type.value, NotificationType::PREF_CHANGED); 43 PrefService* prefs_in = Source<PrefService>(source).ptr(); 44 EXPECT_EQ(prefs_in, prefs_); 45 std::string* pref_name_in = Details<std::string>(details).ptr(); 46 EXPECT_EQ(*pref_name_in, pref_name_); 47 EXPECT_EQ(new_pref_value_, prefs_in->GetString("homepage")); 48 observer_fired_ = true; 49 } 50 51 bool observer_fired() { return observer_fired_; } 52 53 void Reset(const std::string& new_pref_value) { 54 observer_fired_ = false; 55 new_pref_value_ = new_pref_value; 56 } 57 58 private: 59 bool observer_fired_; 60 const PrefService* prefs_; 61 const std::string pref_name_; 62 std::string new_pref_value_; 63}; 64 65// TODO(port): port this test to POSIX. 66#if defined(OS_WIN) 67TEST(PrefServiceTest, LocalizedPrefs) { 68 TestingPrefService prefs; 69 const char kBoolean[] = "boolean"; 70 const char kInteger[] = "integer"; 71 const char kString[] = "string"; 72 prefs.RegisterLocalizedBooleanPref(kBoolean, IDS_LOCALE_BOOL); 73 prefs.RegisterLocalizedIntegerPref(kInteger, IDS_LOCALE_INT); 74 prefs.RegisterLocalizedStringPref(kString, IDS_LOCALE_STRING); 75 76 // The locale default should take preference over the user default. 77 EXPECT_FALSE(prefs.GetBoolean(kBoolean)); 78 EXPECT_EQ(1, prefs.GetInteger(kInteger)); 79 EXPECT_EQ("hello", prefs.GetString(kString)); 80 81 prefs.SetBoolean(kBoolean, true); 82 EXPECT_TRUE(prefs.GetBoolean(kBoolean)); 83 prefs.SetInteger(kInteger, 5); 84 EXPECT_EQ(5, prefs.GetInteger(kInteger)); 85 prefs.SetString(kString, "foo"); 86 EXPECT_EQ("foo", prefs.GetString(kString)); 87} 88#endif 89 90TEST(PrefServiceTest, NoObserverFire) { 91 TestingPrefService prefs; 92 93 const char pref_name[] = "homepage"; 94 prefs.RegisterStringPref(pref_name, ""); 95 96 const std::string new_pref_value("http://www.google.com/"); 97 TestPrefObserver obs(&prefs, pref_name, new_pref_value); 98 99 PrefChangeRegistrar registrar; 100 registrar.Init(&prefs); 101 registrar.Add(pref_name, &obs); 102 // This should fire the checks in TestPrefObserver::Observe. 103 prefs.SetString(pref_name, new_pref_value); 104 105 // Make sure the observer was actually fired. 106 EXPECT_TRUE(obs.observer_fired()); 107 108 // Setting the pref to the same value should not set the pref value a second 109 // time. 110 obs.Reset(new_pref_value); 111 prefs.SetString(pref_name, new_pref_value); 112 EXPECT_FALSE(obs.observer_fired()); 113 114 // Clearing the pref should cause the pref to fire. 115 obs.Reset(""); 116 prefs.ClearPref(pref_name); 117 EXPECT_TRUE(obs.observer_fired()); 118 119 // Clearing the pref again should not cause the pref to fire. 120 obs.Reset(""); 121 prefs.ClearPref(pref_name); 122 EXPECT_FALSE(obs.observer_fired()); 123} 124 125TEST(PrefServiceTest, HasPrefPath) { 126 TestingPrefService prefs; 127 128 const char path[] = "fake.path"; 129 130 // Shouldn't initially have a path. 131 EXPECT_FALSE(prefs.HasPrefPath(path)); 132 133 // Register the path. This doesn't set a value, so the path still shouldn't 134 // exist. 135 prefs.RegisterStringPref(path, std::string()); 136 EXPECT_FALSE(prefs.HasPrefPath(path)); 137 138 // Set a value and make sure we have a path. 139 prefs.SetString(path, "blah"); 140 EXPECT_TRUE(prefs.HasPrefPath(path)); 141} 142 143TEST(PrefServiceTest, Observers) { 144 const char pref_name[] = "homepage"; 145 146 TestingPrefService prefs; 147 prefs.SetUserPref(pref_name, Value::CreateStringValue("http://www.cnn.com")); 148 prefs.RegisterStringPref(pref_name, ""); 149 150 const std::string new_pref_value("http://www.google.com/"); 151 TestPrefObserver obs(&prefs, pref_name, new_pref_value); 152 PrefChangeRegistrar registrar; 153 registrar.Init(&prefs); 154 registrar.Add(pref_name, &obs); 155 // This should fire the checks in TestPrefObserver::Observe. 156 prefs.SetString(pref_name, new_pref_value); 157 158 // Make sure the tests were actually run. 159 EXPECT_TRUE(obs.observer_fired()); 160 161 // Now try adding a second pref observer. 162 const std::string new_pref_value2("http://www.youtube.com/"); 163 obs.Reset(new_pref_value2); 164 TestPrefObserver obs2(&prefs, pref_name, new_pref_value2); 165 registrar.Add(pref_name, &obs2); 166 // This should fire the checks in obs and obs2. 167 prefs.SetString(pref_name, new_pref_value2); 168 EXPECT_TRUE(obs.observer_fired()); 169 EXPECT_TRUE(obs2.observer_fired()); 170 171 // Make sure obs2 still works after removing obs. 172 registrar.Remove(pref_name, &obs); 173 obs.Reset(""); 174 obs2.Reset(new_pref_value); 175 // This should only fire the observer in obs2. 176 prefs.SetString(pref_name, new_pref_value); 177 EXPECT_FALSE(obs.observer_fired()); 178 EXPECT_TRUE(obs2.observer_fired()); 179} 180 181class PrefServiceSetValueTest : public testing::Test { 182 protected: 183 static const char name_[]; 184 static const char value_[]; 185 186 PrefServiceSetValueTest() 187 : name_string_(name_), 188 null_value_(Value::CreateNullValue()) {} 189 190 void SetExpectNoNotification() { 191 EXPECT_CALL(observer_, Observe(_, _, _)).Times(0); 192 } 193 194 void SetExpectPrefChanged() { 195 EXPECT_CALL(observer_, 196 Observe(NotificationType(NotificationType::PREF_CHANGED), _, 197 Property(&Details<std::string>::ptr, 198 Pointee(name_string_)))); 199 } 200 201 TestingPrefService prefs_; 202 std::string name_string_; 203 scoped_ptr<Value> null_value_; 204 NotificationObserverMock observer_; 205}; 206 207const char PrefServiceSetValueTest::name_[] = "name"; 208const char PrefServiceSetValueTest::value_[] = "value"; 209 210TEST_F(PrefServiceSetValueTest, SetStringValue) { 211 const char default_string[] = "default"; 212 scoped_ptr<Value> default_value(Value::CreateStringValue(default_string)); 213 prefs_.RegisterStringPref(name_, default_string); 214 215 PrefChangeRegistrar registrar; 216 registrar.Init(&prefs_); 217 registrar.Add(name_, &observer_); 218 219 // Changing the controlling store from default to user triggers notification. 220 SetExpectPrefChanged(); 221 prefs_.Set(name_, *default_value); 222 Mock::VerifyAndClearExpectations(&observer_); 223 224 SetExpectNoNotification(); 225 prefs_.Set(name_, *default_value); 226 Mock::VerifyAndClearExpectations(&observer_); 227 228 scoped_ptr<Value> new_value(Value::CreateStringValue(value_)); 229 SetExpectPrefChanged(); 230 prefs_.Set(name_, *new_value); 231 EXPECT_EQ(value_, prefs_.GetString(name_)); 232} 233 234TEST_F(PrefServiceSetValueTest, SetDictionaryValue) { 235 prefs_.RegisterDictionaryPref(name_); 236 PrefChangeRegistrar registrar; 237 registrar.Init(&prefs_); 238 registrar.Add(name_, &observer_); 239 240 // Dictionary values are special: setting one to NULL is the same as clearing 241 // the user value, allowing the NULL default to take (or keep) control. 242 SetExpectNoNotification(); 243 prefs_.Set(name_, *null_value_); 244 Mock::VerifyAndClearExpectations(&observer_); 245 246 DictionaryValue new_value; 247 new_value.SetString(name_, value_); 248 SetExpectPrefChanged(); 249 prefs_.Set(name_, new_value); 250 Mock::VerifyAndClearExpectations(&observer_); 251 DictionaryValue* dict = prefs_.GetMutableDictionary(name_); 252 EXPECT_EQ(1U, dict->size()); 253 std::string out_value; 254 dict->GetString(name_, &out_value); 255 EXPECT_EQ(value_, out_value); 256 257 SetExpectNoNotification(); 258 prefs_.Set(name_, new_value); 259 Mock::VerifyAndClearExpectations(&observer_); 260 261 SetExpectPrefChanged(); 262 prefs_.Set(name_, *null_value_); 263 Mock::VerifyAndClearExpectations(&observer_); 264 dict = prefs_.GetMutableDictionary(name_); 265 EXPECT_EQ(0U, dict->size()); 266} 267 268TEST_F(PrefServiceSetValueTest, SetListValue) { 269 prefs_.RegisterListPref(name_); 270 PrefChangeRegistrar registrar; 271 registrar.Init(&prefs_); 272 registrar.Add(name_, &observer_); 273 274 // List values are special: setting one to NULL is the same as clearing the 275 // user value, allowing the NULL default to take (or keep) control. 276 SetExpectNoNotification(); 277 prefs_.Set(name_, *null_value_); 278 Mock::VerifyAndClearExpectations(&observer_); 279 280 ListValue new_value; 281 new_value.Append(Value::CreateStringValue(value_)); 282 SetExpectPrefChanged(); 283 prefs_.Set(name_, new_value); 284 Mock::VerifyAndClearExpectations(&observer_); 285 ListValue* list = prefs_.GetMutableList(name_); 286 ASSERT_EQ(1U, list->GetSize()); 287 std::string out_value; 288 list->GetString(0, &out_value); 289 EXPECT_EQ(value_, out_value); 290 291 SetExpectNoNotification(); 292 prefs_.Set(name_, new_value); 293 Mock::VerifyAndClearExpectations(&observer_); 294 295 SetExpectPrefChanged(); 296 prefs_.Set(name_, *null_value_); 297 Mock::VerifyAndClearExpectations(&observer_); 298 list = prefs_.GetMutableList(name_); 299 EXPECT_EQ(0U, list->GetSize()); 300} 301