1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/prefs/testing_pref_store.h"
11 #include "base/json/json_writer.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_piece.h"
14 #include "base/values.h"
15 #include "testing/gtest/include/gtest/gtest.h"
19 class ChangedValueWaiter : public PrefStore::Observer {
21 ChangedValueWaiter(scoped_refptr<PrefStore> store, std::string key)
22 : store_(std::move(store)), key_(std::move(key)) {
23 store_->AddObserver(this);
25 const base::Value* old_value = nullptr;
26 if (store_->GetValue(key_, &old_value)) {
27 old_value_ = old_value->Clone();
31 ~ChangedValueWaiter() override { store_->RemoveObserver(this); }
33 void Wait() { run_loop_.Run(); }
36 void QuitRunLoopIfNewValueIsPresent() {
37 absl::optional<base::Value> new_value;
39 const base::Value* value = nullptr;
40 if (store_->GetValue(key_, &value)) {
41 new_value = value->Clone();
45 if (new_value != old_value_) {
50 void OnInitializationCompleted(bool succeeded) override {
51 QuitRunLoopIfNewValueIsPresent();
54 void OnPrefValueChanged(const std::string& key) override {
56 QuitRunLoopIfNewValueIsPresent();
60 scoped_refptr<PrefStore> store_;
62 absl::optional<base::Value> old_value_;
63 base::RunLoop run_loop_;
68 TestingPrefStore::TestingPrefStore()
71 read_error_(PersistentPrefStore::PREF_READ_ERROR_NONE),
72 block_async_read_(false),
73 pending_async_read_(false),
74 init_complete_(false),
77 bool TestingPrefStore::GetValue(base::StringPiece key,
78 const base::Value** value) const {
79 return prefs_.GetValue(key, value);
82 base::Value::Dict TestingPrefStore::GetValues() const {
83 return prefs_.AsDict();
86 bool TestingPrefStore::GetMutableValue(const std::string& key,
87 base::Value** value) {
88 return prefs_.GetValue(key, value);
91 void TestingPrefStore::AddObserver(PrefStore::Observer* observer) {
92 observers_.AddObserver(observer);
95 void TestingPrefStore::RemoveObserver(PrefStore::Observer* observer) {
96 observers_.RemoveObserver(observer);
99 bool TestingPrefStore::HasObservers() const {
100 return !observers_.empty();
103 bool TestingPrefStore::IsInitializationComplete() const {
104 return init_complete_;
107 void TestingPrefStore::SetValue(const std::string& key,
110 if (prefs_.SetValue(key, std::move(value))) {
112 NotifyPrefValueChanged(key);
116 void TestingPrefStore::SetValueSilently(const std::string& key,
119 CheckPrefIsSerializable(key, value);
120 if (prefs_.SetValue(key, std::move(value)))
124 void TestingPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
125 if (prefs_.RemoveValue(key)) {
127 NotifyPrefValueChanged(key);
131 void TestingPrefStore::RemoveValuesByPrefixSilently(const std::string& prefix) {
132 prefs_.ClearWithPrefix(prefix);
135 bool TestingPrefStore::ReadOnly() const {
139 PersistentPrefStore::PrefReadError TestingPrefStore::GetReadError() const {
143 PersistentPrefStore::PrefReadError TestingPrefStore::ReadPrefs() {
144 NotifyInitializationCompleted();
148 void TestingPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
149 DCHECK(!pending_async_read_);
150 error_delegate_.reset(error_delegate);
151 if (block_async_read_)
152 pending_async_read_ = true;
154 NotifyInitializationCompleted();
157 void TestingPrefStore::CommitPendingWrite(
158 base::OnceClosure reply_callback,
159 base::OnceClosure synchronous_done_callback) {
161 PersistentPrefStore::CommitPendingWrite(std::move(reply_callback),
162 std::move(synchronous_done_callback));
165 void TestingPrefStore::SchedulePendingLossyWrites() {}
167 void TestingPrefStore::SetInitializationCompleted() {
168 NotifyInitializationCompleted();
171 void TestingPrefStore::NotifyPrefValueChanged(const std::string& key) {
172 for (Observer& observer : observers_)
173 observer.OnPrefValueChanged(key);
176 void TestingPrefStore::NotifyInitializationCompleted() {
177 DCHECK(!init_complete_);
178 init_complete_ = true;
179 if (read_success_ && read_error_ != PREF_READ_ERROR_NONE && error_delegate_)
180 error_delegate_->OnError(read_error_);
181 for (Observer& observer : observers_)
182 observer.OnInitializationCompleted(read_success_);
185 void TestingPrefStore::ReportValueChanged(const std::string& key,
187 const base::Value* value = nullptr;
188 if (prefs_.GetValue(key, &value))
189 CheckPrefIsSerializable(key, *value);
191 for (Observer& observer : observers_)
192 observer.OnPrefValueChanged(key);
195 void TestingPrefStore::SetString(const std::string& key,
196 const std::string& value) {
197 SetValue(key, base::Value(value), DEFAULT_PREF_WRITE_FLAGS);
200 void TestingPrefStore::SetInteger(const std::string& key, int value) {
201 SetValue(key, base::Value(value), DEFAULT_PREF_WRITE_FLAGS);
204 void TestingPrefStore::SetBoolean(const std::string& key, bool value) {
205 SetValue(key, base::Value(value), DEFAULT_PREF_WRITE_FLAGS);
208 bool TestingPrefStore::GetString(const std::string& key,
209 std::string* value) const {
210 const base::Value* stored_value;
211 if (!prefs_.GetValue(key, &stored_value) || !stored_value)
214 if (value && stored_value->is_string()) {
215 *value = stored_value->GetString();
218 return stored_value->is_string();
221 bool TestingPrefStore::GetInteger(const std::string& key, int* value) const {
222 const base::Value* stored_value;
223 if (!prefs_.GetValue(key, &stored_value) || !stored_value)
226 if (value && stored_value->is_int()) {
227 *value = stored_value->GetInt();
230 return stored_value->is_int();
233 bool TestingPrefStore::GetBoolean(const std::string& key, bool* value) const {
234 const base::Value* stored_value;
235 if (!prefs_.GetValue(key, &stored_value) || !stored_value)
238 if (value && stored_value->is_bool()) {
239 *value = stored_value->GetBool();
242 return stored_value->is_bool();
245 void TestingPrefStore::SetBlockAsyncRead(bool block_async_read) {
246 DCHECK(!init_complete_);
247 block_async_read_ = block_async_read;
248 if (pending_async_read_ && !block_async_read_)
249 NotifyInitializationCompleted();
252 void TestingPrefStore::WaitUntilValueChanges(std::string key) {
253 ChangedValueWaiter waiter(this, std::move(key));
257 void TestingPrefStore::WaitForValue(std::string key,
258 base::Value expected_value) {
260 const base::Value* curr_value = nullptr;
261 if (GetValue(key, &curr_value) && *curr_value == expected_value) {
265 WaitUntilValueChanges(key);
269 void TestingPrefStore::OnStoreDeletionFromDisk() {}
271 void TestingPrefStore::set_read_only(bool read_only) {
272 read_only_ = read_only;
275 void TestingPrefStore::set_read_success(bool read_success) {
276 DCHECK(!init_complete_);
277 read_success_ = read_success;
280 void TestingPrefStore::set_read_error(
281 PersistentPrefStore::PrefReadError read_error) {
282 DCHECK(!init_complete_);
283 read_error_ = read_error;
286 TestingPrefStore::~TestingPrefStore() {
287 for (auto& pref : prefs_)
288 CheckPrefIsSerializable(pref.first, pref.second);
291 void TestingPrefStore::CheckPrefIsSerializable(const std::string& key,
292 const base::Value& value) {
294 EXPECT_TRUE(base::JSONWriter::Write(value, &json))
295 << "Pref \"" << key << "\" is not serializable as JSON.";