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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
index 0267e79c297c3b7402e505c3c5f73a62f1622777..ab58034023a490e7ace778017eb31daefa64bddb 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
@@ -10,9 +10,12 @@
#import "chrome/browser/ui/cocoa/tabs/tab_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h"
+#include "grit/theme_resources.h"
+#include "grit/ui_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
#include "testing/platform_test.h"
+#include "ui/base/resource/resource_bundle.h"
// Implements the target interface for the tab, which gets sent messages when
// the tab is clicked on by the user and when its close box is clicked.
@@ -91,11 +94,137 @@ CGFloat RightMargin(NSRect superFrame, NSRect subFrame) {
return NSMaxX(superFrame) - NSMaxX(subFrame);
}
+// Helper to create an NSImageView that contains an image fetched from
+// ui::ResourceBundle.
+NSImageView* CreateImageViewFromResourceBundle(int resource_id) {
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ NSImage* const image = rb.GetNativeImageNamed(resource_id).ToNSImage();
+ CHECK(!!image);
+ NSRect frame;
+ frame.size = [image size];
+ NSImageView* const view = [[NSImageView alloc] initWithFrame:frame];
+ [view setImage:image];
+ return view;
+}
+
// The dragging code in TabView makes heavy use of autorelease pools so
// inherit from CocoaTest to have one created for us.
class TabControllerTest : public CocoaTest {
public:
TabControllerTest() { }
+
+ static void CheckForExpectedLayoutAndVisibilityOfSubviews(
+ const TabController* controller) {
+ // Check whether subviews should be visible when they are supposed to be,
+ // given Tab size and TabRendererData state.
+ if ([controller mini]) {
+ if ([controller projecting])
+ EXPECT_TRUE([controller shouldShowIcon]);
+ else
+ EXPECT_TRUE([controller shouldShowIcon] !=
+ [controller shouldShowAudioIndicator]);
+ EXPECT_FALSE([controller shouldShowCloseButton]);
+ } else if ([controller selected]) {
+ EXPECT_TRUE([controller shouldShowCloseButton]);
+ switch ([controller iconCapacity]) {
+ case 0:
+ case 1:
+ EXPECT_FALSE([controller shouldShowIcon]);
+ EXPECT_FALSE([controller shouldShowAudioIndicator]);
+ break;
+ case 2:
+ if ([controller projecting])
+ EXPECT_TRUE([controller shouldShowIcon]);
+ else
+ EXPECT_TRUE([controller shouldShowIcon] !=
+ [controller shouldShowAudioIndicator]);
+ break;
+ default:
+ EXPECT_LE(3, [controller iconCapacity]);
+ EXPECT_TRUE([controller shouldShowIcon]);
+ if ([controller projecting])
+ EXPECT_FALSE([controller shouldShowAudioIndicator]);
+ else
+ EXPECT_TRUE(!![controller audioIndicatorView] ==
+ [controller shouldShowAudioIndicator]);
+ break;
+ }
+ } else { // Tab not selected/active and not mini tab.
+ switch ([controller iconCapacity]) {
+ case 0:
+ EXPECT_FALSE([controller shouldShowCloseButton]);
+ EXPECT_FALSE([controller shouldShowIcon]);
+ EXPECT_FALSE([controller shouldShowAudioIndicator]);
+ break;
+ case 1:
+ EXPECT_FALSE([controller shouldShowCloseButton]);
+ if ([controller projecting])
+ EXPECT_TRUE([controller shouldShowIcon]);
+ else
+ EXPECT_TRUE([controller shouldShowIcon] !=
+ [controller shouldShowAudioIndicator]);
+ break;
+ default:
+ EXPECT_LE(2, [controller iconCapacity]);
+ EXPECT_TRUE([controller shouldShowIcon]);
+ if ([controller projecting])
+ EXPECT_FALSE([controller shouldShowAudioIndicator]);
+ else
+ EXPECT_TRUE(!![controller audioIndicatorView] ==
+ [controller shouldShowAudioIndicator]);
+ break;
+ }
+ }
+
+ // Make sure the NSView's "isHidden" state jives with the "shouldShowXXX."
+ EXPECT_TRUE([controller shouldShowIcon] ==
+ (!![controller iconView] && ![[controller iconView] isHidden]));
+ EXPECT_TRUE([controller mini] == [[controller titleView] isHidden]);
+ EXPECT_TRUE([controller shouldShowAudioIndicator] ==
+ (!![controller audioIndicatorView] &&
+ ![[controller audioIndicatorView] isHidden]));
+ EXPECT_TRUE([controller shouldShowCloseButton] !=
+ [[controller closeButton] isHidden]);
+
+ // Check positioning of elements with respect to each other, and that they
+ // are fully within the tab frame.
+ const NSRect tabFrame = [[controller view] frame];
+ const NSRect titleFrame = [[controller titleView] frame];
+ if ([controller shouldShowIcon]) {
+ const NSRect iconFrame = [[controller iconView] frame];
+ EXPECT_LE(NSMinX(tabFrame), NSMinX(iconFrame));
+ if (NSWidth(titleFrame) > 0)
+ EXPECT_LE(NSMaxX(iconFrame), NSMinX(titleFrame));
+ EXPECT_LE(NSMinY(tabFrame), NSMinY(iconFrame));
+ EXPECT_LE(NSMaxY(iconFrame), NSMaxY(tabFrame));
+ }
+ if ([controller shouldShowIcon] && [controller shouldShowAudioIndicator]) {
+ EXPECT_LE(NSMaxX([[controller iconView] frame]),
+ NSMinX([[controller audioIndicatorView] frame]));
+ }
+ if ([controller shouldShowAudioIndicator]) {
+ const NSRect audioIndicatorFrame =
+ [[controller audioIndicatorView] frame];
+ if (NSWidth(titleFrame) > 0)
+ EXPECT_LE(NSMaxX(titleFrame), NSMinX(audioIndicatorFrame));
+ EXPECT_LE(NSMaxX(audioIndicatorFrame), NSMaxX(tabFrame));
+ EXPECT_LE(NSMinY(tabFrame), NSMinY(audioIndicatorFrame));
+ EXPECT_LE(NSMaxY(audioIndicatorFrame), NSMaxY(tabFrame));
+ }
+ if ([controller shouldShowAudioIndicator] &&
+ [controller shouldShowCloseButton]) {
+ EXPECT_LE(NSMaxX([[controller audioIndicatorView] frame]),
+ NSMinX([[controller closeButton] frame]));
+ }
+ if ([controller shouldShowCloseButton]) {
+ const NSRect closeButtonFrame = [[controller closeButton] frame];
+ if (NSWidth(titleFrame) > 0)
+ EXPECT_LE(NSMaxX(titleFrame), NSMinX(closeButtonFrame));
+ EXPECT_LE(NSMaxX(closeButtonFrame), NSMaxX(tabFrame));
+ EXPECT_LE(NSMinY(tabFrame), NSMinY(closeButtonFrame));
+ EXPECT_LE(NSMaxY(closeButtonFrame), NSMaxY(tabFrame));
+ }
+ }
};
// Tests creating the controller, sticking it in a window, and removing it.
@@ -355,4 +484,73 @@ TEST_F(TabControllerTest, TitleViewLayout) {
[[controller titleView] frame]));
}
+// A comprehensive test of the layout and visibility of all elements (favicon,
+// throbber indicators, titile text, audio indicator, and close button) over all
+// relevant combinations of tab state. This test overlaps with parts of the
+// other tests above.
+TEST_F(TabControllerTest, LayoutAndVisibilityOfSubviews) {
+ NSWindow* const window = test_window();
+
+ // Create TabController instance and place its view into the test window.
+ base::scoped_nsobject<TabController> controller([[TabController alloc] init]);
+ [[window contentView] addSubview:[controller view]];
+
+ // Create favicon and audio indicator icon views.
+ base::scoped_nsobject<NSImageView> faviconView(
+ CreateImageViewFromResourceBundle(IDR_DEFAULT_FAVICON));
+ base::scoped_nsobject<NSImageView> audioIndicatorView(
+ CreateImageViewFromResourceBundle(IDR_TAB_AUDIO_INDICATOR));
+
+ [controller setIconView:faviconView];
+
+ // Perform layout over all possible combinations, checking for correct
+ // results.
+ for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) {
+ for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) {
+ for (int is_audio_playing = 0; is_audio_playing < 2; ++is_audio_playing) {
+ for (int is_capturing = 0; is_capturing < 2; ++is_capturing) {
+ SCOPED_TRACE(::testing::Message()
+ << (is_active_tab ? "Active" : "Inactive") << ' '
+ << (is_mini_tab ? "Mini " : "")
+ << "Tab with is_audio_playing=" << !!is_audio_playing
+ << " and is_capturing=" << !!is_capturing);
+
+ // Simulate what tab_strip_controller would do to set up the
+ // TabController state.
+ [controller setMini:(is_mini_tab ? YES : NO)];
+ [controller setActive:(is_active_tab ? YES : NO)];
+ if (is_capturing) {
+ [controller setProjecting:YES];
+ [controller setAudioIndicatorView:nil];
+ } else {
+ [controller setProjecting:NO];
+ if (is_audio_playing)
+ [controller setAudioIndicatorView:audioIndicatorView];
+ else
+ [controller setAudioIndicatorView:nil];
+ }
+
+ // Test layout for every width from maximum to minimum.
+ NSRect tabFrame = [[controller view] frame];
+ int min_width;
+ if (is_mini_tab) {
+ tabFrame.size.width = min_width = [TabController miniTabWidth];
+ } else {
+ tabFrame.size.width = [TabController maxTabWidth];
+ min_width = is_active_tab ? [TabController minSelectedTabWidth] :
+ [TabController minTabWidth];
+ }
+ while (NSWidth(tabFrame) >= min_width) {
+ SCOPED_TRACE(::testing::Message()
+ << "width=" << tabFrame.size.width);
+ [[controller view] setFrame:tabFrame];
+ CheckForExpectedLayoutAndVisibilityOfSubviews(controller);
+ --tabFrame.size.width;
+ }
+ }
+ }
+ }
+ }
+}
+
} // namespace
« 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