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

Unified Diff: webkit/dom_storage/dom_storage_cached_area_unittest.cc

Issue 10450009: DomStorageCachedArea + DomStorageProxy interface and unittests. These classes aren't used yet. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « webkit/dom_storage/dom_storage_cached_area.cc ('k') | webkit/dom_storage/dom_storage_map.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/dom_storage/dom_storage_cached_area_unittest.cc
===================================================================
--- webkit/dom_storage/dom_storage_cached_area_unittest.cc (revision 0)
+++ webkit/dom_storage/dom_storage_cached_area_unittest.cc (revision 0)
@@ -0,0 +1,349 @@
+// Copyright (c) 2012 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 <list>
+
+#include "base/bind.h"
+#include "base/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/dom_storage/dom_storage_cached_area.h"
+#include "webkit/dom_storage/dom_storage_proxy.h"
+
+namespace dom_storage {
+
+namespace {
+// A mock implementation of the DomStorageProxy interface.
+class MockProxy : public DomStorageProxy {
+ public:
+ MockProxy() {
+ ResetObservations();
+ }
+
+ // DomStorageProxy interface for use by DomStorageCachedArea.
+
+ virtual void LoadArea(int connection_id, ValuesMap* values,
+ const CompletionCallback& callback) OVERRIDE {
+ pending_callbacks_.push_back(callback);
+ observed_load_area_ = true;
+ observed_connection_id_ = connection_id;
+ *values = load_area_return_values_;
+ }
+
+ virtual void SetItem(int connection_id, const string16& key,
+ const string16& value, const GURL& page_url,
+ const CompletionCallback& callback) OVERRIDE {
+ pending_callbacks_.push_back(callback);
+ observed_set_item_ = true;
+ observed_connection_id_ = connection_id;
+ observed_key_ = key;
+ observed_value_ = value;
+ observed_page_url_ = page_url;
+ }
+
+ virtual void RemoveItem(int connection_id, const string16& key,
+ const GURL& page_url,
+ const CompletionCallback& callback) OVERRIDE {
+ pending_callbacks_.push_back(callback);
+ observed_remove_item_ = true;
+ observed_connection_id_ = connection_id;
+ observed_key_ = key;
+ observed_page_url_ = page_url;
+ }
+
+ virtual void ClearArea(int connection_id,
+ const GURL& page_url,
+ const CompletionCallback& callback) OVERRIDE {
+ pending_callbacks_.push_back(callback);
+ observed_clear_area_ = true;
+ observed_connection_id_ = connection_id;
+ observed_page_url_ = page_url;
+ }
+
+ // Methods and members for use by test fixtures.
+
+ void ResetObservations() {
+ observed_load_area_ = false;
+ observed_set_item_ = false;
+ observed_remove_item_ = false;
+ observed_clear_area_ = false;
+ observed_connection_id_ = 0;
+ observed_key_.clear();
+ observed_value_.clear();
+ observed_page_url_ = GURL();
+ }
+
+ void CompleteAllPendingCallbacks() {
+ while (!pending_callbacks_.empty())
+ CompleteOnePendingCallback(true);
+ }
+
+ void CompleteOnePendingCallback(bool success) {
+ ASSERT_TRUE(!pending_callbacks_.empty());
+ pending_callbacks_.front().Run(success);
+ pending_callbacks_.pop_front();
+ }
+
+ typedef std::list<CompletionCallback> CallbackList;
+
+ ValuesMap load_area_return_values_;
+ CallbackList pending_callbacks_;
+ bool observed_load_area_;
+ bool observed_set_item_;
+ bool observed_remove_item_;
+ bool observed_clear_area_;
+ int observed_connection_id_;
+ string16 observed_key_;
+ string16 observed_value_;
+ GURL observed_page_url_;
+
+ private:
+ virtual ~MockProxy() {}
+};
+} // namespace
+
+class DomStorageCachedAreaTest : public testing::Test {
+ public:
+ DomStorageCachedAreaTest()
+ : kNamespaceId(10),
+ kOrigin("http://dom_storage/"),
+ kKey(ASCIIToUTF16("key")),
+ kValue(ASCIIToUTF16("value")),
+ kPageUrl("http://dom_storage/page") {
+ }
+
+ const int64 kNamespaceId;
+ const GURL kOrigin;
+ const string16 kKey;
+ const string16 kValue;
+ const GURL kPageUrl;
+
+ virtual void SetUp() {
+ mock_proxy_ = new MockProxy();
+ }
+
+ bool IsPrimed(DomStorageCachedArea* cached_area) {
+ return cached_area->map_.get();
+ }
+
+ bool IsIgnoringAllMutations(DomStorageCachedArea* cached_area) {
+ return cached_area->ignore_all_mutations_;
+ }
+
+ bool IsIgnoringKeyMutations(DomStorageCachedArea* cached_area,
+ const string16& key) {
+ return cached_area->should_ignore_key_mutation(key);
+ }
+
+ void ResetAll(DomStorageCachedArea* cached_area) {
+ cached_area->Reset();
+ mock_proxy_->ResetObservations();
+ mock_proxy_->pending_callbacks_.clear();
+ }
+
+ void ResetCacheOnly(DomStorageCachedArea* cached_area) {
+ cached_area->Reset();
+ }
+
+ protected:
+ scoped_refptr<MockProxy> mock_proxy_;
+};
+
+TEST_F(DomStorageCachedAreaTest, Basics) {
+ EXPECT_TRUE(mock_proxy_->HasOneRef());
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+ EXPECT_EQ(kNamespaceId, cached_area->namespace_id());
+ EXPECT_EQ(kOrigin, cached_area->origin());
+ EXPECT_FALSE(mock_proxy_->HasOneRef());
+ cached_area->ApplyMutation(NullableString16(kKey, false),
+ NullableString16(kValue, false));
+ EXPECT_FALSE(IsPrimed(cached_area));
+
+ ResetAll(cached_area);
+ EXPECT_EQ(kNamespaceId, cached_area->namespace_id());
+ EXPECT_EQ(kOrigin, cached_area->origin());
+
+ const int kConnectionId = 1;
+ EXPECT_EQ(0u, cached_area->GetLength(kConnectionId));
+ EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
+ EXPECT_EQ(1u, cached_area->GetLength(kConnectionId));
+ EXPECT_EQ(kKey, cached_area->GetKey(kConnectionId, 0).string());
+ EXPECT_EQ(kValue, cached_area->GetItem(kConnectionId, kKey).string());
+ cached_area->RemoveItem(kConnectionId, kKey, kPageUrl);
+ EXPECT_EQ(0u, cached_area->GetLength(kConnectionId));
+}
+
+TEST_F(DomStorageCachedAreaTest, Getters) {
+ const int kConnectionId = 7;
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+
+ // GetLength, we expect to see one call to load in the proxy.
+ EXPECT_FALSE(IsPrimed(cached_area));
+ EXPECT_EQ(0u, cached_area->GetLength(kConnectionId));
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(1u, mock_proxy_->pending_callbacks_.size());
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+ mock_proxy_->CompleteAllPendingCallbacks();
+ EXPECT_FALSE(IsIgnoringAllMutations(cached_area));
+
+ // GetKey, expect the one call to load.
+ ResetAll(cached_area);
+ EXPECT_FALSE(IsPrimed(cached_area));
+ EXPECT_TRUE(cached_area->GetKey(kConnectionId, 2).is_null());
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(1u, mock_proxy_->pending_callbacks_.size());
+
+ // GetItem, ditto.
+ ResetAll(cached_area);
+ EXPECT_FALSE(IsPrimed(cached_area));
+ EXPECT_TRUE(cached_area->GetItem(kConnectionId, kKey).is_null());
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(1u, mock_proxy_->pending_callbacks_.size());
+}
+
+TEST_F(DomStorageCachedAreaTest, Setters) {
+ const int kConnectionId = 7;
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+
+ // SetItem, we expect a call to load followed by a call to set item
+ // in the proxy.
+ EXPECT_FALSE(IsPrimed(cached_area));
+ EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_TRUE(mock_proxy_->observed_set_item_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(kPageUrl, mock_proxy_->observed_page_url_);
+ EXPECT_EQ(kKey, mock_proxy_->observed_key_);
+ EXPECT_EQ(kValue, mock_proxy_->observed_value_);
+ EXPECT_EQ(2u, mock_proxy_->pending_callbacks_.size());
+
+ // Clear, we expect a just the one call to clear in the proxy since
+ // there's no need to load the data prior to deleting it.
+ ResetAll(cached_area);
+ EXPECT_FALSE(IsPrimed(cached_area));
+ cached_area->Clear(kConnectionId, kPageUrl);
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_clear_area_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(kPageUrl, mock_proxy_->observed_page_url_);
+ EXPECT_EQ(1u, mock_proxy_->pending_callbacks_.size());
+
+ // RemoveItem with nothing to remove, expect just one call to load.
+ ResetAll(cached_area);
+ EXPECT_FALSE(IsPrimed(cached_area));
+ cached_area->RemoveItem(kConnectionId, kKey, kPageUrl);
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_FALSE(mock_proxy_->observed_remove_item_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(1u, mock_proxy_->pending_callbacks_.size());
+
+ // RemoveItem with something to remove, expect a call to load followed
+ // by a call to remove.
+ ResetAll(cached_area);
+ mock_proxy_->load_area_return_values_[kKey] = NullableString16(kValue, false);
+ EXPECT_FALSE(IsPrimed(cached_area));
+ cached_area->RemoveItem(kConnectionId, kKey, kPageUrl);
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(mock_proxy_->observed_load_area_);
+ EXPECT_TRUE(mock_proxy_->observed_remove_item_);
+ EXPECT_EQ(kConnectionId, mock_proxy_->observed_connection_id_);
+ EXPECT_EQ(kPageUrl, mock_proxy_->observed_page_url_);
+ EXPECT_EQ(kKey, mock_proxy_->observed_key_);
+ EXPECT_EQ(2u, mock_proxy_->pending_callbacks_.size());
+}
+
+TEST_F(DomStorageCachedAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
+ const int kConnectionId = 7;
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+ EXPECT_TRUE(cached_area->GetItem(kConnectionId, kKey).is_null());
+ EXPECT_TRUE(IsPrimed(cached_area));
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+
+ // Before load completion, the mutation should be ignored.
+ cached_area->ApplyMutation(NullableString16(kKey, false),
+ NullableString16(kValue, false));
+ EXPECT_TRUE(cached_area->GetItem(kConnectionId, kKey).is_null());
+
+ // Call the load completion callback.
+ mock_proxy_->CompleteOnePendingCallback(true);
+ EXPECT_FALSE(IsIgnoringAllMutations(cached_area));
+
+ // Verify that mutations are now applied.
+ cached_area->ApplyMutation(NullableString16(kKey, false),
+ NullableString16(kValue, false));
+ EXPECT_EQ(kValue, cached_area->GetItem(kConnectionId, kKey).string());
+}
+
+TEST_F(DomStorageCachedAreaTest, MutationsAreIgnoredUntilClearCompletion) {
+ const int kConnectionId = 4;
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+ cached_area->Clear(kConnectionId, kPageUrl);
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+ mock_proxy_->CompleteOnePendingCallback(true);
+ EXPECT_FALSE(IsIgnoringAllMutations(cached_area));
+
+ // Verify that calling Clear twice works as expected, the first
+ // completion callback should have been cancelled.
+ ResetCacheOnly(cached_area);
+ cached_area->Clear(kConnectionId, kPageUrl);
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+ cached_area->Clear(kConnectionId, kPageUrl);
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+ mock_proxy_->CompleteOnePendingCallback(true);
+ EXPECT_TRUE(IsIgnoringAllMutations(cached_area));
+ mock_proxy_->CompleteOnePendingCallback(true);
+ EXPECT_FALSE(IsIgnoringAllMutations(cached_area));
+}
+
+TEST_F(DomStorageCachedAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
+ const int kConnectionId = 8;
+ scoped_refptr<DomStorageCachedArea> cached_area =
+ new DomStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_);
+
+ // SetItem
+ EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
+ mock_proxy_->CompleteOnePendingCallback(true); // load completion
+ EXPECT_FALSE(IsIgnoringAllMutations(cached_area));
+ EXPECT_TRUE(IsIgnoringKeyMutations(cached_area, kKey));
+ cached_area->ApplyMutation(NullableString16(kKey, false),
+ NullableString16(true));
+ EXPECT_EQ(kValue, cached_area->GetItem(kConnectionId, kKey).string());
+ mock_proxy_->CompleteOnePendingCallback(true); // set completion
+ EXPECT_FALSE(IsIgnoringKeyMutations(cached_area, kKey));
+
+ // RemoveItem
+ cached_area->RemoveItem(kConnectionId, kKey, kPageUrl);
+ EXPECT_TRUE(IsIgnoringKeyMutations(cached_area, kKey));
+ mock_proxy_->CompleteOnePendingCallback(true); // remove completion
+ EXPECT_FALSE(IsIgnoringKeyMutations(cached_area, kKey));
+
+ // Multiple mutations to the same key.
+ EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
+ cached_area->RemoveItem(kConnectionId, kKey, kPageUrl);
+ EXPECT_TRUE(IsIgnoringKeyMutations(cached_area, kKey));
+ mock_proxy_->CompleteOnePendingCallback(true); // set completion
+ EXPECT_TRUE(IsIgnoringKeyMutations(cached_area, kKey));
+ mock_proxy_->CompleteOnePendingCallback(true); // remove completion
+ EXPECT_FALSE(IsIgnoringKeyMutations(cached_area, kKey));
+
+ // A failed set item operation should Reset the cache.
+ EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
+ EXPECT_TRUE(IsIgnoringKeyMutations(cached_area, kKey));
+ mock_proxy_->CompleteOnePendingCallback(false);
+ EXPECT_FALSE(IsPrimed(cached_area));
+}
+
+} // namespace dom_storage
Property changes on: webkit\dom_storage\dom_storage_cached_area_unittest.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « webkit/dom_storage/dom_storage_cached_area.cc ('k') | webkit/dom_storage/dom_storage_map.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698