Home | History | Annotate | Download | only in toolbar
      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/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"
     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 
     51 namespace {
     52 
     53 class ToolbarButtonTest : public CocoaTest {
     54  public:
     55   ToolbarButtonTest() {
     56     NSRect frame = NSMakeRect(0, 0, 20, 20);
     57     base::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         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     72                                                   NSLeftMouseDown,
     73                                                   0);
     74     left_up_in_view =
     75         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     76                                                   NSLeftMouseUp,
     77                                                   0);
     78     right_down_in_view =
     79         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     80                                                   NSRightMouseDown,
     81                                                   0);
     82     right_up_in_view =
     83         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     84                                                   NSRightMouseUp,
     85                                                   0);
     86     other_down_in_view =
     87         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     88                                                   NSOtherMouseDown,
     89                                                   0);
     90     other_dragged_in_view =
     91         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     92                                                   NSOtherMouseDragged,
     93                                                   0);
     94     other_up_in_view =
     95         cocoa_test_event_utils::MouseEventAtPoint(mid_point,
     96                                                   NSOtherMouseUp,
     97                                                   0);
     98     other_down_out_view =
     99         cocoa_test_event_utils::MouseEventAtPoint(out_point,
    100                                                   NSOtherMouseDown,
    101                                                   0);
    102     other_dragged_out_view =
    103         cocoa_test_event_utils::MouseEventAtPoint(out_point,
    104                                                   NSOtherMouseDragged,
    105                                                   0);
    106     other_up_out_view =
    107         cocoa_test_event_utils::MouseEventAtPoint(out_point,
    108                                                   NSOtherMouseUp,
    109                                                   0);
    110   }
    111 
    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;
    123 };
    124 
    125 TEST_VIEW(ToolbarButtonTest, button_)
    126 
    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]);
    142 
    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]);
    153 }
    154 
    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]);
    161 
    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]);
    169 }
    170 
    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]);
    179 
    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]);
    187 }
    188 
    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]);
    199 
    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]);
    210 }
    211 
    212 TEST_F(ToolbarButtonTest, WithoutMouseDownOnYES) {
    213   // Enable middle button handling.
    214   [button_ setHandleMiddleClick:YES];
    215 
    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]);
    221 
    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]);
    229 }
    230 
    231 TEST_F(ToolbarButtonTest, MouseClickInsideOnYES) {
    232   // Enable middle button handling.
    233   [button_ setHandleMiddleClick:YES];
    234 
    235   // Middle button clicking in the view.
    236   [NSApp postEvent:other_up_in_view atStart:YES];
    237   [button_ otherMouseDown:other_down_in_view];
    238 
    239   EXPECT_EQ(NSOffState, [button_ state]);
    240   EXPECT_EQ(1, [button_ numOfClick]);
    241   EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
    242 }
    243 
    244 TEST_F(ToolbarButtonTest, MouseClickOutsideOnYES) {
    245   // Enable middle button handling.
    246   [button_ setHandleMiddleClick:YES];
    247 
    248   // Middle button clicking outside of the view.
    249   [NSApp postEvent:other_up_out_view atStart:YES];
    250   [button_ otherMouseDown:other_down_out_view];
    251 
    252   EXPECT_EQ(NSOffState, [button_ state]);
    253   EXPECT_EQ(0, [button_ numOfClick]);
    254   EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
    255 }
    256 
    257 TEST_F(ToolbarButtonTest, MouseDraggingOnYES) {
    258   // Enable middle button handling.
    259   [button_ setHandleMiddleClick:YES];
    260 
    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];
    265 
    266   EXPECT_EQ(NSOffState, [button_ state]);
    267   EXPECT_EQ(0, [button_ numOfClick]);
    268   EXPECT_EQ(IDC_STOP, [button_ lastCommand]);
    269 
    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];
    276 
    277   EXPECT_EQ(NSOffState, [button_ state]);
    278   EXPECT_EQ(1, [button_ numOfClick]);
    279   EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
    280 }
    281 
    282 TEST_F(ToolbarButtonTest, DoesSwallowRightClickOnYES) {
    283   // Enable middle button handling.
    284   [button_ setHandleMiddleClick:YES];
    285 
    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];
    291 
    292   EXPECT_EQ(NSOffState, [button_ state]);
    293   EXPECT_EQ(1, [button_ numOfClick]);
    294   EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
    295 }
    296 
    297 TEST_F(ToolbarButtonTest, DoesSwallowLeftClickOnYES) {
    298   // Enable middle button handling.
    299   [button_ setHandleMiddleClick:YES];
    300 
    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];
    306 
    307   EXPECT_EQ(NSOffState, [button_ state]);
    308   EXPECT_EQ(1, [button_ numOfClick]);
    309   EXPECT_EQ(IDC_HOME, [button_ lastCommand]);
    310 }
    311 
    312 }  // namespace
    313