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.
5 #import <Cocoa/Cocoa.h>
7 #import "base/mac/scoped_nsobject.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
10 #import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
11 #import "testing/gtest_mac.h"
12 #import "ui/events/test/cocoa_test_event_utils.h"
14 @interface TestableToolbarButton : ToolbarButton {
16 NSInteger numOfClick_;
17 NSInteger lastCommand_;
20 @property(assign, nonatomic) NSInteger numOfClick;
21 @property(assign, nonatomic) NSInteger lastCommand;
23 - (id)initWithFrame:(NSRect)frame;
24 - (void)doAction:(id)sender;
27 @implementation TestableToolbarButton
29 @synthesize numOfClick = numOfClick_;
30 @synthesize lastCommand = lastCommand_;
32 - (id)initWithFrame:(NSRect)frame {
33 if ((self = [super initWithFrame:frame])) {
34 lastCommand_ = IDC_STOP;
39 - (void)doAction:(id)sender {
40 lastCommand_ = [sender tag];
41 if (lastCommand_ == [self tag])
45 - (BOOL)shouldHandleEvent:(NSEvent*)theEvent {
46 return handleMiddleClick_;
53 class ToolbarButtonTest : public CocoaTest {
56 NSRect frame = NSMakeRect(0, 0, 20, 20);
57 base::scoped_nsobject<TestableToolbarButton> button(
58 [[TestableToolbarButton alloc] initWithFrame:frame]);
59 button_ = button.get();
61 [button_ setTag:IDC_HOME];
62 [button_ setTarget:button_];
63 [button_ setAction:@selector(doAction:)];
64 [[test_window() contentView] addSubview:button_];
66 NSRect bounds = [button_ bounds];
67 NSPoint mid_point = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
68 NSPoint out_point = NSMakePoint(bounds.origin.x - 10,
69 bounds.origin.y - 10);
71 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
75 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
79 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
83 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
87 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
90 other_dragged_in_view =
91 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
95 cocoa_test_event_utils::MouseEventAtPoint(mid_point,
99 cocoa_test_event_utils::MouseEventAtPoint(out_point,
102 other_dragged_out_view =
103 cocoa_test_event_utils::MouseEventAtPoint(out_point,
107 cocoa_test_event_utils::MouseEventAtPoint(out_point,
112 TestableToolbarButton* button_;
113 NSEvent* left_down_in_view;
114 NSEvent* left_up_in_view;
115 NSEvent* right_down_in_view;
116 NSEvent* right_up_in_view;
117 NSEvent* other_down_in_view;
118 NSEvent* other_dragged_in_view;
119 NSEvent* other_up_in_view;
120 NSEvent* other_down_out_view;
121 NSEvent* other_dragged_out_view;
122 NSEvent* other_up_out_view;
125 TEST_VIEW(ToolbarButtonTest, button_)
127 TEST_F(ToolbarButtonTest, DoesNotSwallowClicksOnNO) {
128 // Middle button being down doesn't swallow right button clicks. But
129 // ToolbarButton doesn't handle right button events.
130 [button_ otherMouseDown:other_down_in_view];
131 EXPECT_EQ(NSOffState, [button_ state]);
132 [button_ rightMouseDown:right_down_in_view];
133 EXPECT_EQ(NSOffState, [button_ state]);
134 [button_ rightMouseUp:right_up_in_view];
135 EXPECT_EQ(NSOffState, [button_ state]);
136 EXPECT_EQ(0, [button_ numOfClick]);
137 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
138 [button_ otherMouseUp:other_up_in_view];
139 EXPECT_EQ(NSOffState, [button_ state]);
140 EXPECT_EQ(0, [button_ numOfClick]);
141 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
143 // Middle button being down doesn't swallows left button clicks.
144 [button_ otherMouseDown:other_down_in_view];
145 EXPECT_EQ(NSOffState, [button_ state]);
146 [NSApp postEvent:left_up_in_view atStart:YES];
147 [button_ mouseDown:left_down_in_view];
148 EXPECT_EQ(1, [button_ numOfClick]);
149 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
150 [button_ otherMouseUp:other_up_in_view];
151 EXPECT_EQ(1, [button_ numOfClick]);
152 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
155 TEST_F(ToolbarButtonTest, WithoutMouseDownOnNO) {
156 // Middle button mouse up without leading mouse down in the view.
157 [button_ otherMouseUp:other_up_in_view];
158 EXPECT_EQ(NSOffState, [button_ state]);
159 EXPECT_EQ(0, [button_ numOfClick]);
160 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
162 // Middle button mouse dragged in the view and up without leading mouse down.
163 [button_ otherMouseDragged:other_dragged_in_view];
164 EXPECT_EQ(NSOffState, [button_ state]);
165 [button_ otherMouseUp:other_up_in_view];
166 EXPECT_EQ(NSOffState, [button_ state]);
167 EXPECT_EQ(0, [button_ numOfClick]);
168 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
171 TEST_F(ToolbarButtonTest, MouseClickOnNO) {
172 // Middle button clicking in the view.
173 [button_ otherMouseDown:other_down_in_view];
174 EXPECT_EQ(NSOffState, [button_ state]);
175 [button_ otherMouseUp:other_up_in_view];
176 EXPECT_EQ(NSOffState, [button_ state]);
177 EXPECT_EQ(0, [button_ numOfClick]);
178 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
180 // Middle button clicking outside of the view.
181 [button_ otherMouseDown:other_down_out_view];
182 EXPECT_EQ(NSOffState, [button_ state]);
183 [button_ otherMouseUp:other_up_out_view];
184 EXPECT_EQ(NSOffState, [button_ state]);
185 EXPECT_EQ(0, [button_ numOfClick]);
186 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
189 TEST_F(ToolbarButtonTest, MouseDraggingOnNO) {
190 // Middle button being down in the view and up outside of the view.
191 [button_ otherMouseDown:other_down_in_view];
192 EXPECT_EQ(NSOffState, [button_ state]);
193 [button_ otherMouseDragged:other_dragged_out_view];
194 EXPECT_EQ(NSOffState, [button_ state]);
195 [button_ otherMouseUp:other_up_out_view];
196 EXPECT_EQ(NSOffState, [button_ state]);
197 EXPECT_EQ(0, [button_ numOfClick]);
198 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
200 // Middle button being down on the button, move to outside and move on it
201 // again, then up on the button.
202 [button_ otherMouseDown:other_down_in_view];
203 EXPECT_EQ(NSOffState, [button_ state]);
204 [button_ otherMouseDragged:other_dragged_in_view];
205 EXPECT_EQ(NSOffState, [button_ state]);
206 [button_ otherMouseUp:other_up_in_view];
207 EXPECT_EQ(NSOffState, [button_ state]);
208 EXPECT_EQ(0, [button_ numOfClick]);
209 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
212 TEST_F(ToolbarButtonTest, WithoutMouseDownOnYES) {
213 // Enable middle button handling.
214 [button_ setHandleMiddleClick:YES];
216 // Middle button mouse up without leading mouse down in the view.
217 [button_ otherMouseUp:other_up_in_view];
218 EXPECT_EQ(NSOffState, [button_ state]);
219 EXPECT_EQ(0, [button_ numOfClick]);
220 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
222 // Middle button mouse dragged in the view and up without leading mouse down.
223 [button_ otherMouseDragged:other_dragged_in_view];
224 EXPECT_EQ(NSOffState, [button_ state]);
225 [button_ otherMouseUp:other_up_in_view];
226 EXPECT_EQ(NSOffState, [button_ state]);
227 EXPECT_EQ(0, [button_ numOfClick]);
228 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
231 TEST_F(ToolbarButtonTest, MouseClickInsideOnYES) {
232 // Enable middle button handling.
233 [button_ setHandleMiddleClick:YES];
235 // Middle button clicking in the view.
236 [NSApp postEvent:other_up_in_view atStart:YES];
237 [button_ otherMouseDown:other_down_in_view];
239 EXPECT_EQ(NSOffState, [button_ state]);
240 EXPECT_EQ(1, [button_ numOfClick]);
241 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
244 TEST_F(ToolbarButtonTest, MouseClickOutsideOnYES) {
245 // Enable middle button handling.
246 [button_ setHandleMiddleClick:YES];
248 // Middle button clicking outside of the view.
249 [NSApp postEvent:other_up_out_view atStart:YES];
250 [button_ otherMouseDown:other_down_out_view];
252 EXPECT_EQ(NSOffState, [button_ state]);
253 EXPECT_EQ(0, [button_ numOfClick]);
254 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
257 TEST_F(ToolbarButtonTest, MouseDraggingOnYES) {
258 // Enable middle button handling.
259 [button_ setHandleMiddleClick:YES];
261 // Middle button being down in the view and up outside of the view.
262 [NSApp postEvent:other_up_out_view atStart:YES];
263 [NSApp postEvent:other_dragged_out_view atStart:YES];
264 [button_ otherMouseDown:other_down_in_view];
266 EXPECT_EQ(NSOffState, [button_ state]);
267 EXPECT_EQ(0, [button_ numOfClick]);
268 EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
270 // Middle button being down on the button, move to outside and move on it
271 // again, then up on the button.
272 [NSApp postEvent:other_up_in_view atStart:YES];
273 [NSApp postEvent:other_dragged_in_view atStart:YES];
274 [NSApp postEvent:other_dragged_out_view atStart:YES];
275 [button_ otherMouseDown:other_down_in_view];
277 EXPECT_EQ(NSOffState, [button_ state]);
278 EXPECT_EQ(1, [button_ numOfClick]);
279 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
282 TEST_F(ToolbarButtonTest, DoesSwallowRightClickOnYES) {
283 // Enable middle button handling.
284 [button_ setHandleMiddleClick:YES];
286 // Middle button being down should swallow right button clicks.
287 [NSApp postEvent:other_up_in_view atStart:YES];
288 [NSApp postEvent:right_up_in_view atStart:YES];
289 [NSApp postEvent:right_down_in_view atStart:YES];
290 [button_ otherMouseDown:other_down_in_view];
292 EXPECT_EQ(NSOffState, [button_ state]);
293 EXPECT_EQ(1, [button_ numOfClick]);
294 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
297 TEST_F(ToolbarButtonTest, DoesSwallowLeftClickOnYES) {
298 // Enable middle button handling.
299 [button_ setHandleMiddleClick:YES];
301 // Middle button being down swallows left button clicks.
302 [NSApp postEvent:other_up_in_view atStart:YES];
303 [NSApp postEvent:left_up_in_view atStart:YES];
304 [NSApp postEvent:left_down_in_view atStart:YES];
305 [button_ otherMouseDown:other_down_in_view];
307 EXPECT_EQ(NSOffState, [button_ state]);
308 EXPECT_EQ(1, [button_ numOfClick]);
309 EXPECT_EQ(IDC_HOME, [button_ lastCommand]);