OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 // TODO(kalman): More tests: |
| 6 // - Keys/values containing dots. |
| 7 // - More than one active settings object. |
| 8 // - Failure cases. |
| 9 // - Test with existing data (i.e. shut down leveldb storage, re-start). |
| 10 |
| 11 #include "chrome/browser/extensions/extension_settings_storage_unittest.h" |
| 12 |
| 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/json/json_writer.h" |
| 15 #include "base/values.h" |
| 16 #include "chrome/browser/extensions/extension_settings.h" |
| 17 |
| 18 // Define macros for these to get the __LINE__ expansion. |
| 19 // Undefined at the end of the file. |
| 20 #define newCallback(expected) \ |
| 21 (new AssertEqualsCallback((expected), false, __LINE__)) |
| 22 #define newQuittingCallback(expected) \ |
| 23 (new AssertEqualsCallback((expected), true, __LINE__)) |
| 24 |
| 25 namespace { |
| 26 |
| 27 // Callback from GetStorage() which places the new storage in a given location. |
| 28 // Posts a QuitTask to the current message loop when done. |
| 29 class GetStorageCallback : public ExtensionSettings::Callback { |
| 30 public: |
| 31 explicit GetStorageCallback(ExtensionSettingsStorage** storagePtr) |
| 32 : storagePtr_(storagePtr) { |
| 33 *storagePtr = NULL; |
| 34 } |
| 35 |
| 36 ~GetStorageCallback() {} |
| 37 |
| 38 void Run(ExtensionSettingsStorage* storage) { |
| 39 DCHECK(*storagePtr_ == NULL); |
| 40 *storagePtr_ = storage; |
| 41 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 42 } |
| 43 |
| 44 private: |
| 45 ExtensionSettingsStorage** storagePtr_; |
| 46 }; |
| 47 |
| 48 // Callback from storage methods which performs the test assertions. |
| 49 class AssertEqualsCallback : public ExtensionSettingsStorage::Callback { |
| 50 public: |
| 51 AssertEqualsCallback(DictionaryValue* expected, bool quit_when_done, int line) |
| 52 : expected_(expected), quit_when_done_(quit_when_done), line_(line), |
| 53 called_(false) { |
| 54 } |
| 55 |
| 56 ~AssertEqualsCallback() { |
| 57 // Need to DCHECK since ASSERT_* can't be used from destructors. |
| 58 DCHECK(called_); |
| 59 } |
| 60 |
| 61 void OnSuccess(DictionaryValue* actual) { |
| 62 // Post quit task first so that it always runs even if the test fails. |
| 63 MaybePostQuitTask(); |
| 64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 65 ASSERT_FALSE(called_) << "Callback has already been called"; |
| 66 called_ = true; |
| 67 ASSERT_TRUE(expected_->Equals(actual)) << "Values are different:\n" << |
| 68 "Line: " << line_ << "\n" << |
| 69 "Expected: " << GetJson(expected_) << |
| 70 "Got: " << GetJson(actual); |
| 71 delete actual; |
| 72 } |
| 73 |
| 74 void OnFailure(const std::string& message) { |
| 75 // Post quit task first so that it always runs even if the test fails. |
| 76 MaybePostQuitTask(); |
| 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 78 ASSERT_FALSE(called_) << "Callback has already been called"; |
| 79 called_ = true; |
| 80 // No tests allow failure (yet). |
| 81 ASSERT_TRUE(false) << "Callback failed on line " << line_; |
| 82 } |
| 83 |
| 84 private: |
| 85 std::string GetJson(Value* value) { |
| 86 std::string json; |
| 87 base::JSONWriter::Write(value, true, &json); |
| 88 return json; |
| 89 } |
| 90 |
| 91 void MaybePostQuitTask() { |
| 92 if (quit_when_done_) { |
| 93 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 94 } |
| 95 } |
| 96 |
| 97 DictionaryValue* expected_; |
| 98 bool quit_when_done_; |
| 99 int line_; |
| 100 bool called_; |
| 101 }; |
| 102 |
| 103 class TestSettingsCallback : public ExtensionSettings::Callback { |
| 104 public: |
| 105 explicit TestSettingsCallback(ExtensionSettingsStorage** storagePtr) |
| 106 : storagePtr_(storagePtr) { |
| 107 *storagePtr_ = NULL; |
| 108 } |
| 109 |
| 110 void Run(ExtensionSettingsStorage* storage) { |
| 111 DCHECK(*storagePtr_ == NULL); |
| 112 DCHECK(storage != NULL); |
| 113 *storagePtr_ = storage; |
| 114 } |
| 115 |
| 116 private: |
| 117 ExtensionSettingsStorage** storagePtr_; |
| 118 }; |
| 119 |
| 120 std::string key1() { |
| 121 return "foo"; |
| 122 } |
| 123 |
| 124 std::string key2() { |
| 125 return "bar"; |
| 126 } |
| 127 |
| 128 std::string key3() { |
| 129 return "baz"; |
| 130 } |
| 131 |
| 132 Value* val1() { |
| 133 Value* val = NULL; |
| 134 if (val == NULL) { |
| 135 val = Value::CreateStringValue(key1() + "Value"); |
| 136 } |
| 137 return val; |
| 138 } |
| 139 |
| 140 Value* val2() { |
| 141 static Value* val = NULL; |
| 142 if (val == NULL) { |
| 143 val = Value::CreateStringValue(key2() + "Value"); |
| 144 } |
| 145 return val; |
| 146 } |
| 147 |
| 148 Value* val3() { |
| 149 static Value* val = NULL; |
| 150 if (val == NULL) { |
| 151 val = Value::CreateStringValue(key3() + "Value"); |
| 152 } |
| 153 return val; |
| 154 } |
| 155 |
| 156 ListValue* emptyList() { |
| 157 static ListValue* val = NULL; |
| 158 if (val == NULL) { |
| 159 val = new ListValue(); |
| 160 } |
| 161 return val; |
| 162 } |
| 163 |
| 164 ListValue* list1() { |
| 165 static ListValue* val = NULL; |
| 166 if (val == NULL) { |
| 167 val = new ListValue(); |
| 168 val->Append(Value::CreateStringValue(key1())); |
| 169 } |
| 170 return val; |
| 171 } |
| 172 |
| 173 ListValue* list2() { |
| 174 static ListValue* val = NULL; |
| 175 if (val == NULL) { |
| 176 val = new ListValue(); |
| 177 val->Append(Value::CreateStringValue(key2())); |
| 178 } |
| 179 return val; |
| 180 } |
| 181 |
| 182 ListValue* list12() { |
| 183 static ListValue* val = NULL; |
| 184 if (val == NULL) { |
| 185 val = new ListValue(); |
| 186 val->Append(Value::CreateStringValue(key1())); |
| 187 val->Append(Value::CreateStringValue(key2())); |
| 188 } |
| 189 return val; |
| 190 } |
| 191 |
| 192 ListValue* list13() { |
| 193 static ListValue* val = NULL; |
| 194 if (val == NULL) { |
| 195 val = new ListValue(); |
| 196 val->Append(Value::CreateStringValue(key1())); |
| 197 val->Append(Value::CreateStringValue(key3())); |
| 198 } |
| 199 return val; |
| 200 } |
| 201 |
| 202 ListValue* list123() { |
| 203 static ListValue* val = NULL; |
| 204 if (val == NULL) { |
| 205 val = new ListValue(); |
| 206 val->Append(Value::CreateStringValue(key1())); |
| 207 val->Append(Value::CreateStringValue(key2())); |
| 208 val->Append(Value::CreateStringValue(key3())); |
| 209 } |
| 210 return val; |
| 211 } |
| 212 |
| 213 DictionaryValue* emptyDict() { |
| 214 static DictionaryValue* val = NULL; |
| 215 if (val == NULL) { |
| 216 val = new DictionaryValue(); |
| 217 } |
| 218 return val; |
| 219 } |
| 220 |
| 221 DictionaryValue* dict1() { |
| 222 static DictionaryValue* val = NULL; |
| 223 if (val == NULL) { |
| 224 val = new DictionaryValue(); |
| 225 val->Set(key1(), val1()->DeepCopy()); |
| 226 } |
| 227 return val; |
| 228 } |
| 229 |
| 230 DictionaryValue* dict12() { |
| 231 static DictionaryValue* val = NULL; |
| 232 if (val == NULL) { |
| 233 val = new DictionaryValue(); |
| 234 val->Set(key1(), val1()->DeepCopy()); |
| 235 val->Set(key2(), val2()->DeepCopy()); |
| 236 } |
| 237 return val; |
| 238 } |
| 239 |
| 240 DictionaryValue* dict123() { |
| 241 static DictionaryValue* val = NULL; |
| 242 if (val == NULL) { |
| 243 val = new DictionaryValue(); |
| 244 val->Set(key1(), val1()->DeepCopy()); |
| 245 val->Set(key2(), val2()->DeepCopy()); |
| 246 val->Set(key3(), val3()->DeepCopy()); |
| 247 } |
| 248 return val; |
| 249 } |
| 250 |
| 251 } // namespace |
| 252 |
| 253 void ExtensionSettingsStorageTest::SetUp() { |
| 254 ui_message_loop_ = new MessageLoopForUI(); |
| 255 ui_thread_ = new BrowserThread(BrowserThread::UI, MessageLoop::current()); |
| 256 file_thread_ = new BrowserThread(BrowserThread::FILE); |
| 257 file_thread_->Start(); |
| 258 |
| 259 FilePath temp_dir; |
| 260 file_util::CreateNewTempDirectory("", &temp_dir); |
| 261 settings_ = new ExtensionSettings(temp_dir); |
| 262 |
| 263 storage_ = NULL; |
| 264 settings_->GetStorageForTesting(GetParam(), "fakeExtension", |
| 265 new GetStorageCallback(&storage_)); |
| 266 MessageLoop::current()->Run(); |
| 267 DCHECK(storage_ != NULL); |
| 268 } |
| 269 |
| 270 void ExtensionSettingsStorageTest::TearDown() { |
| 271 delete settings_; |
| 272 |
| 273 file_thread_->Stop(); |
| 274 delete file_thread_; |
| 275 delete ui_thread_; |
| 276 delete ui_message_loop_; |
| 277 } |
| 278 |
| 279 TEST_P(ExtensionSettingsStorageTest, GetWhenEmpty) { |
| 280 storage_->Get(key1(), newCallback(emptyDict())); |
| 281 storage_->Get(key2(), newCallback(emptyDict())); |
| 282 storage_->Get(key3(), newCallback(emptyDict())); |
| 283 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 284 storage_->Get(*list1(), newCallback(emptyDict())); |
| 285 storage_->Get(*list123(), newCallback(emptyDict())); |
| 286 |
| 287 storage_->Get(newQuittingCallback(emptyDict())); |
| 288 MessageLoop::current()->Run(); |
| 289 } |
| 290 |
| 291 TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) { |
| 292 storage_->Set(key1(), *val1(), newQuittingCallback(dict1())); |
| 293 MessageLoop::current()->Run(); |
| 294 |
| 295 storage_->Get(key1(), newCallback(dict1())); |
| 296 storage_->Get(key2(), newCallback(emptyDict())); |
| 297 storage_->Get(key3(), newCallback(emptyDict())); |
| 298 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 299 storage_->Get(*list1(), newCallback(dict1())); |
| 300 storage_->Get(*list2(), newCallback(emptyDict())); |
| 301 storage_->Get(*list123(), newCallback(dict1())); |
| 302 |
| 303 storage_->Get(newQuittingCallback(dict1())); |
| 304 MessageLoop::current()->Run(); |
| 305 } |
| 306 |
| 307 TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) { |
| 308 storage_->Set(*dict12(), newQuittingCallback(dict12())); |
| 309 MessageLoop::current()->Run(); |
| 310 |
| 311 storage_->Get(key1(), newCallback(dict1())); |
| 312 storage_->Get(key3(), newCallback(emptyDict())); |
| 313 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 314 storage_->Get(*list1(), newCallback(dict1())); |
| 315 storage_->Get(*list13(), newCallback(dict1())); |
| 316 storage_->Get(*list12(), newCallback(dict12())); |
| 317 storage_->Get(*list123(), newCallback(dict12())); |
| 318 |
| 319 storage_->Get(newQuittingCallback(dict12())); |
| 320 MessageLoop::current()->Run(); |
| 321 } |
| 322 |
| 323 TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) { |
| 324 storage_->Remove(key1(), newQuittingCallback(emptyDict())); |
| 325 MessageLoop::current()->Run(); |
| 326 |
| 327 storage_->Get(key1(), newCallback(emptyDict())); |
| 328 storage_->Get(*list1(), newCallback(emptyDict())); |
| 329 |
| 330 storage_->Get(newQuittingCallback(emptyDict())); |
| 331 MessageLoop::current()->Run(); |
| 332 } |
| 333 |
| 334 TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) { |
| 335 storage_->Set(key1(), *val1(), newQuittingCallback(dict1())); |
| 336 MessageLoop::current()->Run(); |
| 337 storage_->Remove(key1(), newQuittingCallback(emptyDict())); |
| 338 MessageLoop::current()->Run(); |
| 339 |
| 340 storage_->Get(key1(), newCallback(emptyDict())); |
| 341 storage_->Get(key2(), newCallback(emptyDict())); |
| 342 storage_->Get(*list1(), newCallback(emptyDict())); |
| 343 storage_->Get(*list12(), newCallback(emptyDict())); |
| 344 |
| 345 storage_->Get(newQuittingCallback(emptyDict())); |
| 346 MessageLoop::current()->Run(); |
| 347 } |
| 348 |
| 349 TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) { |
| 350 storage_->Set(*dict123(), newQuittingCallback(dict123())); |
| 351 MessageLoop::current()->Run(); |
| 352 storage_->Remove(key3(), newQuittingCallback(emptyDict())); |
| 353 MessageLoop::current()->Run(); |
| 354 |
| 355 storage_->Get(key1(), newCallback(dict1())); |
| 356 storage_->Get(key3(), newCallback(emptyDict())); |
| 357 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 358 storage_->Get(*list1(), newCallback(dict1())); |
| 359 storage_->Get(*list13(), newCallback(dict1())); |
| 360 storage_->Get(*list12(), newCallback(dict12())); |
| 361 storage_->Get(*list123(), newCallback(dict12())); |
| 362 storage_->Get(newCallback(dict12())); |
| 363 |
| 364 storage_->Remove(*list2(), newQuittingCallback(emptyDict())); |
| 365 MessageLoop::current()->Run(); |
| 366 |
| 367 storage_->Get(key1(), newCallback(dict1())); |
| 368 storage_->Get(key2(), newCallback(emptyDict())); |
| 369 storage_->Get(key3(), newCallback(emptyDict())); |
| 370 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 371 storage_->Get(*list1(), newCallback(dict1())); |
| 372 storage_->Get(*list2(), newCallback(emptyDict())); |
| 373 storage_->Get(*list123(), newCallback(dict1())); |
| 374 |
| 375 storage_->Get(newQuittingCallback(dict1())); |
| 376 MessageLoop::current()->Run(); |
| 377 } |
| 378 |
| 379 TEST_P(ExtensionSettingsStorageTest, SetWhenOverwriting) { |
| 380 DictionaryValue key1Val2; |
| 381 key1Val2.Set(key1(), val2()->DeepCopy()); |
| 382 storage_->Set(key1(), *val2(), newQuittingCallback(&key1Val2)); |
| 383 MessageLoop::current()->Run(); |
| 384 |
| 385 storage_->Set(*dict12(), newQuittingCallback(dict12())); |
| 386 MessageLoop::current()->Run(); |
| 387 |
| 388 storage_->Get(key1(), newCallback(dict1())); |
| 389 storage_->Get(key3(), newCallback(emptyDict())); |
| 390 storage_->Get(*emptyList(), newCallback(emptyDict())); |
| 391 storage_->Get(*list1(), newCallback(dict1())); |
| 392 storage_->Get(*list13(), newCallback(dict1())); |
| 393 storage_->Get(*list12(), newCallback(dict12())); |
| 394 storage_->Get(*list123(), newCallback(dict12())); |
| 395 |
| 396 storage_->Get(newQuittingCallback(dict12())); |
| 397 MessageLoop::current()->Run(); |
| 398 } |
| 399 |
| 400 TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) { |
| 401 storage_->Clear(newQuittingCallback(emptyDict())); |
| 402 MessageLoop::current()->Run(); |
| 403 |
| 404 storage_->Get(key1(), newCallback(emptyDict())); |
| 405 storage_->Get(*list1(), newCallback(emptyDict())); |
| 406 |
| 407 storage_->Get(newQuittingCallback(emptyDict())); |
| 408 MessageLoop::current()->Run(); |
| 409 } |
| 410 |
| 411 TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) { |
| 412 storage_->Set(*dict12(), newQuittingCallback(dict12())); |
| 413 MessageLoop::current()->Run(); |
| 414 storage_->Clear(newQuittingCallback(emptyDict())); |
| 415 MessageLoop::current()->Run(); |
| 416 |
| 417 storage_->Get(key1(), newCallback(emptyDict())); |
| 418 storage_->Get(*list1(), newCallback(emptyDict())); |
| 419 |
| 420 storage_->Get(newQuittingCallback(emptyDict())); |
| 421 MessageLoop::current()->Run(); |
| 422 } |
| 423 |
| 424 #undef newCallback |
| 425 #undef newQuittingCallback |
OLD | NEW |