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

Unified Diff: components/bubble/bubble_manager_unittest.cc

Issue 1251633002: Add BubbleManager to manage bubbles and ChromeBubbleManager for events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: gn nit Created 5 years, 4 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 | « components/bubble/bubble_manager.cc ('k') | components/bubble/bubble_ui.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/bubble/bubble_manager_unittest.cc
diff --git a/components/bubble/bubble_manager_unittest.cc b/components/bubble/bubble_manager_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f18c678985d83dfb47f7d9d274b521f915cda992
--- /dev/null
+++ b/components/bubble/bubble_manager_unittest.cc
@@ -0,0 +1,347 @@
+// Copyright 2015 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 "components/bubble/bubble_manager.h"
+
+#include "components/bubble/bubble_controller.h"
+#include "components/bubble/bubble_delegate.h"
+#include "components/bubble/bubble_ui.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class MockBubbleUI : public BubbleUI {
+ public:
+ MockBubbleUI() {}
+ ~MockBubbleUI() override { Destroyed(); }
+
+ MOCK_METHOD0(Show, void());
+ MOCK_METHOD0(Close, void());
+ MOCK_METHOD0(UpdateAnchorPosition, void());
+
+ // To verify destructor call.
+ MOCK_METHOD0(Destroyed, void());
+};
+
+class MockBubbleDelegate : public BubbleDelegate {
+ public:
+ MockBubbleDelegate() {}
+ ~MockBubbleDelegate() override { Destroyed(); }
+
+ // Default bubble shows UI and closes when asked to close.
+ static scoped_ptr<MockBubbleDelegate> Default();
+
+ // Stubborn bubble shows UI and doesn't want to close.
+ static scoped_ptr<MockBubbleDelegate> Stubborn();
+
+ MOCK_METHOD1(ShouldClose, bool(BubbleCloseReason reason));
+
+ // A scoped_ptr can't be returned in MOCK_METHOD.
+ MOCK_METHOD0(BuildBubbleUIMock, BubbleUI*());
+ scoped_ptr<BubbleUI> BuildBubbleUI() override {
+ return make_scoped_ptr(BuildBubbleUIMock());
+ }
+
+ // To verify destructor call.
+ MOCK_METHOD0(Destroyed, void());
+};
+
+// static
+scoped_ptr<MockBubbleDelegate> MockBubbleDelegate::Default() {
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(new MockBubbleUI));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::Return(true));
+ return make_scoped_ptr(delegate);
+}
+
+// static
+scoped_ptr<MockBubbleDelegate> MockBubbleDelegate::Stubborn() {
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(new MockBubbleUI));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillRepeatedly(testing::Return(false));
+ return make_scoped_ptr(delegate);
+}
+
+// Helper class used to test chaining another bubble.
+class DelegateChainHelper {
+ public:
+ DelegateChainHelper(BubbleManager* manager,
+ scoped_ptr<BubbleDelegate> next_delegate);
+
+ // Will show the bubble in |next_delegate_|.
+ void Chain() { manager_->ShowBubble(next_delegate_.Pass()); }
+
+ // True if the bubble was taken by the bubble manager.
+ bool BubbleWasTaken() { return !next_delegate_; }
+
+ private:
+ BubbleManager* manager_; // Weak.
+ scoped_ptr<BubbleDelegate> next_delegate_;
+};
+
+DelegateChainHelper::DelegateChainHelper(
+ BubbleManager* manager,
+ scoped_ptr<BubbleDelegate> next_delegate)
+ : manager_(manager), next_delegate_(next_delegate.Pass()) {}
+
+class BubbleManagerTest : public testing::Test {
+ public:
+ BubbleManagerTest();
+ ~BubbleManagerTest() override {}
+
+ void SetUp() override;
+ void TearDown() override;
+
+ protected:
+ scoped_ptr<BubbleManager> manager_;
+};
+
+BubbleManagerTest::BubbleManagerTest() {}
+
+void BubbleManagerTest::SetUp() {
+ testing::Test::SetUp();
+ manager_.reset(new BubbleManager);
+}
+
+void BubbleManagerTest::TearDown() {
+ manager_.reset();
+ testing::Test::TearDown();
+}
+
+TEST_F(BubbleManagerTest, ManagerShowsBubbleUI) {
+ // Manager will delete bubble_ui.
+ MockBubbleUI* bubble_ui = new MockBubbleUI;
+ EXPECT_CALL(*bubble_ui, Destroyed());
+ EXPECT_CALL(*bubble_ui, Show());
+ EXPECT_CALL(*bubble_ui, Close());
+ EXPECT_CALL(*bubble_ui, UpdateAnchorPosition()).Times(0);
+
+ // Manager will delete delegate.
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, Destroyed());
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(bubble_ui));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::Return(true));
+
+ manager_->ShowBubble(make_scoped_ptr(delegate));
+}
+
+TEST_F(BubbleManagerTest, ManagerUpdatesBubbleUI) {
+ // Manager will delete bubble_ui.
+ MockBubbleUI* bubble_ui = new MockBubbleUI;
+ EXPECT_CALL(*bubble_ui, Destroyed());
+ EXPECT_CALL(*bubble_ui, Show());
+ EXPECT_CALL(*bubble_ui, Close());
+ EXPECT_CALL(*bubble_ui, UpdateAnchorPosition());
+
+ // Manager will delete delegate.
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, Destroyed());
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(bubble_ui));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::Return(true));
+
+ manager_->ShowBubble(make_scoped_ptr(delegate));
+ manager_->UpdateAllBubbleAnchors();
+}
+
+TEST_F(BubbleManagerTest, CloseOnReferenceInvalidatesReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+
+ ASSERT_TRUE(ref->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST));
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseOnStubbornReferenceDoesNotInvalidate) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ ASSERT_FALSE(ref->CloseBubble(BUBBLE_CLOSE_FOCUS_LOST));
+
+ ASSERT_TRUE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseInvalidatesReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+
+ ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FOCUS_LOST));
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseAllInvalidatesReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, DestroyInvalidatesReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+
+ manager_.reset();
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseInvalidatesStubbornReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseAllInvalidatesStubbornReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FORCED);
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, DestroyInvalidatesStubbornReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ manager_.reset();
+
+ ASSERT_FALSE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseDoesNotInvalidateStubbornReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ ASSERT_FALSE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FOCUS_LOST));
+
+ ASSERT_TRUE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseAllDoesNotInvalidateStubbornReference) {
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
+
+ ASSERT_TRUE(ref);
+}
+
+TEST_F(BubbleManagerTest, CloseAllInvalidatesMixAppropriately) {
+ BubbleReference stubborn_ref1 =
+ manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+ BubbleReference normal_ref1 =
+ manager_->ShowBubble(MockBubbleDelegate::Default());
+ BubbleReference stubborn_ref2 =
+ manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+ BubbleReference normal_ref2 =
+ manager_->ShowBubble(MockBubbleDelegate::Default());
+ BubbleReference stubborn_ref3 =
+ manager_->ShowBubble(MockBubbleDelegate::Stubborn());
+ BubbleReference normal_ref3 =
+ manager_->ShowBubble(MockBubbleDelegate::Default());
+
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
+
+ ASSERT_TRUE(stubborn_ref1);
+ ASSERT_TRUE(stubborn_ref2);
+ ASSERT_TRUE(stubborn_ref3);
+ ASSERT_FALSE(normal_ref1);
+ ASSERT_FALSE(normal_ref2);
+ ASSERT_FALSE(normal_ref3);
+}
+
+TEST_F(BubbleManagerTest, UpdateAllShouldWorkWithoutBubbles) {
+ // Manager shouldn't crash if bubbles have never been added.
+ manager_->UpdateAllBubbleAnchors();
+
+ // Add a bubble and close it.
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+ ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
+
+ // Bubble should NOT get an update event because it's already closed.
+ manager_->UpdateAllBubbleAnchors();
+}
+
+TEST_F(BubbleManagerTest, CloseAllShouldWorkWithoutBubbles) {
+ // Manager shouldn't crash if bubbles have never been added.
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
+
+ // Add a bubble and close it.
+ BubbleReference ref = manager_->ShowBubble(MockBubbleDelegate::Default());
+ ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
+
+ // Bubble should NOT get a close event because it's already closed.
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FOCUS_LOST);
+}
+
+TEST_F(BubbleManagerTest, AllowBubbleChainingOnClose) {
+ scoped_ptr<BubbleDelegate> chained_delegate = MockBubbleDelegate::Default();
+ DelegateChainHelper chain_helper(manager_.get(), chained_delegate.Pass());
+
+ // Manager will delete delegate.
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(new MockBubbleUI));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
+ &chain_helper, &DelegateChainHelper::Chain),
+ testing::Return(true)));
+
+ BubbleReference ref = manager_->ShowBubble(make_scoped_ptr(delegate));
+ ASSERT_TRUE(manager_->CloseBubble(ref, BUBBLE_CLOSE_FORCED));
+
+ ASSERT_TRUE(chain_helper.BubbleWasTaken());
+}
+
+TEST_F(BubbleManagerTest, AllowBubbleChainingOnCloseAll) {
+ scoped_ptr<BubbleDelegate> chained_delegate = MockBubbleDelegate::Default();
+ DelegateChainHelper chain_helper(manager_.get(), chained_delegate.Pass());
+
+ // Manager will delete delegate.
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(new MockBubbleUI));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
+ &chain_helper, &DelegateChainHelper::Chain),
+ testing::Return(true)));
+
+ manager_->ShowBubble(make_scoped_ptr(delegate));
+ manager_->CloseAllBubbles(BUBBLE_CLOSE_FORCED);
+
+ ASSERT_TRUE(chain_helper.BubbleWasTaken());
+}
+
+TEST_F(BubbleManagerTest, BubblesDoNotChainOnDestroy) {
+ // Manager will delete delegate.
+ MockBubbleDelegate* chained_delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*chained_delegate, BuildBubbleUIMock()).Times(0);
+ EXPECT_CALL(*chained_delegate, ShouldClose(testing::_)).Times(0);
+
+ DelegateChainHelper chain_helper(manager_.get(),
+ make_scoped_ptr(chained_delegate));
+
+ // Manager will delete delegate.
+ MockBubbleDelegate* delegate = new MockBubbleDelegate;
+ EXPECT_CALL(*delegate, BuildBubbleUIMock())
+ .WillOnce(testing::Return(new MockBubbleUI));
+ EXPECT_CALL(*delegate, ShouldClose(testing::_))
+ .WillOnce(testing::DoAll(testing::InvokeWithoutArgs(
+ &chain_helper, &DelegateChainHelper::Chain),
+ testing::Return(true)));
+
+ manager_->ShowBubble(make_scoped_ptr(delegate));
+ manager_.reset();
+
+ // The manager will take the bubble, but not show it.
+ ASSERT_TRUE(chain_helper.BubbleWasTaken());
+}
+
+} // namespace
« no previous file with comments | « components/bubble/bubble_manager.cc ('k') | components/bubble/bubble_ui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698