1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" 6 7 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" 8 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h" 9 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 10 #include "chrome/browser/ui/omnibox/omnibox_popup_view.h" 11 #include "chrome/browser/ui/toolbar/toolbar_model_delegate.h" 12 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h" 13 #include "chrome/test/base/testing_profile.h" 14 #include "testing/platform_test.h" 15 #include "ui/gfx/image/image.h" 16 #include "ui/gfx/font.h" 17 #include "ui/gfx/rect.h" 18 19 namespace { 20 21 class MockOmniboxEditModel : public OmniboxEditModel { 22 public: 23 MockOmniboxEditModel(OmniboxView* view, 24 OmniboxEditController* controller, 25 Profile* profile) 26 : OmniboxEditModel(view, controller, profile), 27 up_or_down_count_(0) { 28 } 29 30 virtual void OnUpOrDownKeyPressed(int count) OVERRIDE { 31 up_or_down_count_ = count; 32 } 33 34 int up_or_down_count() const { return up_or_down_count_; } 35 36 void set_up_or_down_count(int count) { 37 up_or_down_count_ = count; 38 } 39 40 private: 41 int up_or_down_count_; 42 43 DISALLOW_COPY_AND_ASSIGN(MockOmniboxEditModel); 44 }; 45 46 class MockOmniboxPopupView : public OmniboxPopupView { 47 public: 48 MockOmniboxPopupView() : is_open_(false) {} 49 virtual ~MockOmniboxPopupView() {} 50 51 // Overridden from OmniboxPopupView: 52 virtual bool IsOpen() const OVERRIDE { return is_open_; } 53 virtual void InvalidateLine(size_t line) OVERRIDE {} 54 virtual void UpdatePopupAppearance() OVERRIDE {} 55 virtual gfx::Rect GetTargetBounds() OVERRIDE { return gfx::Rect(); } 56 virtual void PaintUpdatesNow() OVERRIDE {} 57 virtual void OnDragCanceled() OVERRIDE {} 58 59 void set_is_open(bool is_open) { is_open_ = is_open; } 60 61 private: 62 bool is_open_; 63 64 DISALLOW_COPY_AND_ASSIGN(MockOmniboxPopupView); 65 }; 66 67 class TestingToolbarModelDelegate : public ToolbarModelDelegate { 68 public: 69 TestingToolbarModelDelegate() {} 70 virtual ~TestingToolbarModelDelegate() {} 71 72 // Overridden from ToolbarModelDelegate: 73 virtual content::WebContents* GetActiveWebContents() const OVERRIDE { 74 return NULL; 75 } 76 virtual bool InTabbedBrowser() const OVERRIDE { 77 return true; 78 } 79 80 private: 81 DISALLOW_COPY_AND_ASSIGN(TestingToolbarModelDelegate); 82 }; 83 84 class TestingOmniboxEditController : public OmniboxEditController { 85 public: 86 explicit TestingOmniboxEditController(ToolbarModel* toolbar_model) 87 : OmniboxEditController(NULL), 88 toolbar_model_(toolbar_model) { 89 } 90 virtual ~TestingOmniboxEditController() {} 91 92 protected: 93 // Overridden from OmniboxEditController: 94 virtual void Update(const content::WebContents* contents) OVERRIDE {} 95 virtual void OnChanged() OVERRIDE {} 96 virtual void OnSetFocus() OVERRIDE {} 97 virtual void ShowURL() OVERRIDE {} 98 virtual void HideURL() OVERRIDE {} 99 virtual void EndOriginChipAnimations(bool cancel_fade) OVERRIDE {} 100 virtual InstantController* GetInstant() OVERRIDE { return NULL; } 101 virtual content::WebContents* GetWebContents() OVERRIDE { return NULL; } 102 virtual ToolbarModel* GetToolbarModel() OVERRIDE { return toolbar_model_; } 103 virtual const ToolbarModel* GetToolbarModel() const OVERRIDE { 104 return toolbar_model_; 105 } 106 107 private: 108 ToolbarModel* toolbar_model_; 109 110 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController); 111 }; 112 113 } // namespace 114 115 class OmniboxViewMacTest : public CocoaProfileTest { 116 public: 117 void SetModel(OmniboxViewMac* view, OmniboxEditModel* model) { 118 view->model_.reset(model); 119 } 120 }; 121 122 TEST_F(OmniboxViewMacTest, GetFieldFont) { 123 EXPECT_TRUE(OmniboxViewMac::GetFieldFont(gfx::Font::NORMAL)); 124 } 125 126 TEST_F(OmniboxViewMacTest, TabToAutocomplete) { 127 OmniboxViewMac view(NULL, profile(), NULL, NULL); 128 129 // This is deleted by the omnibox view. 130 MockOmniboxEditModel* model = 131 new MockOmniboxEditModel(&view, NULL, profile()); 132 SetModel(&view, model); 133 134 MockOmniboxPopupView popup_view; 135 OmniboxPopupModel popup_model(&popup_view, model); 136 137 // With popup closed verify that tab doesn't autocomplete. 138 popup_view.set_is_open(false); 139 view.OnDoCommandBySelector(@selector(insertTab:)); 140 EXPECT_EQ(0, model->up_or_down_count()); 141 view.OnDoCommandBySelector(@selector(insertBacktab:)); 142 EXPECT_EQ(0, model->up_or_down_count()); 143 144 // With popup open verify that tab does autocomplete. 145 popup_view.set_is_open(true); 146 view.OnDoCommandBySelector(@selector(insertTab:)); 147 EXPECT_EQ(1, model->up_or_down_count()); 148 view.OnDoCommandBySelector(@selector(insertBacktab:)); 149 EXPECT_EQ(-1, model->up_or_down_count()); 150 } 151 152 TEST_F(OmniboxViewMacTest, SetGrayTextAutocompletion) { 153 const NSRect frame = NSMakeRect(0, 0, 50, 30); 154 base::scoped_nsobject<AutocompleteTextField> field( 155 [[AutocompleteTextField alloc] initWithFrame:frame]); 156 157 TestingToolbarModelDelegate delegate; 158 ToolbarModelImpl toolbar_model(&delegate); 159 TestingOmniboxEditController controller(&toolbar_model); 160 OmniboxViewMac view(&controller, profile(), NULL, field.get()); 161 162 // This is deleted by the omnibox view. 163 MockOmniboxEditModel* model = 164 new MockOmniboxEditModel(&view, &controller, profile()); 165 SetModel(&view, model); 166 167 MockOmniboxPopupView popup_view; 168 OmniboxPopupModel popup_model(&popup_view, model); 169 170 view.SetUserText(base::ASCIIToUTF16("Alfred")); 171 EXPECT_EQ("Alfred", base::UTF16ToUTF8(view.GetText())); 172 view.SetGrayTextAutocompletion(base::ASCIIToUTF16(" Hitchcock")); 173 EXPECT_EQ("Alfred", base::UTF16ToUTF8(view.GetText())); 174 EXPECT_EQ(" Hitchcock", base::UTF16ToUTF8(view.GetGrayTextAutocompletion())); 175 176 view.SetUserText(base::string16()); 177 EXPECT_EQ(base::string16(), view.GetText()); 178 EXPECT_EQ(base::string16(), view.GetGrayTextAutocompletion()); 179 } 180 181 TEST_F(OmniboxViewMacTest, UpDownArrow) { 182 OmniboxViewMac view(NULL, profile(), NULL, NULL); 183 184 // This is deleted by the omnibox view. 185 MockOmniboxEditModel* model = 186 new MockOmniboxEditModel(&view, NULL, profile()); 187 SetModel(&view, model); 188 189 MockOmniboxPopupView popup_view; 190 OmniboxPopupModel popup_model(&popup_view, model); 191 192 // With popup closed verify that pressing up and down arrow works. 193 popup_view.set_is_open(false); 194 model->set_up_or_down_count(0); 195 view.OnDoCommandBySelector(@selector(moveDown:)); 196 EXPECT_EQ(1, model->up_or_down_count()); 197 model->set_up_or_down_count(0); 198 view.OnDoCommandBySelector(@selector(moveUp:)); 199 EXPECT_EQ(-1, model->up_or_down_count()); 200 201 // With popup open verify that pressing up and down arrow works. 202 popup_view.set_is_open(true); 203 model->set_up_or_down_count(0); 204 view.OnDoCommandBySelector(@selector(moveDown:)); 205 EXPECT_EQ(1, model->up_or_down_count()); 206 model->set_up_or_down_count(0); 207 view.OnDoCommandBySelector(@selector(moveUp:)); 208 EXPECT_EQ(-1, model->up_or_down_count()); 209 } 210