1 // Copyright 2014 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.
5 #include "extensions/browser/value_store/value_store_unittest.h"
7 #include "base/json/json_writer.h"
8 #include "base/memory/linked_ptr.h"
9 #include "base/values.h"
11 using content::BrowserThread
;
15 // To save typing ValueStore::DEFAULTS everywhere.
16 const ValueStore::WriteOptions DEFAULTS
= ValueStore::DEFAULTS
;
18 // Gets the pretty-printed JSON for a value.
19 std::string
GetJSON(const base::Value
& value
) {
21 base::JSONWriter::WriteWithOptions(
22 value
, base::JSONWriter::OPTIONS_PRETTY_PRINT
, &json
);
28 // Compares two possibly NULL values for equality, filling |error| with an
29 // appropriate error message if they're different.
30 bool ValuesEqual(const base::Value
* expected
,
31 const base::Value
* actual
,
33 if (expected
== actual
) {
36 if (expected
&& !actual
) {
37 *error
= "Expected: " + GetJSON(*expected
) + ", actual: NULL";
40 if (actual
&& !expected
) {
41 *error
= "Expected: NULL, actual: " + GetJSON(*actual
);
44 if (!expected
->Equals(actual
)) {
46 "Expected: " + GetJSON(*expected
) + ", actual: " + GetJSON(*actual
);
52 // Returns whether the read result of a storage operation has the expected
54 testing::AssertionResult
SettingsEq(
55 const char* _1
, const char* _2
,
56 const base::DictionaryValue
& expected
,
57 ValueStore::ReadResult actual_result
) {
58 if (actual_result
->HasError()) {
59 return testing::AssertionFailure() <<
60 "Result has error: " << actual_result
->error().message
;
64 if (!ValuesEqual(&expected
, &actual_result
->settings(), &error
)) {
65 return testing::AssertionFailure() << error
;
68 return testing::AssertionSuccess();
71 // Returns whether the write result of a storage operation has the expected
73 testing::AssertionResult
ChangesEq(
74 const char* _1
, const char* _2
,
75 const ValueStoreChangeList
& expected
,
76 ValueStore::WriteResult actual_result
) {
77 if (actual_result
->HasError()) {
78 return testing::AssertionFailure() <<
79 "Result has error: " << actual_result
->error().message
;
82 const ValueStoreChangeList
& actual
= actual_result
->changes();
83 if (expected
.size() != actual
.size()) {
84 return testing::AssertionFailure() <<
85 "Actual has wrong size, expecting " << expected
.size() <<
86 " but was " << actual
.size();
89 std::map
<std::string
, linked_ptr
<ValueStoreChange
> > expected_as_map
;
90 for (ValueStoreChangeList::const_iterator it
= expected
.begin();
91 it
!= expected
.end(); ++it
) {
92 expected_as_map
[it
->key()] =
93 linked_ptr
<ValueStoreChange
>(new ValueStoreChange(*it
));
96 std::set
<std::string
> keys_seen
;
98 for (ValueStoreChangeList::const_iterator it
= actual
.begin();
99 it
!= actual
.end(); ++it
) {
100 if (keys_seen
.count(it
->key())) {
101 return testing::AssertionFailure() <<
102 "Multiple changes seen for key: " << it
->key();
104 keys_seen
.insert(it
->key());
106 if (!expected_as_map
.count(it
->key())) {
107 return testing::AssertionFailure() <<
108 "Actual has unexpected change for key: " << it
->key();
111 ValueStoreChange expected_change
= *expected_as_map
[it
->key()];
113 if (!ValuesEqual(expected_change
.new_value(), it
->new_value(), &error
)) {
114 return testing::AssertionFailure() <<
115 "New value for " << it
->key() << " was unexpected: " << error
;
117 if (!ValuesEqual(expected_change
.old_value(), it
->old_value(), &error
)) {
118 return testing::AssertionFailure() <<
119 "Old value for " << it
->key() << " was unexpected: " << error
;
123 return testing::AssertionSuccess();
126 ValueStoreTest::ValueStoreTest()
130 empty_dict_(new base::DictionaryValue()),
131 dict1_(new base::DictionaryValue()),
132 dict3_(new base::DictionaryValue()),
133 dict12_(new base::DictionaryValue()),
134 dict123_(new base::DictionaryValue()),
135 ui_thread_(BrowserThread::UI
, base::MessageLoop::current()),
136 file_thread_(BrowserThread::FILE, base::MessageLoop::current()) {
137 val1_
.reset(new base::StringValue(key1_
+ "Value"));
138 val2_
.reset(new base::StringValue(key2_
+ "Value"));
139 val3_
.reset(new base::StringValue(key3_
+ "Value"));
141 list1_
.push_back(key1_
);
142 list2_
.push_back(key2_
);
143 list3_
.push_back(key3_
);
144 list12_
.push_back(key1_
);
145 list12_
.push_back(key2_
);
146 list13_
.push_back(key1_
);
147 list13_
.push_back(key3_
);
148 list123_
.push_back(key1_
);
149 list123_
.push_back(key2_
);
150 list123_
.push_back(key3_
);
152 set1_
.insert(list1_
.begin(), list1_
.end());
153 set2_
.insert(list2_
.begin(), list2_
.end());
154 set3_
.insert(list3_
.begin(), list3_
.end());
155 set12_
.insert(list12_
.begin(), list12_
.end());
156 set13_
.insert(list13_
.begin(), list13_
.end());
157 set123_
.insert(list123_
.begin(), list123_
.end());
159 dict1_
->Set(key1_
, val1_
->DeepCopy());
160 dict3_
->Set(key3_
, val3_
->DeepCopy());
161 dict12_
->Set(key1_
, val1_
->DeepCopy());
162 dict12_
->Set(key2_
, val2_
->DeepCopy());
163 dict123_
->Set(key1_
, val1_
->DeepCopy());
164 dict123_
->Set(key2_
, val2_
->DeepCopy());
165 dict123_
->Set(key3_
, val3_
->DeepCopy());
168 ValueStoreTest::~ValueStoreTest() {}
170 void ValueStoreTest::SetUp() {
171 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
172 storage_
.reset((GetParam())(temp_dir_
.path().AppendASCII("dbName")));
173 ASSERT_TRUE(storage_
.get());
176 void ValueStoreTest::TearDown() {
180 TEST_P(ValueStoreTest
, GetWhenEmpty
) {
181 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
182 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
183 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
184 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
187 TEST_P(ValueStoreTest
, GetWithSingleValue
) {
189 ValueStoreChangeList changes
;
190 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
191 EXPECT_PRED_FORMAT2(ChangesEq
,
192 changes
, storage_
->Set(DEFAULTS
, key1_
, *val1_
));
195 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
196 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key2_
));
197 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
198 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
199 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list123_
));
200 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get());
203 TEST_P(ValueStoreTest
, GetWithMultipleValues
) {
205 ValueStoreChangeList changes
;
206 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
207 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
208 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
211 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
212 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
213 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
214 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
215 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
218 TEST_P(ValueStoreTest
, RemoveWhenEmpty
) {
219 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(),
220 storage_
->Remove(key1_
));
222 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
223 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
224 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
227 TEST_P(ValueStoreTest
, RemoveWithSingleValue
) {
228 storage_
->Set(DEFAULTS
, *dict1_
);
230 ValueStoreChangeList changes
;
231 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
232 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key1_
));
235 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
236 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key2_
));
237 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
238 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list12_
));
239 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
242 TEST_P(ValueStoreTest
, RemoveWithMultipleValues
) {
243 storage_
->Set(DEFAULTS
, *dict123_
);
245 ValueStoreChangeList changes
;
246 changes
.push_back(ValueStoreChange(key3_
, val3_
->DeepCopy(), NULL
));
247 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key3_
));
250 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
251 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
252 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
253 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list1_
));
254 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list12_
));
255 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list13_
));
256 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
257 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
260 ValueStoreChangeList changes
;
261 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
262 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
263 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(list12_
));
266 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
267 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
268 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
269 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
270 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list12_
));
271 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list13_
));
272 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
273 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
276 TEST_P(ValueStoreTest
, SetWhenOverwriting
) {
277 storage_
->Set(DEFAULTS
, key1_
, *val2_
);
279 ValueStoreChangeList changes
;
281 ValueStoreChange(key1_
, val2_
->DeepCopy(), val1_
->DeepCopy()));
282 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
283 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
286 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
287 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
288 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
289 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list1_
));
290 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list12_
));
291 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list13_
));
292 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
293 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
296 TEST_P(ValueStoreTest
, ClearWhenEmpty
) {
297 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());
299 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
300 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
301 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
302 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
305 TEST_P(ValueStoreTest
, ClearWhenNotEmpty
) {
306 storage_
->Set(DEFAULTS
, *dict12_
);
308 ValueStoreChangeList changes
;
309 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
310 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
311 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
314 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
315 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
316 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
317 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
320 // Dots should be allowed in key names; they shouldn't be interpreted as
321 // indexing into a dictionary.
322 TEST_P(ValueStoreTest
, DotsInKeyNames
) {
323 std::string
dot_key("foo.bar");
324 base::StringValue
dot_value("baz.qux");
325 std::vector
<std::string
> dot_list
;
326 dot_list
.push_back(dot_key
);
327 base::DictionaryValue dot_dict
;
328 dot_dict
.SetWithoutPathExpansion(dot_key
, dot_value
.DeepCopy());
330 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(dot_key
));
333 ValueStoreChangeList changes
;
335 ValueStoreChange(dot_key
, NULL
, dot_value
.DeepCopy()));
336 EXPECT_PRED_FORMAT2(ChangesEq
,
337 changes
, storage_
->Set(DEFAULTS
, dot_key
, dot_value
));
339 EXPECT_PRED_FORMAT2(ChangesEq
,
340 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, dot_key
, dot_value
));
342 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get(dot_key
));
345 ValueStoreChangeList changes
;
347 ValueStoreChange(dot_key
, dot_value
.DeepCopy(), NULL
));
348 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(dot_key
));
350 EXPECT_PRED_FORMAT2(ChangesEq
,
351 ValueStoreChangeList(), storage_
->Remove(dot_key
));
353 ValueStoreChangeList changes
;
355 ValueStoreChange(dot_key
, NULL
, dot_value
.DeepCopy()));
356 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, dot_dict
));
359 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get(dot_list
));
360 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get());
363 ValueStoreChangeList changes
;
365 ValueStoreChange(dot_key
, dot_value
.DeepCopy(), NULL
));
366 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(dot_list
));
369 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(dot_key
));
370 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
373 TEST_P(ValueStoreTest
, DotsInKeyNamesWithDicts
) {
374 base::DictionaryValue outer_dict
;
375 base::DictionaryValue
* inner_dict
= new base::DictionaryValue();
376 outer_dict
.Set("foo", inner_dict
);
377 inner_dict
->SetString("bar", "baz");
380 ValueStoreChangeList changes
;
382 ValueStoreChange("foo", NULL
, inner_dict
->DeepCopy()));
383 EXPECT_PRED_FORMAT2(ChangesEq
,
384 changes
, storage_
->Set(DEFAULTS
, outer_dict
));
387 EXPECT_PRED_FORMAT2(SettingsEq
, outer_dict
, storage_
->Get("foo"));
388 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get("foo.bar"));
391 TEST_P(ValueStoreTest
, ComplexChangedKeysScenarios
) {
393 // - Setting over missing/changed/same keys, combinations.
394 // - Removing over missing and present keys, combinations.
396 std::vector
<std::string
> complex_list
;
397 base::DictionaryValue complex_changed_dict
;
399 storage_
->Set(DEFAULTS
, key1_
, *val1_
);
400 EXPECT_PRED_FORMAT2(ChangesEq
,
401 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, key1_
, *val1_
));
403 ValueStoreChangeList changes
;
404 changes
.push_back(ValueStoreChange(
405 key1_
, val1_
->DeepCopy(), val2_
->DeepCopy()));
406 EXPECT_PRED_FORMAT2(ChangesEq
,
407 changes
, storage_
->Set(DEFAULTS
, key1_
, *val2_
));
410 ValueStoreChangeList changes
;
411 changes
.push_back(ValueStoreChange(key1_
, val2_
->DeepCopy(), NULL
));
412 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key1_
));
413 EXPECT_PRED_FORMAT2(ChangesEq
,
414 ValueStoreChangeList(), storage_
->Remove(key1_
));
417 ValueStoreChangeList changes
;
418 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
419 EXPECT_PRED_FORMAT2(ChangesEq
,
420 changes
, storage_
->Set(DEFAULTS
, key1_
, *val1_
));
423 ValueStoreChangeList changes
;
424 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
425 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
426 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());
430 ValueStoreChangeList changes
;
431 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
432 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
433 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
434 EXPECT_PRED_FORMAT2(ChangesEq
,
435 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, *dict12_
));
438 ValueStoreChangeList changes
;
439 changes
.push_back(ValueStoreChange(key3_
, NULL
, val3_
->DeepCopy()));
440 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict123_
));
443 base::DictionaryValue to_set
;
444 to_set
.Set(key1_
, val2_
->DeepCopy());
445 to_set
.Set(key2_
, val2_
->DeepCopy());
446 to_set
.Set("asdf", val1_
->DeepCopy());
447 to_set
.Set("qwerty", val3_
->DeepCopy());
449 ValueStoreChangeList changes
;
451 ValueStoreChange(key1_
, val1_
->DeepCopy(), val2_
->DeepCopy()));
452 changes
.push_back(ValueStoreChange("asdf", NULL
, val1_
->DeepCopy()));
454 ValueStoreChange("qwerty", NULL
, val3_
->DeepCopy()));
455 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, to_set
));
458 ValueStoreChangeList changes
;
459 changes
.push_back(ValueStoreChange(key1_
, val2_
->DeepCopy(), NULL
));
460 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
461 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(list12_
));
464 std::vector
<std::string
> to_remove
;
465 to_remove
.push_back(key1_
);
466 to_remove
.push_back("asdf");
468 ValueStoreChangeList changes
;
469 changes
.push_back(ValueStoreChange("asdf", val1_
->DeepCopy(), NULL
));
470 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(to_remove
));
473 ValueStoreChangeList changes
;
474 changes
.push_back(ValueStoreChange(key3_
, val3_
->DeepCopy(), NULL
));
476 ValueStoreChange("qwerty", val3_
->DeepCopy(), NULL
));
477 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
478 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());