Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / constrained_window / constrained_window_sheet_controller_unittest.mm
blobaeeeb92143d8531aeff18802de2061bd5ea20007
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 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.h"
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"
11 namespace {
13 const int kSystemSheetReturnCode = 77;
15 }  // namespace
17 @interface ConstrainedWindowSystemSheetTest
18     : NSObject <ConstrainedWindowSheet> {
19   int returnCode_;
20   NSAlert* alert_;  // weak
23 @property(nonatomic, readonly) int returnCode;
24 @property(nonatomic, assign) NSAlert* alert;
26 @end
28 @implementation ConstrainedWindowSystemSheetTest
30 @synthesize returnCode = returnCode_;
31 @synthesize alert = alert_;
33 - (void)showSheetForWindow:(NSWindow*)window {
34   [alert_ beginSheetModalForWindow:window
35                      modalDelegate:self
36                     didEndSelector:@selector(alertDidEnd:returnCode:ctxInfo:)
37                        contextInfo:NULL];
40 - (void)closeSheetWithAnimation:(BOOL)withAnimation {
41   [NSApp endSheet:[alert_ window] returnCode:kSystemSheetReturnCode];
44 - (void)hideSheet {
47 - (void)unhideSheet {
50 - (void)pulseSheet {
53 - (void)makeSheetKeyAndOrderFront {
56 - (void)updateSheetPosition {
59 - (NSWindow*)sheetWindow {
60   return [alert_ window];
63 - (void)alertDidEnd:(NSAlert *)alert
64          returnCode:(NSInteger)returnCode
65             ctxInfo:(void *)contextInfo {
66   returnCode_ = returnCode;
69 @end
71 class ConstrainedWindowSheetControllerTest : public CocoaTest {
72  protected:
73   void SetUp() override {
74     CocoaTest::SetUp();
76     // Center the window so that the sheet doesn't go offscreen.
77     [test_window() center];
79     // The real view setup is quite a few levels deep; recreate something
80     // similar.
81     NSRect dummy_rect = NSMakeRect(0, 0, 50, 50);
82     tab_view_parent_ = [test_window() contentView];
83     for (int i = 0; i < 3; ++i) {
84       base::scoped_nsobject<NSView> new_view(
85           [[NSView alloc] initWithFrame:dummy_rect]);
86       [tab_view_parent_ addSubview:new_view.get()];
87       tab_view_parent_ = new_view.get();
88     }
90     // Create two dummy tabs and make the first one active.
91     tab_views_.reset([[NSMutableArray alloc] init]);
92     for (int i = 0; i < 2; ++i) {
93       base::scoped_nsobject<NSView> view(
94           [[NSView alloc] initWithFrame:dummy_rect]);
95       [tab_views_ addObject:view];
96     }
97     tab0_ = [tab_views_ objectAtIndex:0];
98     tab1_ = [tab_views_ objectAtIndex:1];
99     ActivateTabView(tab0_);
101     // Create a test sheet.
102     sheet_window_.reset([[NSWindow alloc]
103         initWithContentRect:dummy_rect
104                   styleMask:NSTitledWindowMask
105                     backing:NSBackingStoreBuffered
106                       defer:NO]);
107     [sheet_window_ setReleasedWhenClosed:NO];
108     sheet_.reset([[CustomConstrainedWindowSheet alloc]
109         initWithCustomWindow:sheet_window_]);
111     controller_.reset([[ConstrainedWindowSheetController
112             controllerForParentWindow:test_window()] retain]);
113     EXPECT_TRUE(controller_);
114     EXPECT_FALSE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
115   }
117   void TearDown() override {
118     sheet_.reset();
119     sheet_window_.reset();
120     CocoaTest::TearDown();
121   }
123   void ActivateTabView(NSView* tab_view) {
124     for (NSView* view in tab_views_.get())
125       [view removeFromSuperview];
126     [tab_view_parent_ addSubview:tab_view];
127     active_tab_view_ = tab_view;
129     ConstrainedWindowSheetController* controller =
130         [ConstrainedWindowSheetController
131             controllerForParentWindow:test_window()];
132     EXPECT_TRUE(controller);
133     [controller parentViewDidBecomeActive:active_tab_view_];
134   }
136   NSRect GetViewFrameInScreenCoordinates(NSView* view) {
137     NSRect rect = [view convertRect:[view bounds] toView:nil];
138     rect.origin = [[view window] convertBaseToScreen:rect.origin];
139     return rect;
140   }
142   void VerifySheetXPosition(NSRect sheet_frame, NSView* parent_view) {
143     NSRect parent_frame = GetViewFrameInScreenCoordinates(parent_view);
144     CGFloat expected_x = NSMinX(parent_frame) +
145         (NSWidth(parent_frame) - NSWidth(sheet_frame)) / 2.0;
146     EXPECT_EQ(expected_x, NSMinX(sheet_frame));
147   }
149   CGFloat GetSheetYOffset(NSRect sheet_frame, NSView* parent_view) {
150     return NSMaxY(sheet_frame) -
151            NSMaxY(GetViewFrameInScreenCoordinates(parent_view));
152   }
154   base::scoped_nsobject<NSWindow> sheet_window_;
155   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet_;
156   base::scoped_nsobject<ConstrainedWindowSheetController> controller_;
157   base::scoped_nsobject<NSMutableArray> tab_views_;
158   NSView* tab_view_parent_;
159   NSView* active_tab_view_;
160   NSView* tab0_;
161   NSView* tab1_;
164 // Test showing then hiding the sheet.
165 TEST_F(ConstrainedWindowSheetControllerTest, ShowHide) {
166   EXPECT_FALSE([sheet_window_ isVisible]);
167   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
168   EXPECT_TRUE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
169   EXPECT_TRUE([sheet_window_ isVisible]);
171   [controller_ closeSheet:sheet_];
172   EXPECT_FALSE([ConstrainedWindowSheetController controllerForSheet:sheet_]);
173   EXPECT_FALSE([sheet_window_ isVisible]);
176 // Test that switching tabs correctly hides the inactive tab's sheet.
177 TEST_F(ConstrainedWindowSheetControllerTest, SwitchTabs) {
178   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
180   EXPECT_TRUE([sheet_window_ isVisible]);
181   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
182   ActivateTabView([tab_views_ objectAtIndex:1]);
183   EXPECT_TRUE([sheet_window_ isVisible]);
184   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
185   ActivateTabView([tab_views_ objectAtIndex:0]);
186   EXPECT_TRUE([sheet_window_ isVisible]);
187   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
190 // Test that adding a sheet to an inactive view doesn't show it.
191 TEST_F(ConstrainedWindowSheetControllerTest, AddToInactiveTab) {
192   ActivateTabView(tab0_);
193   [controller_ showSheet:sheet_ forParentView:tab1_];
194   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
196   ActivateTabView(tab1_);
197   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
198   VerifySheetXPosition([sheet_window_ frame], tab1_);
201 // Test that two parent windows with two sheet controllers don't conflict.
202 TEST_F(ConstrainedWindowSheetControllerTest, TwoParentWindows) {
203   base::scoped_nsobject<NSWindow> parent_window2(
204       [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 30, 30)
205                                   styleMask:NSTitledWindowMask
206                                     backing:NSBackingStoreBuffered
207                                       defer:NO]);
208   [parent_window2 setReleasedWhenClosed:NO];
210   ConstrainedWindowSheetController* controller2 =
211       [ConstrainedWindowSheetController
212           controllerForParentWindow:parent_window2];
213   EXPECT_TRUE(controller2);
214   EXPECT_NSNE(controller_, controller2);
216   [controller2 showSheet:sheet_ forParentView:[parent_window2 contentView]];
217   EXPECT_NSEQ(controller2,
218               [ConstrainedWindowSheetController controllerForSheet:sheet_]);
220   [parent_window2 close];
223 // Test that resizing sheet works.
224 TEST_F(ConstrainedWindowSheetControllerTest, Resize) {
225   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
227   NSRect old_frame = [sheet_window_ frame];
229   NSRect sheet_frame;
230   sheet_frame.size = NSMakeSize(NSWidth(old_frame) + 100,
231                                 NSHeight(old_frame) + 50);
232   sheet_frame.origin = [controller_ originForSheet:sheet_
233                                     withWindowSize:sheet_frame.size];
235   // Y pos should not have changed.
236   EXPECT_EQ(NSMaxY(sheet_frame), NSMaxY(old_frame));
238   // X pos should be centered on parent view.
239   VerifySheetXPosition(sheet_frame, active_tab_view_);
242 // Test that resizing a hidden sheet works.
243 TEST_F(ConstrainedWindowSheetControllerTest, ResizeHiddenSheet) {
244   [controller_ showSheet:sheet_ forParentView:tab0_];
245   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
246   ActivateTabView(tab1_);
247   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
249   NSRect old_frame = [sheet_window_ frame];
250   NSRect new_inactive_frame = NSInsetRect(old_frame, -30, -40);
251   [sheet_window_ setFrame:new_inactive_frame display:YES];
253   ActivateTabView(tab0_);
254   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
256   NSRect new_active_frame = [sheet_window_ frame];
257   EXPECT_EQ(NSWidth(new_inactive_frame), NSWidth(new_active_frame));
258   EXPECT_EQ(NSHeight(new_inactive_frame), NSHeight(new_active_frame));
261 // Test resizing parent window keeps the sheet anchored.
262 TEST_F(ConstrainedWindowSheetControllerTest, ResizeParentWindow) {
263   [controller_ showSheet:sheet_ forParentView:active_tab_view_];
264   CGFloat sheet_offset =
265       GetSheetYOffset([sheet_window_ frame], active_tab_view_);
267   // Test 3x3 different parent window sizes.
268   CGFloat insets[] = {-10, 0, 10};
269   NSRect old_frame = [test_window() frame];
271   for (size_t x = 0; x < arraysize(insets); x++) {
272     for (size_t y = 0; y < arraysize(insets); y++) {
273       NSRect resized_frame = NSInsetRect(old_frame, insets[x], insets[y]);
274       [test_window() setFrame:resized_frame display:YES];
275       NSRect sheet_frame = [sheet_window_ frame];
277       // Y pos should track parent view's position.
278       EXPECT_EQ(sheet_offset, GetSheetYOffset(sheet_frame, active_tab_view_));
280       // X pos should be centered on parent view.
281       VerifySheetXPosition(sheet_frame, active_tab_view_);
282     }
283   }
286 // Test system sheets.
287 TEST_F(ConstrainedWindowSheetControllerTest, SystemSheet) {
288   base::scoped_nsobject<ConstrainedWindowSystemSheetTest> system_sheet(
289       [[ConstrainedWindowSystemSheetTest alloc] init]);
290   base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
291   [system_sheet setAlert:alert];
293   EXPECT_FALSE([[alert window] isVisible]);
294   [controller_ showSheet:system_sheet forParentView:active_tab_view_];
295   EXPECT_TRUE([[alert window] isVisible]);
297   [controller_ closeSheet:system_sheet];
298   EXPECT_FALSE([[alert window] isVisible]);
299   EXPECT_EQ(kSystemSheetReturnCode, [system_sheet returnCode]);
302 // Test showing a system sheet on an inactive tab.
303 TEST_F(ConstrainedWindowSheetControllerTest, SystemSheetAddToInactiveTab) {
304   base::scoped_nsobject<ConstrainedWindowSystemSheetTest> system_sheet(
305       [[ConstrainedWindowSystemSheetTest alloc] init]);
306   base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
307   [system_sheet setAlert:alert];
309   EXPECT_FALSE([[alert window] isVisible]);
310   [controller_ showSheet:system_sheet forParentView:tab1_];
311   EXPECT_FALSE([[alert window] isVisible]);
313   ActivateTabView(tab1_);
314   EXPECT_TRUE([[alert window] isVisible]);
315   EXPECT_EQ(1.0, [[alert window] alphaValue]);
317   [controller_ closeSheet:system_sheet];