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