1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/bubble/border_contents.h" 6#include "testing/gtest/include/gtest/gtest.h" 7 8typedef testing::Test BorderContentsTest; 9 10class TestBorderContents : public BorderContents { 11 public: 12 TestBorderContents() {} 13 14 void set_monitor_bounds(const gfx::Rect& bounds) { 15 monitor_bounds_ = bounds; 16 } 17 18 BubbleBorder* bubble_border() const { return bubble_border_; } 19 20 protected: 21 virtual gfx::Rect GetMonitorBounds(const gfx::Rect& rect) { 22 return monitor_bounds_; 23 } 24 25 private: 26 gfx::Rect monitor_bounds_; 27 28 DISALLOW_COPY_AND_ASSIGN(TestBorderContents); 29}; 30 31// Tests that the arrow is moved appropriately when the info-bubble does not fit 32// the screen. 33TEST_F(BorderContentsTest, BorderContentsSizeAndGetBounds) { 34 TestBorderContents border_contents; 35 border_contents.Init(); 36 37 // Test that the info bubble displays normally when it fits. 38 gfx::Rect contents_bounds; 39 gfx::Rect window_bounds; 40 border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); 41 border_contents.SizeAndGetBounds( 42 gfx::Rect(100, 100, 50, 50), // |position_relative_to| 43 BubbleBorder::TOP_LEFT, 44 false, // |allow_bubble_offscreen| 45 gfx::Size(500, 500), // |contents_size| 46 &contents_bounds, &window_bounds); 47 // The arrow shouldn't have changed from TOP_LEFT. 48 BubbleBorder::ArrowLocation arrow_location = 49 border_contents.bubble_border()->arrow_location(); 50 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 51 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 52 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 53 EXPECT_GT(window_bounds.x(), 100); 54 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 55 // arrow overlap. 56 57 // Test bubble not fitting on left. 58 border_contents.SizeAndGetBounds( 59 gfx::Rect(100, 100, 50, 50), // |position_relative_to| 60 BubbleBorder::TOP_RIGHT, 61 false, // |allow_bubble_offscreen| 62 gfx::Size(500, 500), // |contents_size| 63 &contents_bounds, &window_bounds); 64 arrow_location = border_contents.bubble_border()->arrow_location(); 65 // The arrow should have changed to TOP_LEFT. 66 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 67 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 68 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 69 EXPECT_GT(window_bounds.x(), 100); 70 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 71 // arrow overlap. 72 73 // Test bubble not fitting on left or top. 74 border_contents.SizeAndGetBounds( 75 gfx::Rect(100, 100, 50, 50), // |position_relative_to| 76 BubbleBorder::BOTTOM_RIGHT, 77 false, // |allow_bubble_offscreen| 78 gfx::Size(500, 500), // |contents_size| 79 &contents_bounds, &window_bounds); 80 arrow_location = border_contents.bubble_border()->arrow_location(); 81 // The arrow should have changed to TOP_LEFT. 82 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 83 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 84 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 85 EXPECT_GT(window_bounds.x(), 100); 86 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 87 // arrow overlap. 88 89 // Test bubble not fitting on top. 90 border_contents.SizeAndGetBounds( 91 gfx::Rect(100, 100, 50, 50), // |position_relative_to| 92 BubbleBorder::BOTTOM_LEFT, 93 false, // |allow_bubble_offscreen| 94 gfx::Size(500, 500), // |contents_size| 95 &contents_bounds, &window_bounds); 96 arrow_location = border_contents.bubble_border()->arrow_location(); 97 // The arrow should have changed to TOP_LEFT. 98 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 99 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 100 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 101 EXPECT_GT(window_bounds.x(), 100); 102 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 103 // arrow overlap. 104 105 // Test bubble not fitting on top and right. 106 border_contents.SizeAndGetBounds( 107 gfx::Rect(900, 100, 50, 50), // |position_relative_to| 108 BubbleBorder::BOTTOM_LEFT, 109 false, // |allow_bubble_offscreen| 110 gfx::Size(500, 500), // |contents_size| 111 &contents_bounds, &window_bounds); 112 arrow_location = border_contents.bubble_border()->arrow_location(); 113 // The arrow should have changed to TOP_RIGHT. 114 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 115 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 116 EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); 117 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); 118 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 119 // arrow overlap. 120 121 // Test bubble not fitting on right. 122 border_contents.SizeAndGetBounds( 123 gfx::Rect(900, 100, 50, 50), // |position_relative_to| 124 BubbleBorder::TOP_LEFT, 125 false, // |allow_bubble_offscreen| 126 gfx::Size(500, 500), // |contents_size| 127 &contents_bounds, &window_bounds); 128 arrow_location = border_contents.bubble_border()->arrow_location(); 129 // The arrow should have changed to TOP_RIGHT. 130 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 131 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 132 EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); 133 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); 134 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for 135 // arrow overlap. 136 137 // Test bubble not fitting on bottom and right. 138 border_contents.SizeAndGetBounds( 139 gfx::Rect(900, 900, 50, 50), // |position_relative_to| 140 BubbleBorder::TOP_LEFT, 141 false, // |allow_bubble_offscreen| 142 gfx::Size(500, 500), // |contents_size| 143 &contents_bounds, &window_bounds); 144 arrow_location = border_contents.bubble_border()->arrow_location(); 145 // The arrow should have changed to BOTTOM_RIGHT. 146 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 147 EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); 148 EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); 149 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); 150 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate 151 // for arrow height. 152 153 // Test bubble not fitting at the bottom. 154 border_contents.SizeAndGetBounds( 155 gfx::Rect(100, 900, 50, 50), // |position_relative_to| 156 BubbleBorder::TOP_LEFT, 157 false, // |allow_bubble_offscreen| 158 gfx::Size(500, 500), // |contents_size| 159 &contents_bounds, &window_bounds); 160 arrow_location = border_contents.bubble_border()->arrow_location(); 161 // The arrow should have changed to BOTTOM_LEFT. 162 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 163 EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); 164 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 165 // The window should be right aligned with the position_relative_to. 166 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); 167 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate 168 // for arrow height. 169 170 // Test bubble not fitting at the bottom and left. 171 border_contents.SizeAndGetBounds( 172 gfx::Rect(100, 900, 50, 50), // |position_relative_to| 173 BubbleBorder::TOP_RIGHT, 174 false, // |allow_bubble_offscreen| 175 gfx::Size(500, 500), // |contents_size| 176 &contents_bounds, &window_bounds); 177 arrow_location = border_contents.bubble_border()->arrow_location(); 178 // The arrow should have changed to BOTTOM_LEFT. 179 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 180 EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location)); 181 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 182 // The window should be right aligned with the position_relative_to. 183 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); 184 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate 185 // for arrow height. 186} 187 188// Tests that the arrow is not moved when the info-bubble does not fit the 189// screen but moving it would make matter worse. 190TEST_F(BorderContentsTest, BorderContentsSizeAndGetBoundsDontMoveArrow) { 191 TestBorderContents border_contents; 192 border_contents.Init(); 193 gfx::Rect contents_bounds; 194 gfx::Rect window_bounds; 195 border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); 196 border_contents.SizeAndGetBounds( 197 gfx::Rect(400, 100, 50, 50), // |position_relative_to| 198 BubbleBorder::TOP_LEFT, 199 false, // |allow_bubble_offscreen| 200 gfx::Size(500, 700), // |contents_size| 201 &contents_bounds, &window_bounds); 202 203 // The arrow should not have changed, as it would make it the bubble even more 204 // offscreen. 205 BubbleBorder::ArrowLocation arrow_location = 206 border_contents.bubble_border()->arrow_location(); 207 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 208 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 209 EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location)); 210} 211 212// Test that the 'allow offscreen' prevents the bubble from moving. 213TEST_F(BorderContentsTest, BorderContentsSizeAndGetBoundsAllowOffscreen) { 214 TestBorderContents border_contents; 215 border_contents.Init(); 216 gfx::Rect contents_bounds; 217 gfx::Rect window_bounds; 218 border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000)); 219 border_contents.SizeAndGetBounds( 220 gfx::Rect(100, 900, 50, 50), // |position_relative_to| 221 BubbleBorder::TOP_RIGHT, 222 true, // |allow_bubble_offscreen| 223 gfx::Size(500, 500), // |contents_size| 224 &contents_bounds, &window_bounds); 225 226 // The arrow should not have changed (eventhough the bubble does not fit). 227 BubbleBorder::ArrowLocation arrow_location = 228 border_contents.bubble_border()->arrow_location(); 229 EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location)); 230 EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location)); 231 EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location)); 232 // The coordinates should be pointing to 'positive relative to' from 233 // TOP_RIGHT. 234 EXPECT_LT(window_bounds.x(), 100 + 50 - 500); 235 EXPECT_GT(window_bounds.y(), 900 + 50 - 10); // -10 to roughly compensate for 236 // arrow overlap. 237} 238