diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-15 09:38:43 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-15 09:38:43 +0000 |
commit | a2ec1c5ab77e17e3022d651630fe59e24ae71f4c (patch) | |
tree | a638e50b00f60546c97ae1acc18dd17f0d698a4d /chrome/browser/cocoa | |
parent | 621f5c6a910d919e9980a7adf4ed478985eb4e84 (diff) | |
download | chromium_src-a2ec1c5ab77e17e3022d651630fe59e24ae71f4c.zip chromium_src-a2ec1c5ab77e17e3022d651630fe59e24ae71f4c.tar.gz chromium_src-a2ec1c5ab77e17e3022d651630fe59e24ae71f4c.tar.bz2 |
Reland translate toolbar unit tests (originally landed as r41274, rolled back at r41284).
BUG=None
TEST=New unit tests, tree should stay green after this checkin.
Review URL: http://codereview.chromium.org/938001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41569 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/translate_infobar.h | 26 | ||||
-rw-r--r-- | chrome/browser/cocoa/translate_infobar.mm | 84 | ||||
-rw-r--r-- | chrome/browser/cocoa/translate_infobar_unittest.mm | 187 |
3 files changed, 290 insertions, 7 deletions
diff --git a/chrome/browser/cocoa/translate_infobar.h b/chrome/browser/cocoa/translate_infobar.h index 410c60a..3df507b 100644 --- a/chrome/browser/cocoa/translate_infobar.h +++ b/chrome/browser/cocoa/translate_infobar.h @@ -9,6 +9,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/translate/languages_menu_model.h" #include "chrome/browser/translate/options_menu_model.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" #include "chrome/common/notification_registrar.h" class TranslateInfoBarMenuModel; @@ -56,3 +57,28 @@ class TranslateNotificationObserverBridge; } @end + +@interface TranslateInfoBarController (TestingAPI) + +// Main function to update the toolbar graphic state and data model after +// the state has changed. +// Controls are moved around as needed and visibility changed to match the +// current state. +- (void)updateState; + +// Called when the source or target language selection changes in a menu. +// |newLanguageIdx| is the index of the newly selected item in the appropriate +// menu. +- (void)sourceLanguageModified:(NSInteger)newLanguageIdx; +- (void)targetLanguageModified:(NSInteger)newLanguageIdx; + +// Called when an item in one of the toolbar's menus is selected. +- (void)menuItemSelected:(id)item; + +// Returns the underlying options menu. +- (NSMenu*)optionsMenu; + +// Verifies that the layout of the infobar is correct for |state|. +- (bool)verifyLayout:(TranslateInfoBarDelegate::TranslateState)state; + +@end diff --git a/chrome/browser/cocoa/translate_infobar.mm b/chrome/browser/cocoa/translate_infobar.mm index f727401..bb277db 100644 --- a/chrome/browser/cocoa/translate_infobar.mm +++ b/chrome/browser/cocoa/translate_infobar.mm @@ -15,7 +15,6 @@ #import "chrome/browser/cocoa/infobar_controller.h" #import "chrome/browser/cocoa/infobar_gradient_view.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/translate/translate_infobars_delegates.h" #include "chrome/common/notification_service.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -58,6 +57,21 @@ void VerticallyCenterView(NSView *toMove) { [toMove setFrame:viewFrame]; } +// Check that the control |before| is ordered visually before the |after| +// control. +// Also, check that there is space between them. +bool VerifyControlOrderAndSpacing(id before, id after) { + NSRect beforeFrame = [before frame]; + NSRect afterFrame = [after frame]; + NSUInteger spaceBetweenControls = -1; + + spaceBetweenControls = NSMaxX(beforeFrame) - NSMinX(afterFrame); + // RTL case to be used when we have an RTL version of this UI. + // spaceBetweenControls = NSMaxX(afterFrame) - NSMinX(beforeFrame); + + return (spaceBetweenControls >= 0); +} + // Creates a label control in the style we need for the translate infobar's // labels within |bounds|. NSTextField* CreateLabel(NSRect bounds) { @@ -134,12 +148,6 @@ class TranslateNotificationObserverBridge : // Returns the main translate delegate. - (TranslateInfoBarDelegate*)delegate; -// Main function to update the toolbar graphic state and data model after -// the state has changed. -// Controls are moved around as needed and visibility changed to match the -// current state. -- (void)updateState; - // Make the infobar blue. - (void)setInfoBarGradientColor; @@ -540,6 +548,68 @@ class TranslateNotificationObserverBridge : } } +#pragma mark TestingAPI +- (NSMenu*)optionsMenu { + return [optionsPopUp_ menu]; +} + +- (bool)verifyLayout:(TranslateInfoBarDelegate::TranslateState)state { + NSArray* allControls = [NSArray arrayWithObjects:label_, label2_.get(), + label3_.get(), translatingLabel_.get(), fromLanguagePopUp_.get(), + toLanguagePopUp_.get(), optionsPopUp_.get(), closeButton_, nil]; + + // Array of all visible controls ordered from start -> end. + NSArray* visibleControls = nil; + + switch (state) { + case TranslateInfoBarDelegate::kBeforeTranslate: + visibleControls = [NSArray arrayWithObjects:label_, + fromLanguagePopUp_.get(), label2_.get(), optionsPopUp_.get(), + closeButton_, nil]; + break; + case TranslateInfoBarDelegate::kTranslating: + visibleControls = [NSArray arrayWithObjects:label_, + fromLanguagePopUp_.get(), label2_.get(), translatingLabel_.get(), + optionsPopUp_.get(), closeButton_, nil]; + break; + case TranslateInfoBarDelegate::kAfterTranslate: + visibleControls = [NSArray arrayWithObjects:label_, + fromLanguagePopUp_.get(), label2_.get(), toLanguagePopUp_.get(), + optionsPopUp_.get(), closeButton_, nil]; + break; + default: + NOTREACHED() << "Unknown state"; + return false; + } + + // Step 1: Make sure control visibility is what we expect. + for (NSUInteger i = 0; i < [allControls count]; ++i) { + id control = [allControls objectAtIndex:i]; + bool hasSuperView = [control superview]; + bool expectedVisibility = [visibleControls containsObject:control]; + if (expectedVisibility != hasSuperView) { + LOG(ERROR) << + "Control @" << i << (hasSuperView ? " has" : " doesn't have") << + "a superview" << base::SysNSStringToUTF8([control description]); + return false; + } + } + + // Step 2: Check that controls are ordered correctly with no overlap. + id previousControl = nil; + for (NSUInteger i = 0; i < [allControls count]; ++i) { + id control = [allControls objectAtIndex:i]; + if (!VerifyControlOrderAndSpacing(previousControl, control)) { + LOG(ERROR) << + "Control @" << i << " not ordered correctly: " << + base::SysNSStringToUTF8([control description]); + return false; + } + previousControl = control; + } + return true; +} + @end #pragma mark CreateInfoBar implementation. diff --git a/chrome/browser/cocoa/translate_infobar_unittest.mm b/chrome/browser/cocoa/translate_infobar_unittest.mm new file mode 100644 index 0000000..9a7042a --- /dev/null +++ b/chrome/browser/cocoa/translate_infobar_unittest.mm @@ -0,0 +1,187 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> +#import "chrome/browser/cocoa/translate_infobar.h" + +#include "base/scoped_nsobject.h" +#include "base/string_util.h" +#include "chrome/app/chrome_dll_resource.h" // For translate menu command ids. +#import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace { + +// All states the translate toolbar can assume. +TranslateInfoBarDelegate::TranslateState kTranslateToolbarStates[] = { + TranslateInfoBarDelegate::kBeforeTranslate, + TranslateInfoBarDelegate::kTranslating, + TranslateInfoBarDelegate::kAfterTranslate}; + +class MockTranslateInfoBarDelegate : public TranslateInfoBarDelegate { + public: + MockTranslateInfoBarDelegate() { + // Start out in the "Before Translate" state. + UpdateState(kBeforeTranslate); + } + + virtual string16 GetDisplayNameForLocale(const std::string& language_code) { + return ASCIIToUTF16("Foo"); + } + + virtual bool IsLanguageBlacklisted() { + return false; + } + + virtual bool IsSiteBlacklisted() { + return false; + } + + virtual bool ShouldAlwaysTranslate() { + return false; + } + + MOCK_METHOD0(Translate, void()); + MOCK_METHOD0(TranslationDeclined, void()); + MOCK_METHOD0(ToggleLanguageBlacklist, void()); + MOCK_METHOD0(ToggleSiteBlacklist, void()); + MOCK_METHOD0(ToggleAlwaysTranslate, void()); + +}; + +class TranslationBarInfoTest : public CocoaTest { + public: + scoped_ptr<MockTranslateInfoBarDelegate> infobar_delegate; + scoped_nsobject<TranslateInfoBarController> infobar_controller; + + public: + // Each test gets a single Mock translate delegate for the lifetime of + // the test. + virtual void SetUp() { + CocoaTest::SetUp(); + infobar_delegate.reset(new MockTranslateInfoBarDelegate); + } + + void CreateInfoBar() { + CreateInfoBar(TranslateInfoBarDelegate::kBeforeTranslate); + } + + void CreateInfoBar(TranslateInfoBarDelegate::TranslateState initial_state) { + infobar_delegate->UpdateState(initial_state); + [[infobar_controller view] removeFromSuperview]; + infobar_controller.reset( + [[TranslateInfoBarController alloc] + initWithDelegate:infobar_delegate.get()]); + // Need to call this to get the view to load from nib. + [[test_window() contentView] addSubview:[infobar_controller view]]; + } +}; + +// Check that we can instantiate a Translate Infobar correctly. +TEST_F(TranslationBarInfoTest, Instantiate) { + CreateInfoBar(); + ASSERT_TRUE(infobar_controller.get()); +} + +// Check that clicking the Translate button calls Translate(). +TEST_F(TranslationBarInfoTest, TranslateCalledOnButtonPress) { + CreateInfoBar(); + + EXPECT_CALL(*infobar_delegate, Translate()) + .Times(1); + [infobar_controller ok:nil]; +} + +// Check that UI is layed out correctly as we transition synchronously through +// toolbar states. +TEST_F(TranslationBarInfoTest, StateTransitions) { + EXPECT_CALL(*infobar_delegate, Translate()) + .Times(0); + CreateInfoBar(); + + for (size_t i = 0; i < arraysize(kTranslateToolbarStates); ++i) { + infobar_delegate->UpdateState(kTranslateToolbarStates[i]); + + // First time around, the toolbar should already be layed out. + if (i != 0) + [infobar_controller updateState]; + + bool result = + [infobar_controller verifyLayout:kTranslateToolbarStates[i]]; + EXPECT_TRUE(result) << "Layout wrong, for state #" << i; + } +} + +// Check that items in the options menu are hooked up correctly. +TEST_F(TranslationBarInfoTest, OptionsMenuItemsHookedUp) { + EXPECT_CALL(*infobar_delegate, Translate()) + .Times(0); + CreateInfoBar(); + + NSMenu* optionsMenu = [infobar_controller optionsMenu]; + NSArray* optionsMenuItems = [optionsMenu itemArray]; + + EXPECT_EQ([optionsMenuItems count], 4U); + + // First item is the options menu button's title, so there's no need to test + // that the target on that is setup correctly. + for (NSUInteger i = 1; i < [optionsMenuItems count]; ++i) { + NSMenuItem* item = [optionsMenuItems objectAtIndex:i]; + EXPECT_EQ([item target], infobar_controller.get()); + } + NSMenuItem* neverTranslateLanguateItem = [optionsMenuItems objectAtIndex:1]; + NSMenuItem* neverTranslateSiteItem = [optionsMenuItems objectAtIndex:2]; + NSMenuItem* aboutTranslateItem = [optionsMenuItems objectAtIndex:3]; + + { + EXPECT_CALL(*infobar_delegate, ToggleLanguageBlacklist()) + .Times(1); + [infobar_controller menuItemSelected:neverTranslateLanguateItem]; + } + + { + EXPECT_CALL(*infobar_delegate, ToggleSiteBlacklist()) + .Times(1); + [infobar_controller menuItemSelected:neverTranslateSiteItem]; + } + + { + // Can't mock this effectively, so just check that the tag is set correctly. + EXPECT_EQ([aboutTranslateItem tag], IDC_TRANSLATE_OPTIONS_ABOUT); + } +} + +// Check that selecting a new item from the "Source Language" popup in "before +// translate" mode doesn't trigger a translation or change state. +// http://crbug.com/36666 +TEST_F(TranslationBarInfoTest, Bug36666) { + EXPECT_CALL(*infobar_delegate, Translate()) + .Times(0); + + CreateInfoBar(); + int arbitrary_index = 2; + [infobar_controller sourceLanguageModified:arbitrary_index]; + EXPECT_EQ(infobar_delegate->state(), + TranslateInfoBarDelegate::kBeforeTranslate); +} + +// Check that the infobar lays itself out correctly when instantiated in +// each of the states. +// http://crbug.com/36895 +TEST_F(TranslationBarInfoTest, Bug36895) { + EXPECT_CALL(*infobar_delegate, Translate()) + .Times(0); + + for (size_t i = 0; i < arraysize(kTranslateToolbarStates); ++i) { + CreateInfoBar(kTranslateToolbarStates[i]); + EXPECT_TRUE( + [infobar_controller verifyLayout:kTranslateToolbarStates[i]]) << + "Layout wrong, for state #" << i; + } +} + +} // namespace |