Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(548)

Side by Side Diff: chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm

Issue 23513039: Replace animated tab audio indicator with static tab audio indicator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments from sky@. Also, rebased. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/mac/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 "grit/theme_resources.h"
14 #include "grit/ui_resources.h"
13 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
14 #import "testing/gtest_mac.h" 16 #import "testing/gtest_mac.h"
15 #include "testing/platform_test.h" 17 #include "testing/platform_test.h"
18 #include "ui/base/resource/resource_bundle.h"
16 19
17 // Implements the target interface for the tab, which gets sent messages when 20 // 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. 21 // the tab is clicked on by the user and when its close box is clicked.
19 @interface TabControllerTestTarget : NSObject<TabControllerTarget> { 22 @interface TabControllerTestTarget : NSObject<TabControllerTarget> {
20 @private 23 @private
21 bool selected_; 24 bool selected_;
22 bool closed_; 25 bool closed_;
23 base::scoped_nsobject<TabStripDragController> dragController_; 26 base::scoped_nsobject<TabStripDragController> dragController_;
24 } 27 }
25 - (bool)selected; 28 - (bool)selected;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 namespace { 87 namespace {
85 88
86 CGFloat LeftMargin(NSRect superFrame, NSRect subFrame) { 89 CGFloat LeftMargin(NSRect superFrame, NSRect subFrame) {
87 return NSMinX(subFrame) - NSMinX(superFrame); 90 return NSMinX(subFrame) - NSMinX(superFrame);
88 } 91 }
89 92
90 CGFloat RightMargin(NSRect superFrame, NSRect subFrame) { 93 CGFloat RightMargin(NSRect superFrame, NSRect subFrame) {
91 return NSMaxX(superFrame) - NSMaxX(subFrame); 94 return NSMaxX(superFrame) - NSMaxX(subFrame);
92 } 95 }
93 96
97 // Helper to create an NSImageView that contains an image fetched from
98 // ui::ResourceBundle.
99 NSImageView* CreateImageViewFromResourceBundle(int resource_id) {
100 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
101 NSImage* const image = rb.GetNativeImageNamed(resource_id).ToNSImage();
102 CHECK(!!image);
103 NSRect frame;
104 frame.size = [image size];
105 NSImageView* const view = [[NSImageView alloc] initWithFrame:frame];
106 [view setImage:image];
107 return view;
108 }
109
94 // The dragging code in TabView makes heavy use of autorelease pools so 110 // The dragging code in TabView makes heavy use of autorelease pools so
95 // inherit from CocoaTest to have one created for us. 111 // inherit from CocoaTest to have one created for us.
96 class TabControllerTest : public CocoaTest { 112 class TabControllerTest : public CocoaTest {
97 public: 113 public:
98 TabControllerTest() { } 114 TabControllerTest() { }
115
116 static void CheckForExpectedLayoutAndVisibilityOfSubviews(
117 const TabController* controller) {
118 // Check whether subviews should be visible when they are supposed to be,
119 // given Tab size and TabRendererData state.
120 if ([controller mini]) {
121 if ([controller projecting])
122 EXPECT_TRUE([controller shouldShowIcon]);
123 else
124 EXPECT_TRUE([controller shouldShowIcon] !=
125 [controller shouldShowAudioIndicator]);
126 EXPECT_FALSE([controller shouldShowCloseButton]);
127 } else if ([controller selected]) {
128 EXPECT_TRUE([controller shouldShowCloseButton]);
129 switch ([controller iconCapacity]) {
130 case 0:
131 case 1:
132 EXPECT_FALSE([controller shouldShowIcon]);
133 EXPECT_FALSE([controller shouldShowAudioIndicator]);
134 break;
135 case 2:
136 if ([controller projecting])
137 EXPECT_TRUE([controller shouldShowIcon]);
138 else
139 EXPECT_TRUE([controller shouldShowIcon] !=
140 [controller shouldShowAudioIndicator]);
141 break;
142 default:
143 EXPECT_LE(3, [controller iconCapacity]);
144 EXPECT_TRUE([controller shouldShowIcon]);
145 if ([controller projecting])
146 EXPECT_FALSE([controller shouldShowAudioIndicator]);
147 else
148 EXPECT_TRUE(!![controller audioIndicatorView] ==
149 [controller shouldShowAudioIndicator]);
150 break;
151 }
152 } else { // Tab not selected/active and not mini tab.
153 switch ([controller iconCapacity]) {
154 case 0:
155 EXPECT_FALSE([controller shouldShowCloseButton]);
156 EXPECT_FALSE([controller shouldShowIcon]);
157 EXPECT_FALSE([controller shouldShowAudioIndicator]);
158 break;
159 case 1:
160 EXPECT_FALSE([controller shouldShowCloseButton]);
161 if ([controller projecting])
162 EXPECT_TRUE([controller shouldShowIcon]);
163 else
164 EXPECT_TRUE([controller shouldShowIcon] !=
165 [controller shouldShowAudioIndicator]);
166 break;
167 default:
168 EXPECT_LE(2, [controller iconCapacity]);
169 EXPECT_TRUE([controller shouldShowIcon]);
170 if ([controller projecting])
171 EXPECT_FALSE([controller shouldShowAudioIndicator]);
172 else
173 EXPECT_TRUE(!![controller audioIndicatorView] ==
174 [controller shouldShowAudioIndicator]);
175 break;
176 }
177 }
178
179 // Make sure the NSView's "isHidden" state jives with the "shouldShowXXX."
180 EXPECT_TRUE([controller shouldShowIcon] ==
181 (!![controller iconView] && ![[controller iconView] isHidden]));
182 EXPECT_TRUE([controller mini] == [[controller titleView] isHidden]);
183 EXPECT_TRUE([controller shouldShowAudioIndicator] ==
184 (!![controller audioIndicatorView] &&
185 ![[controller audioIndicatorView] isHidden]));
186 EXPECT_TRUE([controller shouldShowCloseButton] !=
187 [[controller closeButton] isHidden]);
188
189 // Check positioning of elements with respect to each other, and that they
190 // are fully within the tab frame.
191 const NSRect tabFrame = [[controller view] frame];
192 const NSRect titleFrame = [[controller titleView] frame];
193 if ([controller shouldShowIcon]) {
194 const NSRect iconFrame = [[controller iconView] frame];
195 EXPECT_LE(NSMinX(tabFrame), NSMinX(iconFrame));
196 if (NSWidth(titleFrame) > 0)
197 EXPECT_LE(NSMaxX(iconFrame), NSMinX(titleFrame));
198 EXPECT_LE(NSMinY(tabFrame), NSMinY(iconFrame));
199 EXPECT_LE(NSMaxY(iconFrame), NSMaxY(tabFrame));
200 }
201 if ([controller shouldShowIcon] && [controller shouldShowAudioIndicator]) {
202 EXPECT_LE(NSMaxX([[controller iconView] frame]),
203 NSMinX([[controller audioIndicatorView] frame]));
204 }
205 if ([controller shouldShowAudioIndicator]) {
206 const NSRect audioIndicatorFrame =
207 [[controller audioIndicatorView] frame];
208 if (NSWidth(titleFrame) > 0)
209 EXPECT_LE(NSMaxX(titleFrame), NSMinX(audioIndicatorFrame));
210 EXPECT_LE(NSMaxX(audioIndicatorFrame), NSMaxX(tabFrame));
211 EXPECT_LE(NSMinY(tabFrame), NSMinY(audioIndicatorFrame));
212 EXPECT_LE(NSMaxY(audioIndicatorFrame), NSMaxY(tabFrame));
213 }
214 if ([controller shouldShowAudioIndicator] &&
215 [controller shouldShowCloseButton]) {
216 EXPECT_LE(NSMaxX([[controller audioIndicatorView] frame]),
217 NSMinX([[controller closeButton] frame]));
218 }
219 if ([controller shouldShowCloseButton]) {
220 const NSRect closeButtonFrame = [[controller closeButton] frame];
221 if (NSWidth(titleFrame) > 0)
222 EXPECT_LE(NSMaxX(titleFrame), NSMinX(closeButtonFrame));
223 EXPECT_LE(NSMaxX(closeButtonFrame), NSMaxX(tabFrame));
224 EXPECT_LE(NSMinY(tabFrame), NSMinY(closeButtonFrame));
225 EXPECT_LE(NSMaxY(closeButtonFrame), NSMaxY(tabFrame));
226 }
227 }
99 }; 228 };
100 229
101 // Tests creating the controller, sticking it in a window, and removing it. 230 // Tests creating the controller, sticking it in a window, and removing it.
102 TEST_F(TabControllerTest, Creation) { 231 TEST_F(TabControllerTest, Creation) {
103 NSWindow* window = test_window(); 232 NSWindow* window = test_window();
104 base::scoped_nsobject<TabController> controller([[TabController alloc] init]); 233 base::scoped_nsobject<TabController> controller([[TabController alloc] init]);
105 [[window contentView] addSubview:[controller view]]; 234 [[window contentView] addSubview:[controller view]];
106 EXPECT_TRUE([controller tabView]); 235 EXPECT_TRUE([controller tabView]);
107 EXPECT_EQ([[controller view] window], window); 236 EXPECT_EQ([[controller view] window], window);
108 [[controller view] display]; // Test drawing to ensure nothing leaks/crashes. 237 [[controller view] display]; // Test drawing to ensure nothing leaks/crashes.
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 EXPECT_GT(NSWidth([[controller view] frame]), 477 EXPECT_GT(NSWidth([[controller view] frame]),
349 NSWidth([[controller titleView] frame])); 478 NSWidth([[controller titleView] frame]));
350 EXPECT_EQ(LeftMargin(originalTabFrame, originalTitleFrame), 479 EXPECT_EQ(LeftMargin(originalTabFrame, originalTitleFrame),
351 LeftMargin([[controller view] frame], 480 LeftMargin([[controller view] frame],
352 [[controller titleView] frame])); 481 [[controller titleView] frame]));
353 EXPECT_EQ(RightMargin(originalTabFrame, originalTitleFrame), 482 EXPECT_EQ(RightMargin(originalTabFrame, originalTitleFrame),
354 RightMargin([[controller view] frame], 483 RightMargin([[controller view] frame],
355 [[controller titleView] frame])); 484 [[controller titleView] frame]));
356 } 485 }
357 486
487 // A comprehensive test of the layout and visibility of all elements (favicon,
488 // throbber indicators, titile text, audio indicator, and close button) over all
489 // relevant combinations of tab state. This test overlaps with parts of the
490 // other tests above.
491 TEST_F(TabControllerTest, LayoutAndVisibilityOfSubviews) {
492 NSWindow* const window = test_window();
493
494 // Create TabController instance and place its view into the test window.
495 base::scoped_nsobject<TabController> controller([[TabController alloc] init]);
496 [[window contentView] addSubview:[controller view]];
497
498 // Create favicon and audio indicator icon views.
499 base::scoped_nsobject<NSImageView> faviconView(
500 CreateImageViewFromResourceBundle(IDR_DEFAULT_FAVICON));
501 base::scoped_nsobject<NSImageView> audioIndicatorView(
502 CreateImageViewFromResourceBundle(IDR_TAB_AUDIO_INDICATOR));
503
504 [controller setIconView:faviconView];
505
506 // Perform layout over all possible combinations, checking for correct
507 // results.
508 for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) {
509 for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) {
510 for (int is_audio_playing = 0; is_audio_playing < 2; ++is_audio_playing) {
511 for (int is_capturing = 0; is_capturing < 2; ++is_capturing) {
512 SCOPED_TRACE(::testing::Message()
513 << (is_active_tab ? "Active" : "Inactive") << ' '
514 << (is_mini_tab ? "Mini " : "")
515 << "Tab with is_audio_playing=" << !!is_audio_playing
516 << " and is_capturing=" << !!is_capturing);
517
518 // Simulate what tab_strip_controller would do to set up the
519 // TabController state.
520 [controller setMini:(is_mini_tab ? YES : NO)];
521 [controller setActive:(is_active_tab ? YES : NO)];
522 if (is_capturing) {
523 [controller setProjecting:YES];
524 [controller setAudioIndicatorView:nil];
525 } else {
526 [controller setProjecting:NO];
527 if (is_audio_playing)
528 [controller setAudioIndicatorView:audioIndicatorView];
529 else
530 [controller setAudioIndicatorView:nil];
531 }
532
533 // Test layout for every width from maximum to minimum.
534 NSRect tabFrame = [[controller view] frame];
535 int min_width;
536 if (is_mini_tab) {
537 tabFrame.size.width = min_width = [TabController miniTabWidth];
538 } else {
539 tabFrame.size.width = [TabController maxTabWidth];
540 min_width = is_active_tab ? [TabController minSelectedTabWidth] :
541 [TabController minTabWidth];
542 }
543 while (NSWidth(tabFrame) >= min_width) {
544 SCOPED_TRACE(::testing::Message()
545 << "width=" << tabFrame.size.width);
546 [[controller view] setFrame:tabFrame];
547 CheckForExpectedLayoutAndVisibilityOfSubviews(controller);
548 --tabFrame.size.width;
549 }
550 }
551 }
552 }
553 }
554 }
555
358 } // namespace 556 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_controller.mm ('k') | chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698