Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2703)

Unified Diff: chrome/browser/extensions/extension_settings_storage_unittest.cc

Issue 7189029: Implement an initial extension settings API. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: dgrogan comments #2, mihai comments #1 Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..1f01407904c81014681c1485730007896edb8456
--- /dev/null
+++ b/chrome/browser/extensions/extension_settings_storage_unittest.cc
@@ -0,0 +1,398 @@
+// 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 macro to get the __LINE__ expansion.
+// Undefined at the end of the file.
+#define newCallback(expected) (new AssertEqualsCallback((expected), __LINE__))
Matt Perry 2011/06/23 18:11:45 style should be NEW_CALLBACK for a macro.
not at google - send to devlin 2011/06/27 08:51:02 Done.
+
+namespace {
+
+// Callback from GetStorage() that places the new storage in a given location.
+class GetStorageCallback : public ExtensionSettings::Callback {
+ public:
+ explicit GetStorageCallback(ExtensionSettingsStorage** storagePtr)
+ : storagePtr_(storagePtr) {
+ *storagePtr = NULL;
+ }
+
+ ~GetStorageCallback() {}
+
+ void Run(ExtensionSettingsStorage* storage) {
+ DCHECK(*storagePtr_ == NULL);
+ *storagePtr_ = storage;
+ }
+
+ private:
+ ExtensionSettingsStorage** storagePtr_;
+};
+
+// 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_);
+ }
+
+ void OnSuccess(DictionaryValue* actual) {
+ 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) {
+ 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_;
+};
+
+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;
Matt Perry 2011/06/23 18:11:45 valgrind will complain about all these values bein
not at google - send to devlin 2011/06/27 08:51:02 Done.
+ 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();
+ // 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("", &temp_dir);
+ settings_ = new ExtensionSettings(temp_dir);
+
+ storage_ = NULL;
+ (GetParam())(settings_, "fakeExtension", new GetStorageCallback(&storage_));
+ MessageLoop::current()->RunAllPending();
+ DCHECK(storage_ != NULL);
+}
+
+void ExtensionSettingsStorageTest::TearDown() {
+ delete settings_;
+ 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(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) {
+ storage_->Set(key1(), *val1(), newCallback(dict1()));
+ MessageLoop::current()->RunAllPending();
+
+ 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(newCallback(dict1()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) {
+ storage_->Set(*dict12(), newCallback(dict12()));
+ MessageLoop::current()->RunAllPending();
+
+ 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()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) {
+ storage_->Remove(key1(), newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Get(key1(), newCallback(emptyDict()));
+ storage_->Get(*list1(), newCallback(emptyDict()));
+ storage_->Get(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) {
+ storage_->Set(key1(), *val1(), newCallback(dict1()));
+ MessageLoop::current()->RunAllPending();
+ storage_->Remove(key1(), newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Get(key1(), newCallback(emptyDict()));
+ storage_->Get(key2(), newCallback(emptyDict()));
+ storage_->Get(*list1(), newCallback(emptyDict()));
+ storage_->Get(*list12(), newCallback(emptyDict()));
+ storage_->Get(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) {
+ storage_->Set(*dict123(), newCallback(dict123()));
+ MessageLoop::current()->RunAllPending();
+ storage_->Remove(key3(), newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ 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(), newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ 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(newCallback(dict1()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, SetWhenOverwriting) {
+ DictionaryValue key1Val2;
+ key1Val2.Set(key1(), val2()->DeepCopy());
+ storage_->Set(key1(), *val2(), newCallback(&key1Val2));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Set(*dict12(), newCallback(dict12()));
+ MessageLoop::current()->RunAllPending();
+
+ 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()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) {
+ storage_->Clear(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Get(key1(), newCallback(emptyDict()));
+ storage_->Get(*list1(), newCallback(emptyDict()));
+ storage_->Get(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+}
+
+TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) {
+ storage_->Set(*dict12(), newCallback(dict12()));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Clear(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+
+ storage_->Get(key1(), newCallback(emptyDict()));
+ storage_->Get(*list1(), newCallback(emptyDict()));
+ storage_->Get(newCallback(emptyDict()));
+ MessageLoop::current()->RunAllPending();
+}
+
+#undef newCallback

Powered by Google App Engine
This is Rietveld 408576698