1// Copyright 2013 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#import "chrome/browser/ui/app_list/app_list_service_mac.h" 6 7#include "testing/gtest/include/gtest/gtest.h" 8#include "ui/gfx/display.h" 9#include "ui/gfx/point.h" 10#include "ui/gfx/rect.h" 11#include "ui/gfx/size.h" 12 13namespace { 14 15const int kScreenWidth = 800; 16const int kScreenHeight = 600; 17 18const int kWindowWidth = 100; 19const int kWindowHeight = 200; 20 21// Size of the menu bar along the top of the screen. 22const int kMenuBarSize = 22; 23// Size of the normal (non-hidden) dock. 24const int kDockSize = 30; 25// Size of the hidden dock. 26const int kHiddenDockSize = 4; 27 28// Distance to move during the opening animation. 29const int kAnimationOffset = 20; 30 31// The assumed size of the hidden dock. 32const int kExtraDistance = 50; 33 34// A cursor position that is within the dock. This must be < kDockSize. 35const int kCursorOnDock = kDockSize / 2; 36// A cursor position that is within kWindowWidth pixels of the dock. 37const int kCursorNearDockX = kDockSize + kWindowWidth; 38// A cursor position that is more than kWindowWidth pixels away from the dock. 39const int kCursorAwayFromDockX = kCursorNearDockX + 1; 40// A cursor position that is within kWindowHeight pixels of the dock. 41const int kCursorNearDockY = kDockSize + kWindowHeight; 42// A cursor position that is more than kWindowHeight pixels away from the dock. 43const int kCursorAwayFromDockY = kCursorNearDockY + 1; 44 45// A position for the center of the window that causes the window to overlap the 46// edge of the screen. This must be < kWindowWidth / 2 and < kWindowHeight / 2. 47const int kWindowNearEdge = kWindowWidth / 4; 48// A position for the center of the window that places the window away from all 49// edges of the screen. This must be > kWindowWidth / 2, > kWindowHeight / 2, < 50// kScreenWidth - kWindowWidth / 2 and < kScreenHeight - kWindowHeight / 2. 51const int kWindowAwayFromEdge = 158; 52 53enum DockLocation { 54 DOCK_LOCATION_BOTTOM, 55 DOCK_LOCATION_LEFT, 56 DOCK_LOCATION_RIGHT, 57}; 58 59// Returns |point| offset by (|x_offset|, |y_offset|). 60NSPoint OffsetPoint(const NSPoint& point, CGFloat x_offset, CGFloat y_offset) { 61 return NSMakePoint(point.x + x_offset, point.y + y_offset); 62} 63 64} // namespace 65 66class AppListServiceMacUnitTest : public testing::Test { 67 public: 68 virtual void SetUp() OVERRIDE { 69 display_.set_bounds(gfx::Rect(0, 0, kScreenWidth, kScreenHeight)); 70 display_.set_work_area( 71 gfx::Rect(0, kMenuBarSize, kScreenWidth, kScreenHeight - kMenuBarSize)); 72 window_size_ = gfx::Size(kWindowWidth, kWindowHeight); 73 cursor_is_visible_ = true; 74 cursor_ = gfx::Point(); 75 } 76 77 // Sets up the test environment with the dock in a given location. 78 void PlaceDock(DockLocation location, bool hidden) { 79 int dock_size = hidden ? kHiddenDockSize : kDockSize; 80 switch (location) { 81 case DOCK_LOCATION_BOTTOM: 82 display_.set_work_area( 83 gfx::Rect(0, 84 kMenuBarSize, 85 kScreenWidth, 86 kScreenHeight - kMenuBarSize - dock_size)); 87 break; 88 case DOCK_LOCATION_LEFT: 89 display_.set_work_area(gfx::Rect(dock_size, 90 kMenuBarSize, 91 kScreenWidth - dock_size, 92 kScreenHeight - kMenuBarSize)); 93 break; 94 case DOCK_LOCATION_RIGHT: 95 display_.set_work_area(gfx::Rect(0, 96 kMenuBarSize, 97 kScreenWidth - dock_size, 98 kScreenHeight - kMenuBarSize)); 99 break; 100 } 101 } 102 103 // Set whether the test mouse cursor is visible. 104 void SetCursorVisible(bool visible) { 105 cursor_is_visible_ = visible; 106 } 107 108 // Set up the test mouse cursor in a given location. 109 void PlaceCursor(int x, int y) { 110 cursor_ = gfx::Point(x, y); 111 } 112 113 void DoFindAnchorPoint(NSPoint* target_origin, 114 NSPoint* start_origin) { 115 AppListServiceMac::FindAnchorPoint(window_size_, 116 display_, 117 kScreenHeight, 118 cursor_is_visible_, 119 cursor_, 120 target_origin, 121 start_origin); 122 } 123 124 private: 125 gfx::Display display_; 126 gfx::Size window_size_; 127 bool cursor_is_visible_; 128 gfx::Point cursor_; 129}; 130 131// Tests positioning the app list when there is no visible mouse cursor. 132TEST_F(AppListServiceMacUnitTest, FindAnchorPointNoCursor) { 133 SetCursorVisible(false); 134 PlaceCursor(0, 0); 135 NSPoint target_origin; 136 NSPoint start_origin; 137 138 // Bottom dock. Expect the app list to be centered on the dock. 139 PlaceDock(DOCK_LOCATION_BOTTOM, false); 140 DoFindAnchorPoint(&target_origin, &start_origin); 141 EXPECT_TRUE( 142 NSEqualPoints(NSMakePoint(kScreenWidth / 2 - kWindowWidth / 2, kDockSize), 143 target_origin)); 144 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 145 start_origin)); 146 147 // Left dock. Expect the app list to be centered on the dock. 148 PlaceDock(DOCK_LOCATION_LEFT, false); 149 DoFindAnchorPoint(&target_origin, &start_origin); 150 EXPECT_TRUE(NSEqualPoints( 151 NSMakePoint(kDockSize, 152 (kScreenHeight - kMenuBarSize) / 2 - kWindowHeight / 2), 153 target_origin)); 154 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, -kAnimationOffset, 0), 155 start_origin)); 156 157 // Right dock. Expect the app list to be centered on the dock. 158 PlaceDock(DOCK_LOCATION_RIGHT, false); 159 DoFindAnchorPoint(&target_origin, &start_origin); 160 EXPECT_TRUE(NSEqualPoints( 161 NSMakePoint(kScreenWidth - kDockSize - kWindowWidth, 162 (kScreenHeight - kMenuBarSize) / 2 - kWindowHeight / 2), 163 target_origin)); 164 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, kAnimationOffset, 0), 165 start_origin)); 166} 167 168// Tests positioning the app list when there is no dock on the display. 169TEST_F(AppListServiceMacUnitTest, FindAnchorPointNoDock) { 170 SetCursorVisible(true); 171 PlaceCursor(0, 0); 172 NSPoint target_origin; 173 NSPoint start_origin; 174 175 // Expect the app list to be in the bottom-left corner. 176 DoFindAnchorPoint(&target_origin, &start_origin); 177 EXPECT_TRUE(NSEqualPoints(NSMakePoint(0, 0), target_origin)); 178 EXPECT_TRUE(NSEqualPoints(target_origin, start_origin)); 179 180 // No mouse cursor. This should have no effect. 181 SetCursorVisible(false); 182 DoFindAnchorPoint(&target_origin, &start_origin); 183 EXPECT_TRUE(NSEqualPoints(NSMakePoint(0, 0), target_origin)); 184 EXPECT_TRUE(NSEqualPoints(target_origin, start_origin)); 185} 186 187// Tests positioning the app list when the mouse is away from the dock. 188TEST_F(AppListServiceMacUnitTest, FindAnchorPointMouseOffDock) { 189 SetCursorVisible(true); 190 NSPoint target_origin; 191 NSPoint start_origin; 192 193 // Bottom dock. Expect the app list to be centered on the dock. 194 PlaceDock(DOCK_LOCATION_BOTTOM, false); 195 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorAwayFromDockY); 196 DoFindAnchorPoint(&target_origin, &start_origin); 197 EXPECT_TRUE( 198 NSEqualPoints(NSMakePoint(kScreenWidth / 2 - kWindowWidth / 2, kDockSize), 199 target_origin)); 200 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 201 start_origin)); 202 203 // Left dock. Expect the app list to be centered on the dock. 204 PlaceDock(DOCK_LOCATION_LEFT, false); 205 PlaceCursor(kCursorAwayFromDockX, kWindowAwayFromEdge); 206 DoFindAnchorPoint(&target_origin, &start_origin); 207 EXPECT_TRUE(NSEqualPoints( 208 NSMakePoint(kDockSize, 209 (kScreenHeight - kMenuBarSize) / 2 - kWindowHeight / 2), 210 target_origin)); 211 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, -kAnimationOffset, 0), 212 start_origin)); 213 214 // Right dock. Expect the app list to be centered on the dock. 215 PlaceDock(DOCK_LOCATION_RIGHT, false); 216 PlaceCursor(kScreenWidth - kCursorAwayFromDockX, kWindowAwayFromEdge); 217 DoFindAnchorPoint(&target_origin, &start_origin); 218 EXPECT_TRUE(NSEqualPoints( 219 NSMakePoint(kScreenWidth - kDockSize - kWindowWidth, 220 (kScreenHeight - kMenuBarSize) / 2 - kWindowHeight / 2), 221 target_origin)); 222 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, kAnimationOffset, 0), 223 start_origin)); 224} 225 226// Tests positioning the app list when the dock is hidden. 227TEST_F(AppListServiceMacUnitTest, FindAnchorPointHiddenDock) { 228 SetCursorVisible(true); 229 NSPoint target_origin; 230 NSPoint start_origin; 231 232 // Bottom dock. Expect the app list to be kExtraDistance pixels from the dock 233 // centered on the mouse X coordinate. 234 PlaceDock(DOCK_LOCATION_BOTTOM, true); 235 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorAwayFromDockY); 236 DoFindAnchorPoint(&target_origin, &start_origin); 237 EXPECT_TRUE(NSEqualPoints(NSMakePoint(kWindowAwayFromEdge - kWindowWidth / 2, 238 kHiddenDockSize + kExtraDistance), 239 target_origin)); 240 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 241 start_origin)); 242 243 // Left dock. Expect the app list to be kExtraDistance pixels from the dock 244 // centered on the mouse Y coordinate. 245 PlaceDock(DOCK_LOCATION_LEFT, true); 246 PlaceCursor(kCursorAwayFromDockX, kWindowAwayFromEdge); 247 DoFindAnchorPoint(&target_origin, &start_origin); 248 EXPECT_TRUE(NSEqualPoints( 249 NSMakePoint(kHiddenDockSize + kExtraDistance, 250 kScreenHeight - kWindowAwayFromEdge - kWindowHeight / 2), 251 target_origin)); 252 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, -kAnimationOffset, 0), 253 start_origin)); 254 255 // Right dock. Expect the app list to be kExtraDistance pixels from the dock 256 // centered on the mouse Y coordinate. 257 PlaceDock(DOCK_LOCATION_RIGHT, true); 258 PlaceCursor(kScreenWidth - kCursorAwayFromDockX, kWindowAwayFromEdge); 259 DoFindAnchorPoint(&target_origin, &start_origin); 260 EXPECT_TRUE(NSEqualPoints( 261 NSMakePoint( 262 kScreenWidth - kHiddenDockSize - kWindowWidth - kExtraDistance, 263 kScreenHeight - kWindowAwayFromEdge - kWindowHeight / 2), 264 target_origin)); 265 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, kAnimationOffset, 0), 266 start_origin)); 267} 268 269// Tests positioning the app list when the mouse is over the dock. 270TEST_F(AppListServiceMacUnitTest, FindAnchorPointMouseOnDock) { 271 SetCursorVisible(true); 272 NSPoint target_origin; 273 NSPoint start_origin; 274 275 // Bottom dock (mouse well within dock). Expect the app list to be at the 276 // bottom centered on the mouse X coordinate. 277 PlaceDock(DOCK_LOCATION_BOTTOM, false); 278 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorOnDock); 279 DoFindAnchorPoint(&target_origin, &start_origin); 280 EXPECT_TRUE(NSEqualPoints( 281 NSMakePoint(kWindowAwayFromEdge - kWindowWidth / 2, kDockSize), 282 target_origin)); 283 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 284 start_origin)); 285 286 // Bottom dock (outside the dock but still close enough). Expect the app list 287 // to be at the bottom centered on the mouse X coordinate. 288 PlaceDock(DOCK_LOCATION_BOTTOM, false); 289 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorNearDockY); 290 DoFindAnchorPoint(&target_origin, &start_origin); 291 EXPECT_TRUE(NSEqualPoints( 292 NSMakePoint(kWindowAwayFromEdge - kWindowWidth / 2, kDockSize), 293 target_origin)); 294 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 295 start_origin)); 296 297 // Left dock. Expect the app list to be at the left centered on the mouse Y 298 // coordinate. 299 PlaceDock(DOCK_LOCATION_LEFT, false); 300 PlaceCursor(kCursorNearDockX, kWindowAwayFromEdge); 301 DoFindAnchorPoint(&target_origin, &start_origin); 302 EXPECT_TRUE(NSEqualPoints( 303 NSMakePoint(kDockSize, 304 kScreenHeight - kWindowAwayFromEdge - kWindowHeight / 2), 305 target_origin)); 306 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, -kAnimationOffset, 0), 307 start_origin)); 308 309 // Right dock. Expect the app list to be at the right centered on the mouse Y 310 // coordinate. 311 PlaceDock(DOCK_LOCATION_RIGHT, false); 312 PlaceCursor(kScreenWidth - kCursorNearDockX, kWindowAwayFromEdge); 313 DoFindAnchorPoint(&target_origin, &start_origin); 314 EXPECT_TRUE(NSEqualPoints( 315 NSMakePoint(kScreenWidth - kDockSize - kWindowWidth, 316 kScreenHeight - kWindowAwayFromEdge - kWindowHeight / 2), 317 target_origin)); 318 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, kAnimationOffset, 0), 319 start_origin)); 320 321 // Bottom dock. Mouse near left edge. App list must not go off screen. 322 PlaceDock(DOCK_LOCATION_BOTTOM, false); 323 PlaceCursor(kWindowNearEdge, kScreenHeight - kCursorOnDock); 324 DoFindAnchorPoint(&target_origin, &start_origin); 325 EXPECT_TRUE(NSEqualPoints(NSMakePoint(0, kDockSize), target_origin)); 326 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 327 start_origin)); 328 329 // Bottom dock. Mouse near right edge. App list must not go off screen. 330 PlaceDock(DOCK_LOCATION_BOTTOM, false); 331 PlaceCursor(kScreenWidth - kWindowNearEdge, kScreenHeight - kCursorOnDock); 332 DoFindAnchorPoint(&target_origin, &start_origin); 333 EXPECT_TRUE(NSEqualPoints(NSMakePoint(kScreenWidth - kWindowWidth, kDockSize), 334 target_origin)); 335 EXPECT_TRUE(NSEqualPoints(OffsetPoint(target_origin, 0, -kAnimationOffset), 336 start_origin)); 337} 338