Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / menu_button_unittest.mm
blobc5938beb895fedc80f591ff869047bbe997e1fe3
1 // Copyright (c) 2012 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 #include "base/mac/scoped_nsobject.h"
6 #import "chrome/browser/ui/cocoa/clickhold_button_cell.h"
7 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
8 #import "chrome/browser/ui/cocoa/menu_button.h"
10 @interface MenuButtonTestDelegate : NSObject<NSMenuDelegate> {
11  @private
12   base::scoped_nsobject<NSMenu> menu_;
13   BOOL open_;
14   BOOL didOpen_;
16 - (BOOL)isOpen;
17 - (BOOL)didOpen;
18 @end
20 @implementation MenuButtonTestDelegate
21 - (id)initWithMenu:(NSMenu*)menu {
22   if ((self = [super init])) {
23     menu_.reset([menu retain]);
24   }
25   return self;
28 - (BOOL)isOpen {
29   return open_;
32 - (BOOL)didOpen {
33   return didOpen_;
36 - (void)menuWillOpen:(NSMenu*)menu {
37   EXPECT_EQ(menu_.get(), menu);
38   EXPECT_FALSE(open_);
39   open_ = YES;
40   didOpen_ = YES;
41   NSArray* modes = [NSArray arrayWithObjects:NSEventTrackingRunLoopMode,
42                                              NSDefaultRunLoopMode,
43                                              nil];
44   [menu performSelector:@selector(cancelTracking)
45              withObject:nil
46              afterDelay:0.1
47                 inModes:modes];
50 - (void)menuDidClose:(NSMenu*)menu {
51   EXPECT_EQ(menu_.get(), menu);
52   EXPECT_TRUE(open_);
53   open_ = NO;
55 @end
57 namespace {
59 class MenuButtonTest : public CocoaTest {
60  public:
61   MenuButtonTest() {
62     NSRect frame = NSMakeRect(0, 0, 50, 30);
63     base::scoped_nsobject<MenuButton> button(
64         [[MenuButton alloc] initWithFrame:frame]);
65     button_ = button.get();
66     base::scoped_nsobject<ClickHoldButtonCell> cell(
67         [[ClickHoldButtonCell alloc] initTextCell:@"Testing"]);
68     [button_ setCell:cell.get()];
69     [[test_window() contentView] addSubview:button_];
70   }
72   NSMenu* CreateMenu() {
73     NSMenu* menu = [[NSMenu alloc] initWithTitle:@""];
74     [menu insertItemWithTitle:@"" action:nil keyEquivalent:@"" atIndex:0];
75     [menu insertItemWithTitle:@"foo" action:nil keyEquivalent:@"" atIndex:1];
76     [menu insertItemWithTitle:@"bar" action:nil keyEquivalent:@"" atIndex:2];
77     [menu insertItemWithTitle:@"baz" action:nil keyEquivalent:@"" atIndex:3];
78     return menu;
79   }
81   NSEvent* MouseEvent(NSEventType eventType) {
82     NSPoint location;
83     if (button_)
84       location = [button_ frame].origin;
85     else
86       location.x = location.y = 0;
88     NSGraphicsContext* context = [NSGraphicsContext currentContext];
89     NSEvent* event = [NSEvent mouseEventWithType:eventType
90                                         location:location
91                                    modifierFlags:0
92                                        timestamp:0
93                                     windowNumber:[test_window() windowNumber]
94                                          context:context
95                                      eventNumber:0
96                                       clickCount:1
97                                         pressure:1.0F];
99     return event;
100   }
102   MenuButton* button_;
105 TEST_VIEW(MenuButtonTest, button_);
107 // Test assigning a menu, again mostly to ensure nothing leaks or crashes.
108 TEST_F(MenuButtonTest, MenuAssign) {
109   base::scoped_nsobject<NSMenu> menu(CreateMenu());
110   ASSERT_TRUE(menu.get());
112   [button_ setAttachedMenu:menu];
113   EXPECT_TRUE([button_ attachedMenu]);
116 TEST_F(MenuButtonTest, OpenOnClick) {
117   base::scoped_nsobject<NSMenu> menu(CreateMenu());
118   ASSERT_TRUE(menu.get());
120   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
121       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
122   ASSERT_TRUE(delegate.get());
124   [menu setDelegate:delegate.get()];
125   [button_ setAttachedMenu:menu];
126   [button_ setOpenMenuOnClick:YES];
128   EXPECT_FALSE([delegate isOpen]);
129   EXPECT_FALSE([delegate didOpen]);
131   // Should open the menu.
132   [button_ performClick:nil];
134   EXPECT_TRUE([delegate didOpen]);
135   EXPECT_FALSE([delegate isOpen]);
138 // Test classic Mac menu behavior.
139 TEST_F(MenuButtonTest, DISABLED_OpenOnClickAndHold) {
140   base::scoped_nsobject<NSMenu> menu(CreateMenu());
141   ASSERT_TRUE(menu.get());
143   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
144       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
145   ASSERT_TRUE(delegate.get());
147   [menu setDelegate:delegate.get()];
148   [button_ setAttachedMenu:menu];
149   [button_ setOpenMenuOnClick:YES];
151   EXPECT_FALSE([delegate isOpen]);
152   EXPECT_FALSE([delegate didOpen]);
154   // Should open the menu.
155   NSEvent* event = MouseEvent(NSLeftMouseDown);
156   [test_window() sendEvent:event];
158   EXPECT_TRUE([delegate didOpen]);
159   EXPECT_FALSE([delegate isOpen]);
162 TEST_F(MenuButtonTest, OpenOnRightClick) {
163   base::scoped_nsobject<NSMenu> menu(CreateMenu());
164   ASSERT_TRUE(menu.get());
166   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
167       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
168   ASSERT_TRUE(delegate.get());
170   [menu setDelegate:delegate.get()];
171   [button_ setAttachedMenu:menu];
172   [button_ setOpenMenuOnClick:YES];
173   // Right click is enabled.
174   [button_ setOpenMenuOnRightClick:YES];
176   EXPECT_FALSE([delegate isOpen]);
177   EXPECT_FALSE([delegate didOpen]);
179   // Should open the menu.
180   NSEvent* event = MouseEvent(NSRightMouseDown);
181   [button_ rightMouseDown:event];
183   EXPECT_TRUE([delegate didOpen]);
184   EXPECT_FALSE([delegate isOpen]);
187 TEST_F(MenuButtonTest, DontOpenOnRightClickWithoutSetRightClick) {
188   base::scoped_nsobject<NSMenu> menu(CreateMenu());
189   ASSERT_TRUE(menu.get());
191   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
192       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
193   ASSERT_TRUE(delegate.get());
195   [menu setDelegate:delegate.get()];
196   [button_ setAttachedMenu:menu];
197   [button_ setOpenMenuOnClick:YES];
199   EXPECT_FALSE([delegate isOpen]);
200   EXPECT_FALSE([delegate didOpen]);
202   // Should not open the menu.
203   NSEvent* event = MouseEvent(NSRightMouseDown);
204   [button_ rightMouseDown:event];
206   EXPECT_FALSE([delegate didOpen]);
207   EXPECT_FALSE([delegate isOpen]);
209   // Should open the menu in this case.
210   [button_ performClick:nil];
212   EXPECT_TRUE([delegate didOpen]);
213   EXPECT_FALSE([delegate isOpen]);
216 TEST_F(MenuButtonTest, OpenOnAccessibilityPerformAction) {
217   base::scoped_nsobject<NSMenu> menu(CreateMenu());
218   ASSERT_TRUE(menu.get());
220   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
221       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
222   ASSERT_TRUE(delegate.get());
224   [menu setDelegate:delegate.get()];
225   [button_ setAttachedMenu:menu];
226   NSCell* buttonCell = [button_ cell];
228   EXPECT_FALSE([delegate isOpen]);
229   EXPECT_FALSE([delegate didOpen]);
231   [button_ setOpenMenuOnClick:YES];
233   // NSAccessibilityShowMenuAction should not be available but
234   // NSAccessibilityPressAction should.
235   NSArray* actionNames = [buttonCell accessibilityActionNames];
236   EXPECT_FALSE([actionNames containsObject:NSAccessibilityShowMenuAction]);
237   EXPECT_TRUE([actionNames containsObject:NSAccessibilityPressAction]);
239   [button_ setOpenMenuOnClick:NO];
241   // NSAccessibilityPressAction should not be the one used to open the menu now.
242   actionNames = [buttonCell accessibilityActionNames];
243   EXPECT_TRUE([actionNames containsObject:NSAccessibilityShowMenuAction]);
244   EXPECT_TRUE([actionNames containsObject:NSAccessibilityPressAction]);
246   [buttonCell accessibilityPerformAction:NSAccessibilityShowMenuAction];
247   EXPECT_TRUE([delegate didOpen]);
248   EXPECT_FALSE([delegate isOpen]);
251 TEST_F(MenuButtonTest, OpenOnAccessibilityPerformActionWithSetRightClick) {
252   base::scoped_nsobject<NSMenu> menu(CreateMenu());
253   ASSERT_TRUE(menu.get());
255   base::scoped_nsobject<MenuButtonTestDelegate> delegate(
256       [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
257   ASSERT_TRUE(delegate.get());
259   [menu setDelegate:delegate.get()];
260   [button_ setAttachedMenu:menu];
261   NSCell* buttonCell = [button_ cell];
263   EXPECT_FALSE([delegate isOpen]);
264   EXPECT_FALSE([delegate didOpen]);
266   [button_ setOpenMenuOnClick:YES];
268   // Command to open the menu should not be available.
269   NSArray* actionNames = [buttonCell accessibilityActionNames];
270   EXPECT_FALSE([actionNames containsObject:NSAccessibilityShowMenuAction]);
272   [button_ setOpenMenuOnRightClick:YES];
274   // Command to open the menu should now become available.
275   actionNames = [buttonCell accessibilityActionNames];
276   EXPECT_TRUE([actionNames containsObject:NSAccessibilityShowMenuAction]);
278   [button_ setOpenMenuOnClick:NO];
280   // Command should still be available, even when both click + hold and right
281   // click are turned on.
282   actionNames = [buttonCell accessibilityActionNames];
283   EXPECT_TRUE([actionNames containsObject:NSAccessibilityShowMenuAction]);
285   [buttonCell accessibilityPerformAction:NSAccessibilityShowMenuAction];
286   EXPECT_TRUE([delegate didOpen]);
287   EXPECT_FALSE([delegate isOpen]);
290 }  // namespace