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/mac/scoped_nsobject.h" 6 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 7 #import "chrome/browser/ui/cocoa/draggable_button.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/platform_test.h" 10 #import "ui/base/test/cocoa_test_event_utils.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 base::scoped_nsobject<TestableDraggableButton> button( 51 [[TestableDraggableButton alloc] 52 initWithFrame:NSMakeRect(0, 0, 500, 500)]); 53 [[test_window() contentView] addSubview:button.get()]; 54 [button setTarget:button]; 55 [button setAction:@selector(trigger:)]; 56 EXPECT_FALSE([button wasTriggered]); 57 NSEvent* downEvent = 58 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 59 NSLeftMouseDown, 60 0); 61 NSEvent* upEvent = 62 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 63 NSLeftMouseUp, 64 0); 65 [NSApp postEvent:upEvent atStart:YES]; 66 [test_window() sendEvent:downEvent]; 67 EXPECT_TRUE([button wasTriggered]); // confirms target/action fired 68 } 69 70 TEST_F(DraggableButtonTest, DraggableHysteresis) { 71 base::scoped_nsobject<TestableDraggableButton> button( 72 [[TestableDraggableButton alloc] 73 initWithFrame:NSMakeRect(0, 0, 500, 500)]); 74 [[test_window() contentView] addSubview:button.get()]; 75 NSEvent* downEvent = 76 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 77 NSLeftMouseDown, 78 0); 79 NSEvent* firstMove = 80 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(11,11), 81 NSLeftMouseDragged, 82 0); 83 NSEvent* firstUpEvent = 84 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(11,11), 85 NSLeftMouseUp, 86 0); 87 NSEvent* secondMove = 88 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 89 NSLeftMouseDragged, 90 0); 91 NSEvent* secondUpEvent = 92 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 93 NSLeftMouseUp, 94 0); 95 // If the mouse only moves one pixel in each direction 96 // it should not cause a drag. 97 [NSApp postEvent:firstUpEvent atStart:YES]; 98 [NSApp postEvent:firstMove atStart:YES]; 99 [button mouseDown:downEvent]; 100 EXPECT_EQ(0U, [button dragCount]); 101 102 // If the mouse moves > 5 pixels in either direciton 103 // it should cause a drag. 104 [NSApp postEvent:secondUpEvent atStart:YES]; 105 [NSApp postEvent:secondMove atStart:YES]; 106 [button mouseDown:downEvent]; 107 EXPECT_EQ(1U, [button dragCount]); 108 } 109 110 TEST_F(DraggableButtonTest, ResetState) { 111 base::scoped_nsobject<TestableDraggableButton> button( 112 [[TestableDraggableButton alloc] 113 initWithFrame:NSMakeRect(0, 0, 500, 500)]); 114 [[test_window() contentView] addSubview:button.get()]; 115 NSEvent* downEvent = 116 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), 117 NSLeftMouseDown, 118 0); 119 NSEvent* moveEvent = 120 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 121 NSLeftMouseDragged, 122 0); 123 NSEvent* upEvent = 124 cocoa_test_event_utils::MouseEventAtPoint(NSMakePoint(100,100), 125 NSLeftMouseUp, 126 0); 127 // If the mouse moves > 5 pixels in either direciton it should cause a drag. 128 [NSApp postEvent:upEvent atStart:YES]; 129 [NSApp postEvent:moveEvent atStart:YES]; 130 [button mouseDown:downEvent]; 131 132 // The button should not be highlighted after the drag finishes. 133 EXPECT_FALSE([[button cell] isHighlighted]); 134 EXPECT_EQ(1U, [button dragCount]); 135 136 // We should be able to initiate another drag immediately after the first one. 137 [NSApp postEvent:upEvent atStart:YES]; 138 [NSApp postEvent:moveEvent atStart:YES]; 139 [button mouseDown:downEvent]; 140 EXPECT_EQ(2U, [button dragCount]); 141 EXPECT_FALSE([[button cell] isHighlighted]); 142 } 143