| 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..970906f956bcb4fc380ee501611329c141d0cae8
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/extension_settings_storage_unittest.cc
|
| @@ -0,0 +1,300 @@
|
| +// 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/bind.h"
|
| +#include "base/json/json_writer.h"
|
| +#include "base/file_util.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/extensions/extension_settings.h"
|
| +#include "content/browser/browser_thread.h"
|
| +
|
| +// Define macro to get the __LINE__ expansion.
|
| +#define NEW_CALLBACK(expected) (new AssertEqualsCallback((expected), __LINE__))
|
| +
|
| +namespace {
|
| +
|
| +// Callback from storage methods which performs the test assertions.
|
| +class AssertEqualsCallback : public ExtensionSettingsStorage::Callback {
|
| + public:
|
| + AssertEqualsCallback(DictionaryValue* expected, int line)
|
| + : expected_(expected), line_(line), called_(false) {
|
| + }
|
| +
|
| + ~AssertEqualsCallback() {
|
| + // Need to DCHECK since ASSERT_* can't be used from destructors.
|
| + DCHECK(called_);
|
| + }
|
| +
|
| + virtual void OnSuccess(DictionaryValue* actual) OVERRIDE {
|
| + 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;
|
| + }
|
| +
|
| + virtual void OnFailure(const std::string& message) OVERRIDE {
|
| + 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;
|
| + }
|
| +
|
| + DictionaryValue* expected_;
|
| + int line_;
|
| + bool called_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +ExtensionSettingsStorageTest::ExtensionSettingsStorageTest()
|
| + : key1_("foo"), key2_("bar"), key3_("baz") {
|
| + val1_ = Value::CreateStringValue(key1_ + "Value");
|
| + val2_ = Value::CreateStringValue(key2_ + "Value");
|
| + val3_ = Value::CreateStringValue(key3_ + "Value");
|
| +
|
| + emptyList_ = new ListValue();
|
| +
|
| + list1_ = new ListValue();
|
| + list1_->Append(Value::CreateStringValue(key1_));
|
| +
|
| + list2_ = new ListValue();
|
| + list2_->Append(Value::CreateStringValue(key2_));
|
| +
|
| + list12_ = new ListValue();
|
| + list12_->Append(Value::CreateStringValue(key1_));
|
| + list12_->Append(Value::CreateStringValue(key2_));
|
| +
|
| + list13_ = new ListValue();
|
| + list13_->Append(Value::CreateStringValue(key1_));
|
| + list13_->Append(Value::CreateStringValue(key3_));
|
| +
|
| + list123_ = new ListValue();
|
| + list123_->Append(Value::CreateStringValue(key1_));
|
| + list123_->Append(Value::CreateStringValue(key2_));
|
| + list123_->Append(Value::CreateStringValue(key3_));
|
| +
|
| + emptyDict_ = new DictionaryValue();
|
| +
|
| + dict1_ = new DictionaryValue();
|
| + dict1_->Set(key1_, val1_->DeepCopy());
|
| +
|
| + dict12_ = new DictionaryValue();
|
| + dict12_->Set(key1_, val1_->DeepCopy());
|
| + dict12_->Set(key2_, val2_->DeepCopy());
|
| +
|
| + dict123_ = new DictionaryValue();
|
| + dict123_->Set(key1_, val1_->DeepCopy());
|
| + dict123_->Set(key2_, val2_->DeepCopy());
|
| + dict123_->Set(key3_, val3_->DeepCopy());
|
| +}
|
| +
|
| +ExtensionSettingsStorageTest::~ExtensionSettingsStorageTest() {
|
| + delete val1_;
|
| + delete val2_;
|
| + delete val3_;
|
| + delete emptyList_;
|
| + delete list1_;
|
| + delete list2_;
|
| + delete list12_;
|
| + delete list13_;
|
| + delete list123_;
|
| + delete emptyDict_;
|
| + delete dict1_;
|
| + delete dict12_;
|
| + delete dict123_;
|
| +}
|
| +
|
| +void ExtensionSettingsStorageTest::SetUp() {
|
| + ui_message_loop_ = new MessageLoopForUI();
|
| + // Use the same message loop for the UI and FILE threads, giving a test
|
| + // pattern where storage API calls get posted to the same message loop (the
|
| + // current one), then all run with MessageLoop::current()->RunAllPending().
|
| + ui_thread_ = new BrowserThread(BrowserThread::UI, MessageLoop::current());
|
| + file_thread_ = new BrowserThread(BrowserThread::FILE, MessageLoop::current());
|
| +
|
| + FilePath temp_dir;
|
| + file_util::CreateNewTempDirectory(FilePath::StringType(), &temp_dir);
|
| + settings_ = new ExtensionSettings(temp_dir);
|
| +
|
| + storage_ = NULL;
|
| + (GetParam())(
|
| + settings_,
|
| + "fakeExtension",
|
| + base::Bind(
|
| + &ExtensionSettingsStorageTest::SetStorage,
|
| + base::Unretained(this)));
|
| + MessageLoop::current()->RunAllPending();
|
| + DCHECK(storage_ != NULL);
|
| +}
|
| +
|
| +void ExtensionSettingsStorageTest::TearDown() {
|
| + settings_ = NULL;
|
| + delete file_thread_;
|
| + delete ui_thread_;
|
| + delete ui_message_loop_;
|
| +}
|
| +
|
| +void ExtensionSettingsStorageTest::SetStorage(
|
| + ExtensionSettingsStorage* storage) {
|
| + storage_ = storage;
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWhenEmpty) {
|
| + storage_->Get(key1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(key2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) {
|
| + storage_->Set(key1_, *val1_, NEW_CALLBACK(dict1_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(key2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(NEW_CALLBACK(dict1_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) {
|
| + storage_->Set(*dict12_, NEW_CALLBACK(dict12_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list13_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list12_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(NEW_CALLBACK(dict12_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) {
|
| + storage_->Remove(key1_, NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) {
|
| + storage_->Set(key1_, *val1_, NEW_CALLBACK(dict1_));
|
| + MessageLoop::current()->RunAllPending();
|
| + storage_->Remove(key1_, NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(key2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list12_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) {
|
| + storage_->Set(*dict123_, NEW_CALLBACK(dict123_));
|
| + MessageLoop::current()->RunAllPending();
|
| + storage_->Remove(key3_, NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list13_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list12_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(NEW_CALLBACK(dict12_));
|
| +
|
| + storage_->Remove(*list2_, NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(key2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list2_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(NEW_CALLBACK(dict1_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, SetWhenOverwriting) {
|
| + DictionaryValue key1Val2;
|
| + key1Val2.Set(key1_, val2_->DeepCopy());
|
| + storage_->Set(key1_, *val2_, NEW_CALLBACK(&key1Val2));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Set(*dict12_, NEW_CALLBACK(dict12_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(key3_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list13_, NEW_CALLBACK(dict1_));
|
| + storage_->Get(*list12_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(*list123_, NEW_CALLBACK(dict12_));
|
| + storage_->Get(NEW_CALLBACK(dict12_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) {
|
| + storage_->Clear(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| +TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) {
|
| + storage_->Set(*dict12_, NEW_CALLBACK(dict12_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Clear(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + storage_->Get(key1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(*list1_, NEW_CALLBACK(emptyDict_));
|
| + storage_->Get(NEW_CALLBACK(emptyDict_));
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
|
|