• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
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"
9
10@interface MenuButtonTestDelegate : NSObject<NSMenuDelegate> {
11 @private
12  base::scoped_nsobject<NSMenu> menu_;
13  BOOL open_;
14  BOOL didOpen_;
15}
16- (BOOL)isOpen;
17- (BOOL)didOpen;
18@end
19
20@implementation MenuButtonTestDelegate
21- (id)initWithMenu:(NSMenu*)menu {
22  if ((self = [super init])) {
23    menu_.reset([menu retain]);
24  }
25  return self;
26}
27
28- (BOOL)isOpen {
29  return open_;
30}
31
32- (BOOL)didOpen {
33  return didOpen_;
34}
35
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];
48}
49
50- (void)menuDidClose:(NSMenu*)menu {
51  EXPECT_EQ(menu_.get(), menu);
52  EXPECT_TRUE(open_);
53  open_ = NO;
54}
55@end
56
57namespace {
58
59class 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  }
71
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  }
80
81  NSEvent* MouseDownEvent(NSEventType eventType) {
82    NSPoint location;
83    location.x = location.y = 0;
84    NSGraphicsContext* context = [NSGraphicsContext currentContext];
85    NSEvent* event = [NSEvent mouseEventWithType:eventType
86                                        location:location
87                                   modifierFlags:0
88                                       timestamp:0
89                                    windowNumber:0
90                                         context:context
91                                     eventNumber:0
92                                      clickCount:1
93                                        pressure:0.0F];
94
95    return event;
96  }
97
98  MenuButton* button_;
99};
100
101TEST_VIEW(MenuButtonTest, button_);
102
103// Test assigning a menu, again mostly to ensure nothing leaks or crashes.
104TEST_F(MenuButtonTest, MenuAssign) {
105  base::scoped_nsobject<NSMenu> menu(CreateMenu());
106  ASSERT_TRUE(menu.get());
107
108  [button_ setAttachedMenu:menu];
109  EXPECT_TRUE([button_ attachedMenu]);
110}
111
112TEST_F(MenuButtonTest, OpenOnClick) {
113  base::scoped_nsobject<NSMenu> menu(CreateMenu());
114  ASSERT_TRUE(menu.get());
115
116  base::scoped_nsobject<MenuButtonTestDelegate> delegate(
117      [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
118  ASSERT_TRUE(delegate.get());
119
120  [menu setDelegate:delegate.get()];
121  [button_ setAttachedMenu:menu];
122  [button_ setOpenMenuOnClick:YES];
123
124  EXPECT_FALSE([delegate isOpen]);
125  EXPECT_FALSE([delegate didOpen]);
126
127  // Should open the menu.
128  [button_ performClick:nil];
129
130  EXPECT_TRUE([delegate didOpen]);
131  EXPECT_FALSE([delegate isOpen]);
132}
133
134TEST_F(MenuButtonTest, OpenOnRightClick) {
135  base::scoped_nsobject<NSMenu> menu(CreateMenu());
136  ASSERT_TRUE(menu.get());
137
138  base::scoped_nsobject<MenuButtonTestDelegate> delegate(
139      [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
140  ASSERT_TRUE(delegate.get());
141
142  [menu setDelegate:delegate.get()];
143  [button_ setAttachedMenu:menu];
144  [button_ setOpenMenuOnClick:YES];
145  // Right click is enabled.
146  [button_ setOpenMenuOnRightClick:YES];
147
148  EXPECT_FALSE([delegate isOpen]);
149  EXPECT_FALSE([delegate didOpen]);
150
151  // Should open the menu.
152  NSEvent* event = MouseDownEvent(NSRightMouseDown);
153  [button_ rightMouseDown:event];
154
155  EXPECT_TRUE([delegate didOpen]);
156  EXPECT_FALSE([delegate isOpen]);
157}
158
159TEST_F(MenuButtonTest, DontOpenOnRightClickWithoutSetRightClick) {
160  base::scoped_nsobject<NSMenu> menu(CreateMenu());
161  ASSERT_TRUE(menu.get());
162
163  base::scoped_nsobject<MenuButtonTestDelegate> delegate(
164      [[MenuButtonTestDelegate alloc] initWithMenu:menu.get()]);
165  ASSERT_TRUE(delegate.get());
166
167  [menu setDelegate:delegate.get()];
168  [button_ setAttachedMenu:menu];
169  [button_ setOpenMenuOnClick:YES];
170
171  EXPECT_FALSE([delegate isOpen]);
172  EXPECT_FALSE([delegate didOpen]);
173
174  // Should not open the menu.
175  NSEvent* event = MouseDownEvent(NSRightMouseDown);
176  [button_ rightMouseDown:event];
177
178  EXPECT_FALSE([delegate didOpen]);
179  EXPECT_FALSE([delegate isOpen]);
180
181  // Should open the menu in this case.
182  [button_ performClick:nil];
183
184  EXPECT_TRUE([delegate didOpen]);
185  EXPECT_FALSE([delegate isOpen]);
186}
187
188}  // namespace
189