pref_member_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. #include "components/prefs/pref_member.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/location.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/synchronization/waitable_event.h"
  10. #include "base/task/sequenced_task_runner.h"
  11. #include "base/task/thread_pool.h"
  12. #include "base/test/task_environment.h"
  13. #include "components/prefs/pref_registry_simple.h"
  14. #include "components/prefs/testing_pref_service.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. namespace {
  17. const char kBoolPref[] = "bool";
  18. const char kIntPref[] = "int";
  19. const char kDoublePref[] = "double";
  20. const char kStringPref[] = "string";
  21. const char kStringListPref[] = "string_list";
  22. void RegisterTestPrefs(PrefRegistrySimple* registry) {
  23. registry->RegisterBooleanPref(kBoolPref, false);
  24. registry->RegisterIntegerPref(kIntPref, 0);
  25. registry->RegisterDoublePref(kDoublePref, 0.0);
  26. registry->RegisterStringPref(kStringPref, "default");
  27. registry->RegisterListPref(kStringListPref);
  28. }
  29. class GetPrefValueHelper
  30. : public base::RefCountedThreadSafe<GetPrefValueHelper> {
  31. public:
  32. GetPrefValueHelper()
  33. : value_(false),
  34. task_runner_(base::ThreadPool::CreateSequencedTaskRunner({})) {}
  35. void Init(const std::string& pref_name, PrefService* prefs) {
  36. pref_.Init(pref_name, prefs);
  37. pref_.MoveToSequence(task_runner_);
  38. }
  39. void Destroy() {
  40. pref_.Destroy();
  41. }
  42. void FetchValue() {
  43. base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
  44. base::WaitableEvent::InitialState::NOT_SIGNALED);
  45. ASSERT_TRUE(task_runner_->PostTask(
  46. FROM_HERE,
  47. base::BindOnce(&GetPrefValueHelper::GetPrefValue, this, &event)));
  48. event.Wait();
  49. }
  50. bool value() { return value_; }
  51. private:
  52. friend class base::RefCountedThreadSafe<GetPrefValueHelper>;
  53. ~GetPrefValueHelper() {}
  54. void GetPrefValue(base::WaitableEvent* event) {
  55. value_ = pref_.GetValue();
  56. event->Signal();
  57. }
  58. BooleanPrefMember pref_;
  59. bool value_;
  60. // The sequence |pref_| runs on.
  61. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  62. };
  63. class PrefMemberTestClass {
  64. public:
  65. explicit PrefMemberTestClass(PrefService* prefs)
  66. : observe_cnt_(0), prefs_(prefs) {
  67. str_.Init(kStringPref, prefs,
  68. base::BindRepeating(&PrefMemberTestClass::OnPreferenceChanged,
  69. base::Unretained(this)));
  70. }
  71. void OnPreferenceChanged(const std::string& pref_name) {
  72. EXPECT_EQ(pref_name, kStringPref);
  73. EXPECT_EQ(str_.GetValue(), prefs_->GetString(kStringPref));
  74. EXPECT_EQ(str_.IsDefaultValue(),
  75. prefs_->FindPreference(kStringPref)->IsDefaultValue());
  76. ++observe_cnt_;
  77. }
  78. StringPrefMember str_;
  79. int observe_cnt_;
  80. private:
  81. raw_ptr<PrefService> prefs_;
  82. };
  83. } // anonymous namespace
  84. class PrefMemberTest : public testing::Test {
  85. base::test::TaskEnvironment task_environment_;
  86. };
  87. TEST_F(PrefMemberTest, BasicGetAndSet) {
  88. TestingPrefServiceSimple prefs;
  89. RegisterTestPrefs(prefs.registry());
  90. // Test bool
  91. BooleanPrefMember boolean;
  92. boolean.Init(kBoolPref, &prefs);
  93. // Check the defaults
  94. EXPECT_FALSE(prefs.GetBoolean(kBoolPref));
  95. EXPECT_FALSE(boolean.GetValue());
  96. EXPECT_FALSE(*boolean);
  97. EXPECT_TRUE(boolean.IsDefaultValue());
  98. // Try changing through the member variable.
  99. boolean.SetValue(true);
  100. EXPECT_TRUE(boolean.GetValue());
  101. EXPECT_TRUE(prefs.GetBoolean(kBoolPref));
  102. EXPECT_TRUE(*boolean);
  103. EXPECT_FALSE(boolean.IsDefaultValue());
  104. // Try changing back through the pref.
  105. prefs.SetBoolean(kBoolPref, false);
  106. EXPECT_FALSE(prefs.GetBoolean(kBoolPref));
  107. EXPECT_FALSE(boolean.GetValue());
  108. EXPECT_FALSE(*boolean);
  109. EXPECT_FALSE(boolean.IsDefaultValue());
  110. // Test int
  111. IntegerPrefMember integer;
  112. integer.Init(kIntPref, &prefs);
  113. // Check the defaults
  114. EXPECT_EQ(0, prefs.GetInteger(kIntPref));
  115. EXPECT_EQ(0, integer.GetValue());
  116. EXPECT_EQ(0, *integer);
  117. EXPECT_TRUE(integer.IsDefaultValue());
  118. // Try changing through the member variable.
  119. integer.SetValue(5);
  120. EXPECT_EQ(5, integer.GetValue());
  121. EXPECT_EQ(5, prefs.GetInteger(kIntPref));
  122. EXPECT_EQ(5, *integer);
  123. EXPECT_FALSE(integer.IsDefaultValue());
  124. // Try changing back through the pref.
  125. prefs.SetInteger(kIntPref, 2);
  126. EXPECT_EQ(2, prefs.GetInteger(kIntPref));
  127. EXPECT_EQ(2, integer.GetValue());
  128. EXPECT_EQ(2, *integer);
  129. EXPECT_FALSE(integer.IsDefaultValue());
  130. // Test double
  131. DoublePrefMember double_member;
  132. double_member.Init(kDoublePref, &prefs);
  133. // Check the defaults
  134. EXPECT_EQ(0.0, prefs.GetDouble(kDoublePref));
  135. EXPECT_EQ(0.0, double_member.GetValue());
  136. EXPECT_EQ(0.0, *double_member);
  137. EXPECT_TRUE(double_member.IsDefaultValue());
  138. // Try changing through the member variable.
  139. double_member.SetValue(1.0);
  140. EXPECT_EQ(1.0, double_member.GetValue());
  141. EXPECT_EQ(1.0, prefs.GetDouble(kDoublePref));
  142. EXPECT_EQ(1.0, *double_member);
  143. EXPECT_FALSE(double_member.IsDefaultValue());
  144. // Try changing back through the pref.
  145. prefs.SetDouble(kDoublePref, 3.0);
  146. EXPECT_EQ(3.0, prefs.GetDouble(kDoublePref));
  147. EXPECT_EQ(3.0, double_member.GetValue());
  148. EXPECT_EQ(3.0, *double_member);
  149. EXPECT_FALSE(double_member.IsDefaultValue());
  150. // Test string
  151. StringPrefMember string;
  152. string.Init(kStringPref, &prefs);
  153. // Check the defaults
  154. EXPECT_EQ("default", prefs.GetString(kStringPref));
  155. EXPECT_EQ("default", string.GetValue());
  156. EXPECT_EQ("default", *string);
  157. EXPECT_TRUE(string.IsDefaultValue());
  158. // Try changing through the member variable.
  159. string.SetValue("foo");
  160. EXPECT_EQ("foo", string.GetValue());
  161. EXPECT_EQ("foo", prefs.GetString(kStringPref));
  162. EXPECT_EQ("foo", *string);
  163. EXPECT_FALSE(string.IsDefaultValue());
  164. // Try changing back through the pref.
  165. prefs.SetString(kStringPref, "bar");
  166. EXPECT_EQ("bar", prefs.GetString(kStringPref));
  167. EXPECT_EQ("bar", string.GetValue());
  168. EXPECT_EQ("bar", *string);
  169. EXPECT_FALSE(string.IsDefaultValue());
  170. // Test string list
  171. base::Value::List expected_list;
  172. std::vector<std::string> expected_vector;
  173. StringListPrefMember string_list;
  174. string_list.Init(kStringListPref, &prefs);
  175. // Check the defaults
  176. EXPECT_EQ(expected_list, prefs.GetValueList(kStringListPref));
  177. EXPECT_EQ(expected_vector, string_list.GetValue());
  178. EXPECT_EQ(expected_vector, *string_list);
  179. EXPECT_TRUE(string_list.IsDefaultValue());
  180. // Try changing through the pref member.
  181. expected_list.Append("foo");
  182. expected_vector.push_back("foo");
  183. string_list.SetValue(expected_vector);
  184. EXPECT_EQ(expected_list, prefs.GetValueList(kStringListPref));
  185. EXPECT_EQ(expected_vector, string_list.GetValue());
  186. EXPECT_EQ(expected_vector, *string_list);
  187. EXPECT_FALSE(string_list.IsDefaultValue());
  188. // Try adding through the pref.
  189. expected_list.Append("bar");
  190. expected_vector.push_back("bar");
  191. prefs.SetList(kStringListPref, expected_list.Clone());
  192. EXPECT_EQ(expected_list, prefs.GetValueList(kStringListPref));
  193. EXPECT_EQ(expected_vector, string_list.GetValue());
  194. EXPECT_EQ(expected_vector, *string_list);
  195. EXPECT_FALSE(string_list.IsDefaultValue());
  196. // Try removing through the pref.
  197. expected_list.erase(expected_list.begin());
  198. expected_vector.erase(expected_vector.begin());
  199. prefs.SetList(kStringListPref, expected_list.Clone());
  200. EXPECT_EQ(expected_list, prefs.GetValueList(kStringListPref));
  201. EXPECT_EQ(expected_vector, string_list.GetValue());
  202. EXPECT_EQ(expected_vector, *string_list);
  203. EXPECT_FALSE(string_list.IsDefaultValue());
  204. }
  205. TEST_F(PrefMemberTest, InvalidList) {
  206. // Set the vector to an initial good value.
  207. std::vector<std::string> expected_vector;
  208. expected_vector.push_back("foo");
  209. // Try to add a valid list first.
  210. base::Value list(base::Value::Type::LIST);
  211. list.Append("foo");
  212. std::vector<std::string> vector;
  213. EXPECT_TRUE(subtle::PrefMemberVectorStringUpdate(list, &vector));
  214. EXPECT_EQ(expected_vector, vector);
  215. // Now try to add an invalid list. |vector| should not be changed.
  216. list.Append(0);
  217. EXPECT_FALSE(subtle::PrefMemberVectorStringUpdate(list, &vector));
  218. EXPECT_EQ(expected_vector, vector);
  219. }
  220. TEST_F(PrefMemberTest, TwoPrefs) {
  221. // Make sure two DoublePrefMembers stay in sync.
  222. TestingPrefServiceSimple prefs;
  223. RegisterTestPrefs(prefs.registry());
  224. DoublePrefMember pref1;
  225. pref1.Init(kDoublePref, &prefs);
  226. DoublePrefMember pref2;
  227. pref2.Init(kDoublePref, &prefs);
  228. pref1.SetValue(2.3);
  229. EXPECT_EQ(2.3, *pref2);
  230. pref2.SetValue(3.5);
  231. EXPECT_EQ(3.5, *pref1);
  232. prefs.SetDouble(kDoublePref, 4.2);
  233. EXPECT_EQ(4.2, *pref1);
  234. EXPECT_EQ(4.2, *pref2);
  235. }
  236. TEST_F(PrefMemberTest, Observer) {
  237. TestingPrefServiceSimple prefs;
  238. RegisterTestPrefs(prefs.registry());
  239. PrefMemberTestClass test_obj(&prefs);
  240. EXPECT_EQ("default", *test_obj.str_);
  241. EXPECT_TRUE(test_obj.str_.IsDefaultValue());
  242. // Changing the pref from the default value to an explicitly-set version of
  243. // the same value fires the observer. The caller may be sensitive to
  244. // IsDefaultValue().
  245. prefs.SetString(kStringPref, "default");
  246. EXPECT_EQ("default", *test_obj.str_);
  247. EXPECT_EQ(1, test_obj.observe_cnt_);
  248. EXPECT_FALSE(test_obj.str_.IsDefaultValue());
  249. // Calling SetValue should not fire the observer.
  250. test_obj.str_.SetValue("hello");
  251. EXPECT_EQ(1, test_obj.observe_cnt_);
  252. EXPECT_EQ("hello", prefs.GetString(kStringPref));
  253. // Changing the pref does fire the observer.
  254. prefs.SetString(kStringPref, "world");
  255. EXPECT_EQ(2, test_obj.observe_cnt_);
  256. EXPECT_EQ("world", *(test_obj.str_));
  257. // Not changing the value should not fire the observer.
  258. prefs.SetString(kStringPref, "world");
  259. EXPECT_EQ(2, test_obj.observe_cnt_);
  260. EXPECT_EQ("world", *(test_obj.str_));
  261. prefs.SetString(kStringPref, "hello");
  262. EXPECT_EQ(3, test_obj.observe_cnt_);
  263. EXPECT_EQ("hello", prefs.GetString(kStringPref));
  264. }
  265. TEST_F(PrefMemberTest, NoInit) {
  266. // Make sure not calling Init on a PrefMember doesn't cause problems.
  267. IntegerPrefMember pref;
  268. }
  269. TEST_F(PrefMemberTest, MoveToSequence) {
  270. TestingPrefServiceSimple prefs;
  271. scoped_refptr<GetPrefValueHelper> helper(new GetPrefValueHelper());
  272. RegisterTestPrefs(prefs.registry());
  273. helper->Init(kBoolPref, &prefs);
  274. helper->FetchValue();
  275. EXPECT_FALSE(helper->value());
  276. prefs.SetBoolean(kBoolPref, true);
  277. helper->FetchValue();
  278. EXPECT_TRUE(helper->value());
  279. helper->Destroy();
  280. helper->FetchValue();
  281. EXPECT_TRUE(helper->value());
  282. }