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(&value
,
22 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
29 // Compares two possibly NULL values for equality, filling |error| with an
30 // appropriate error message if they're different.
31 bool ValuesEqual(const base::Value
* expected
,
32 const base::Value
* actual
,
34 if (expected
== actual
) {
37 if (expected
&& !actual
) {
38 *error
= "Expected: " + GetJSON(*expected
) + ", actual: NULL";
41 if (actual
&& !expected
) {
42 *error
= "Expected: NULL, actual: " + GetJSON(*actual
);
45 if (!expected
->Equals(actual
)) {
47 "Expected: " + GetJSON(*expected
) + ", actual: " + GetJSON(*actual
);
53 // Returns whether the read result of a storage operation has the expected
55 testing::AssertionResult
SettingsEq(
56 const char* _1
, const char* _2
,
57 const base::DictionaryValue
& expected
,
58 ValueStore::ReadResult actual_result
) {
59 if (actual_result
->HasError()) {
60 return testing::AssertionFailure() <<
61 "Result has error: " << actual_result
->error().message
;
65 if (!ValuesEqual(&expected
, &actual_result
->settings(), &error
)) {
66 return testing::AssertionFailure() << error
;
69 return testing::AssertionSuccess();
72 // Returns whether the write result of a storage operation has the expected
74 testing::AssertionResult
ChangesEq(
75 const char* _1
, const char* _2
,
76 const ValueStoreChangeList
& expected
,
77 ValueStore::WriteResult actual_result
) {
78 if (actual_result
->HasError()) {
79 return testing::AssertionFailure() <<
80 "Result has error: " << actual_result
->error().message
;
83 const ValueStoreChangeList
& actual
= actual_result
->changes();
84 if (expected
.size() != actual
.size()) {
85 return testing::AssertionFailure() <<
86 "Actual has wrong size, expecting " << expected
.size() <<
87 " but was " << actual
.size();
90 std::map
<std::string
, linked_ptr
<ValueStoreChange
> > expected_as_map
;
91 for (ValueStoreChangeList::const_iterator it
= expected
.begin();
92 it
!= expected
.end(); ++it
) {
93 expected_as_map
[it
->key()] =
94 linked_ptr
<ValueStoreChange
>(new ValueStoreChange(*it
));
97 std::set
<std::string
> keys_seen
;
99 for (ValueStoreChangeList::const_iterator it
= actual
.begin();
100 it
!= actual
.end(); ++it
) {
101 if (keys_seen
.count(it
->key())) {
102 return testing::AssertionFailure() <<
103 "Multiple changes seen for key: " << it
->key();
105 keys_seen
.insert(it
->key());
107 if (!expected_as_map
.count(it
->key())) {
108 return testing::AssertionFailure() <<
109 "Actual has unexpected change for key: " << it
->key();
112 ValueStoreChange expected_change
= *expected_as_map
[it
->key()];
114 if (!ValuesEqual(expected_change
.new_value(), it
->new_value(), &error
)) {
115 return testing::AssertionFailure() <<
116 "New value for " << it
->key() << " was unexpected: " << error
;
118 if (!ValuesEqual(expected_change
.old_value(), it
->old_value(), &error
)) {
119 return testing::AssertionFailure() <<
120 "Old value for " << it
->key() << " was unexpected: " << error
;
124 return testing::AssertionSuccess();
127 ValueStoreTest::ValueStoreTest()
131 empty_dict_(new base::DictionaryValue()),
132 dict1_(new base::DictionaryValue()),
133 dict3_(new base::DictionaryValue()),
134 dict12_(new base::DictionaryValue()),
135 dict123_(new base::DictionaryValue()),
136 ui_thread_(BrowserThread::UI
, base::MessageLoop::current()),
137 file_thread_(BrowserThread::FILE, base::MessageLoop::current()) {
138 val1_
.reset(new base::StringValue(key1_
+ "Value"));
139 val2_
.reset(new base::StringValue(key2_
+ "Value"));
140 val3_
.reset(new base::StringValue(key3_
+ "Value"));
142 list1_
.push_back(key1_
);
143 list2_
.push_back(key2_
);
144 list3_
.push_back(key3_
);
145 list12_
.push_back(key1_
);
146 list12_
.push_back(key2_
);
147 list13_
.push_back(key1_
);
148 list13_
.push_back(key3_
);
149 list123_
.push_back(key1_
);
150 list123_
.push_back(key2_
);
151 list123_
.push_back(key3_
);
153 set1_
.insert(list1_
.begin(), list1_
.end());
154 set2_
.insert(list2_
.begin(), list2_
.end());
155 set3_
.insert(list3_
.begin(), list3_
.end());
156 set12_
.insert(list12_
.begin(), list12_
.end());
157 set13_
.insert(list13_
.begin(), list13_
.end());
158 set123_
.insert(list123_
.begin(), list123_
.end());
160 dict1_
->Set(key1_
, val1_
->DeepCopy());
161 dict3_
->Set(key3_
, val3_
->DeepCopy());
162 dict12_
->Set(key1_
, val1_
->DeepCopy());
163 dict12_
->Set(key2_
, val2_
->DeepCopy());
164 dict123_
->Set(key1_
, val1_
->DeepCopy());
165 dict123_
->Set(key2_
, val2_
->DeepCopy());
166 dict123_
->Set(key3_
, val3_
->DeepCopy());
169 ValueStoreTest::~ValueStoreTest() {}
171 void ValueStoreTest::SetUp() {
172 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
173 storage_
.reset((GetParam())(temp_dir_
.path().AppendASCII("dbName")));
174 ASSERT_TRUE(storage_
.get());
177 void ValueStoreTest::TearDown() {
181 TEST_P(ValueStoreTest
, GetWhenEmpty
) {
182 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
183 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
184 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
185 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
188 TEST_P(ValueStoreTest
, GetWithSingleValue
) {
190 ValueStoreChangeList changes
;
191 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
192 EXPECT_PRED_FORMAT2(ChangesEq
,
193 changes
, storage_
->Set(DEFAULTS
, key1_
, *val1_
));
196 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
197 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key2_
));
198 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
199 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
200 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list123_
));
201 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get());
204 TEST_P(ValueStoreTest
, GetWithMultipleValues
) {
206 ValueStoreChangeList changes
;
207 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
208 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
209 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
212 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
213 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
214 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
215 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
216 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
219 TEST_P(ValueStoreTest
, RemoveWhenEmpty
) {
220 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(),
221 storage_
->Remove(key1_
));
223 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
224 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
225 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
228 TEST_P(ValueStoreTest
, RemoveWithSingleValue
) {
229 storage_
->Set(DEFAULTS
, *dict1_
);
231 ValueStoreChangeList changes
;
232 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
233 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key1_
));
236 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
237 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key2_
));
238 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
239 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list12_
));
240 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
243 TEST_P(ValueStoreTest
, RemoveWithMultipleValues
) {
244 storage_
->Set(DEFAULTS
, *dict123_
);
246 ValueStoreChangeList changes
;
247 changes
.push_back(ValueStoreChange(key3_
, val3_
->DeepCopy(), NULL
));
248 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key3_
));
251 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
252 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
253 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
254 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list1_
));
255 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list12_
));
256 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list13_
));
257 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
258 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
261 ValueStoreChangeList changes
;
262 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
263 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
264 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(list12_
));
267 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
268 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
269 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
270 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list1_
));
271 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list12_
));
272 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list13_
));
273 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
274 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
277 TEST_P(ValueStoreTest
, SetWhenOverwriting
) {
278 storage_
->Set(DEFAULTS
, key1_
, *val2_
);
280 ValueStoreChangeList changes
;
282 ValueStoreChange(key1_
, val2_
->DeepCopy(), val1_
->DeepCopy()));
283 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
284 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
287 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(key1_
));
288 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key3_
));
289 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
290 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list1_
));
291 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list12_
));
292 EXPECT_PRED_FORMAT2(SettingsEq
, *dict1_
, storage_
->Get(list13_
));
293 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get(list123_
));
294 EXPECT_PRED_FORMAT2(SettingsEq
, *dict12_
, storage_
->Get());
297 TEST_P(ValueStoreTest
, ClearWhenEmpty
) {
298 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());
300 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
301 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
302 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
303 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
306 TEST_P(ValueStoreTest
, ClearWhenNotEmpty
) {
307 storage_
->Set(DEFAULTS
, *dict12_
);
309 ValueStoreChangeList changes
;
310 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
311 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
312 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
315 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(key1_
));
316 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(empty_list_
));
317 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(list123_
));
318 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
321 // Dots should be allowed in key names; they shouldn't be interpreted as
322 // indexing into a dictionary.
323 TEST_P(ValueStoreTest
, DotsInKeyNames
) {
324 std::string
dot_key("foo.bar");
325 base::StringValue
dot_value("baz.qux");
326 std::vector
<std::string
> dot_list
;
327 dot_list
.push_back(dot_key
);
328 base::DictionaryValue dot_dict
;
329 dot_dict
.SetWithoutPathExpansion(dot_key
, dot_value
.DeepCopy());
331 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(dot_key
));
334 ValueStoreChangeList changes
;
336 ValueStoreChange(dot_key
, NULL
, dot_value
.DeepCopy()));
337 EXPECT_PRED_FORMAT2(ChangesEq
,
338 changes
, storage_
->Set(DEFAULTS
, dot_key
, dot_value
));
340 EXPECT_PRED_FORMAT2(ChangesEq
,
341 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, dot_key
, dot_value
));
343 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get(dot_key
));
346 ValueStoreChangeList changes
;
348 ValueStoreChange(dot_key
, dot_value
.DeepCopy(), NULL
));
349 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(dot_key
));
351 EXPECT_PRED_FORMAT2(ChangesEq
,
352 ValueStoreChangeList(), storage_
->Remove(dot_key
));
354 ValueStoreChangeList changes
;
356 ValueStoreChange(dot_key
, NULL
, dot_value
.DeepCopy()));
357 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, dot_dict
));
360 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get(dot_list
));
361 EXPECT_PRED_FORMAT2(SettingsEq
, dot_dict
, storage_
->Get());
364 ValueStoreChangeList changes
;
366 ValueStoreChange(dot_key
, dot_value
.DeepCopy(), NULL
));
367 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(dot_list
));
370 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get(dot_key
));
371 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get());
374 TEST_P(ValueStoreTest
, DotsInKeyNamesWithDicts
) {
375 base::DictionaryValue outer_dict
;
376 base::DictionaryValue
* inner_dict
= new base::DictionaryValue();
377 outer_dict
.Set("foo", inner_dict
);
378 inner_dict
->SetString("bar", "baz");
381 ValueStoreChangeList changes
;
383 ValueStoreChange("foo", NULL
, inner_dict
->DeepCopy()));
384 EXPECT_PRED_FORMAT2(ChangesEq
,
385 changes
, storage_
->Set(DEFAULTS
, outer_dict
));
388 EXPECT_PRED_FORMAT2(SettingsEq
, outer_dict
, storage_
->Get("foo"));
389 EXPECT_PRED_FORMAT2(SettingsEq
, *empty_dict_
, storage_
->Get("foo.bar"));
392 TEST_P(ValueStoreTest
, ComplexChangedKeysScenarios
) {
394 // - Setting over missing/changed/same keys, combinations.
395 // - Removing over missing and present keys, combinations.
397 std::vector
<std::string
> complex_list
;
398 base::DictionaryValue complex_changed_dict
;
400 storage_
->Set(DEFAULTS
, key1_
, *val1_
);
401 EXPECT_PRED_FORMAT2(ChangesEq
,
402 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, key1_
, *val1_
));
404 ValueStoreChangeList changes
;
405 changes
.push_back(ValueStoreChange(
406 key1_
, val1_
->DeepCopy(), val2_
->DeepCopy()));
407 EXPECT_PRED_FORMAT2(ChangesEq
,
408 changes
, storage_
->Set(DEFAULTS
, key1_
, *val2_
));
411 ValueStoreChangeList changes
;
412 changes
.push_back(ValueStoreChange(key1_
, val2_
->DeepCopy(), NULL
));
413 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(key1_
));
414 EXPECT_PRED_FORMAT2(ChangesEq
,
415 ValueStoreChangeList(), storage_
->Remove(key1_
));
418 ValueStoreChangeList changes
;
419 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
420 EXPECT_PRED_FORMAT2(ChangesEq
,
421 changes
, storage_
->Set(DEFAULTS
, key1_
, *val1_
));
424 ValueStoreChangeList changes
;
425 changes
.push_back(ValueStoreChange(key1_
, val1_
->DeepCopy(), NULL
));
426 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
427 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());
431 ValueStoreChangeList changes
;
432 changes
.push_back(ValueStoreChange(key1_
, NULL
, val1_
->DeepCopy()));
433 changes
.push_back(ValueStoreChange(key2_
, NULL
, val2_
->DeepCopy()));
434 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict12_
));
435 EXPECT_PRED_FORMAT2(ChangesEq
,
436 ValueStoreChangeList(), storage_
->Set(DEFAULTS
, *dict12_
));
439 ValueStoreChangeList changes
;
440 changes
.push_back(ValueStoreChange(key3_
, NULL
, val3_
->DeepCopy()));
441 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, *dict123_
));
444 base::DictionaryValue to_set
;
445 to_set
.Set(key1_
, val2_
->DeepCopy());
446 to_set
.Set(key2_
, val2_
->DeepCopy());
447 to_set
.Set("asdf", val1_
->DeepCopy());
448 to_set
.Set("qwerty", val3_
->DeepCopy());
450 ValueStoreChangeList changes
;
452 ValueStoreChange(key1_
, val1_
->DeepCopy(), val2_
->DeepCopy()));
453 changes
.push_back(ValueStoreChange("asdf", NULL
, val1_
->DeepCopy()));
455 ValueStoreChange("qwerty", NULL
, val3_
->DeepCopy()));
456 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Set(DEFAULTS
, to_set
));
459 ValueStoreChangeList changes
;
460 changes
.push_back(ValueStoreChange(key1_
, val2_
->DeepCopy(), NULL
));
461 changes
.push_back(ValueStoreChange(key2_
, val2_
->DeepCopy(), NULL
));
462 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(list12_
));
465 std::vector
<std::string
> to_remove
;
466 to_remove
.push_back(key1_
);
467 to_remove
.push_back("asdf");
469 ValueStoreChangeList changes
;
470 changes
.push_back(ValueStoreChange("asdf", val1_
->DeepCopy(), NULL
));
471 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Remove(to_remove
));
474 ValueStoreChangeList changes
;
475 changes
.push_back(ValueStoreChange(key3_
, val3_
->DeepCopy(), NULL
));
477 ValueStoreChange("qwerty", val3_
->DeepCopy(), NULL
));
478 EXPECT_PRED_FORMAT2(ChangesEq
, changes
, storage_
->Clear());
479 EXPECT_PRED_FORMAT2(ChangesEq
, ValueStoreChangeList(), storage_
->Clear());