diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-14 17:20:19 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-14 17:20:19 +0000 |
commit | e5ba874f019eb505a048ffb38aadf8bb5f495d7f (patch) | |
tree | cd845816e0959333555fc883d2fac49e3374fecc /base/prefs | |
parent | ad694eb0fddfdbcb74e31d13e473ce277c680ca8 (diff) | |
download | chromium_src-e5ba874f019eb505a048ffb38aadf8bb5f495d7f.zip chromium_src-e5ba874f019eb505a048ffb38aadf8bb5f495d7f.tar.gz chromium_src-e5ba874f019eb505a048ffb38aadf8bb5f495d7f.tar.bz2 |
Moving last generic Prefs implementation files to base/prefs/.
This completes componentization of Prefs, although there are some
remaining TODOs that were created during componentization and
interface improvement that still need to be tackled.
TBR=ben@chromium.org
BUG=155525
Review URL: https://chromiumcodereview.appspot.com/12253004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182485 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/prefs')
-rw-r--r-- | base/prefs/pref_notifier_impl_unittest.cc | 227 | ||||
-rw-r--r-- | base/prefs/pref_service_unittest.cc | 316 | ||||
-rw-r--r-- | base/prefs/public/pref_change_registrar_unittest.cc | 2 | ||||
-rw-r--r-- | base/prefs/public/pref_member_unittest.cc | 2 | ||||
-rw-r--r-- | base/prefs/testing_pref_service.cc | 56 | ||||
-rw-r--r-- | base/prefs/testing_pref_service.h | 196 |
6 files changed, 797 insertions, 2 deletions
diff --git a/base/prefs/pref_notifier_impl_unittest.cc b/base/prefs/pref_notifier_impl_unittest.cc new file mode 100644 index 0000000..ff36ca8 --- /dev/null +++ b/base/prefs/pref_notifier_impl_unittest.cc @@ -0,0 +1,227 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/callback.h" +#include "base/prefs/mock_pref_change_callback.h" +#include "base/prefs/pref_notifier_impl.h" +#include "base/prefs/pref_observer.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/pref_value_store.h" +#include "base/prefs/testing_pref_service.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Field; +using testing::Invoke; +using testing::Mock; +using testing::Truly; + +namespace { + +const char kChangedPref[] = "changed_pref"; +const char kUnchangedPref[] = "unchanged_pref"; + +class MockPrefInitObserver { + public: + MOCK_METHOD1(OnInitializationCompleted, void(bool)); +}; + +// This is an unmodified PrefNotifierImpl, except we make +// OnPreferenceChanged public for tests. +class TestingPrefNotifierImpl : public PrefNotifierImpl { + public: + explicit TestingPrefNotifierImpl(PrefService* service) + : PrefNotifierImpl(service) { + } + + // Make public for tests. + using PrefNotifierImpl::OnPreferenceChanged; +}; + +// Mock PrefNotifier that allows tracking of observers and notifications. +class MockPrefNotifier : public PrefNotifierImpl { + public: + explicit MockPrefNotifier(PrefService* pref_service) + : PrefNotifierImpl(pref_service) {} + virtual ~MockPrefNotifier() {} + + MOCK_METHOD1(FireObservers, void(const std::string& path)); + + size_t CountObserver(const char* path, PrefObserver* obs) { + PrefObserverMap::const_iterator observer_iterator = + pref_observers()->find(path); + if (observer_iterator == pref_observers()->end()) + return false; + + PrefObserverList* observer_list = observer_iterator->second; + PrefObserverList::Iterator it(*observer_list); + PrefObserver* existing_obs; + size_t count = 0; + while ((existing_obs = it.GetNext()) != NULL) { + if (existing_obs == obs) + count++; + } + + return count; + } + + // Make public for tests below. + using PrefNotifierImpl::OnPreferenceChanged; + using PrefNotifierImpl::OnInitializationCompleted; +}; + +class PrefObserverMock : public PrefObserver { + public: + PrefObserverMock() {} + virtual ~PrefObserverMock() {} + + MOCK_METHOD2(OnPreferenceChanged, void(PrefServiceBase*, const std::string&)); + + void Expect(PrefServiceBase* prefs, + const std::string& pref_name, + const Value* value) { + EXPECT_CALL(*this, OnPreferenceChanged(prefs, pref_name)) + .With(PrefValueMatches(prefs, pref_name, value)); + } +}; + +// Test fixture class. +class PrefNotifierTest : public testing::Test { + protected: + virtual void SetUp() { + pref_service_.registry()->RegisterBooleanPref(kChangedPref, true); + pref_service_.registry()->RegisterBooleanPref(kUnchangedPref, true); + } + + TestingPrefServiceSimple pref_service_; + + PrefObserverMock obs1_; + PrefObserverMock obs2_; +}; + +TEST_F(PrefNotifierTest, OnPreferenceChanged) { + MockPrefNotifier notifier(&pref_service_); + EXPECT_CALL(notifier, FireObservers(kChangedPref)).Times(1); + notifier.OnPreferenceChanged(kChangedPref); +} + +TEST_F(PrefNotifierTest, OnInitializationCompleted) { + MockPrefNotifier notifier(&pref_service_); + MockPrefInitObserver observer; + notifier.AddInitObserver( + base::Bind(&MockPrefInitObserver::OnInitializationCompleted, + base::Unretained(&observer))); + EXPECT_CALL(observer, OnInitializationCompleted(true)); + notifier.OnInitializationCompleted(true); +} + +TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) { + const char pref_name[] = "homepage"; + const char pref_name2[] = "proxy"; + + MockPrefNotifier notifier(&pref_service_); + notifier.AddPrefObserver(pref_name, &obs1_); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + // Re-adding the same observer for the same pref doesn't change anything. + // Skip this in debug mode, since it hits a DCHECK and death tests aren't + // thread-safe. +#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) + notifier.AddPrefObserver(pref_name, &obs1_); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); +#endif + + // Ensure that we can add the same observer to a different pref. + notifier.AddPrefObserver(pref_name2, &obs1_); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + // Ensure that we can add another observer to the same pref. + notifier.AddPrefObserver(pref_name, &obs2_); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + // Ensure that we can remove all observers, and that removing a non-existent + // observer is harmless. + notifier.RemovePrefObserver(pref_name, &obs1_); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + notifier.RemovePrefObserver(pref_name, &obs2_); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + notifier.RemovePrefObserver(pref_name, &obs1_); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); + + notifier.RemovePrefObserver(pref_name2, &obs1_); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_)); + ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_)); +} + +TEST_F(PrefNotifierTest, FireObservers) { + TestingPrefNotifierImpl notifier(&pref_service_); + notifier.AddPrefObserver(kChangedPref, &obs1_); + notifier.AddPrefObserver(kUnchangedPref, &obs1_); + + EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref)); + EXPECT_CALL(obs2_, OnPreferenceChanged(_, _)).Times(0); + notifier.OnPreferenceChanged(kChangedPref); + Mock::VerifyAndClearExpectations(&obs1_); + Mock::VerifyAndClearExpectations(&obs2_); + + notifier.AddPrefObserver(kChangedPref, &obs2_); + notifier.AddPrefObserver(kUnchangedPref, &obs2_); + + EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref)); + EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref)); + notifier.OnPreferenceChanged(kChangedPref); + Mock::VerifyAndClearExpectations(&obs1_); + Mock::VerifyAndClearExpectations(&obs2_); + + // Make sure removing an observer from one pref doesn't affect anything else. + notifier.RemovePrefObserver(kChangedPref, &obs1_); + + EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0); + EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref)); + notifier.OnPreferenceChanged(kChangedPref); + Mock::VerifyAndClearExpectations(&obs1_); + Mock::VerifyAndClearExpectations(&obs2_); + + // Make sure removing an observer entirely doesn't affect anything else. + notifier.RemovePrefObserver(kUnchangedPref, &obs1_); + + EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0); + EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref)); + notifier.OnPreferenceChanged(kChangedPref); + Mock::VerifyAndClearExpectations(&obs1_); + Mock::VerifyAndClearExpectations(&obs2_); + + notifier.RemovePrefObserver(kChangedPref, &obs2_); + notifier.RemovePrefObserver(kUnchangedPref, &obs2_); +} + +} // namespace diff --git a/base/prefs/pref_service_unittest.cc b/base/prefs/pref_service_unittest.cc new file mode 100644 index 0000000..0c61a8e --- /dev/null +++ b/base/prefs/pref_service_unittest.cc @@ -0,0 +1,316 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/prefs/json_pref_store.h" +#include "base/prefs/mock_pref_change_callback.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_value_store.h" +#include "base/prefs/public/pref_change_registrar.h" +#include "base/prefs/testing_pref_service.h" +#include "base/prefs/testing_pref_store.h" +#include "base/values.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Mock; + +const char kPrefName[] = "pref.name"; + +TEST(PrefServiceTest, NoObserverFire) { + TestingPrefServiceSimple prefs; + + const char pref_name[] = "homepage"; + prefs.registry()->RegisterStringPref(pref_name, std::string()); + + const char new_pref_value[] = "http://www.google.com/"; + MockPrefChangeCallback obs(&prefs); + PrefChangeRegistrar registrar; + registrar.Init(&prefs); + registrar.Add(pref_name, obs.GetCallback()); + + // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged. + const StringValue expected_value(new_pref_value); + obs.Expect(pref_name, &expected_value); + prefs.SetString(pref_name, new_pref_value); + Mock::VerifyAndClearExpectations(&obs); + + // Setting the pref to the same value should not set the pref value a second + // time. + EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); + prefs.SetString(pref_name, new_pref_value); + Mock::VerifyAndClearExpectations(&obs); + + // Clearing the pref should cause the pref to fire. + const StringValue expected_default_value(""); + obs.Expect(pref_name, &expected_default_value); + prefs.ClearPref(pref_name); + Mock::VerifyAndClearExpectations(&obs); + + // Clearing the pref again should not cause the pref to fire. + EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); + prefs.ClearPref(pref_name); + Mock::VerifyAndClearExpectations(&obs); +} + +TEST(PrefServiceTest, HasPrefPath) { + TestingPrefServiceSimple prefs; + + const char path[] = "fake.path"; + + // Shouldn't initially have a path. + EXPECT_FALSE(prefs.HasPrefPath(path)); + + // Register the path. This doesn't set a value, so the path still shouldn't + // exist. + prefs.registry()->RegisterStringPref(path, std::string()); + EXPECT_FALSE(prefs.HasPrefPath(path)); + + // Set a value and make sure we have a path. + prefs.SetString(path, "blah"); + EXPECT_TRUE(prefs.HasPrefPath(path)); +} + +TEST(PrefServiceTest, Observers) { + const char pref_name[] = "homepage"; + + TestingPrefServiceSimple prefs; + prefs.SetUserPref(pref_name, Value::CreateStringValue("http://www.cnn.com")); + prefs.registry()->RegisterStringPref(pref_name, std::string()); + + const char new_pref_value[] = "http://www.google.com/"; + const StringValue expected_new_pref_value(new_pref_value); + MockPrefChangeCallback obs(&prefs); + PrefChangeRegistrar registrar; + registrar.Init(&prefs); + registrar.Add(pref_name, obs.GetCallback()); + + PrefChangeRegistrar registrar_two; + registrar_two.Init(&prefs); + + // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged. + obs.Expect(pref_name, &expected_new_pref_value); + prefs.SetString(pref_name, new_pref_value); + Mock::VerifyAndClearExpectations(&obs); + + // Now try adding a second pref observer. + const char new_pref_value2[] = "http://www.youtube.com/"; + const StringValue expected_new_pref_value2(new_pref_value2); + MockPrefChangeCallback obs2(&prefs); + obs.Expect(pref_name, &expected_new_pref_value2); + obs2.Expect(pref_name, &expected_new_pref_value2); + registrar_two.Add(pref_name, obs2.GetCallback()); + // This should fire the checks in obs and obs2. + prefs.SetString(pref_name, new_pref_value2); + Mock::VerifyAndClearExpectations(&obs); + Mock::VerifyAndClearExpectations(&obs2); + + // Set a recommended value. + const StringValue recommended_pref_value("http://www.gmail.com/"); + obs.Expect(pref_name, &expected_new_pref_value2); + obs2.Expect(pref_name, &expected_new_pref_value2); + // This should fire the checks in obs and obs2 but with an unchanged value + // as the recommended value is being overridden by the user-set value. + prefs.SetRecommendedPref(pref_name, recommended_pref_value.DeepCopy()); + Mock::VerifyAndClearExpectations(&obs); + Mock::VerifyAndClearExpectations(&obs2); + + // Make sure obs2 still works after removing obs. + registrar.Remove(pref_name); + EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0); + obs2.Expect(pref_name, &expected_new_pref_value); + // This should only fire the observer in obs2. + prefs.SetString(pref_name, new_pref_value); + Mock::VerifyAndClearExpectations(&obs); + Mock::VerifyAndClearExpectations(&obs2); +} + +// Make sure that if a preference changes type, so the wrong type is stored in +// the user pref file, it uses the correct fallback value instead. +TEST(PrefServiceTest, GetValueChangedType) { + const int kTestValue = 10; + TestingPrefServiceSimple prefs; + prefs.registry()->RegisterIntegerPref(kPrefName, kTestValue); + + // Check falling back to a recommended value. + prefs.SetUserPref(kPrefName, Value::CreateStringValue("not an integer")); + const PrefService::Preference* pref = prefs.FindPreference(kPrefName); + ASSERT_TRUE(pref); + const Value* value = pref->GetValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + int actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kTestValue, actual_int_value); +} + +TEST(PrefServiceTest, GetValueAndGetRecommendedValue) { + const int kDefaultValue = 5; + const int kUserValue = 10; + const int kRecommendedValue = 15; + TestingPrefServiceSimple prefs; + prefs.registry()->RegisterIntegerPref(kPrefName, kDefaultValue); + + // Create pref with a default value only. + const PrefService::Preference* pref = prefs.FindPreference(kPrefName); + ASSERT_TRUE(pref); + + // Check that GetValue() returns the default value. + const Value* value = pref->GetValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + int actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kDefaultValue, actual_int_value); + + // Check that GetRecommendedValue() returns no value. + value = pref->GetRecommendedValue(); + ASSERT_FALSE(value); + + // Set a user-set value. + prefs.SetUserPref(kPrefName, Value::CreateIntegerValue(kUserValue)); + + // Check that GetValue() returns the user-set value. + value = pref->GetValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kUserValue, actual_int_value); + + // Check that GetRecommendedValue() returns no value. + value = pref->GetRecommendedValue(); + ASSERT_FALSE(value); + + // Set a recommended value. + prefs.SetRecommendedPref(kPrefName, + Value::CreateIntegerValue(kRecommendedValue)); + + // Check that GetValue() returns the user-set value. + value = pref->GetValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kUserValue, actual_int_value); + + // Check that GetRecommendedValue() returns the recommended value. + value = pref->GetRecommendedValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kRecommendedValue, actual_int_value); + + // Remove the user-set value. + prefs.RemoveUserPref(kPrefName); + + // Check that GetValue() returns the recommended value. + value = pref->GetValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kRecommendedValue, actual_int_value); + + // Check that GetRecommendedValue() returns the recommended value. + value = pref->GetRecommendedValue(); + ASSERT_TRUE(value); + EXPECT_EQ(Value::TYPE_INTEGER, value->GetType()); + actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(kRecommendedValue, actual_int_value); +} + +class PrefServiceSetValueTest : public testing::Test { + protected: + static const char kName[]; + static const char kValue[]; + + PrefServiceSetValueTest() : observer_(&prefs_) {} + + TestingPrefServiceSimple prefs_; + MockPrefChangeCallback observer_; +}; + +const char PrefServiceSetValueTest::kName[] = "name"; +const char PrefServiceSetValueTest::kValue[] = "value"; + +TEST_F(PrefServiceSetValueTest, SetStringValue) { + const char default_string[] = "default"; + const StringValue default_value(default_string); + prefs_.registry()->RegisterStringPref(kName, default_string); + + PrefChangeRegistrar registrar; + registrar.Init(&prefs_); + registrar.Add(kName, observer_.GetCallback()); + + // Changing the controlling store from default to user triggers notification. + observer_.Expect(kName, &default_value); + prefs_.Set(kName, default_value); + Mock::VerifyAndClearExpectations(&observer_); + + EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); + prefs_.Set(kName, default_value); + Mock::VerifyAndClearExpectations(&observer_); + + StringValue new_value(kValue); + observer_.Expect(kName, &new_value); + prefs_.Set(kName, new_value); + Mock::VerifyAndClearExpectations(&observer_); +} + +TEST_F(PrefServiceSetValueTest, SetDictionaryValue) { + prefs_.registry()->RegisterDictionaryPref(kName); + PrefChangeRegistrar registrar; + registrar.Init(&prefs_); + registrar.Add(kName, observer_.GetCallback()); + + EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); + prefs_.RemoveUserPref(kName); + Mock::VerifyAndClearExpectations(&observer_); + + DictionaryValue new_value; + new_value.SetString(kName, kValue); + observer_.Expect(kName, &new_value); + prefs_.Set(kName, new_value); + Mock::VerifyAndClearExpectations(&observer_); + + EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); + prefs_.Set(kName, new_value); + Mock::VerifyAndClearExpectations(&observer_); + + DictionaryValue empty; + observer_.Expect(kName, &empty); + prefs_.Set(kName, empty); + Mock::VerifyAndClearExpectations(&observer_); +} + +TEST_F(PrefServiceSetValueTest, SetListValue) { + prefs_.registry()->RegisterListPref(kName); + PrefChangeRegistrar registrar; + registrar.Init(&prefs_); + registrar.Add(kName, observer_.GetCallback()); + + EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); + prefs_.RemoveUserPref(kName); + Mock::VerifyAndClearExpectations(&observer_); + + ListValue new_value; + new_value.Append(Value::CreateStringValue(kValue)); + observer_.Expect(kName, &new_value); + prefs_.Set(kName, new_value); + Mock::VerifyAndClearExpectations(&observer_); + + EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0); + prefs_.Set(kName, new_value); + Mock::VerifyAndClearExpectations(&observer_); + + ListValue empty; + observer_.Expect(kName, &empty); + prefs_.Set(kName, empty); + Mock::VerifyAndClearExpectations(&observer_); +} diff --git a/base/prefs/public/pref_change_registrar_unittest.cc b/base/prefs/public/pref_change_registrar_unittest.cc index 5e1ad5f..b29f43a 100644 --- a/base/prefs/public/pref_change_registrar_unittest.cc +++ b/base/prefs/public/pref_change_registrar_unittest.cc @@ -7,7 +7,7 @@ #include "base/prefs/pref_observer.h" #include "base/prefs/pref_registry_simple.h" #include "base/prefs/public/pref_change_registrar.h" -#include "chrome/test/base/testing_pref_service.h" +#include "base/prefs/testing_pref_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/base/prefs/public/pref_member_unittest.cc b/base/prefs/public/pref_member_unittest.cc index 5f1c3f1..2a68059 100644 --- a/base/prefs/public/pref_member_unittest.cc +++ b/base/prefs/public/pref_member_unittest.cc @@ -7,9 +7,9 @@ #include "base/bind.h" #include "base/message_loop.h" #include "base/prefs/pref_registry_simple.h" +#include "base/prefs/testing_pref_service.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" -#include "chrome/test/base/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace { diff --git a/base/prefs/testing_pref_service.cc b/base/prefs/testing_pref_service.cc new file mode 100644 index 0000000..22755da --- /dev/null +++ b/base/prefs/testing_pref_service.cc @@ -0,0 +1,56 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/prefs/testing_pref_service.h" + +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/prefs/default_pref_store.h" +#include "base/prefs/pref_notifier_impl.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_value_store.h" +#include "testing/gtest/include/gtest/gtest.h" + +template<> +TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase( + TestingPrefStore* managed_prefs, + TestingPrefStore* user_prefs, + TestingPrefStore* recommended_prefs, + PrefRegistry* pref_registry, + PrefNotifierImpl* pref_notifier) + : PrefService(pref_notifier, + new PrefValueStore( + managed_prefs, + NULL, + NULL, + user_prefs, + recommended_prefs, + pref_registry->defaults(), + pref_notifier), + user_prefs, + pref_registry, + base::Bind( + &TestingPrefServiceBase< + PrefService, PrefRegistry>::HandleReadError), + false), + managed_prefs_(managed_prefs), + user_prefs_(user_prefs), + recommended_prefs_(recommended_prefs) { +} + +TestingPrefServiceSimple::TestingPrefServiceSimple() + : TestingPrefServiceBase<PrefService, PrefRegistry>( + new TestingPrefStore(), + new TestingPrefStore(), + new TestingPrefStore(), + new PrefRegistrySimple(), + new PrefNotifierImpl()) { +} + +TestingPrefServiceSimple::~TestingPrefServiceSimple() { +} + +PrefRegistrySimple* TestingPrefServiceSimple::registry() { + return static_cast<PrefRegistrySimple*>(DeprecatedGetPrefRegistry()); +} diff --git a/base/prefs/testing_pref_service.h b/base/prefs/testing_pref_service.h new file mode 100644 index 0000000..9d290fe --- /dev/null +++ b/base/prefs/testing_pref_service.h @@ -0,0 +1,196 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_PREFS_TESTING_PREF_SERVICE_H_ +#define BASE_PREFS_TESTING_PREF_SERVICE_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/prefs/pref_registry.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/testing_pref_store.h" + +class PrefNotifierImpl; +class PrefRegistrySimple; +class TestingPrefStore; + +// A PrefService subclass for testing. It operates totally in memory and +// provides additional API for manipulating preferences at the different levels +// (managed, extension, user) conveniently. +// +// Use this via its specializations, e.g. TestingPrefServiceSimple. +template <class SuperPrefService, class ConstructionPrefRegistry> +class TestingPrefServiceBase : public SuperPrefService { + public: + virtual ~TestingPrefServiceBase(); + + // Read the value of a preference from the managed layer. Returns NULL if the + // preference is not defined at the managed layer. + const Value* GetManagedPref(const char* path) const; + + // Set a preference on the managed layer and fire observers if the preference + // changed. Assumes ownership of |value|. + void SetManagedPref(const char* path, Value* value); + + // Clear the preference on the managed layer and fire observers if the + // preference has been defined previously. + void RemoveManagedPref(const char* path); + + // Similar to the above, but for user preferences. + const Value* GetUserPref(const char* path) const; + void SetUserPref(const char* path, Value* value); + void RemoveUserPref(const char* path); + + // Similar to the above, but for recommended policy preferences. + const Value* GetRecommendedPref(const char* path) const; + void SetRecommendedPref(const char* path, Value* value); + void RemoveRecommendedPref(const char* path); + + // Do-nothing implementation for TestingPrefService. + static void HandleReadError(PersistentPrefStore::PrefReadError error) {} + + protected: + TestingPrefServiceBase( + TestingPrefStore* managed_prefs, + TestingPrefStore* user_prefs, + TestingPrefStore* recommended_prefs, + ConstructionPrefRegistry* pref_registry, + PrefNotifierImpl* pref_notifier); + + private: + // Reads the value of the preference indicated by |path| from |pref_store|. + // Returns NULL if the preference was not found. + const Value* GetPref(TestingPrefStore* pref_store, const char* path) const; + + // Sets the value for |path| in |pref_store|. + void SetPref(TestingPrefStore* pref_store, const char* path, Value* value); + + // Removes the preference identified by |path| from |pref_store|. + void RemovePref(TestingPrefStore* pref_store, const char* path); + + // Pointers to the pref stores our value store uses. + scoped_refptr<TestingPrefStore> managed_prefs_; + scoped_refptr<TestingPrefStore> user_prefs_; + scoped_refptr<TestingPrefStore> recommended_prefs_; + + DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceBase); +}; + +// Test version of PrefService. +class TestingPrefServiceSimple + : public TestingPrefServiceBase<PrefService, PrefRegistry> { + public: + TestingPrefServiceSimple(); + virtual ~TestingPrefServiceSimple(); + + // This is provided as a convenience for registering preferences on + // an existing TestingPrefServiceSimple instance. On a production + // PrefService you would do all registrations before constructing + // it, passing it a PrefRegistry via its constructor (or via + // e.g. PrefServiceBuilder). + PrefRegistrySimple* registry(); + + private: + DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceSimple); +}; + +template<> +TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase( + TestingPrefStore* managed_prefs, + TestingPrefStore* user_prefs, + TestingPrefStore* recommended_prefs, + PrefRegistry* pref_registry, + PrefNotifierImpl* pref_notifier); + +template<class SuperPrefService, class ConstructionPrefRegistry> +TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::~TestingPrefServiceBase() { +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +const Value* TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::GetManagedPref( + const char* path) const { + return GetPref(managed_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::SetManagedPref( + const char* path, Value* value) { + SetPref(managed_prefs_, path, value); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::RemoveManagedPref( + const char* path) { + RemovePref(managed_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +const Value* TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::GetUserPref( + const char* path) const { + return GetPref(user_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::SetUserPref( + const char* path, Value* value) { + SetPref(user_prefs_, path, value); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::RemoveUserPref( + const char* path) { + RemovePref(user_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +const Value* TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::GetRecommendedPref( + const char* path) const { + return GetPref(recommended_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::SetRecommendedPref( + const char* path, Value* value) { + SetPref(recommended_prefs_, path, value); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::RemoveRecommendedPref( + const char* path) { + RemovePref(recommended_prefs_, path); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +const Value* TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::GetPref( + TestingPrefStore* pref_store, const char* path) const { + const Value* res; + return pref_store->GetValue(path, &res) ? res : NULL; +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::SetPref( + TestingPrefStore* pref_store, const char* path, Value* value) { + pref_store->SetValue(path, value); +} + +template<class SuperPrefService, class ConstructionPrefRegistry> +void TestingPrefServiceBase< + SuperPrefService, ConstructionPrefRegistry>::RemovePref( + TestingPrefStore* pref_store, const char* path) { + pref_store->RemoveValue(path); +} + +#endif // BASE_PREFS_TESTING_PREF_SERVICE_H_ |