Home | History | Annotate | Download | only in value_store
      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 "base/json/json_writer.h"
      8 #include "base/memory/linked_ptr.h"
      9 #include "base/values.h"
     10 
     11 using content::BrowserThread;
     12 
     13 namespace {
     14 
     15 // To save typing ValueStore::DEFAULTS everywhere.
     16 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
     17 
     18 // Gets the pretty-printed JSON for a value.
     19 std::string GetJSON(const base::Value& value) {
     20   std::string json;
     21   base::JSONWriter::WriteWithOptions(&value,
     22                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
     23                                      &json);
     24   return json;
     25 }
     26 
     27 }  // namespace
     28 
     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,
     33                  std::string* error) {
     34   if (expected == actual) {
     35     return true;
     36   }
     37   if (expected && !actual) {
     38     *error = "Expected: " + GetJSON(*expected) + ", actual: NULL";
     39     return false;
     40   }
     41   if (actual && !expected) {
     42     *error = "Expected: NULL, actual: " + GetJSON(*actual);
     43     return false;
     44   }
     45   if (!expected->Equals(actual)) {
     46     *error =
     47         "Expected: " + GetJSON(*expected) + ", actual: " + GetJSON(*actual);
     48     return false;
     49   }
     50   return true;
     51 }
     52 
     53 // Returns whether the read result of a storage operation has the expected
     54 // settings.
     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;
     62   }
     63 
     64   std::string error;
     65   if (!ValuesEqual(&expected, &actual_result->settings(), &error)) {
     66     return testing::AssertionFailure() << error;
     67   }
     68 
     69   return testing::AssertionSuccess();
     70 }
     71 
     72 // Returns whether the write result of a storage operation has the expected
     73 // changes.
     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;
     81   }
     82 
     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();
     88   }
     89 
     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));
     95   }
     96 
     97   std::set<std::string> keys_seen;
     98 
     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();
    104     }
    105     keys_seen.insert(it->key());
    106 
    107     if (!expected_as_map.count(it->key())) {
    108       return testing::AssertionFailure() <<
    109           "Actual has unexpected change for key: " << it->key();
    110     }
    111 
    112     ValueStoreChange expected_change = *expected_as_map[it->key()];
    113     std::string error;
    114     if (!ValuesEqual(expected_change.new_value(), it->new_value(), &error)) {
    115       return testing::AssertionFailure() <<
    116           "New value for " << it->key() << " was unexpected: " << error;
    117     }
    118     if (!ValuesEqual(expected_change.old_value(), it->old_value(), &error)) {
    119       return testing::AssertionFailure() <<
    120           "Old value for " << it->key() << " was unexpected: " << error;
    121     }
    122   }
    123 
    124   return testing::AssertionSuccess();
    125 }
    126 
    127 ValueStoreTest::ValueStoreTest()
    128     : key1_("foo"),
    129       key2_("bar"),
    130       key3_("baz"),
    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(base::Value::CreateStringValue(key1_ + "Value"));
    139   val2_.reset(base::Value::CreateStringValue(key2_ + "Value"));
    140   val3_.reset(base::Value::CreateStringValue(key3_ + "Value"));
    141 
    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_);
    152 
    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());
    159 
    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());
    167 }
    168 
    169 ValueStoreTest::~ValueStoreTest() {}
    170 
    171 void ValueStoreTest::SetUp() {
    172   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    173   storage_.reset((GetParam())(temp_dir_.path().AppendASCII("dbName")));
    174   ASSERT_TRUE(storage_.get());
    175 }
    176 
    177 void ValueStoreTest::TearDown() {
    178   storage_.reset();
    179 }
    180 
    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());
    186 }
    187 
    188 TEST_P(ValueStoreTest, GetWithSingleValue) {
    189   {
    190     ValueStoreChangeList changes;
    191     changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
    192     EXPECT_PRED_FORMAT2(ChangesEq,
    193         changes, storage_->Set(DEFAULTS, key1_, *val1_));
    194   }
    195 
    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());
    202 }
    203 
    204 TEST_P(ValueStoreTest, GetWithMultipleValues) {
    205   {
    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_));
    210   }
    211 
    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());
    217 }
    218 
    219 TEST_P(ValueStoreTest, RemoveWhenEmpty) {
    220   EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(),
    221                       storage_->Remove(key1_));
    222 
    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());
    226 }
    227 
    228 TEST_P(ValueStoreTest, RemoveWithSingleValue) {
    229   storage_->Set(DEFAULTS, *dict1_);
    230   {
    231     ValueStoreChangeList changes;
    232     changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL));
    233     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_));
    234   }
    235 
    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());
    241 }
    242 
    243 TEST_P(ValueStoreTest, RemoveWithMultipleValues) {
    244   storage_->Set(DEFAULTS, *dict123_);
    245   {
    246     ValueStoreChangeList changes;
    247     changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL));
    248     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key3_));
    249   }
    250 
    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());
    259 
    260   {
    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_));
    265   }
    266 
    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());
    275 }
    276 
    277 TEST_P(ValueStoreTest, SetWhenOverwriting) {
    278   storage_->Set(DEFAULTS, key1_, *val2_);
    279   {
    280     ValueStoreChangeList changes;
    281     changes.push_back(
    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_));
    285   }
    286 
    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());
    295 }
    296 
    297 TEST_P(ValueStoreTest, ClearWhenEmpty) {
    298   EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
    299 
    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());
    304 }
    305 
    306 TEST_P(ValueStoreTest, ClearWhenNotEmpty) {
    307   storage_->Set(DEFAULTS, *dict12_);
    308   {
    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());
    313   }
    314 
    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());
    319 }
    320 
    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());
    330 
    331   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
    332 
    333   {
    334     ValueStoreChangeList changes;
    335     changes.push_back(
    336         ValueStoreChange(dot_key, NULL, dot_value.DeepCopy()));
    337     EXPECT_PRED_FORMAT2(ChangesEq,
    338         changes, storage_->Set(DEFAULTS, dot_key, dot_value));
    339   }
    340   EXPECT_PRED_FORMAT2(ChangesEq,
    341       ValueStoreChangeList(), storage_->Set(DEFAULTS, dot_key, dot_value));
    342 
    343   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_key));
    344 
    345   {
    346     ValueStoreChangeList changes;
    347     changes.push_back(
    348         ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL));
    349     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_key));
    350   }
    351   EXPECT_PRED_FORMAT2(ChangesEq,
    352       ValueStoreChangeList(), storage_->Remove(dot_key));
    353   {
    354     ValueStoreChangeList changes;
    355     changes.push_back(
    356         ValueStoreChange(dot_key, NULL, dot_value.DeepCopy()));
    357     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, dot_dict));
    358   }
    359 
    360   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_list));
    361   EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get());
    362 
    363   {
    364     ValueStoreChangeList changes;
    365     changes.push_back(
    366         ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL));
    367     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_list));
    368   }
    369 
    370   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
    371   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
    372 }
    373 
    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");
    379 
    380   {
    381     ValueStoreChangeList changes;
    382     changes.push_back(
    383         ValueStoreChange("foo", NULL, inner_dict->DeepCopy()));
    384     EXPECT_PRED_FORMAT2(ChangesEq,
    385         changes, storage_->Set(DEFAULTS, outer_dict));
    386   }
    387 
    388   EXPECT_PRED_FORMAT2(SettingsEq, outer_dict, storage_->Get("foo"));
    389   EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get("foo.bar"));
    390 }
    391 
    392 TEST_P(ValueStoreTest, ComplexChangedKeysScenarios) {
    393   // Test:
    394   //   - Setting over missing/changed/same keys, combinations.
    395   //   - Removing over missing and present keys, combinations.
    396   //   - Clearing.
    397   std::vector<std::string> complex_list;
    398   base::DictionaryValue complex_changed_dict;
    399 
    400   storage_->Set(DEFAULTS, key1_, *val1_);
    401   EXPECT_PRED_FORMAT2(ChangesEq,
    402       ValueStoreChangeList(), storage_->Set(DEFAULTS, key1_, *val1_));
    403   {
    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_));
    409   }
    410   {
    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_));
    416   }
    417   {
    418     ValueStoreChangeList changes;
    419     changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
    420     EXPECT_PRED_FORMAT2(ChangesEq,
    421         changes, storage_->Set(DEFAULTS, key1_, *val1_));
    422   }
    423   {
    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());
    428   }
    429 
    430   {
    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_));
    437   }
    438   {
    439     ValueStoreChangeList changes;
    440     changes.push_back(ValueStoreChange(key3_, NULL, val3_->DeepCopy()));
    441     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict123_));
    442   }
    443   {
    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());
    449 
    450     ValueStoreChangeList changes;
    451     changes.push_back(
    452         ValueStoreChange(key1_, val1_->DeepCopy(), val2_->DeepCopy()));
    453     changes.push_back(ValueStoreChange("asdf", NULL, val1_->DeepCopy()));
    454     changes.push_back(
    455         ValueStoreChange("qwerty", NULL, val3_->DeepCopy()));
    456     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, to_set));
    457   }
    458   {
    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_));
    463   }
    464   {
    465     std::vector<std::string> to_remove;
    466     to_remove.push_back(key1_);
    467     to_remove.push_back("asdf");
    468 
    469     ValueStoreChangeList changes;
    470     changes.push_back(ValueStoreChange("asdf", val1_->DeepCopy(), NULL));
    471     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(to_remove));
    472   }
    473   {
    474     ValueStoreChangeList changes;
    475     changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL));
    476     changes.push_back(
    477         ValueStoreChange("qwerty", val3_->DeepCopy(), NULL));
    478     EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
    479     EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
    480   }
    481 }
    482