Home | History | Annotate | Download | only in cocoa
      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