Index: base/prefs/pref_member_unittest.cc |
diff --git a/base/prefs/pref_member_unittest.cc b/base/prefs/pref_member_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a776e2c25535a36f86a362f37974b258dc809fc8 |
--- /dev/null |
+++ b/base/prefs/pref_member_unittest.cc |
@@ -0,0 +1,325 @@ |
+// 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/prefs/pref_member.h" |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/prefs/pref_registry_simple.h" |
+#include "base/prefs/testing_pref_service.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "base/threading/thread.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+const char kBoolPref[] = "bool"; |
+const char kIntPref[] = "int"; |
+const char kDoublePref[] = "double"; |
+const char kStringPref[] = "string"; |
+const char kStringListPref[] = "string_list"; |
+ |
+void RegisterTestPrefs(PrefRegistrySimple* registry) { |
+ registry->RegisterBooleanPref(kBoolPref, false); |
+ registry->RegisterIntegerPref(kIntPref, 0); |
+ registry->RegisterDoublePref(kDoublePref, 0.0); |
+ registry->RegisterStringPref(kStringPref, "default"); |
+ registry->RegisterListPref(kStringListPref, new base::ListValue()); |
+} |
+ |
+class GetPrefValueHelper |
+ : public base::RefCountedThreadSafe<GetPrefValueHelper> { |
+ public: |
+ GetPrefValueHelper() : value_(false), pref_thread_("pref thread") { |
+ pref_thread_.Start(); |
+ } |
+ |
+ void Init(const std::string& pref_name, PrefService* prefs) { |
+ pref_.Init(pref_name, prefs); |
+ pref_.MoveToThread(pref_thread_.task_runner()); |
+ } |
+ |
+ void Destroy() { |
+ pref_.Destroy(); |
+ } |
+ |
+ void FetchValue() { |
+ base::WaitableEvent event(true, false); |
+ ASSERT_TRUE(pref_thread_.task_runner()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&GetPrefValueHelper::GetPrefValue, this, &event))); |
+ event.Wait(); |
+ } |
+ |
+ // The thread must be stopped on the main thread. GetPrefValueHelper being |
+ // ref-counted, the destructor can be called from any thread. |
+ void StopThread() { |
+ pref_thread_.Stop(); |
+ } |
+ |
+ bool value() { return value_; } |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<GetPrefValueHelper>; |
+ ~GetPrefValueHelper() {} |
+ |
+ void GetPrefValue(base::WaitableEvent* event) { |
+ value_ = pref_.GetValue(); |
+ event->Signal(); |
+ } |
+ |
+ BooleanPrefMember pref_; |
+ bool value_; |
+ |
+ base::Thread pref_thread_; // The thread |pref_| runs on. |
+}; |
+ |
+class PrefMemberTestClass { |
+ public: |
+ explicit PrefMemberTestClass(PrefService* prefs) |
+ : observe_cnt_(0), prefs_(prefs) { |
+ str_.Init(kStringPref, prefs, |
+ base::Bind(&PrefMemberTestClass::OnPreferenceChanged, |
+ base::Unretained(this))); |
+ } |
+ |
+ void OnPreferenceChanged(const std::string& pref_name) { |
+ EXPECT_EQ(pref_name, kStringPref); |
+ EXPECT_EQ(str_.GetValue(), prefs_->GetString(kStringPref)); |
+ ++observe_cnt_; |
+ } |
+ |
+ StringPrefMember str_; |
+ int observe_cnt_; |
+ |
+ private: |
+ PrefService* prefs_; |
+}; |
+ |
+} // anonymous namespace |
+ |
+class PrefMemberTest : public testing::Test { |
+ base::MessageLoop message_loop_; |
+}; |
+ |
+TEST_F(PrefMemberTest, BasicGetAndSet) { |
+ TestingPrefServiceSimple prefs; |
+ RegisterTestPrefs(prefs.registry()); |
+ |
+ // Test bool |
+ BooleanPrefMember boolean; |
+ boolean.Init(kBoolPref, &prefs); |
+ |
+ // Check the defaults |
+ EXPECT_FALSE(prefs.GetBoolean(kBoolPref)); |
+ EXPECT_FALSE(boolean.GetValue()); |
+ EXPECT_FALSE(*boolean); |
+ |
+ // Try changing through the member variable. |
+ boolean.SetValue(true); |
+ EXPECT_TRUE(boolean.GetValue()); |
+ EXPECT_TRUE(prefs.GetBoolean(kBoolPref)); |
+ EXPECT_TRUE(*boolean); |
+ |
+ // Try changing back through the pref. |
+ prefs.SetBoolean(kBoolPref, false); |
+ EXPECT_FALSE(prefs.GetBoolean(kBoolPref)); |
+ EXPECT_FALSE(boolean.GetValue()); |
+ EXPECT_FALSE(*boolean); |
+ |
+ // Test int |
+ IntegerPrefMember integer; |
+ integer.Init(kIntPref, &prefs); |
+ |
+ // Check the defaults |
+ EXPECT_EQ(0, prefs.GetInteger(kIntPref)); |
+ EXPECT_EQ(0, integer.GetValue()); |
+ EXPECT_EQ(0, *integer); |
+ |
+ // Try changing through the member variable. |
+ integer.SetValue(5); |
+ EXPECT_EQ(5, integer.GetValue()); |
+ EXPECT_EQ(5, prefs.GetInteger(kIntPref)); |
+ EXPECT_EQ(5, *integer); |
+ |
+ // Try changing back through the pref. |
+ prefs.SetInteger(kIntPref, 2); |
+ EXPECT_EQ(2, prefs.GetInteger(kIntPref)); |
+ EXPECT_EQ(2, integer.GetValue()); |
+ EXPECT_EQ(2, *integer); |
+ |
+ // Test double |
+ DoublePrefMember double_member; |
+ double_member.Init(kDoublePref, &prefs); |
+ |
+ // Check the defaults |
+ EXPECT_EQ(0.0, prefs.GetDouble(kDoublePref)); |
+ EXPECT_EQ(0.0, double_member.GetValue()); |
+ EXPECT_EQ(0.0, *double_member); |
+ |
+ // Try changing through the member variable. |
+ double_member.SetValue(1.0); |
+ EXPECT_EQ(1.0, double_member.GetValue()); |
+ EXPECT_EQ(1.0, prefs.GetDouble(kDoublePref)); |
+ EXPECT_EQ(1.0, *double_member); |
+ |
+ // Try changing back through the pref. |
+ prefs.SetDouble(kDoublePref, 3.0); |
+ EXPECT_EQ(3.0, prefs.GetDouble(kDoublePref)); |
+ EXPECT_EQ(3.0, double_member.GetValue()); |
+ EXPECT_EQ(3.0, *double_member); |
+ |
+ // Test string |
+ StringPrefMember string; |
+ string.Init(kStringPref, &prefs); |
+ |
+ // Check the defaults |
+ EXPECT_EQ("default", prefs.GetString(kStringPref)); |
+ EXPECT_EQ("default", string.GetValue()); |
+ EXPECT_EQ("default", *string); |
+ |
+ // Try changing through the member variable. |
+ string.SetValue("foo"); |
+ EXPECT_EQ("foo", string.GetValue()); |
+ EXPECT_EQ("foo", prefs.GetString(kStringPref)); |
+ EXPECT_EQ("foo", *string); |
+ |
+ // Try changing back through the pref. |
+ prefs.SetString(kStringPref, "bar"); |
+ EXPECT_EQ("bar", prefs.GetString(kStringPref)); |
+ EXPECT_EQ("bar", string.GetValue()); |
+ EXPECT_EQ("bar", *string); |
+ |
+ // Test string list |
+ base::ListValue expected_list; |
+ std::vector<std::string> expected_vector; |
+ StringListPrefMember string_list; |
+ string_list.Init(kStringListPref, &prefs); |
+ |
+ // Check the defaults |
+ EXPECT_TRUE(expected_list.Equals(prefs.GetList(kStringListPref))); |
+ EXPECT_EQ(expected_vector, string_list.GetValue()); |
+ EXPECT_EQ(expected_vector, *string_list); |
+ |
+ // Try changing through the pref member. |
+ expected_list.AppendString("foo"); |
+ expected_vector.push_back("foo"); |
+ string_list.SetValue(expected_vector); |
+ |
+ EXPECT_TRUE(expected_list.Equals(prefs.GetList(kStringListPref))); |
+ EXPECT_EQ(expected_vector, string_list.GetValue()); |
+ EXPECT_EQ(expected_vector, *string_list); |
+ |
+ // Try adding through the pref. |
+ expected_list.AppendString("bar"); |
+ expected_vector.push_back("bar"); |
+ prefs.Set(kStringListPref, expected_list); |
+ |
+ EXPECT_TRUE(expected_list.Equals(prefs.GetList(kStringListPref))); |
+ EXPECT_EQ(expected_vector, string_list.GetValue()); |
+ EXPECT_EQ(expected_vector, *string_list); |
+ |
+ // Try removing through the pref. |
+ expected_list.Remove(0, NULL); |
+ expected_vector.erase(expected_vector.begin()); |
+ prefs.Set(kStringListPref, expected_list); |
+ |
+ EXPECT_TRUE(expected_list.Equals(prefs.GetList(kStringListPref))); |
+ EXPECT_EQ(expected_vector, string_list.GetValue()); |
+ EXPECT_EQ(expected_vector, *string_list); |
+} |
+ |
+TEST_F(PrefMemberTest, InvalidList) { |
+ // Set the vector to an initial good value. |
+ std::vector<std::string> expected_vector; |
+ expected_vector.push_back("foo"); |
+ |
+ // Try to add a valid list first. |
+ base::ListValue list; |
+ list.AppendString("foo"); |
+ std::vector<std::string> vector; |
+ EXPECT_TRUE(subtle::PrefMemberVectorStringUpdate(list, &vector)); |
+ EXPECT_EQ(expected_vector, vector); |
+ |
+ // Now try to add an invalid list. |vector| should not be changed. |
+ list.AppendInteger(0); |
+ EXPECT_FALSE(subtle::PrefMemberVectorStringUpdate(list, &vector)); |
+ EXPECT_EQ(expected_vector, vector); |
+} |
+ |
+TEST_F(PrefMemberTest, TwoPrefs) { |
+ // Make sure two DoublePrefMembers stay in sync. |
+ TestingPrefServiceSimple prefs; |
+ RegisterTestPrefs(prefs.registry()); |
+ |
+ DoublePrefMember pref1; |
+ pref1.Init(kDoublePref, &prefs); |
+ DoublePrefMember pref2; |
+ pref2.Init(kDoublePref, &prefs); |
+ |
+ pref1.SetValue(2.3); |
+ EXPECT_EQ(2.3, *pref2); |
+ |
+ pref2.SetValue(3.5); |
+ EXPECT_EQ(3.5, *pref1); |
+ |
+ prefs.SetDouble(kDoublePref, 4.2); |
+ EXPECT_EQ(4.2, *pref1); |
+ EXPECT_EQ(4.2, *pref2); |
+} |
+ |
+TEST_F(PrefMemberTest, Observer) { |
+ TestingPrefServiceSimple prefs; |
+ RegisterTestPrefs(prefs.registry()); |
+ |
+ PrefMemberTestClass test_obj(&prefs); |
+ EXPECT_EQ("default", *test_obj.str_); |
+ |
+ // Calling SetValue should not fire the observer. |
+ test_obj.str_.SetValue("hello"); |
+ EXPECT_EQ(0, test_obj.observe_cnt_); |
+ EXPECT_EQ("hello", prefs.GetString(kStringPref)); |
+ |
+ // Changing the pref does fire the observer. |
+ prefs.SetString(kStringPref, "world"); |
+ EXPECT_EQ(1, test_obj.observe_cnt_); |
+ EXPECT_EQ("world", *(test_obj.str_)); |
+ |
+ // Not changing the value should not fire the observer. |
+ prefs.SetString(kStringPref, "world"); |
+ EXPECT_EQ(1, test_obj.observe_cnt_); |
+ EXPECT_EQ("world", *(test_obj.str_)); |
+ |
+ prefs.SetString(kStringPref, "hello"); |
+ EXPECT_EQ(2, test_obj.observe_cnt_); |
+ EXPECT_EQ("hello", prefs.GetString(kStringPref)); |
+} |
+ |
+TEST_F(PrefMemberTest, NoInit) { |
+ // Make sure not calling Init on a PrefMember doesn't cause problems. |
+ IntegerPrefMember pref; |
+} |
+ |
+TEST_F(PrefMemberTest, MoveToThread) { |
+ TestingPrefServiceSimple prefs; |
+ scoped_refptr<GetPrefValueHelper> helper(new GetPrefValueHelper()); |
+ RegisterTestPrefs(prefs.registry()); |
+ helper->Init(kBoolPref, &prefs); |
+ |
+ helper->FetchValue(); |
+ EXPECT_FALSE(helper->value()); |
+ |
+ prefs.SetBoolean(kBoolPref, true); |
+ |
+ helper->FetchValue(); |
+ EXPECT_TRUE(helper->value()); |
+ |
+ helper->Destroy(); |
+ |
+ helper->FetchValue(); |
+ EXPECT_TRUE(helper->value()); |
+ |
+ helper->StopThread(); |
+} |