| // 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/ui/views/info_bubble.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| typedef testing::Test InfoBubbleTest; |
| |
| class TestBorderContents : public BorderContents { |
| public: |
| TestBorderContents() {} |
| |
| void set_monitor_bounds(const gfx::Rect& bounds) { |
| monitor_bounds_ = bounds; |
| } |
| |
| BubbleBorder* bubble_border() const { return bubble_border_; } |
| |
| protected: |
| virtual gfx::Rect GetMonitorBounds(const gfx::Rect& rect) { |
| return monitor_bounds_; |
| } |
| |
| private: |
| gfx::Rect monitor_bounds_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestBorderContents); |
| }; |
| |
| // Tests that the arrow is moved appropriately when the info-bubble does not fit |
| // the screen. |
| TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBounds) { |
| TestBorderContents border_contents; |
| border_contents.Init(); |
| |
| // Test that the info bubble displays normally when it fits. |
| gfx::Rect contents_bounds; |
| gfx::Rect window_bounds; |
| border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| // The arrow shouldn't have changed from TOP_LEFT. |
| BubbleBorder::ArrowLocation arrow_location = |
| border_contents.bubble_border()->arrow_location(); |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_GT(window_bounds.x(), 100); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on left. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_RIGHT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to TOP_LEFT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_GT(window_bounds.x(), 100); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on left or top. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::BOTTOM_RIGHT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to TOP_LEFT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_GT(window_bounds.x(), 100); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on top. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::BOTTOM_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to TOP_LEFT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_GT(window_bounds.x(), 100); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on top and right. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(900, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::BOTTOM_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to TOP_RIGHT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_LT(window_bounds.x(), 900 + 50 - 500); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on right. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(900, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to TOP_RIGHT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_LT(window_bounds.x(), 900 + 50 - 500); |
| EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| |
| // Test bubble not fitting on bottom and right. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(900, 900, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to BOTTOM_RIGHT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| EXPECT_LT(window_bounds.x(), 900 + 50 - 500); |
| EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate |
| // for arrow height. |
| |
| // Test bubble not fitting at the bottom. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 900, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to BOTTOM_LEFT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| // The window should be right aligned with the position_relative_to. |
| EXPECT_LT(window_bounds.x(), 900 + 50 - 500); |
| EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate |
| // for arrow height. |
| |
| // Test bubble not fitting at the bottom and left. |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 900, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_RIGHT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| arrow_location = border_contents.bubble_border()->arrow_location(); |
| // The arrow should have changed to BOTTOM_LEFT. |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| // The window should be right aligned with the position_relative_to. |
| EXPECT_LT(window_bounds.x(), 900 + 50 - 500); |
| EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate |
| // for arrow height. |
| } |
| |
| // Tests that the arrow is not moved when the info-bubble does not fit the |
| // screen but moving it would make matter worse. |
| TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBoundsDontMoveArrow) { |
| TestBorderContents border_contents; |
| border_contents.Init(); |
| gfx::Rect contents_bounds; |
| gfx::Rect window_bounds; |
| border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(400, 100, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_LEFT, |
| false, // |allow_bubble_offscreen| |
| gfx::Size(500, 700), // |contents_size| |
| &contents_bounds, &window_bounds); |
| |
| // The arrow should not have changed, as it would make it the bubble even more |
| // offscreen. |
| BubbleBorder::ArrowLocation arrow_location = |
| border_contents.bubble_border()->arrow_location(); |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| } |
| |
| // Test that the 'allow offscreen' prevents the bubble from moving. |
| TEST_F(InfoBubbleTest, BorderContentsSizeAndGetBoundsAllowOffscreen) { |
| TestBorderContents border_contents; |
| border_contents.Init(); |
| gfx::Rect contents_bounds; |
| gfx::Rect window_bounds; |
| border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); |
| border_contents.SizeAndGetBounds( |
| gfx::Rect(100, 900, 50, 50), // |position_relative_to| |
| BubbleBorder::TOP_RIGHT, |
| true, // |allow_bubble_offscreen| |
| gfx::Size(500, 500), // |contents_size| |
| &contents_bounds, &window_bounds); |
| |
| // The arrow should not have changed (eventhough the bubble does not fit). |
| BubbleBorder::ArrowLocation arrow_location = |
| border_contents.bubble_border()->arrow_location(); |
| EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); |
| EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); |
| EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); |
| // The coordinates should be pointing to 'positive relative to' from |
| // TOP_RIGHT. |
| EXPECT_LT(window_bounds.x(), 100 + 50 - 500); |
| EXPECT_GT(window_bounds.y(), 900 + 50 - 10); // -10 to roughly compensate for |
| // arrow overlap. |
| } |