- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / constrained_window / constrained_window_sheet_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/constrained_window/constrained_window_sheet_controller.h"
6
7 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
8 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
9 #import "testing/gtest_mac.h"
10
11 namespace {
12
13 const int kSystemSheetReturnCode = 77;
14
15 }  // namespace
16
17 @interface ConstrainedWindowSystemSheetTest
18     : NSObject <ConstrainedWindowSheet> {
19   int returnCode_;
20   NSAlert* alert_;  // weak
21 }
22
23 @property(nonatomic, readonly) int returnCode;
24 @property(nonatomic, assign) NSAlert* alert;
25
26 @end
27
28 @implementation ConstrainedWindowSystemSheetTest
29
30 @synthesize returnCode = returnCode_;
31 @synthesize alert = alert_;
32
33 - (void)showSheetForWindow:(NSWindow*)window {
34   [alert_ beginSheetModalForWindow:window
35                      modalDelegate:self
36                     didEndSelector:@selector(alertDidEnd:returnCode:ctxInfo:)
37                        contextInfo:NULL];
38 }
39
40 - (void)closeSheetWithAnimation:(BOOL)withAnimation {
41   [NSApp endSheet:[alert_ window] returnCode:kSystemSheetReturnCode];
42 }
43
44 - (void)hideSheet {
45 }
46
47 - (void)unhideSheet {
48 }
49
50 - (void)pulseSheet {
51 }
52
53 - (void)makeSheetKeyAndOrderFront {
54 }
55
56 - (void)updateSheetPosition {
57 }
58
59 - (void)alertDidEnd:(NSAlert *)alert
60          returnCode:(NSInteger)returnCode
61             ctxInfo:(void *)contextInfo {
62   returnCode_ = returnCode;
63 }
64
65 @end
66
67 class ConstrainedWindowSheetControllerTest : public CocoaTest {
68  protected:
69   virtual ~ConstrainedWindowSheetControllerTest() {
70   }
71
72   virtual void SetUp() OVERRIDE {
73     CocoaTest::SetUp();
74
75     // Center the window so that the sheet doesn't go offscreen.
76     [test_window() center];
77
78     // Create two dummy tabs and make the first one active.
79     NSRect dummyRect = NSMakeRect(0, 0, 50, 50);
80     tab_views_.reset([[NSMutableArray alloc] init]);
81     for (int i = 0; i < 2; ++i) {
82       base::scoped_nsobject<NSView> view(
83           [[NSView alloc] initWithFrame:dummyRect]);
84       [tab_views_ addObject:view];
85     }
86     tab0_.reset([[tab_views_ objectAtIndex:0] retain]);
87     tab1_.reset([[tab_views_ objectAtIndex:1] retain]);
88     ActivateTabView(tab0_);
89
90     // Create a test sheet.
91     sheet_window_.reset([[NSWindow alloc]
92         initWithContentRect:dummyRect
93                   styleMask:NSTitledWindowMask
94                     backing:NSBackingStoreBuffered
95                       defer:NO]);
96     [sheet_window_ setReleasedWhenClosed:NO];
97     sheet_.reset([[CustomConstrainedWindowSheet alloc]
98         initWithCustomWindow:sheet_window_]);
99
100     controller_.reset([[ConstrainedWindowSheetController
101             controllerForParentWindow:test_window()] retain]);
102     EXPECT_TRUE(controller_);
103     EXPECT_FALSE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
104   }
105
106   virtual void TearDown() OVERRIDE {
107     sheet_.reset();
108     sheet_window_.reset();
109     CocoaTest::TearDown();
110   }
111
112   void ActivateTabView(NSView* tab_view) {
113     for (NSView* view in tab_views_.get()) {
114       [view removeFromSuperview];
115     }
116     [[test_window() contentView] addSubview:tab_view];
117     active_tab_view_.reset([tab_view retain]);
118
119     ConstrainedWindowSheetController* controller =
120         [ConstrainedWindowSheetController
121             controllerForParentWindow:test_window()];
122     EXPECT_TRUE(controller);
123     [controller parentViewDidBecomeActive:active_tab_view_];
124   }
125
126   NSRect GetViewFrameInScreenCoordinates(NSView* view) {
127     NSRect rect = [view convertRect:[view bounds] toView:nil];
128     rect.origin = [[view window] convertBaseToScreen:rect.origin];
129     return rect;
130   }
131
132   void VerifySheetXPosition(NSRect sheet_frame, NSView* parent_view) {
133     NSRect parent_frame = GetViewFrameInScreenCoordinates(parent_view);
134     CGFloat expected_x = NSMinX(parent_frame) +
135         (NSWidth(parent_frame) - NSWidth(sheet_frame)) / 2.0;
136     EXPECT_EQ(expected_x, NSMinX(sheet_frame));
137   }
138
139   base::scoped_nsobject<NSWindow> sheet_window_;
140   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet_;
141   base::scoped_nsobject<ConstrainedWindowSheetController> controller_;
142   base::scoped_nsobject<NSMutableArray> tab_views_;
143   base::scoped_nsobject<NSView> active_tab_view_;
144   base::scoped_nsobject<NSView> tab0_;
145   base::scoped_nsobject<NSView> tab1_;
146 };
147
148 // Test showing then hiding the sheet.
149 TEST_F(ConstrainedWindowSheetControllerTest, ShowHide) {
150   EXPECT_FALSE([sheet_window_ isVisible]);
151   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
152   EXPECT_TRUE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
153   EXPECT_TRUE([sheet_window_ isVisible]);
154
155   [controller_ closeSheet:sheet_];
156   EXPECT_FALSE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
157   EXPECT_FALSE([sheet_window_ isVisible]);
158 }
159
160 // Test that switching tabs correctly hides the inactive tab's sheet.
161 TEST_F(ConstrainedWindowSheetControllerTest, SwitchTabs) {
162   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
163
164   EXPECT_TRUE([sheet_window_ isVisible]);
165   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
166   ActivateTabView([tab_views_ objectAtIndex:1]);
167   EXPECT_TRUE([sheet_window_ isVisible]);
168   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
169   ActivateTabView([tab_views_ objectAtIndex:0]);
170   EXPECT_TRUE([sheet_window_ isVisible]);
171   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
172 }
173
174 // Test that adding a sheet to an inactive view doesn't show it.
175 TEST_F(ConstrainedWindowSheetControllerTest, AddToInactiveTab) {
176   ActivateTabView(tab0_);
177   [controller_ showSheet:sheet_ forParentView:tab1_];
178   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
179
180   ActivateTabView(tab1_);
181   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
182   VerifySheetXPosition([sheet_window_ frame], tab1_);
183 }
184
185 // Test that two parent windows with two sheet controllers don't conflict.
186 TEST_F(ConstrainedWindowSheetControllerTest, TwoParentWindows) {
187   base::scoped_nsobject<NSWindow> parent_window2(
188       [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 30, 30)
189                                   styleMask:NSTitledWindowMask
190                                     backing:NSBackingStoreBuffered
191                                       defer:NO]);
192   [parent_window2 setReleasedWhenClosed:NO];
193
194   ConstrainedWindowSheetController* controller2 =
195       [ConstrainedWindowSheetController
196           controllerForParentWindow:parent_window2];
197   EXPECT_TRUE(controller2);
198   EXPECT_NSNE(controller_, controller2);
199
200   [controller2 showSheet:sheet_ forParentView:[parent_window2 contentView]];
201   EXPECT_NSEQ(controller2,
202               [ConstrainedWindowSheetController controllerForSheet:sheet_]);
203
204   [parent_window2 close];
205 }
206
207 // Test that using a top level parent view works.
208 TEST_F(ConstrainedWindowSheetControllerTest, TopLevelView) {
209   NSView* parentView = [[test_window() contentView] superview];
210   [controller_ parentViewDidBecomeActive:parentView];
211
212   EXPECT_FALSE([sheet_window_ isVisible]);
213   [controller_ showSheet:sheet_ forParentView:parentView];
214   EXPECT_TRUE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
215   EXPECT_TRUE([sheet_window_ isVisible]);
216   VerifySheetXPosition([sheet_window_ frame], parentView);
217 }
218
219 // Test that resizing sheet works.
220 TEST_F(ConstrainedWindowSheetControllerTest, Resize) {
221   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
222
223   NSRect old_frame = [sheet_window_ frame];
224
225   NSRect sheet_frame;
226   sheet_frame.size = NSMakeSize(NSWidth(old_frame) + 100,
227                                 NSHeight(old_frame) + 50);
228   sheet_frame.origin = [controller_ originForSheet:sheet_
229                                     withWindowSize:sheet_frame.size];
230
231   // Y pos should not have changed.
232   EXPECT_EQ(NSMaxY(sheet_frame), NSMaxY(old_frame));
233
234   // X pos should be centered on parent view.
235   VerifySheetXPosition(sheet_frame, active_tab_view_);
236 }
237
238 // Test that resizing a hidden sheet works.
239 TEST_F(ConstrainedWindowSheetControllerTest, ResizeHiddenSheet) {
240   [controller_ showSheet:sheet_ forParentView:tab0_];
241   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
242   ActivateTabView(tab1_);
243   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
244
245   NSRect old_frame = [sheet_window_ frame];
246   NSRect new_inactive_frame = NSInsetRect(old_frame, -30, -40);
247   [sheet_window_ setFrame:new_inactive_frame display:YES];
248
249   ActivateTabView(tab0_);
250   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
251
252   NSRect new_active_frame = [sheet_window_ frame];
253   EXPECT_EQ(NSWidth(new_inactive_frame), NSWidth(new_active_frame));
254   EXPECT_EQ(NSHeight(new_inactive_frame), NSHeight(new_active_frame));
255 }
256
257 // Test system sheets.
258 TEST_F(ConstrainedWindowSheetControllerTest, SystemSheet) {
259   base::scoped_nsobject<ConstrainedWindowSystemSheetTest> system_sheet(
260       [[ConstrainedWindowSystemSheetTest alloc] init]);
261   base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
262   [system_sheet setAlert:alert];
263
264   EXPECT_FALSE([[alert window] isVisible]);
265   [controller_ showSheet:system_sheet
266                  forParentView:active_tab_view_];
267   EXPECT_TRUE([[alert window] isVisible]);
268
269   [controller_ closeSheet:system_sheet];
270   EXPECT_FALSE([[alert window] isVisible]);
271   EXPECT_EQ(kSystemSheetReturnCode, [system_sheet returnCode]);
272 }
273
274 // Test showing a system sheet on an inactive tab.
275 TEST_F(ConstrainedWindowSheetControllerTest, SystemSheetAddToInactiveTab) {
276   base::scoped_nsobject<ConstrainedWindowSystemSheetTest> system_sheet(
277       [[ConstrainedWindowSystemSheetTest alloc] init]);
278   base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
279   [system_sheet setAlert:alert];
280
281   EXPECT_FALSE([[alert window] isVisible]);
282   [controller_ showSheet:system_sheet
283                  forParentView:tab1_];
284   EXPECT_FALSE([[alert window] isVisible]);
285
286   ActivateTabView(tab1_);
287   EXPECT_TRUE([[alert window] isVisible]);
288   EXPECT_EQ(1.0, [[alert window] alphaValue]);
289
290   [controller_ closeSheet:system_sheet];
291 }