Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Unified Diff: services/preferences/pref_service_factory_unittest.cc

Issue 2812863002: Pref service: Add a ScopedDictionaryPrefUpdate to track value changes. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/preferences/persistent_pref_store_impl.cc ('k') | services/preferences/public/cpp/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/preferences/pref_service_factory_unittest.cc
diff --git a/services/preferences/pref_service_factory_unittest.cc b/services/preferences/pref_service_factory_unittest.cc
index 21094e823adff98799081d2455d458a8237ad647..7310d2e436d9c5e2e327abfee66308edcce05197 100644
--- a/services/preferences/pref_service_factory_unittest.cc
+++ b/services/preferences/pref_service_factory_unittest.cc
@@ -7,6 +7,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
@@ -16,6 +17,7 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/preferences/public/cpp/pref_service_main.h"
#include "services/preferences/public/cpp/pref_store_impl.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/interface_factory.h"
@@ -76,6 +78,7 @@ constexpr int kInitialValue = 1;
constexpr int kUpdatedValue = 2;
constexpr char kKey[] = "some_key";
constexpr char kOtherKey[] = "some_other_key";
+constexpr char kDictionaryKey[] = "a.dictionary.pref";
class PrefServiceFactoryTest : public base::MessageLoop::DestructionObserver,
public service_manager::test::ServiceTest {
@@ -131,6 +134,7 @@ class PrefServiceFactoryTest : public base::MessageLoop::DestructionObserver,
auto pref_registry = make_scoped_refptr(new PrefRegistrySimple());
pref_registry->RegisterIntegerPref(kKey, kInitialValue);
pref_registry->RegisterIntegerPref(kOtherKey, kInitialValue);
+ pref_registry->RegisterDictionaryPref(kDictionaryKey);
ConnectToPrefService(connector(), pref_registry,
std::vector<PrefValueStore::PrefStoreType>(),
base::Bind(&PrefServiceFactoryTest::OnCreate,
@@ -265,5 +269,211 @@ TEST_F(PrefServiceFactoryTest, ReadOnlyPrefStore_UserPrefStoreLayering) {
EXPECT_EQ(2, pref_service->GetInteger(kKey));
}
+void Fail(PrefService* pref_service) {
+ FAIL() << "Unexpected change notification: "
+ << *pref_service->GetDictionary(kDictionaryKey);
+}
+
+TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_Basic) {
+ auto pref_service = Create();
+ auto pref_service2 = Create();
+
+ void (*updates[])(ScopedDictionaryPrefUpdate*) = {
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetInteger("path.to.integer", 1);
+ int out = 0;
+ ASSERT_TRUE((*update)->GetInteger("path.to.integer", &out));
+ EXPECT_EQ(1, out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetIntegerWithoutPathExpansion("key.for.integer", 2);
+ int out = 0;
+ ASSERT_TRUE(
+ (*update)->GetIntegerWithoutPathExpansion("key.for.integer", &out));
+ EXPECT_EQ(2, out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetDouble("path.to.double", 3);
+ double out = 0;
+ ASSERT_TRUE((*update)->GetDouble("path.to.double", &out));
+ EXPECT_EQ(3, out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetDoubleWithoutPathExpansion("key.for.double", 4);
+ double out = 0;
+ ASSERT_TRUE(
+ (*update)->GetDoubleWithoutPathExpansion("key.for.double", &out));
+ EXPECT_EQ(4, out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetBoolean("path.to.boolean", true);
+ bool out = 0;
+ ASSERT_TRUE((*update)->GetBoolean("path.to.boolean", &out));
+ EXPECT_TRUE(out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetBooleanWithoutPathExpansion("key.for.boolean", false);
+ bool out = 0;
+ ASSERT_TRUE(
+ (*update)->GetBooleanWithoutPathExpansion("key.for.boolean", &out));
+ EXPECT_FALSE(out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetString("path.to.string", "hello");
+ std::string out;
+ ASSERT_TRUE((*update)->GetString("path.to.string", &out));
+ EXPECT_EQ("hello", out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetStringWithoutPathExpansion("key.for.string", "prefs!");
+ std::string out;
+ ASSERT_TRUE(
+ (*update)->GetStringWithoutPathExpansion("key.for.string", &out));
+ EXPECT_EQ("prefs!", out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetString("path.to.string", base::ASCIIToUTF16("hello"));
+ base::string16 out;
+ ASSERT_TRUE((*update)->GetString("path.to.string", &out));
+ EXPECT_EQ(base::ASCIIToUTF16("hello"), out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ (*update)->SetStringWithoutPathExpansion("key.for.string16",
+ base::ASCIIToUTF16("prefs!"));
+ base::string16 out;
+ ASSERT_TRUE(
+ (*update)->GetStringWithoutPathExpansion("key.for.string16", &out));
+ EXPECT_EQ(base::ASCIIToUTF16("prefs!"), out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ base::Value buffer(std::vector<char>{1, 2, 3, 4, 5});
+ (*update)->Set("path.to.binary", base::MakeUnique<base::Value>(buffer));
+ const base::Value* out;
+ ASSERT_TRUE((*update)->GetBinary("path.to.binary", &out));
+ EXPECT_EQ(buffer, *out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ base::ListValue list;
+ list.AppendInteger(1);
+ list.AppendDouble(2);
+ list.AppendBoolean(true);
+ list.AppendString("four");
+ (*update)->Set("path.to.list", list.CreateDeepCopy());
+ const base::ListValue* out = nullptr;
+ ASSERT_TRUE((*update)->GetList("path.to.list", &out));
+ EXPECT_EQ(list, *out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ base::ListValue list;
+ list.AppendInteger(1);
+ list.AppendDouble(2);
+ list.AppendBoolean(true);
+ list.AppendString("four");
+ (*update)->SetWithoutPathExpansion("key.for.list",
+ list.CreateDeepCopy());
+ const base::ListValue* out = nullptr;
+ ASSERT_TRUE(
+ (*update)->GetListWithoutPathExpansion("key.for.list", &out));
+ EXPECT_EQ(list, *out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ base::DictionaryValue dict;
+ dict.SetInteger("int", 1);
+ dict.SetDouble("double", 2);
+ dict.SetBoolean("bool", true);
+ dict.SetString("string", "four");
+ (*update)->Set("path.to.dict", dict.CreateDeepCopy());
+ const base::DictionaryValue* out = nullptr;
+ ASSERT_TRUE((*update)->GetDictionary("path.to.dict", &out));
+ EXPECT_EQ(dict, *out);
+ },
+ [](ScopedDictionaryPrefUpdate* update) {
+ base::DictionaryValue dict;
+ dict.SetInteger("int", 1);
+ dict.SetDouble("double", 2);
+ dict.SetBoolean("bool", true);
+ dict.SetString("string", "four");
+ (*update)->SetWithoutPathExpansion("key.for.dict",
+ dict.CreateDeepCopy());
+ const base::DictionaryValue* out = nullptr;
+ ASSERT_TRUE(
+ (*update)->GetDictionaryWithoutPathExpansion("key.for.dict", &out));
+ EXPECT_EQ(dict, *out);
+ },
+ };
+ int current_value = kInitialValue + 1;
+ for (auto& mutation : updates) {
+ base::DictionaryValue expected_value;
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ EXPECT_EQ(update->AsConstDictionary()->empty(), update->empty());
+ EXPECT_EQ(update->AsConstDictionary()->size(), update->size());
+ mutation(&update);
+ EXPECT_EQ(update->AsConstDictionary()->empty(), update->empty());
+ EXPECT_EQ(update->AsConstDictionary()->size(), update->size());
+ expected_value = *update->AsConstDictionary();
+ }
+
+ EXPECT_EQ(expected_value, *pref_service->GetDictionary(kDictionaryKey));
+ WaitForPrefChange(pref_service2.get(), kDictionaryKey);
+ EXPECT_EQ(expected_value, *pref_service2->GetDictionary(kDictionaryKey));
+
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ mutation(&update);
+ EXPECT_EQ(expected_value, *update->AsConstDictionary());
+ }
+ {
+ PrefChangeRegistrar registrar;
+ registrar.Init(pref_service2.get());
+ registrar.Add(kDictionaryKey, base::Bind(&Fail, pref_service2.get()));
+ pref_service->SetInteger(kKey, ++current_value);
+ WaitForPrefChange(pref_service2.get(), kKey);
+ }
+ if (!pref_service->GetDictionary(kDictionaryKey)->empty()) {
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ update->Clear();
+ }
+ WaitForPrefChange(pref_service2.get(), kDictionaryKey);
+ }
+ }
+}
+
+TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_Erase) {
+ auto pref_service = Create();
+ auto pref_service2 = Create();
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ update->SetInteger("path.to.integer", 1);
+ }
+ WaitForPrefChange(pref_service2.get(), kDictionaryKey);
+
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ ASSERT_TRUE(update->RemovePath("path.to.integer", nullptr));
+ }
+ WaitForPrefChange(pref_service2.get(), kDictionaryKey);
+ EXPECT_TRUE(pref_service2->GetDictionary(kDictionaryKey)->empty());
+}
+
+TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_ClearDictionary) {
+ auto pref_service = Create();
+ auto pref_service2 = Create();
+
+ { ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey); }
+ WaitForPrefChange(pref_service2.get(), kDictionaryKey);
+
+ {
+ ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
+ update->Clear();
+ }
+ PrefChangeRegistrar registrar;
+ registrar.Init(pref_service2.get());
+ registrar.Add(kDictionaryKey, base::Bind(&Fail, pref_service2.get()));
+ pref_service->SetInteger(kKey, kUpdatedValue);
+ WaitForPrefChange(pref_service2.get(), kKey);
+}
+
} // namespace
} // namespace prefs
« no previous file with comments | « services/preferences/persistent_pref_store_impl.cc ('k') | services/preferences/public/cpp/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698