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..8096e21ccd355ba7511b80ddff6781850c650bac |
--- /dev/null |
+++ b/chrome/browser/extensions/extension_settings_storage_unittest.cc |
@@ -0,0 +1,289 @@ |
+// 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. |
+ |
+#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; |
+ if (expected_ == NULL) { |
+ ASSERT_TRUE(actual == NULL) << "Values are different:\n" << |
+ "Line: " << line_ << "\n" << |
+ "Expected: NULL\n" << |
+ "Got: " << GetJson(actual); |
+ } else { |
+ 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_.reset(Value::CreateStringValue(key1_ + "Value")); |
+ val2_.reset(Value::CreateStringValue(key2_ + "Value")); |
+ val3_.reset(Value::CreateStringValue(key3_ + "Value")); |
+ |
+ emptyList_.reset(new ListValue()); |
+ |
+ list1_.reset(new ListValue()); |
+ list1_->Append(Value::CreateStringValue(key1_)); |
+ |
+ list2_.reset(new ListValue()); |
+ list2_->Append(Value::CreateStringValue(key2_)); |
+ |
+ list12_.reset(new ListValue()); |
+ list12_->Append(Value::CreateStringValue(key1_)); |
+ list12_->Append(Value::CreateStringValue(key2_)); |
+ |
+ list13_.reset(new ListValue()); |
+ list13_->Append(Value::CreateStringValue(key1_)); |
+ list13_->Append(Value::CreateStringValue(key3_)); |
+ |
+ list123_.reset(new ListValue()); |
+ list123_->Append(Value::CreateStringValue(key1_)); |
+ list123_->Append(Value::CreateStringValue(key2_)); |
+ list123_->Append(Value::CreateStringValue(key3_)); |
+ |
+ emptyDict_.reset(new DictionaryValue()); |
+ |
+ dict1_.reset(new DictionaryValue()); |
+ dict1_->Set(key1_, val1_->DeepCopy()); |
+ |
+ dict12_.reset(new DictionaryValue()); |
+ dict12_->Set(key1_, val1_->DeepCopy()); |
+ dict12_->Set(key2_, val2_->DeepCopy()); |
+ |
+ dict123_.reset(new DictionaryValue()); |
+ dict123_->Set(key1_, val1_->DeepCopy()); |
+ dict123_->Set(key2_, val2_->DeepCopy()); |
+ dict123_->Set(key3_, val3_->DeepCopy()); |
+} |
+ |
+ExtensionSettingsStorageTest::~ExtensionSettingsStorageTest() { |
+} |
+ |
+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_.get())); |
+ storage_->Get(key2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(NEW_CALLBACK(emptyDict_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) { |
+ storage_->Set(key1_, *val1_, NEW_CALLBACK(dict1_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(key2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(NEW_CALLBACK(dict1_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) { |
+ storage_->Set(*dict12_, NEW_CALLBACK(dict12_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list13_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list12_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(NEW_CALLBACK(dict12_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) { |
+ storage_->Remove(key1_, NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(NEW_CALLBACK(emptyDict_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) { |
+ storage_->Set(key1_, *val1_, NEW_CALLBACK(dict1_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ storage_->Remove(key1_, NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(key2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list12_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(NEW_CALLBACK(emptyDict_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) { |
+ storage_->Set(*dict123_, NEW_CALLBACK(dict123_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ storage_->Remove(key3_, NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list13_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list12_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(NEW_CALLBACK(dict12_.get())); |
+ |
+ storage_->Remove(*list2_, NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(key2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list2_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(NEW_CALLBACK(dict1_.get())); |
+ 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_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(key3_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*emptyList_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list13_, NEW_CALLBACK(dict1_.get())); |
+ storage_->Get(*list12_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(*list123_, NEW_CALLBACK(dict12_.get())); |
+ storage_->Get(NEW_CALLBACK(dict12_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) { |
+ storage_->Clear(NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(NEW_CALLBACK(emptyDict_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |
+ |
+TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) { |
+ storage_->Set(*dict12_, NEW_CALLBACK(dict12_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Clear(NEW_CALLBACK(NULL)); |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ storage_->Get(key1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(*list1_, NEW_CALLBACK(emptyDict_.get())); |
+ storage_->Get(NEW_CALLBACK(emptyDict_.get())); |
+ MessageLoop::current()->RunAllPending(); |
+} |