chrome_render_widget_host_view_mac_history_swiper_unit_test.mm revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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#include "testing/gtest/include/gtest/gtest.h" 6#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 7 8#include "base/mac/scoped_nsobject.h" 9 10#import "base/mac/sdk_forward_declarations.h" 11#import "chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h" 12#import "third_party/ocmock/OCMock/OCMock.h" 13#import "third_party/ocmock/ocmock_extensions.h" 14 15@interface HistorySwiper (MacHistorySwiperTest) 16- (BOOL)systemSettingsAllowHistorySwiping:(NSEvent*)event; 17- (BOOL)browserCanNavigateInDirection: 18 (history_swiper::NavigationDirection)forward 19 event:(NSEvent*)event; 20- (void)endHistorySwipe; 21- (void)beginHistorySwipeInDirection: 22 (history_swiper::NavigationDirection)goForward 23 event:(NSEvent*)event; 24- (void)navigateBrowserInDirection:(history_swiper::NavigationDirection)forward; 25@end 26 27class MacHistorySwiperTest : public CocoaTest { 28 public: 29 virtual void SetUp() OVERRIDE { 30 CocoaTest::SetUp(); 31 32 view_ = [[NSView alloc] init]; 33 id mockDelegate = 34 [OCMockObject mockForProtocol:@protocol(HistorySwiperDelegate)]; 35 [[[mockDelegate stub] andReturn:view_] viewThatWantsHistoryOverlay]; 36 [[[mockDelegate stub] andReturnBool:YES] shouldAllowHistorySwiping]; 37 38 base::scoped_nsobject<HistorySwiper> historySwiper( 39 [[HistorySwiper alloc] initWithDelegate:mockDelegate]); 40 id mockHistorySwiper = [OCMockObject partialMockForObject:historySwiper]; 41 [[[mockHistorySwiper stub] andReturnBool:YES] 42 systemSettingsAllowHistorySwiping:[OCMArg any]]; 43 [[[mockHistorySwiper stub] andReturnBool:YES] 44 browserCanNavigateInDirection:history_swiper::kForwards 45 event:[OCMArg any]]; 46 [[[mockHistorySwiper stub] andReturnBool:YES] 47 browserCanNavigateInDirection:history_swiper::kBackwards 48 event:[OCMArg any]]; 49 [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 50 ++begin_count_; 51 }] andForwardToRealObject] 52 beginHistorySwipeInDirection:history_swiper::kForwards 53 event:[OCMArg any]]; 54 [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 55 ++begin_count_; 56 }] andForwardToRealObject] 57 beginHistorySwipeInDirection:history_swiper::kBackwards 58 event:[OCMArg any]]; 59 [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 60 ++end_count_; 61 }] andForwardToRealObject] endHistorySwipe]; 62 [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 63 navigated_right_ = true; 64 }] navigateBrowserInDirection:history_swiper::kForwards]; 65 [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 66 navigated_left_ = true; 67 }] navigateBrowserInDirection:history_swiper::kBackwards]; 68 historySwiper_ = [mockHistorySwiper retain]; 69 70 begin_count_ = 0; 71 end_count_ = 0; 72 navigated_right_ = false; 73 navigated_left_ = false; 74 } 75 76 virtual void TearDown() OVERRIDE { 77 [view_ release]; 78 [historySwiper_ release]; 79 CocoaTest::TearDown(); 80 } 81 82 void startGestureInMiddle(); 83 void moveGestureInMiddle(); 84 void moveGestureAtPoint(NSPoint point); 85 void endGestureAtPoint(NSPoint point); 86 87 HistorySwiper* historySwiper_; 88 NSView* view_; 89 int begin_count_; 90 int end_count_; 91 bool navigated_right_; 92 bool navigated_left_; 93}; 94 95NSPoint makePoint(CGFloat x, CGFloat y) { 96 NSPoint point; 97 point.x = x; 98 point.y = y; 99 return point; 100} 101 102id mockEventWithPoint(NSPoint point, NSEventType type) { 103 id mockEvent = [OCMockObject mockForClass:[NSEvent class]]; 104 id mockTouch = [OCMockObject mockForClass:[NSTouch class]]; 105 [[[mockTouch stub] andReturnNSPoint:point] normalizedPosition]; 106 NSArray* touches = @[mockTouch]; 107 [[[mockEvent stub] andReturn:touches] touchesMatchingPhase:NSTouchPhaseAny 108 inView:[OCMArg any]]; 109 [[[mockEvent stub] andReturnBool:NO] isDirectionInvertedFromDevice]; 110 [(NSEvent*)[[mockEvent stub] andReturnValue:OCMOCK_VALUE(type)] type]; 111 112 return mockEvent; 113} 114 115id scrollWheelEventWithPhase(NSEventPhase phase) { 116 // The point isn't used, so we pass in bogus data. 117 id event = mockEventWithPoint(makePoint(0,0), NSScrollWheel); 118 [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(phase)] phase]; 119 return event; 120} 121 122void MacHistorySwiperTest::startGestureInMiddle() { 123 NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); 124 [historySwiper_ touchesBeganWithEvent:event]; 125 [historySwiper_ beginGestureWithEvent:event]; 126 NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); 127 [historySwiper_ handleEvent:scrollEvent]; 128} 129 130void MacHistorySwiperTest::moveGestureInMiddle() { 131 moveGestureAtPoint(makePoint(0.5, 0.5)); 132 133 // Callbacks from blink to set the relevant state for history swiping. 134 [historySwiper_ gotUnhandledWheelEvent]; 135 [historySwiper_ scrollOffsetPinnedToLeft:YES toRight:YES]; 136 [historySwiper_ setHasHorizontalScrollbar:NO]; 137} 138 139void MacHistorySwiperTest::moveGestureAtPoint(NSPoint point) { 140 NSEvent* event = mockEventWithPoint(point, NSEventTypeGesture); 141 [historySwiper_ touchesMovedWithEvent:event]; 142 143 NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseChanged); 144 [historySwiper_ handleEvent:scrollEvent]; 145} 146 147void MacHistorySwiperTest::endGestureAtPoint(NSPoint point) { 148 NSEvent* event = mockEventWithPoint(point, NSEventTypeGesture); 149 [historySwiper_ touchesEndedWithEvent:event]; 150 151 NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseEnded); 152 [historySwiper_ handleEvent:scrollEvent]; 153} 154 155// Test that a simple left-swipe causes navigation. 156TEST_F(MacHistorySwiperTest, SwipeLeft) { 157 // These tests require 10.7+ APIs. 158 if (![NSEvent 159 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 160 return; 161 162 startGestureInMiddle(); 163 moveGestureInMiddle(); 164 165 EXPECT_EQ(begin_count_, 0); 166 EXPECT_EQ(end_count_, 0); 167 168 moveGestureAtPoint(makePoint(0.2, 0.5)); 169 EXPECT_EQ(begin_count_, 1); 170 EXPECT_EQ(end_count_, 0); 171 EXPECT_FALSE(navigated_right_); 172 EXPECT_FALSE(navigated_left_); 173 174 endGestureAtPoint(makePoint(0.2, 0.5)); 175 EXPECT_EQ(begin_count_, 1); 176 EXPECT_EQ(end_count_, 1); 177 EXPECT_FALSE(navigated_right_); 178 EXPECT_TRUE(navigated_left_); 179} 180 181// Test that a simple right-swipe causes navigation. 182TEST_F(MacHistorySwiperTest, SwipeRight) { 183 // These tests require 10.7+ APIs. 184 if (![NSEvent 185 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 186 return; 187 188 startGestureInMiddle(); 189 moveGestureInMiddle(); 190 191 EXPECT_EQ(begin_count_, 0); 192 EXPECT_EQ(end_count_, 0); 193 194 moveGestureAtPoint(makePoint(0.8, 0.5)); 195 EXPECT_EQ(begin_count_, 1); 196 EXPECT_EQ(end_count_, 0); 197 EXPECT_FALSE(navigated_right_); 198 EXPECT_FALSE(navigated_left_); 199 200 endGestureAtPoint(makePoint(0.8, 0.5)); 201 EXPECT_EQ(begin_count_, 1); 202 EXPECT_EQ(end_count_, 1); 203 EXPECT_TRUE(navigated_right_); 204 EXPECT_FALSE(navigated_left_); 205} 206 207// If the user doesn't swipe enough, the history swiper should begin, but the 208// browser should not navigate. 209TEST_F(MacHistorySwiperTest, SwipeLeftSmallAmount) { 210 // These tests require 10.7+ APIs. 211 if (![NSEvent 212 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 213 return; 214 215 startGestureInMiddle(); 216 moveGestureInMiddle(); 217 moveGestureAtPoint(makePoint(0.45, 0.5)); 218 endGestureAtPoint(makePoint(0.45, 0.5)); 219 EXPECT_EQ(begin_count_, 1); 220 EXPECT_EQ(end_count_, 1); 221 EXPECT_FALSE(navigated_right_); 222 EXPECT_FALSE(navigated_left_); 223} 224 225// Diagonal swipes with a slight horizontal bias should not start the history 226// swiper. 227TEST_F(MacHistorySwiperTest, SwipeDiagonal) { 228 // These tests require 10.7+ APIs. 229 if (![NSEvent 230 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 231 return; 232 233 startGestureInMiddle(); 234 moveGestureInMiddle(); 235 moveGestureAtPoint(makePoint(0.6, 0.59)); 236 endGestureAtPoint(makePoint(0.6, 0.59)); 237 238 EXPECT_EQ(begin_count_, 0); 239 EXPECT_EQ(end_count_, 0); 240 EXPECT_FALSE(navigated_right_); 241 EXPECT_FALSE(navigated_left_); 242} 243 244// Swiping left and then down should cancel the history swiper without 245// navigating. 246TEST_F(MacHistorySwiperTest, SwipeLeftThenDown) { 247 // These tests require 10.7+ APIs. 248 if (![NSEvent 249 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 250 return; 251 252 startGestureInMiddle(); 253 moveGestureInMiddle(); 254 moveGestureAtPoint(makePoint(0.4, 0.5)); 255 moveGestureAtPoint(makePoint(0.4, 0.3)); 256 endGestureAtPoint(makePoint(0.2, 0.2)); 257 EXPECT_EQ(begin_count_, 1); 258 EXPECT_EQ(end_count_, 1); 259 EXPECT_FALSE(navigated_right_); 260 EXPECT_FALSE(navigated_left_); 261} 262 263// User starts a swipe but doesn't move. 264TEST_F(MacHistorySwiperTest, NoSwipe) { 265 // These tests require 10.7+ APIs. 266 if (![NSEvent 267 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 268 return; 269 270 startGestureInMiddle(); 271 moveGestureInMiddle(); 272 moveGestureAtPoint(makePoint(0.5, 0.5)); 273 endGestureAtPoint(makePoint(0.5, 0.5)); 274 275 EXPECT_EQ(begin_count_, 0); 276 EXPECT_EQ(end_count_, 0); 277} 278