summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-15 09:38:43 +0000
committerjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-15 09:38:43 +0000
commita2ec1c5ab77e17e3022d651630fe59e24ae71f4c (patch)
treea638e50b00f60546c97ae1acc18dd17f0d698a4d /chrome/browser/cocoa
parent621f5c6a910d919e9980a7adf4ed478985eb4e84 (diff)
downloadchromium_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.h26
-rw-r--r--chrome/browser/cocoa/translate_infobar.mm84
-rw-r--r--chrome/browser/cocoa/translate_infobar_unittest.mm187
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