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.
4 
5 #include "extensions/browser/value_store/value_store_unittest.h"
6 
7 #include <utility>
8 
9 #include "base/json/json_writer.h"
10 #include "base/values.h"
11 
12 namespace {
13 
14 // To save typing ValueStore::DEFAULTS everywhere.
15 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
16 
17 // Gets the pretty-printed JSON for a value.
GetJSON(const base::Value & value)18 std::string GetJSON(const base::Value& value) {
19   std::string json;
20   base::JSONWriter::WriteWithOptions(
21       value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
22   return json;
23 }
24 
25 }  // namespace
26 
27 // Compares two possibly NULL values for equality, filling |error| with an
28 // appropriate error message if they're different.
ValuesEqual(const base::Value * expected,const base::Value * actual,std::string * error)29 bool ValuesEqual(const base::Value* expected,
30                  const base::Value* actual,
31                  std::string* error) {
32   if (expected == actual) {
33     return true;
34   }
35   if (expected && !actual) {
36     *error = "Expected: " + GetJSON(*expected) + ", actual: NULL";
37     return false;
38   }
39   if (actual && !expected) {
40     *error = "Expected: NULL, actual: " + GetJSON(*actual);
41     return false;
42   }
43   if (!expected->Equals(actual)) {
44     *error =
45         "Expected: " + GetJSON(*expected) + ", actual: " + GetJSON(*actual);
46     return false;
47   }
48   return true;
49 }
50 
51 // Returns whether the read result of a storage operation has the expected
52 // settings.
SettingsEq(const char * _1,const char * _2,const base::DictionaryValue & expected,ValueStore::ReadResult actual_result)53 testing::AssertionResult SettingsEq(
54     const char* _1, const char* _2,
55     const base::DictionaryValue& expected,
56     ValueStore::ReadResult actual_result) {
57   if (!actual_result.status().ok()) {
58     return testing::AssertionFailure()
59            << "Result has error: " << actual_result.status().message;
60   }
61 
62   std::string error;
63   if (!ValuesEqual(&expected, &actual_result.settings(), &error)) {
64     return testing::AssertionFailure() << error;
65   }
66 
67   return testing::AssertionSuccess();
68 }
69 
70 // Returns whether the write result of a storage operation has the expected
71 // changes.
ChangesEq(const char * _1,const char * _2,const ValueStoreChangeList & expected,ValueStore::WriteResult actual_result)72 testing::AssertionResult ChangesEq(
73     const char* _1, const char* _2,
74     const ValueStoreChangeList& expected,
75     ValueStore::WriteResult actual_result) {
76   if (!actual_result.status().ok()) {
77     return testing::AssertionFailure()
78            << "Result has error: " << actual_result.status().message;
79   }
80 
81   const ValueStoreChangeList& actual = actual_result.changes();
82   if (expected.size() != actual.size()) {
83     return testing::AssertionFailure() <<
84         "Actual has wrong size, expecting " << expected.size() <<
85         " but was " << actual.size();
86   }
87 
88   std::map<std::string, std::unique_ptr<ValueStoreChange>> expected_as_map;
89   for (const ValueStoreChange& change : expected)
90     expected_as_map[change.key()] = std::make_unique<ValueStoreChange>(change);
91 
92   std::set<std::string> keys_seen;
93 
94   for (auto it = actual.cbegin(); it != actual.cend(); ++it) {
95     if (keys_seen.count(it->key())) {
96       return testing::AssertionFailure() <<
97           "Multiple changes seen for key: " << it->key();
98     }
99     keys_seen.insert(it->key());
100 
101     if (!expected_as_map.count(it->key())) {
102       return testing::AssertionFailure() <<
103           "Actual has unexpected change for key: " << it->key();
104     }
105 
106     ValueStoreChange expected_change = *expected_as_map[it->key()];
107     std::string error;
108     if (!ValuesEqual(expected_change.new_value(), it->new_value(), &error)) {
109       return testing::AssertionFailure() <<
110           "New value for " << it->key() << " was unexpected: " << error;
111     }
112     if (!ValuesEqual(expected_change.old_value(), it->old_value(), &error)) {
113       return testing::AssertionFailure() <<
114           "Old value for " << it->key() << " was unexpected: " << error;
115     }
116   }
117 
118   return testing::AssertionSuccess();
119 }
120 
ValueStoreTest()121 ValueStoreTest::ValueStoreTest()
122     : key1_("foo"),
123       key2_("bar"),
124       key3_("baz"),
125       empty_dict_(new base::DictionaryValue()),
126       dict1_(new base::DictionaryValue()),
127       dict3_(new base::DictionaryValue()),
128       dict12_(new base::DictionaryValue()),
129       dict123_(new base::DictionaryValue()) {
130   val1_.reset(new base::Value(key1_ + "Value"));
131   val2_.reset(new base::Value(key2_ + "Value"));
132   val3_.reset(new base::Value(key3_ + "Value"));
133 
134   list1_.push_back(key1_);
135   list2_.push_back(key2_);
136   list3_.push_back(key3_);
137   list12_.push_back(key1_);
138   list12_.push_back(key2_);
139   list13_.push_back(key1_);
140   list13_.push_back(key3_);
141   list123_.push_back(key1_);
142   list123_.push_back(key2_);
143   list123_.push_back(key3_);
144 
145   set1_.insert(list1_.begin(), list1_.end());
146   set2_.insert(list2_.begin(), list2_.end());
147   set3_.insert(list3_.begin(), list3_.end());
148   set12_.insert(list12_.begin(), list12_.end());
149   set13_.insert(list13_.begin(), list13_.end());
150   set123_.insert(list123_.begin(), list123_.end());
151 
152   dict1_->Set(key1_, val1_->CreateDeepCopy());
153   dict3_->Set(key3_, val3_->CreateDeepCopy());
154   dict12_->Set(key1_, val1_->CreateDeepCopy());
155   dict12_->Set(key2_, val2_->CreateDeepCopy());
156   dict123_->Set(key1_, val1_->CreateDeepCopy());
157   dict123_->Set(key2_, val2_->CreateDeepCopy());
158   dict123_->Set(key3_, val3_->CreateDeepCopy());
159 }
160 
~ValueStoreTest()161 ValueStoreTest::~ValueStoreTest() {}
162 
SetUp()163 void ValueStoreTest::SetUp() {
164   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
165   storage_.reset((GetParam())(temp_dir_.GetPath().AppendASCII("dbName")));
166   ASSERT_TRUE(storage_.get());
167 }
168 
TearDown()169 void ValueStoreTest::TearDown() {
170   storage_.reset();
171 }
172 
TEST_P(ValueStoreTest,GetWhenEmpty)173 TEST_P(ValueStoreTest, GetWhenEmpty) {
174   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
175   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
176   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
177   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
178 }
179 
TEST_P(ValueStoreTest,GetWithSingleValue)180 TEST_P(ValueStoreTest, GetWithSingleValue) {
181   {
182     ValueStoreChangeList changes;
183     changes.push_back(ValueStoreChange(key1_, base::nullopt, val1_->Clone()));
184     EXPECT_PRED_FORMAT2(ChangesEq,
185         changes, storage_->Set(DEFAULTS, key1_, *val1_));
186   }
187 
188   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
189   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_));
190   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
191   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
192   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list123_));
193   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get());
194 }
195 
TEST_P(ValueStoreTest,GetWithMultipleValues)196 TEST_P(ValueStoreTest, GetWithMultipleValues) {
197   {
198     ValueStoreChangeList changes;
199     changes.push_back(ValueStoreChange(key1_, base::nullopt, val1_->Clone()));
200     changes.push_back(ValueStoreChange(key2_, base::nullopt, val2_->Clone()));
201     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
202   }
203 
204   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
205   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
206   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
207   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
208   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
209 }
210 
TEST_P(ValueStoreTest,RemoveWhenEmpty)211 TEST_P(ValueStoreTest, RemoveWhenEmpty) {
212   EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(),
213                       storage_->Remove(key1_));
214 
215   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
216   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
217   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
218 }
219 
TEST_P(ValueStoreTest,RemoveWithSingleValue)220 TEST_P(ValueStoreTest, RemoveWithSingleValue) {
221   storage_->Set(DEFAULTS, *dict1_);
222   {
223     ValueStoreChangeList changes;
224     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), base::nullopt));
225     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_));
226   }
227 
228   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
229   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_));
230   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
231   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_));
232   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
233 }
234 
TEST_P(ValueStoreTest,RemoveWithMultipleValues)235 TEST_P(ValueStoreTest, RemoveWithMultipleValues) {
236   storage_->Set(DEFAULTS, *dict123_);
237   {
238     ValueStoreChangeList changes;
239     changes.push_back(ValueStoreChange(key3_, val3_->Clone(), base::nullopt));
240     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key3_));
241   }
242 
243   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
244   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
245   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
246   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_));
247   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_));
248   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_));
249   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
250   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
251 
252   {
253     ValueStoreChangeList changes;
254     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), base::nullopt));
255     changes.push_back(ValueStoreChange(key2_, val2_->Clone(), base::nullopt));
256     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_));
257   }
258 
259   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
260   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
261   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
262   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
263   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_));
264   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list13_));
265   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
266   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
267 }
268 
TEST_P(ValueStoreTest,SetWhenOverwriting)269 TEST_P(ValueStoreTest, SetWhenOverwriting) {
270   storage_->Set(DEFAULTS, key1_, *val2_);
271   {
272     ValueStoreChangeList changes;
273     changes.push_back(ValueStoreChange(key1_, val2_->Clone(), val1_->Clone()));
274     changes.push_back(ValueStoreChange(key2_, base::nullopt, val2_->Clone()));
275     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
276   }
277 
278   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
279   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
280   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
281   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_));
282   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_));
283   EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_));
284   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
285   EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
286 }
287 
TEST_P(ValueStoreTest,ClearWhenEmpty)288 TEST_P(ValueStoreTest, ClearWhenEmpty) {
289   EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
290 
291   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
292   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
293   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
294   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
295 }
296 
TEST_P(ValueStoreTest,ClearWhenNotEmpty)297 TEST_P(ValueStoreTest, ClearWhenNotEmpty) {
298   storage_->Set(DEFAULTS, *dict12_);
299   {
300     ValueStoreChangeList changes;
301     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), base::nullopt));
302     changes.push_back(ValueStoreChange(key2_, val2_->Clone(), base::nullopt));
303     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
304   }
305 
306   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
307   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
308   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
309   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
310 }
311 
312 // Dots should be allowed in key names; they shouldn't be interpreted as
313 // indexing into a dictionary.
TEST_P(ValueStoreTest,DotsInKeyNames)314 TEST_P(ValueStoreTest, DotsInKeyNames) {
315   std::string dot_key("foo.bar");
316   base::Value dot_value("baz.qux");
317   std::vector<std::string> dot_list;
318   dot_list.push_back(dot_key);
319   base::DictionaryValue dot_dict;
320   dot_dict.SetWithoutPathExpansion(dot_key, dot_value.CreateDeepCopy());
321 
322   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
323 
324   {
325     ValueStoreChangeList changes;
326     changes.push_back(
327         ValueStoreChange(dot_key, base::nullopt, dot_value.Clone()));
328     EXPECT_PRED_FORMAT2(ChangesEq,
329         changes, storage_->Set(DEFAULTS, dot_key, dot_value));
330   }
331   EXPECT_PRED_FORMAT2(ChangesEq,
332       ValueStoreChangeList(), storage_->Set(DEFAULTS, dot_key, dot_value));
333 
334   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_key));
335 
336   {
337     ValueStoreChangeList changes;
338     changes.push_back(
339         ValueStoreChange(dot_key, dot_value.Clone(), base::nullopt));
340     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_key));
341   }
342   EXPECT_PRED_FORMAT2(ChangesEq,
343       ValueStoreChangeList(), storage_->Remove(dot_key));
344   {
345     ValueStoreChangeList changes;
346     changes.push_back(
347         ValueStoreChange(dot_key, base::nullopt, dot_value.Clone()));
348     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, dot_dict));
349   }
350 
351   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_list));
352   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get());
353 
354   {
355     ValueStoreChangeList changes;
356     changes.push_back(
357         ValueStoreChange(dot_key, dot_value.Clone(), base::nullopt));
358     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_list));
359   }
360 
361   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
362   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
363 }
364 
TEST_P(ValueStoreTest,DotsInKeyNamesWithDicts)365 TEST_P(ValueStoreTest, DotsInKeyNamesWithDicts) {
366   base::DictionaryValue outer_dict;
367   base::DictionaryValue inner_dict;
368   inner_dict.SetString("bar", "baz");
369   outer_dict.Set("foo", inner_dict.CreateDeepCopy());
370 
371   {
372     ValueStoreChangeList changes;
373     changes.push_back(
374         ValueStoreChange("foo", base::nullopt, inner_dict.Clone()));
375     EXPECT_PRED_FORMAT2(ChangesEq, changes,
376                         storage_->Set(DEFAULTS, outer_dict));
377   }
378 
379   EXPECT_PRED_FORMAT2(SettingsEq, outer_dict, storage_->Get("foo"));
380   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get("foo.bar"));
381 }
382 
TEST_P(ValueStoreTest,ComplexChangedKeysScenarios)383 TEST_P(ValueStoreTest, ComplexChangedKeysScenarios) {
384   // Test:
385   //   - Setting over missing/changed/same keys, combinations.
386   //   - Removing over missing and present keys, combinations.
387   //   - Clearing.
388   std::vector<std::string> complex_list;
389   base::DictionaryValue complex_changed_dict;
390 
391   storage_->Set(DEFAULTS, key1_, *val1_);
392   EXPECT_PRED_FORMAT2(ChangesEq,
393       ValueStoreChangeList(), storage_->Set(DEFAULTS, key1_, *val1_));
394   {
395     ValueStoreChangeList changes;
396     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), val2_->Clone()));
397     EXPECT_PRED_FORMAT2(ChangesEq,
398         changes, storage_->Set(DEFAULTS, key1_, *val2_));
399   }
400   {
401     ValueStoreChangeList changes;
402     changes.push_back(ValueStoreChange(key1_, val2_->Clone(), base::nullopt));
403     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_));
404     EXPECT_PRED_FORMAT2(ChangesEq,
405         ValueStoreChangeList(), storage_->Remove(key1_));
406   }
407   {
408     ValueStoreChangeList changes;
409     changes.push_back(ValueStoreChange(key1_, base::nullopt, val1_->Clone()));
410     EXPECT_PRED_FORMAT2(ChangesEq,
411         changes, storage_->Set(DEFAULTS, key1_, *val1_));
412   }
413   {
414     ValueStoreChangeList changes;
415     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), base::nullopt));
416     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
417     EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
418   }
419 
420   {
421     ValueStoreChangeList changes;
422     changes.push_back(ValueStoreChange(key1_, base::nullopt, val1_->Clone()));
423     changes.push_back(ValueStoreChange(key2_, base::nullopt, val2_->Clone()));
424     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
425     EXPECT_PRED_FORMAT2(ChangesEq,
426         ValueStoreChangeList(), storage_->Set(DEFAULTS, *dict12_));
427   }
428   {
429     ValueStoreChangeList changes;
430     changes.push_back(ValueStoreChange(key3_, base::nullopt, val3_->Clone()));
431     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict123_));
432   }
433   {
434     base::DictionaryValue to_set;
435     to_set.Set(key1_, val2_->CreateDeepCopy());
436     to_set.Set(key2_, val2_->CreateDeepCopy());
437     to_set.Set("asdf", val1_->CreateDeepCopy());
438     to_set.Set("qwerty", val3_->CreateDeepCopy());
439 
440     ValueStoreChangeList changes;
441     changes.push_back(ValueStoreChange(key1_, val1_->Clone(), val2_->Clone()));
442     changes.push_back(ValueStoreChange("asdf", base::nullopt, val1_->Clone()));
443     changes.push_back(
444         ValueStoreChange("qwerty", base::nullopt, val3_->Clone()));
445     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, to_set));
446   }
447   {
448     ValueStoreChangeList changes;
449     changes.push_back(ValueStoreChange(key1_, val2_->Clone(), base::nullopt));
450     changes.push_back(ValueStoreChange(key2_, val2_->Clone(), base::nullopt));
451     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_));
452   }
453   {
454     std::vector<std::string> to_remove;
455     to_remove.push_back(key1_);
456     to_remove.push_back("asdf");
457 
458     ValueStoreChangeList changes;
459     changes.push_back(ValueStoreChange("asdf", val1_->Clone(), base::nullopt));
460     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(to_remove));
461   }
462   {
463     ValueStoreChangeList changes;
464     changes.push_back(ValueStoreChange(key3_, val3_->Clone(), base::nullopt));
465     changes.push_back(
466         ValueStoreChange("qwerty", val3_->Clone(), base::nullopt));
467     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
468     EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
469   }
470 }
471