| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #import "base/memory/scoped_nsobject.h" | 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" | 9 #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" |
| 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
| 11 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" | 11 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" |
| 12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" | 12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 #import "testing/gtest_mac.h" | 14 #import "testing/gtest_mac.h" |
| 15 #include "testing/platform_test.h" | 15 #include "testing/platform_test.h" |
| 16 | 16 |
| 17 // Implements the target interface for the tab, which gets sent messages when | 17 // Implements the target interface for the tab, which gets sent messages when |
| 18 // the tab is clicked on by the user and when its close box is clicked. | 18 // the tab is clicked on by the user and when its close box is clicked. |
| 19 @interface TabControllerTestTarget : NSObject<TabControllerTarget> { | 19 @interface TabControllerTestTarget : NSObject<TabControllerTarget> { |
| 20 @private | 20 @private |
| 21 bool selected_; | 21 bool selected_; |
| 22 bool closed_; | 22 bool closed_; |
| 23 scoped_nsobject<TabStripDragController> dragController_; | 23 base::scoped_nsobject<TabStripDragController> dragController_; |
| 24 } | 24 } |
| 25 - (bool)selected; | 25 - (bool)selected; |
| 26 - (bool)closed; | 26 - (bool)closed; |
| 27 @end | 27 @end |
| 28 | 28 |
| 29 @implementation TabControllerTestTarget | 29 @implementation TabControllerTestTarget |
| 30 - (id)init { | 30 - (id)init { |
| 31 if ((self = [super init])) { | 31 if ((self = [super init])) { |
| 32 dragController_.reset( | 32 dragController_.reset( |
| 33 [[TabStripDragController alloc] initWithTabStripController:nil]); | 33 [[TabStripDragController alloc] initWithTabStripController:nil]); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 // The dragging code in TabView makes heavy use of autorelease pools so | 94 // The dragging code in TabView makes heavy use of autorelease pools so |
| 95 // inherit from CocoaTest to have one created for us. | 95 // inherit from CocoaTest to have one created for us. |
| 96 class TabControllerTest : public CocoaTest { | 96 class TabControllerTest : public CocoaTest { |
| 97 public: | 97 public: |
| 98 TabControllerTest() { } | 98 TabControllerTest() { } |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 // Tests creating the controller, sticking it in a window, and removing it. | 101 // Tests creating the controller, sticking it in a window, and removing it. |
| 102 TEST_F(TabControllerTest, Creation) { | 102 TEST_F(TabControllerTest, Creation) { |
| 103 NSWindow* window = test_window(); | 103 NSWindow* window = test_window(); |
| 104 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 104 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 105 [[window contentView] addSubview:[controller view]]; | 105 [[window contentView] addSubview:[controller view]]; |
| 106 EXPECT_TRUE([controller tabView]); | 106 EXPECT_TRUE([controller tabView]); |
| 107 EXPECT_EQ([[controller view] window], window); | 107 EXPECT_EQ([[controller view] window], window); |
| 108 [[controller view] display]; // Test drawing to ensure nothing leaks/crashes. | 108 [[controller view] display]; // Test drawing to ensure nothing leaks/crashes. |
| 109 [[controller view] removeFromSuperview]; | 109 [[controller view] removeFromSuperview]; |
| 110 } | 110 } |
| 111 | 111 |
| 112 // Tests sending it a close message and ensuring that the target/action get | 112 // Tests sending it a close message and ensuring that the target/action get |
| 113 // called. Mimics the user clicking on the close button in the tab. | 113 // called. Mimics the user clicking on the close button in the tab. |
| 114 TEST_F(TabControllerTest, Close) { | 114 TEST_F(TabControllerTest, Close) { |
| 115 NSWindow* window = test_window(); | 115 NSWindow* window = test_window(); |
| 116 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 116 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 117 [[window contentView] addSubview:[controller view]]; | 117 [[window contentView] addSubview:[controller view]]; |
| 118 | 118 |
| 119 scoped_nsobject<TabControllerTestTarget> target( | 119 base::scoped_nsobject<TabControllerTestTarget> target( |
| 120 [[TabControllerTestTarget alloc] init]); | 120 [[TabControllerTestTarget alloc] init]); |
| 121 EXPECT_FALSE([target closed]); | 121 EXPECT_FALSE([target closed]); |
| 122 [controller setTarget:target]; | 122 [controller setTarget:target]; |
| 123 EXPECT_EQ(target.get(), [controller target]); | 123 EXPECT_EQ(target.get(), [controller target]); |
| 124 | 124 |
| 125 [controller closeTab:nil]; | 125 [controller closeTab:nil]; |
| 126 EXPECT_TRUE([target closed]); | 126 EXPECT_TRUE([target closed]); |
| 127 | 127 |
| 128 [[controller view] removeFromSuperview]; | 128 [[controller view] removeFromSuperview]; |
| 129 } | 129 } |
| 130 | 130 |
| 131 // Tests setting the |selected| property via code. | 131 // Tests setting the |selected| property via code. |
| 132 TEST_F(TabControllerTest, APISelection) { | 132 TEST_F(TabControllerTest, APISelection) { |
| 133 NSWindow* window = test_window(); | 133 NSWindow* window = test_window(); |
| 134 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 134 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 135 [[window contentView] addSubview:[controller view]]; | 135 [[window contentView] addSubview:[controller view]]; |
| 136 | 136 |
| 137 EXPECT_FALSE([controller selected]); | 137 EXPECT_FALSE([controller selected]); |
| 138 [controller setSelected:YES]; | 138 [controller setSelected:YES]; |
| 139 EXPECT_TRUE([controller selected]); | 139 EXPECT_TRUE([controller selected]); |
| 140 | 140 |
| 141 [[controller view] removeFromSuperview]; | 141 [[controller view] removeFromSuperview]; |
| 142 } | 142 } |
| 143 | 143 |
| 144 // Tests that setting the title of a tab sets the tooltip as well. | 144 // Tests that setting the title of a tab sets the tooltip as well. |
| 145 TEST_F(TabControllerTest, ToolTip) { | 145 TEST_F(TabControllerTest, ToolTip) { |
| 146 NSWindow* window = test_window(); | 146 NSWindow* window = test_window(); |
| 147 | 147 |
| 148 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 148 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 149 [[window contentView] addSubview:[controller view]]; | 149 [[window contentView] addSubview:[controller view]]; |
| 150 | 150 |
| 151 EXPECT_TRUE([[controller toolTip] length] == 0); | 151 EXPECT_TRUE([[controller toolTip] length] == 0); |
| 152 NSString *tooltip_string = @"Some text to use as a tab title"; | 152 NSString *tooltip_string = @"Some text to use as a tab title"; |
| 153 [controller setTitle:tooltip_string]; | 153 [controller setTitle:tooltip_string]; |
| 154 EXPECT_NSEQ(tooltip_string, [controller toolTip]); | 154 EXPECT_NSEQ(tooltip_string, [controller toolTip]); |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Tests setting the |loading| property via code. | 157 // Tests setting the |loading| property via code. |
| 158 TEST_F(TabControllerTest, Loading) { | 158 TEST_F(TabControllerTest, Loading) { |
| 159 NSWindow* window = test_window(); | 159 NSWindow* window = test_window(); |
| 160 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 160 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 161 [[window contentView] addSubview:[controller view]]; | 161 [[window contentView] addSubview:[controller view]]; |
| 162 | 162 |
| 163 EXPECT_EQ(kTabDone, [controller loadingState]); | 163 EXPECT_EQ(kTabDone, [controller loadingState]); |
| 164 [controller setLoadingState:kTabWaiting]; | 164 [controller setLoadingState:kTabWaiting]; |
| 165 EXPECT_EQ(kTabWaiting, [controller loadingState]); | 165 EXPECT_EQ(kTabWaiting, [controller loadingState]); |
| 166 [controller setLoadingState:kTabLoading]; | 166 [controller setLoadingState:kTabLoading]; |
| 167 EXPECT_EQ(kTabLoading, [controller loadingState]); | 167 EXPECT_EQ(kTabLoading, [controller loadingState]); |
| 168 [controller setLoadingState:kTabDone]; | 168 [controller setLoadingState:kTabDone]; |
| 169 EXPECT_EQ(kTabDone, [controller loadingState]); | 169 EXPECT_EQ(kTabDone, [controller loadingState]); |
| 170 | 170 |
| 171 [[controller view] removeFromSuperview]; | 171 [[controller view] removeFromSuperview]; |
| 172 } | 172 } |
| 173 | 173 |
| 174 // Tests selecting the tab with the mouse click and ensuring the target/action | 174 // Tests selecting the tab with the mouse click and ensuring the target/action |
| 175 // get called. | 175 // get called. |
| 176 TEST_F(TabControllerTest, UserSelection) { | 176 TEST_F(TabControllerTest, UserSelection) { |
| 177 NSWindow* window = test_window(); | 177 NSWindow* window = test_window(); |
| 178 | 178 |
| 179 // Create a tab at a known location in the window that we can click on | 179 // Create a tab at a known location in the window that we can click on |
| 180 // to activate selection. | 180 // to activate selection. |
| 181 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 181 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 182 [[window contentView] addSubview:[controller view]]; | 182 [[window contentView] addSubview:[controller view]]; |
| 183 NSRect frame = [[controller view] frame]; | 183 NSRect frame = [[controller view] frame]; |
| 184 frame.size.width = [TabController minTabWidth]; | 184 frame.size.width = [TabController minTabWidth]; |
| 185 frame.origin = NSMakePoint(0, 0); | 185 frame.origin = NSMakePoint(0, 0); |
| 186 [[controller view] setFrame:frame]; | 186 [[controller view] setFrame:frame]; |
| 187 | 187 |
| 188 // Set the target and action. | 188 // Set the target and action. |
| 189 scoped_nsobject<TabControllerTestTarget> target( | 189 base::scoped_nsobject<TabControllerTestTarget> target( |
| 190 [[TabControllerTestTarget alloc] init]); | 190 [[TabControllerTestTarget alloc] init]); |
| 191 EXPECT_FALSE([target selected]); | 191 EXPECT_FALSE([target selected]); |
| 192 [controller setTarget:target]; | 192 [controller setTarget:target]; |
| 193 [controller setAction:@selector(selectTab:)]; | 193 [controller setAction:@selector(selectTab:)]; |
| 194 EXPECT_EQ(target.get(), [controller target]); | 194 EXPECT_EQ(target.get(), [controller target]); |
| 195 EXPECT_EQ(@selector(selectTab:), [controller action]); | 195 EXPECT_EQ(@selector(selectTab:), [controller action]); |
| 196 | 196 |
| 197 // In order to track a click, we have to fake a mouse down and a mouse | 197 // In order to track a click, we have to fake a mouse down and a mouse |
| 198 // up, but the down goes into a tight drag loop. To break the loop, we have | 198 // up, but the down goes into a tight drag loop. To break the loop, we have |
| 199 // to fire a timer that sends a mouse up event while the "drag" is ongoing. | 199 // to fire a timer that sends a mouse up event while the "drag" is ongoing. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 217 [[controller view] mouseDown:down]; | 217 [[controller view] mouseDown:down]; |
| 218 | 218 |
| 219 // Check our target was told the tab got selected. | 219 // Check our target was told the tab got selected. |
| 220 EXPECT_TRUE([target selected]); | 220 EXPECT_TRUE([target selected]); |
| 221 | 221 |
| 222 [[controller view] removeFromSuperview]; | 222 [[controller view] removeFromSuperview]; |
| 223 } | 223 } |
| 224 | 224 |
| 225 TEST_F(TabControllerTest, IconCapacity) { | 225 TEST_F(TabControllerTest, IconCapacity) { |
| 226 NSWindow* window = test_window(); | 226 NSWindow* window = test_window(); |
| 227 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 227 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 228 [[window contentView] addSubview:[controller view]]; | 228 [[window contentView] addSubview:[controller view]]; |
| 229 int cap = [controller iconCapacity]; | 229 int cap = [controller iconCapacity]; |
| 230 EXPECT_GE(cap, 1); | 230 EXPECT_GE(cap, 1); |
| 231 | 231 |
| 232 NSRect frame = [[controller view] frame]; | 232 NSRect frame = [[controller view] frame]; |
| 233 frame.size.width += 500; | 233 frame.size.width += 500; |
| 234 [[controller view] setFrame:frame]; | 234 [[controller view] setFrame:frame]; |
| 235 int newcap = [controller iconCapacity]; | 235 int newcap = [controller iconCapacity]; |
| 236 EXPECT_GT(newcap, cap); | 236 EXPECT_GT(newcap, cap); |
| 237 } | 237 } |
| 238 | 238 |
| 239 TEST_F(TabControllerTest, ShouldShowIcon) { | 239 TEST_F(TabControllerTest, ShouldShowIcon) { |
| 240 NSWindow* window = test_window(); | 240 NSWindow* window = test_window(); |
| 241 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 241 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 242 [[window contentView] addSubview:[controller view]]; | 242 [[window contentView] addSubview:[controller view]]; |
| 243 int cap = [controller iconCapacity]; | 243 int cap = [controller iconCapacity]; |
| 244 EXPECT_GT(cap, 0); | 244 EXPECT_GT(cap, 0); |
| 245 | 245 |
| 246 // Tab is minimum width, both icon and close box should be hidden. | 246 // Tab is minimum width, both icon and close box should be hidden. |
| 247 NSRect frame = [[controller view] frame]; | 247 NSRect frame = [[controller view] frame]; |
| 248 frame.size.width = [TabController minTabWidth]; | 248 frame.size.width = [TabController minTabWidth]; |
| 249 [[controller view] setFrame:frame]; | 249 [[controller view] setFrame:frame]; |
| 250 EXPECT_FALSE([controller shouldShowIcon]); | 250 EXPECT_FALSE([controller shouldShowIcon]); |
| 251 EXPECT_FALSE([controller shouldShowCloseButton]); | 251 EXPECT_FALSE([controller shouldShowCloseButton]); |
| 252 | 252 |
| 253 // Setting the icon when tab is at min width should not show icon (bug 18359). | 253 // Setting the icon when tab is at min width should not show icon (bug 18359). |
| 254 scoped_nsobject<NSView> newIcon( | 254 base::scoped_nsobject<NSView> newIcon( |
| 255 [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)]); | 255 [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)]); |
| 256 [controller setIconView:newIcon.get()]; | 256 [controller setIconView:newIcon.get()]; |
| 257 EXPECT_TRUE([newIcon isHidden]); | 257 EXPECT_TRUE([newIcon isHidden]); |
| 258 | 258 |
| 259 // Tab is at selected minimum width. Since it's selected, the close box | 259 // Tab is at selected minimum width. Since it's selected, the close box |
| 260 // should be visible. | 260 // should be visible. |
| 261 [controller setSelected:YES]; | 261 [controller setSelected:YES]; |
| 262 frame = [[controller view] frame]; | 262 frame = [[controller view] frame]; |
| 263 frame.size.width = [TabController minSelectedTabWidth]; | 263 frame.size.width = [TabController minSelectedTabWidth]; |
| 264 [[controller view] setFrame:frame]; | 264 [[controller view] setFrame:frame]; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 276 [controller setSelected:NO]; | 276 [controller setSelected:NO]; |
| 277 EXPECT_TRUE([controller shouldShowIcon]); | 277 EXPECT_TRUE([controller shouldShowIcon]); |
| 278 EXPECT_TRUE([controller shouldShowCloseButton]); | 278 EXPECT_TRUE([controller shouldShowCloseButton]); |
| 279 | 279 |
| 280 cap = [controller iconCapacity]; | 280 cap = [controller iconCapacity]; |
| 281 EXPECT_GT(cap, 0); | 281 EXPECT_GT(cap, 0); |
| 282 } | 282 } |
| 283 | 283 |
| 284 TEST_F(TabControllerTest, Menu) { | 284 TEST_F(TabControllerTest, Menu) { |
| 285 NSWindow* window = test_window(); | 285 NSWindow* window = test_window(); |
| 286 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 286 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 287 scoped_nsobject<TabControllerTestTarget> target( | 287 base::scoped_nsobject<TabControllerTestTarget> target( |
| 288 [[TabControllerTestTarget alloc] init]); | 288 [[TabControllerTestTarget alloc] init]); |
| 289 [controller setTarget:target]; | 289 [controller setTarget:target]; |
| 290 | 290 |
| 291 [[window contentView] addSubview:[controller view]]; | 291 [[window contentView] addSubview:[controller view]]; |
| 292 int cap = [controller iconCapacity]; | 292 int cap = [controller iconCapacity]; |
| 293 EXPECT_GT(cap, 0); | 293 EXPECT_GT(cap, 0); |
| 294 | 294 |
| 295 // Asking the view for its menu should yield a valid menu. | 295 // Asking the view for its menu should yield a valid menu. |
| 296 NSMenu* menu = [[controller view] menu]; | 296 NSMenu* menu = [[controller view] menu]; |
| 297 EXPECT_TRUE(menu); | 297 EXPECT_TRUE(menu); |
| 298 EXPECT_EQ(3, [menu numberOfItems]); | 298 EXPECT_EQ(3, [menu numberOfItems]); |
| 299 } | 299 } |
| 300 | 300 |
| 301 // Tests that the title field is correctly positioned and sized when the | 301 // Tests that the title field is correctly positioned and sized when the |
| 302 // view is resized. | 302 // view is resized. |
| 303 TEST_F(TabControllerTest, TitleViewLayout) { | 303 TEST_F(TabControllerTest, TitleViewLayout) { |
| 304 NSWindow* window = test_window(); | 304 NSWindow* window = test_window(); |
| 305 | 305 |
| 306 scoped_nsobject<TabController> controller([[TabController alloc] init]); | 306 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); |
| 307 [[window contentView] addSubview:[controller view]]; | 307 [[window contentView] addSubview:[controller view]]; |
| 308 NSRect tabFrame = [[controller view] frame]; | 308 NSRect tabFrame = [[controller view] frame]; |
| 309 tabFrame.size.width = [TabController maxTabWidth]; | 309 tabFrame.size.width = [TabController maxTabWidth]; |
| 310 [[controller view] setFrame:tabFrame]; | 310 [[controller view] setFrame:tabFrame]; |
| 311 | 311 |
| 312 const NSRect originalTabFrame = [[controller view] frame]; | 312 const NSRect originalTabFrame = [[controller view] frame]; |
| 313 const NSRect originalIconFrame = [[controller iconView] frame]; | 313 const NSRect originalIconFrame = [[controller iconView] frame]; |
| 314 const NSRect originalCloseFrame = [[controller closeButton] frame]; | 314 const NSRect originalCloseFrame = [[controller closeButton] frame]; |
| 315 const NSRect originalTitleFrame = [[controller titleView] frame]; | 315 const NSRect originalTitleFrame = [[controller titleView] frame]; |
| 316 | 316 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 NSWidth([[controller titleView] frame])); | 349 NSWidth([[controller titleView] frame])); |
| 350 EXPECT_EQ(LeftMargin(originalTabFrame, originalTitleFrame), | 350 EXPECT_EQ(LeftMargin(originalTabFrame, originalTitleFrame), |
| 351 LeftMargin([[controller view] frame], | 351 LeftMargin([[controller view] frame], |
| 352 [[controller titleView] frame])); | 352 [[controller titleView] frame])); |
| 353 EXPECT_EQ(RightMargin(originalTabFrame, originalTitleFrame), | 353 EXPECT_EQ(RightMargin(originalTabFrame, originalTitleFrame), |
| 354 RightMargin([[controller view] frame], | 354 RightMargin([[controller view] frame], |
| 355 [[controller titleView] frame])); | 355 [[controller titleView] frame])); |
| 356 } | 356 } |
| 357 | 357 |
| 358 } // namespace | 358 } // namespace |
| OLD | NEW |