| Index: chrome/browser/extensions/extension_settings_storage_unittest.cc
|
| diff --git a/chrome/browser/extensions/extension_settings_storage_unittest.cc b/chrome/browser/extensions/extension_settings_storage_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7a793b79c614cf8afe50329568c48b80f1f52570
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/extension_settings_storage_unittest.cc
|
| @@ -0,0 +1,425 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// TODO(kalman): More tests:
|
| +// - Keys/values containing dots.
|
| +// - More than one active settings object.
|
| +// - Failure cases.
|
| +// - Test with existing data (i.e. shut down leveldb storage, re-start).
|
| +
|
| +#include "chrome/browser/extensions/extension_settings_storage_unittest.h"
|
| +
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/json/json_writer.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/extensions/extension_settings.h"
|
| +
|
| +// Define macros for these to get the __LINE__ expansion.
|
| +// Undefined at the end of the file.
|
| +#define newCallback(expected) \
|
| + (new AssertEqualsCallback((expected), false, __LINE__))
|
| +#define newQuittingCallback(expected) \
|
| + (new AssertEqualsCallback((expected), true, __LINE__))
|
| +
|
| +namespace {
|
| +
|
| +// Callback from GetStorage() which places the new storage in a given location.
|
| +// Posts a QuitTask to the current message loop when done.
|
| +class GetStorageCallback : public ExtensionSettings::Callback {
|
| + public:
|
| + explicit GetStorageCallback(ExtensionSettingsStorage** storagePtr)
|
| + : storagePtr_(storagePtr) {
|
| + *storagePtr = NULL;
|
| + }
|
| +
|
| + ~GetStorageCallback() {}
|
| +
|
| + void Run(ExtensionSettingsStorage* storage) {
|
| + DCHECK(*storagePtr_ == NULL);
|
| + *storagePtr_ = storage;
|
| + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
|
| + }
|
| +
|
| + private:
|
| + ExtensionSettingsStorage** storagePtr_;
|
| +};
|
| +
|
| +// Callback from storage methods which performs the test assertions.
|
| +class AssertEqualsCallback : public ExtensionSettingsStorage::Callback {
|
| + public:
|
| + AssertEqualsCallback(DictionaryValue* expected, bool quit_when_done, int line)
|
| + : expected_(expected), quit_when_done_(quit_when_done), line_(line),
|
| + called_(false) {
|
| + }
|
| +
|
| + ~AssertEqualsCallback() {
|
| + // Need to DCHECK since ASSERT_* can't be used from destructors.
|
| + DCHECK(called_);
|
| + }
|
| +
|
| + void OnSuccess(DictionaryValue* actual) {
|
| + // Post quit task first so that it always runs even if the test fails.
|
| + MaybePostQuitTask();
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + ASSERT_FALSE(called_) << "Callback has already been called";
|
| + called_ = true;
|
| + ASSERT_TRUE(expected_->Equals(actual)) << "Values are different:\n" <<
|
| + "Line: " << line_ << "\n" <<
|
| + "Expected: " << GetJson(expected_) <<
|
| + "Got: " << GetJson(actual);
|
| + delete actual;
|
| + }
|
| +
|
| + void OnFailure(const std::string& message) {
|
| + // Post quit task first so that it always runs even if the test fails.
|
| + MaybePostQuitTask();
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + ASSERT_FALSE(called_) << "Callback has already been called";
|
| + called_ = true;
|
| + // No tests allow failure (yet).
|
| + ASSERT_TRUE(false) << "Callback failed on line " << line_;
|
| + }
|
| +
|
| + private:
|
| + std::string GetJson(Value* value) {
|
| + std::string json;
|
| + base::JSONWriter::Write(value, true, &json);
|
| + return json;
|
| + }
|
| +
|
| + void MaybePostQuitTask() {
|
| + if (quit_when_done_) {
|
| + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
|
| + }
|
| + }
|
| +
|
| + DictionaryValue* expected_;
|
| + bool quit_when_done_;
|
| + int line_;
|
| + bool called_;
|
| +};
|
| +
|
| +class TestSettingsCallback : public ExtensionSettings::Callback {
|
| + public:
|
| + explicit TestSettingsCallback(ExtensionSettingsStorage** storagePtr)
|
| + : storagePtr_(storagePtr) {
|
| + *storagePtr_ = NULL;
|
| + }
|
| +
|
| + void Run(ExtensionSettingsStorage* storage) {
|
| + DCHECK(*storagePtr_ == NULL);
|
| + DCHECK(storage != NULL);
|
| + *storagePtr_ = storage;
|
| + }
|
| +
|
| + private:
|
| + ExtensionSettingsStorage** storagePtr_;
|
| +};
|
| +
|
| +std::string key1() {
|
| + return "foo";
|
| +}
|
| +
|
| +std::string key2() {
|
| + return "bar";
|
| +}
|
| +
|
| +std::string key3() {
|
| + return "baz";
|
| +}
|
| +
|
| +Value* val1() {
|
| + Value* val = NULL;
|
| + if (val == NULL) {
|
| + val = Value::CreateStringValue(key1() + "Value");
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +Value* val2() {
|
| + static Value* val = NULL;
|
| + if (val == NULL) {
|
| + val = Value::CreateStringValue(key2() + "Value");
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +Value* val3() {
|
| + static Value* val = NULL;
|
| + if (val == NULL) {
|
| + val = Value::CreateStringValue(key3() + "Value");
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* emptyList() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* list1() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + val->Append(Value::CreateStringValue(key1()));
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* list2() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + val->Append(Value::CreateStringValue(key2()));
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* list12() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + val->Append(Value::CreateStringValue(key1()));
|
| + val->Append(Value::CreateStringValue(key2()));
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* list13() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + val->Append(Value::CreateStringValue(key1()));
|
| + val->Append(Value::CreateStringValue(key3()));
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +ListValue* list123() {
|
| + static ListValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new ListValue();
|
| + val->Append(Value::CreateStringValue(key1()));
|
| + val->Append(Value::CreateStringValue(key2()));
|
| + val->Append(Value::CreateStringValue(key3()));
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +DictionaryValue* emptyDict() {
|
| + static DictionaryValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new DictionaryValue();
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +DictionaryValue* dict1() {
|
| + static DictionaryValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new DictionaryValue();
|
| + val->Set(key1(), val1()->DeepCopy());
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +DictionaryValue* dict12() {
|
| + static DictionaryValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new DictionaryValue();
|
| + val->Set(key1(), val1()->DeepCopy());
|
| + val->Set(key2(), val2()->DeepCopy());
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +DictionaryValue* dict123() {
|
| + static DictionaryValue* val = NULL;
|
| + if (val == NULL) {
|
| + val = new DictionaryValue();
|
| + val->Set(key1(), val1()->DeepCopy());
|
| + val->Set(key2(), val2()->DeepCopy());
|
| + val->Set(key3(), val3()->DeepCopy());
|
| + }
|
| + return val;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +void ExtensionSettingsStorageTest::SetUp() {
|
| + ui_message_loop_ = new MessageLoopForUI();
|
| + ui_thread_ = new BrowserThread(BrowserThread::UI, MessageLoop::current());
|
| + file_thread_ = new BrowserThread(BrowserThread::FILE);
|
| + file_thread_->Start();
|
| +
|
| + FilePath temp_dir;
|
| + file_util::CreateNewTempDirectory("", &temp_dir);
|
| + settings_ = new ExtensionSettings(temp_dir);
|
| +
|
| + storage_ = NULL;
|
| + settings_->GetStorageForTesting(GetParam(), "fakeExtension",
|
| + new GetStorageCallback(&storage_));
|
| + MessageLoop::current()->Run();
|
| + DCHECK(storage_ != NULL);
|
| +}
|
| +
|
| +void ExtensionSettingsStorageTest::TearDown() {
|
| + delete settings_;
|
| +
|
| + file_thread_->Stop();
|
| + delete file_thread_;
|
| + delete ui_thread_;
|
| + delete ui_message_loop_;
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWhenEmpty) {
|
| + storage_->Get(key1(), newCallback(emptyDict()));
|
| + storage_->Get(key2(), newCallback(emptyDict()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(emptyDict()));
|
| + storage_->Get(*list123(), newCallback(emptyDict()));
|
| +
|
| + storage_->Get(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) {
|
| + storage_->Set(key1(), *val1(), newQuittingCallback(dict1()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(dict1()));
|
| + storage_->Get(key2(), newCallback(emptyDict()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(dict1()));
|
| + storage_->Get(*list2(), newCallback(emptyDict()));
|
| + storage_->Get(*list123(), newCallback(dict1()));
|
| +
|
| + storage_->Get(newQuittingCallback(dict1()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) {
|
| + storage_->Set(*dict12(), newQuittingCallback(dict12()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(dict1()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(dict1()));
|
| + storage_->Get(*list13(), newCallback(dict1()));
|
| + storage_->Get(*list12(), newCallback(dict12()));
|
| + storage_->Get(*list123(), newCallback(dict12()));
|
| +
|
| + storage_->Get(newQuittingCallback(dict12()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) {
|
| + storage_->Remove(key1(), newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(emptyDict()));
|
| +
|
| + storage_->Get(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) {
|
| + storage_->Set(key1(), *val1(), newQuittingCallback(dict1()));
|
| + MessageLoop::current()->Run();
|
| + storage_->Remove(key1(), newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(emptyDict()));
|
| + storage_->Get(key2(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(emptyDict()));
|
| + storage_->Get(*list12(), newCallback(emptyDict()));
|
| +
|
| + storage_->Get(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) {
|
| + storage_->Set(*dict123(), newQuittingCallback(dict123()));
|
| + MessageLoop::current()->Run();
|
| + storage_->Remove(key3(), newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(dict1()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(dict1()));
|
| + storage_->Get(*list13(), newCallback(dict1()));
|
| + storage_->Get(*list12(), newCallback(dict12()));
|
| + storage_->Get(*list123(), newCallback(dict12()));
|
| + storage_->Get(newCallback(dict12()));
|
| +
|
| + storage_->Remove(*list2(), newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(dict1()));
|
| + storage_->Get(key2(), newCallback(emptyDict()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(dict1()));
|
| + storage_->Get(*list2(), newCallback(emptyDict()));
|
| + storage_->Get(*list123(), newCallback(dict1()));
|
| +
|
| + storage_->Get(newQuittingCallback(dict1()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, SetWhenOverwriting) {
|
| + DictionaryValue key1Val2;
|
| + key1Val2.Set(key1(), val2()->DeepCopy());
|
| + storage_->Set(key1(), *val2(), newQuittingCallback(&key1Val2));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Set(*dict12(), newQuittingCallback(dict12()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(dict1()));
|
| + storage_->Get(key3(), newCallback(emptyDict()));
|
| + storage_->Get(*emptyList(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(dict1()));
|
| + storage_->Get(*list13(), newCallback(dict1()));
|
| + storage_->Get(*list12(), newCallback(dict12()));
|
| + storage_->Get(*list123(), newCallback(dict12()));
|
| +
|
| + storage_->Get(newQuittingCallback(dict12()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) {
|
| + storage_->Clear(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(emptyDict()));
|
| +
|
| + storage_->Get(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) {
|
| + storage_->Set(*dict12(), newQuittingCallback(dict12()));
|
| + MessageLoop::current()->Run();
|
| + storage_->Clear(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +
|
| + storage_->Get(key1(), newCallback(emptyDict()));
|
| + storage_->Get(*list1(), newCallback(emptyDict()));
|
| +
|
| + storage_->Get(newQuittingCallback(emptyDict()));
|
| + MessageLoop::current()->Run();
|
| +}
|
| +
|
| +#undef newCallback
|
| +#undef newQuittingCallback
|
|
|