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 "base/memory/scoped_nsobject.h" 6 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 7 #import "chrome/browser/ui/cocoa/draggable_button.h" 8 #import "chrome/browser/ui/cocoa/test_event_utils.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/platform_test.h" 11 12 @interface TestableDraggableButton : DraggableButton { 13 NSUInteger dragCount_; 14 BOOL wasTriggered_; 15 } 16 - (void)trigger:(id)sender; 17 - (BOOL)wasTriggered; 18 - (NSUInteger)dragCount; 19 @end 20 21 @implementation TestableDraggableButton 22 - (id)initWithFrame:(NSRect)frame { 23 if ((self = [super initWithFrame:frame])) { 24 dragCount_ = 0; 25 wasTriggered_ = NO; 26 } 27 return self; 28 } 29 - (void)beginDrag:(NSEvent*)theEvent { 30 dragCount_++; 31 } 32 33 - (void)trigger:(id)sender { 34 wasTriggered_ = YES; 35 } 36 37 - (BOOL)wasTriggered { 38 return wasTriggered_; 39 } 40 41 - (NSUInteger)dragCount { 42 return dragCount_; 43 } 44 @end 45 46 class DraggableButtonTest : public CocoaTest {}; 47 48 // Make sure the basic case of "click" still works. 49 TEST_F(DraggableButtonTest, DownUp) { 50 scoped_nsobject<TestableDraggableButton> button( 51 [[TestableDraggableButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 52 [[test_window() contentView] addSubview:button.get()]; 53 [button setTarget:button]; 54 [button setAction:@selector(trigger:)]; 55 EXPECT_FALSE([button wasTriggered]); 56 NSEvent* downEvent = 57 test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 58 NSLeftMouseDown, 0); 59 NSEvent* upEvent = 60 test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 61 NSLeftMouseUp, 0); 62 [NSApp postEvent:upEvent atStart:YES]; 63 [test_window() sendEvent:downEvent]; 64 EXPECT_TRUE([button wasTriggered]); // confirms target/action fired 65 } 66 67 TEST_F(DraggableButtonTest, DraggableHysteresis) { 68 scoped_nsobject<TestableDraggableButton> button( 69 [[TestableDraggableButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 70 [[test_window() contentView] addSubview:button.get()]; 71 NSEvent* downEvent = 72 test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 73 NSLeftMouseDown, 74 0); 75 NSEvent* firstMove = 76 test_event_utils::MouseEventAtPoint(NSMakePoint(11,11), 77 NSLeftMouseDragged, 78 0); 79 NSEvent* firstUpEvent = 80 test_event_utils::MouseEventAtPoint(NSMakePoint(11,11), 81 NSLeftMouseUp, 82 0); 83 NSEvent* secondMove = 84 test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 85 NSLeftMouseDragged, 86 0); 87 NSEvent* secondUpEvent = 88 test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 89 NSLeftMouseUp, 90 0); 91 // If the mouse only moves one pixel in each direction 92 // it should not cause a drag. 93 [NSApp postEvent:firstUpEvent atStart:YES]; 94 [NSApp postEvent:firstMove atStart:YES]; 95 [button mouseDown:downEvent]; 96 EXPECT_EQ(0U, [button dragCount]); 97 98 // If the mouse moves > 5 pixels in either direciton 99 // it should cause a drag. 100 [NSApp postEvent:secondUpEvent atStart:YES]; 101 [NSApp postEvent:secondMove atStart:YES]; 102 [button mouseDown:downEvent]; 103 EXPECT_EQ(1U, [button dragCount]); 104 } 105 106 TEST_F(DraggableButtonTest, ResetState) { 107 scoped_nsobject<TestableDraggableButton> button( 108 [[TestableDraggableButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]); 109 [[test_window() contentView] addSubview:button.get()]; 110 NSEvent* downEvent = 111 test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 112 NSLeftMouseDown, 113 0); 114 NSEvent* moveEvent = 115 test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 116 NSLeftMouseDragged, 117 0); 118 NSEvent* upEvent = 119 test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 120 NSLeftMouseUp, 121 0); 122 // If the mouse moves > 5 pixels in either direciton it should cause a drag. 123 [NSApp postEvent:upEvent atStart:YES]; 124 [NSApp postEvent:moveEvent atStart:YES]; 125 [button mouseDown:downEvent]; 126 127 // The button should not be highlighted after the drag finishes. 128 EXPECT_FALSE([[button cell] isHighlighted]); 129 EXPECT_EQ(1U, [button dragCount]); 130 131 // We should be able to initiate another drag immediately after the first one. 132 [NSApp postEvent:upEvent atStart:YES]; 133 [NSApp postEvent:moveEvent atStart:YES]; 134 [button mouseDown:downEvent]; 135 EXPECT_EQ(2U, [button dragCount]); 136 EXPECT_FALSE([[button cell] isHighlighted]); 137 } 138