• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#import <Cocoa/Cocoa.h>
6
7#import "base/memory/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/test_event_utils.h"
11#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
12#import "testing/gtest_mac.h"
13
14@interface TestableToolbarButton : ToolbarButton {
15 @private
16  NSInteger numOfClick_;
17  NSInteger lastCommand_;
18}
19
20@property(assign, nonatomic) NSInteger numOfClick;
21@property(assign, nonatomic) NSInteger lastCommand;
22
23- (id)initWithFrame:(NSRect)frame;
24- (void)doAction:(id)sender;
25@end
26
27@implementation TestableToolbarButton
28
29@synthesize numOfClick = numOfClick_;
30@synthesize lastCommand = lastCommand_;
31
32- (id)initWithFrame:(NSRect)frame {
33  if ((self = [super initWithFrame:frame])) {
34    lastCommand_ = IDC_STOP;
35  }
36  return self;
37}
38
39- (void)doAction:(id)sender {
40  lastCommand_ = [sender tag];
41  if (lastCommand_ == [self tag])
42    ++numOfClick_;
43}
44
45- (BOOL)shouldHandleEvent:(NSEvent*)theEvent {
46  return handleMiddleClick_;
47}
48
49@end
50
51namespace {
52
53class ToolbarButtonTest : public CocoaTest {
54 public:
55  ToolbarButtonTest() {
56    NSRect frame = NSMakeRect(0, 0, 20, 20);
57    scoped_nsobject<TestableToolbarButton> button(
58        [[TestableToolbarButton alloc] initWithFrame:frame]);
59    button_ = button.get();
60
61    [button_ setTag:IDC_HOME];
62    [button_ setTarget:button_];
63    [button_ setAction:@selector(doAction:)];
64    [[test_window() contentView] addSubview:button_];
65
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);
70    left_down_in_view =
71        test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseDown, 0);
72    left_up_in_view =
73        test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseUp, 0);
74    right_down_in_view =
75        test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseDown, 0);
76    right_up_in_view =
77        test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseUp, 0);
78    other_down_in_view =
79        test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDown, 0);
80    other_dragged_in_view =
81        test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDragged, 0);
82    other_up_in_view =
83        test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseUp, 0);
84    other_down_out_view =
85        test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDown, 0);
86    other_dragged_out_view =
87        test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDragged, 0);
88    other_up_out_view =
89        test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseUp, 0);
90  }
91
92  TestableToolbarButton* button_;
93  NSEvent* left_down_in_view;
94  NSEvent* left_up_in_view;
95  NSEvent* right_down_in_view;
96  NSEvent* right_up_in_view;
97  NSEvent* other_down_in_view;
98  NSEvent* other_dragged_in_view;
99  NSEvent* other_up_in_view;
100  NSEvent* other_down_out_view;
101  NSEvent* other_dragged_out_view;
102  NSEvent* other_up_out_view;
103};
104
105TEST_VIEW(ToolbarButtonTest, button_)
106
107TEST_F(ToolbarButtonTest, DoesNotSwallowClicksOnNO) {
108  // Middle button being down doesn't swallow right button clicks. But
109  // ToolbarButton doesn't handle right button events.
110  [button_ otherMouseDown:other_down_in_view];
111  EXPECT_EQ(NSOffState, [button_ state]);
112  [button_ rightMouseDown:right_down_in_view];
113  EXPECT_EQ(NSOffState, [button_ state]);
114  [button_ rightMouseUp:right_up_in_view];
115  EXPECT_EQ(NSOffState, [button_ state]);
116  EXPECT_EQ(0, [button_ numOfClick]);
117  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
118  [button_ otherMouseUp:other_up_in_view];
119  EXPECT_EQ(NSOffState, [button_ state]);
120  EXPECT_EQ(0, [button_ numOfClick]);
121  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
122
123  // Middle button being down doesn't swallows left button clicks.
124  [button_ otherMouseDown:other_down_in_view];
125  EXPECT_EQ(NSOffState, [button_ state]);
126  [NSApp postEvent:left_up_in_view atStart:YES];
127  [button_ mouseDown:left_down_in_view];
128  EXPECT_EQ(1, [button_ numOfClick]);
129  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
130  [button_ otherMouseUp:other_up_in_view];
131  EXPECT_EQ(1, [button_ numOfClick]);
132  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
133}
134
135TEST_F(ToolbarButtonTest, WithoutMouseDownOnNO) {
136  // Middle button mouse up without leading mouse down in the view.
137  [button_ otherMouseUp:other_up_in_view];
138  EXPECT_EQ(NSOffState, [button_ state]);
139  EXPECT_EQ(0, [button_ numOfClick]);
140  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
141
142  // Middle button mouse dragged in the view and up without leading mouse down.
143  [button_ otherMouseDragged:other_dragged_in_view];
144  EXPECT_EQ(NSOffState, [button_ state]);
145  [button_ otherMouseUp:other_up_in_view];
146  EXPECT_EQ(NSOffState, [button_ state]);
147  EXPECT_EQ(0, [button_ numOfClick]);
148  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
149}
150
151TEST_F(ToolbarButtonTest, MouseClickOnNO) {
152  // Middle button clicking in the view.
153  [button_ otherMouseDown:other_down_in_view];
154  EXPECT_EQ(NSOffState, [button_ state]);
155  [button_ otherMouseUp:other_up_in_view];
156  EXPECT_EQ(NSOffState, [button_ state]);
157  EXPECT_EQ(0, [button_ numOfClick]);
158  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
159
160  // Middle button clicking outside of the view.
161  [button_ otherMouseDown:other_down_out_view];
162  EXPECT_EQ(NSOffState, [button_ state]);
163  [button_ otherMouseUp:other_up_out_view];
164  EXPECT_EQ(NSOffState, [button_ state]);
165  EXPECT_EQ(0, [button_ numOfClick]);
166  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
167}
168
169TEST_F(ToolbarButtonTest, MouseDraggingOnNO) {
170  // Middle button being down in the view and up outside of the view.
171  [button_ otherMouseDown:other_down_in_view];
172  EXPECT_EQ(NSOffState, [button_ state]);
173  [button_ otherMouseDragged:other_dragged_out_view];
174  EXPECT_EQ(NSOffState, [button_ state]);
175  [button_ otherMouseUp:other_up_out_view];
176  EXPECT_EQ(NSOffState, [button_ state]);
177  EXPECT_EQ(0, [button_ numOfClick]);
178  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
179
180  // Middle button being down on the button, move to outside and move on it
181  // again, then up on the button.
182  [button_ otherMouseDown:other_down_in_view];
183  EXPECT_EQ(NSOffState, [button_ state]);
184  [button_ otherMouseDragged:other_dragged_in_view];
185  EXPECT_EQ(NSOffState, [button_ state]);
186  [button_ otherMouseUp:other_up_in_view];
187  EXPECT_EQ(NSOffState, [button_ state]);
188  EXPECT_EQ(0, [button_ numOfClick]);
189  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
190}
191
192TEST_F(ToolbarButtonTest, WithoutMouseDownOnYES) {
193  // Enable middle button handling.
194  [button_ setHandleMiddleClick:YES];
195
196  // Middle button mouse up without leading mouse down in the view.
197  [button_ otherMouseUp:other_up_in_view];
198  EXPECT_EQ(NSOffState, [button_ state]);
199  EXPECT_EQ(0, [button_ numOfClick]);
200  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
201
202  // Middle button mouse dragged in the view and up without leading mouse down.
203  [button_ otherMouseDragged:other_dragged_in_view];
204  EXPECT_EQ(NSOffState, [button_ state]);
205  [button_ otherMouseUp:other_up_in_view];
206  EXPECT_EQ(NSOffState, [button_ state]);
207  EXPECT_EQ(0, [button_ numOfClick]);
208  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
209}
210
211TEST_F(ToolbarButtonTest, MouseClickInsideOnYES) {
212  // Enable middle button handling.
213  [button_ setHandleMiddleClick:YES];
214
215  // Middle button clicking in the view.
216  [button_ otherMouseDown:other_down_in_view];
217  EXPECT_EQ(NSOnState, [button_ state]);
218  [button_ otherMouseUp:other_up_in_view];
219  EXPECT_EQ(NSOffState, [button_ state]);
220  EXPECT_EQ(1, [button_ numOfClick]);
221  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
222}
223
224TEST_F(ToolbarButtonTest, MouseClickOutsideOnYES) {
225  // Enable middle button handling.
226  [button_ setHandleMiddleClick:YES];
227
228  // Middle button clicking outside of the view.
229  [button_ otherMouseDown:other_down_out_view];
230  EXPECT_EQ(NSOffState, [button_ state]);
231  [button_ otherMouseUp:other_up_out_view];
232  EXPECT_EQ(NSOffState, [button_ state]);
233  EXPECT_EQ(0, [button_ numOfClick]);
234  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
235}
236
237TEST_F(ToolbarButtonTest, MouseDraggingOnYES) {
238  // Enable middle button handling.
239  [button_ setHandleMiddleClick:YES];
240
241  // Middle button being down in the view and up outside of the view.
242  [button_ otherMouseDown:other_down_in_view];
243  EXPECT_EQ(NSOnState, [button_ state]);
244  [button_ otherMouseDragged:other_dragged_out_view];
245  EXPECT_EQ(NSOffState, [button_ state]);
246  [button_ otherMouseUp:other_up_out_view];
247  EXPECT_EQ(NSOffState, [button_ state]);
248  EXPECT_EQ(0, [button_ numOfClick]);
249  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
250
251  // Middle button being down on the button, move to outside and move on it
252  // again, then up on the button.
253  [button_ otherMouseDown:other_down_in_view];
254  EXPECT_EQ(NSOnState, [button_ state]);
255  [button_ otherMouseDragged:other_dragged_out_view];
256  EXPECT_EQ(NSOffState, [button_ state]);
257  [button_ otherMouseDragged:other_dragged_in_view];
258  EXPECT_EQ(NSOnState, [button_ state]);
259  [button_ otherMouseUp:other_up_in_view];
260  EXPECT_EQ(NSOffState, [button_ state]);
261  EXPECT_EQ(1, [button_ numOfClick]);
262  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
263}
264
265TEST_F(ToolbarButtonTest, DoesNotSwallowRightClickOnYES) {
266  // Enable middle button handling.
267  [button_ setHandleMiddleClick:YES];
268
269  // Middle button being down should swallow right button clicks, but
270  // ToolbarButton doesn't swallow it because it doesn't handle right button
271  // events.
272  [button_ otherMouseDown:other_down_in_view];
273  EXPECT_EQ(NSOnState, [button_ state]);
274  [button_ rightMouseDown:right_down_in_view];
275  EXPECT_EQ(NSOnState, [button_ state]);
276  [button_ rightMouseUp:right_up_in_view];
277  EXPECT_EQ(NSOnState, [button_ state]);
278  EXPECT_EQ(0, [button_ numOfClick]);
279  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
280  [button_ otherMouseUp:other_up_in_view];
281  EXPECT_EQ(NSOffState, [button_ state]);
282  EXPECT_EQ(1, [button_ numOfClick]);
283  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
284}
285
286TEST_F(ToolbarButtonTest, DoesSwallowLeftClickOnYES) {
287  // Enable middle button handling.
288  [button_ setHandleMiddleClick:YES];
289
290  // Middle button being down swallows left button clicks.
291  [button_ otherMouseDown:other_down_in_view];
292  EXPECT_EQ(NSOnState, [button_ state]);
293  [NSApp postEvent:left_up_in_view atStart:YES];
294  [button_ mouseDown:left_down_in_view];
295  EXPECT_EQ(0, [button_ numOfClick]);
296  EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
297  [button_ otherMouseUp:other_up_in_view];
298  EXPECT_EQ(1, [button_ numOfClick]);
299  EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
300}
301
302}  // namespace
303