Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / base_bubble_controller_unittest.mm
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 #import "chrome/browser/ui/cocoa/base_bubble_controller.h"
6
7 #include "base/mac/mac_util.h"
8 #import "base/mac/scoped_nsobject.h"
9 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
10 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
11 #import "chrome/browser/ui/cocoa/run_loop_testing.h"
12 #import "ui/events/test/cocoa_test_event_utils.h"
13
14 namespace {
15 const CGFloat kBubbleWindowWidth = 100;
16 const CGFloat kBubbleWindowHeight = 50;
17 const CGFloat kAnchorPointX = 400;
18 const CGFloat kAnchorPointY = 300;
19 }  // namespace
20
21 class BaseBubbleControllerTest : public CocoaTest {
22  public:
23   virtual void SetUp() OVERRIDE {
24     bubbleWindow_.reset([[NSWindow alloc]
25         initWithContentRect:NSMakeRect(0, 0, kBubbleWindowWidth,
26                                        kBubbleWindowHeight)
27                   styleMask:NSBorderlessWindowMask
28                     backing:NSBackingStoreBuffered
29                       defer:YES]);
30
31     // The bubble controller will release itself when the window closes.
32     controller_ = [[BaseBubbleController alloc]
33         initWithWindow:bubbleWindow_.get()
34           parentWindow:test_window()
35             anchoredAt:NSMakePoint(kAnchorPointX, kAnchorPointY)];
36     EXPECT_TRUE([controller_ bubble]);
37   }
38
39   virtual void TearDown() OVERRIDE {
40     // Close our windows.
41     [controller_ close];
42     bubbleWindow_.reset(NULL);
43     CocoaTest::TearDown();
44   }
45
46  public:
47   base::scoped_nsobject<NSWindow> bubbleWindow_;
48   BaseBubbleController* controller_;
49 };
50
51 // Test that kAlignEdgeToAnchorEdge and a left bubble arrow correctly aligns the
52 // left edge of the buble to the anchor point.
53 TEST_F(BaseBubbleControllerTest, LeftAlign) {
54   [[controller_ bubble] setArrowLocation:info_bubble::kTopLeft];
55   [[controller_ bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
56   [controller_ showWindow:nil];
57
58   NSRect frame = [[controller_ window] frame];
59   // Make sure the bubble size hasn't changed.
60   EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
61   EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
62   // Make sure the bubble is left aligned.
63   EXPECT_EQ(NSMinX(frame), kAnchorPointX);
64   EXPECT_GE(NSMaxY(frame), kAnchorPointY);
65 }
66
67 // Test that kAlignEdgeToAnchorEdge and a right bubble arrow correctly aligns
68 // the right edge of the buble to the anchor point.
69 TEST_F(BaseBubbleControllerTest, RightAlign) {
70   [[controller_ bubble] setArrowLocation:info_bubble::kTopRight];
71   [[controller_ bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
72   [controller_ showWindow:nil];
73
74   NSRect frame = [[controller_ window] frame];
75   // Make sure the bubble size hasn't changed.
76   EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
77   EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
78   // Make sure the bubble is left aligned.
79   EXPECT_EQ(NSMaxX(frame), kAnchorPointX);
80   EXPECT_GE(NSMaxY(frame), kAnchorPointY);
81 }
82
83 // Test that kAlignArrowToAnchor and a left bubble arrow correctly aligns
84 // the bubble arrow to the anchor point.
85 TEST_F(BaseBubbleControllerTest, AnchorAlignLeftArrow) {
86   [[controller_ bubble] setArrowLocation:info_bubble::kTopLeft];
87   [[controller_ bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
88   [controller_ showWindow:nil];
89
90   NSRect frame = [[controller_ window] frame];
91   // Make sure the bubble size hasn't changed.
92   EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
93   EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
94   // Make sure the bubble arrow points to the anchor.
95   EXPECT_EQ(NSMinX(frame) + info_bubble::kBubbleArrowXOffset +
96       roundf(info_bubble::kBubbleArrowWidth / 2.0), kAnchorPointX);
97   EXPECT_GE(NSMaxY(frame), kAnchorPointY);
98 }
99
100 // Test that kAlignArrowToAnchor and a right bubble arrow correctly aligns
101 // the bubble arrow to the anchor point.
102 TEST_F(BaseBubbleControllerTest, AnchorAlignRightArrow) {
103   [[controller_ bubble] setArrowLocation:info_bubble::kTopRight];
104   [[controller_ bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
105   [controller_ showWindow:nil];
106
107   NSRect frame = [[controller_ window] frame];
108   // Make sure the bubble size hasn't changed.
109   EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
110   EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
111   // Make sure the bubble arrow points to the anchor.
112   EXPECT_EQ(NSMaxX(frame) - info_bubble::kBubbleArrowXOffset -
113       floorf(info_bubble::kBubbleArrowWidth / 2.0), kAnchorPointX);
114   EXPECT_GE(NSMaxY(frame), kAnchorPointY);
115 }
116
117 // Test that kAlignArrowToAnchor and a center bubble arrow correctly align
118 // the bubble towards the anchor point.
119 TEST_F(BaseBubbleControllerTest, AnchorAlignCenterArrow) {
120   [[controller_ bubble] setArrowLocation:info_bubble::kTopCenter];
121   [[controller_ bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
122   [controller_ showWindow:nil];
123
124   NSRect frame = [[controller_ window] frame];
125   // Make sure the bubble size hasn't changed.
126   EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
127   EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
128   // Make sure the bubble arrow points to the anchor.
129   EXPECT_EQ(NSMidX(frame), kAnchorPointX);
130   EXPECT_GE(NSMaxY(frame), kAnchorPointY);
131 }
132
133 // Tests that when a new window gets key state (and the bubble resigns) that
134 // the key window changes.
135 TEST_F(BaseBubbleControllerTest, ResignKeyCloses) {
136   // Closing the bubble will autorelease the controller.
137   base::scoped_nsobject<BaseBubbleController> keep_alive([controller_ retain]);
138
139   NSWindow* bubble_window = [controller_ window];
140   EXPECT_FALSE([bubble_window isVisible]);
141
142   base::scoped_nsobject<NSWindow> other_window(
143       [[NSWindow alloc] initWithContentRect:NSMakeRect(500, 500, 500, 500)
144                                   styleMask:NSTitledWindowMask
145                                     backing:NSBackingStoreBuffered
146                                       defer:YES]);
147   EXPECT_FALSE([other_window isVisible]);
148
149   [controller_ showWindow:nil];
150   EXPECT_TRUE([bubble_window isVisible]);
151   EXPECT_FALSE([other_window isVisible]);
152
153   [other_window makeKeyAndOrderFront:nil];
154   // Fake the key state notification. Because unit_tests is a "daemon" process
155   // type, its windows can never become key (nor can the app become active).
156   // Instead of the hacks below, one could make a browser_test or transform the
157   // process type, but this seems easiest and is best suited to a unit test.
158   //
159   // On Lion and above, which have the event taps, simply post a notification
160   // that will cause the controller to call |-windowDidResignKey:|. Earlier
161   // OSes can call through directly.
162   NSNotification* notif =
163       [NSNotification notificationWithName:NSWindowDidResignKeyNotification
164                                     object:bubble_window];
165   if (base::mac::IsOSLionOrLater())
166     [[NSNotificationCenter defaultCenter] postNotification:notif];
167   else
168     [controller_ windowDidResignKey:notif];
169
170
171   EXPECT_FALSE([bubble_window isVisible]);
172   EXPECT_TRUE([other_window isVisible]);
173 }
174
175 // Test that clicking outside the window causes the bubble to close if
176 // shouldCloseOnResignKey is YES.
177 TEST_F(BaseBubbleControllerTest, LionClickOutsideCloses) {
178   // The event tap is only installed on 10.7+.
179   if (!base::mac::IsOSLionOrLater())
180     return;
181
182   // Closing the bubble will autorelease the controller.
183   base::scoped_nsobject<BaseBubbleController> keep_alive([controller_ retain]);
184   NSWindow* window = [controller_ window];
185
186   EXPECT_TRUE([controller_ shouldCloseOnResignKey]);  // Verify default value.
187   EXPECT_FALSE([window isVisible]);
188
189   [controller_ showWindow:nil];
190
191   EXPECT_TRUE([window isVisible]);
192
193   [controller_ setShouldCloseOnResignKey:NO];
194   NSEvent* event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
195       NSMakePoint(10, 10), test_window());
196   [NSApp sendEvent:event];
197   chrome::testing::NSRunLoopRunAllPending();
198
199   EXPECT_TRUE([window isVisible]);
200
201   [controller_ setShouldCloseOnResignKey:YES];
202   event = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
203       NSMakePoint(10, 10), test_window());
204   [NSApp sendEvent:event];
205   chrome::testing::NSRunLoopRunAllPending();
206
207   EXPECT_FALSE([window isVisible]);
208 }