Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / views / menu_model_adapter_test.cc
blob22c48ee6512cca8eb27f67e05de79be824f4deea
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.
5 #include "base/callback.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/test/base/interactive_test_utils.h"
8 #include "chrome/test/base/ui_test_utils.h"
9 #include "chrome/test/base/view_event_test_base.h"
10 #include "ui/base/models/menu_model.h"
11 #include "ui/base/test/ui_controls.h"
12 #include "ui/views/controls/button/menu_button.h"
13 #include "ui/views/controls/button/menu_button_listener.h"
14 #include "ui/views/controls/menu/menu_controller.h"
15 #include "ui/views/controls/menu/menu_item_view.h"
16 #include "ui/views/controls/menu/menu_model_adapter.h"
17 #include "ui/views/controls/menu/menu_runner.h"
18 #include "ui/views/controls/menu/submenu_view.h"
19 #include "ui/views/test/test_views_delegate.h"
20 #include "ui/views/widget/root_view.h"
21 #include "ui/views/widget/widget.h"
23 namespace {
25 const int kTopMenuBaseId = 100;
26 const int kSubMenuBaseId = 200;
28 // Implement most of the ui::MenuModel pure virtual methods for subclasses
30 // Exceptions:
31 // virtual int GetItemCount() const = 0;
32 // virtual ItemType GetTypeAt(int index) const = 0;
33 // virtual int GetCommandIdAt(int index) const = 0;
34 // virtual string16 GetLabelAt(int index) const = 0;
35 class CommonMenuModel : public ui::MenuModel {
36 public:
37 CommonMenuModel() {
40 virtual ~CommonMenuModel() {
43 protected:
44 // ui::MenuModel implementation.
45 virtual bool HasIcons() const OVERRIDE {
46 return false;
49 virtual bool IsItemDynamicAt(int index) const OVERRIDE {
50 return false;
53 virtual bool GetAcceleratorAt(int index,
54 ui::Accelerator* accelerator) const OVERRIDE {
55 return false;
58 virtual ui::MenuSeparatorType GetSeparatorTypeAt(int index) const OVERRIDE {
59 return ui::NORMAL_SEPARATOR;
62 virtual bool IsItemCheckedAt(int index) const OVERRIDE {
63 return false;
66 virtual int GetGroupIdAt(int index) const OVERRIDE {
67 return 0;
70 virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE {
71 return false;
74 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(
75 int index) const OVERRIDE {
76 return NULL;
79 virtual bool IsEnabledAt(int index) const OVERRIDE {
80 return true;
83 virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
84 return NULL;
87 virtual void HighlightChangedTo(int index) OVERRIDE {
90 virtual void ActivatedAt(int index) OVERRIDE {
93 virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE {
96 virtual ui::MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE {
97 return NULL;
100 private:
101 DISALLOW_COPY_AND_ASSIGN(CommonMenuModel);
104 class SubMenuModel : public CommonMenuModel {
105 public:
106 SubMenuModel()
107 : showing_(false) {
110 virtual ~SubMenuModel() {
113 bool showing() const {
114 return showing_;
117 private:
118 // ui::MenuModel implementation.
119 virtual int GetItemCount() const OVERRIDE {
120 return 1;
123 virtual ItemType GetTypeAt(int index) const OVERRIDE {
124 return TYPE_COMMAND;
127 virtual int GetCommandIdAt(int index) const OVERRIDE {
128 return index + kSubMenuBaseId;
131 virtual string16 GetLabelAt(int index) const OVERRIDE {
132 return ASCIIToUTF16("Item");
135 virtual void MenuWillShow() OVERRIDE {
136 showing_ = true;
139 // Called when the menu has been closed.
140 virtual void MenuClosed() OVERRIDE {
141 showing_ = false;
144 bool showing_;
146 DISALLOW_COPY_AND_ASSIGN(SubMenuModel);
149 class TopMenuModel : public CommonMenuModel {
150 public:
151 TopMenuModel() {
154 virtual ~TopMenuModel() {
157 bool IsSubmenuShowing() {
158 return sub_menu_model_.showing();
161 private:
162 // ui::MenuModel implementation.
163 virtual int GetItemCount() const OVERRIDE {
164 return 1;
167 virtual ItemType GetTypeAt(int index) const OVERRIDE {
168 return TYPE_SUBMENU;
171 virtual int GetCommandIdAt(int index) const OVERRIDE {
172 return index + kTopMenuBaseId;
175 virtual string16 GetLabelAt(int index) const OVERRIDE {
176 return ASCIIToUTF16("submenu");
179 virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
180 return &sub_menu_model_;
183 mutable SubMenuModel sub_menu_model_;
185 DISALLOW_COPY_AND_ASSIGN(TopMenuModel);
188 } // namespace
190 class MenuModelAdapterTest : public ViewEventTestBase,
191 public views::MenuButtonListener {
192 public:
193 MenuModelAdapterTest()
194 : ViewEventTestBase(),
195 button_(NULL),
196 menu_model_adapter_(&top_menu_model_),
197 menu_(NULL) {
198 old_views_delegate_ = views::ViewsDelegate::views_delegate;
199 views::ViewsDelegate::views_delegate = &views_delegate_;
202 virtual ~MenuModelAdapterTest() {
203 views::ViewsDelegate::views_delegate = old_views_delegate_;
206 // ViewEventTestBase implementation.
208 virtual void SetUp() OVERRIDE {
209 button_ = new views::MenuButton(
210 NULL, ASCIIToUTF16("Menu Adapter Test"), this, true);
212 menu_ = menu_model_adapter_.CreateMenu();
213 menu_runner_.reset(new views::MenuRunner(menu_));
215 ViewEventTestBase::SetUp();
218 virtual void TearDown() OVERRIDE {
219 menu_runner_.reset(NULL);
220 menu_ = NULL;
221 ViewEventTestBase::TearDown();
224 virtual views::View* CreateContentsView() OVERRIDE {
225 return button_;
228 virtual gfx::Size GetPreferredSize() OVERRIDE {
229 return button_->GetPreferredSize();
232 // views::MenuButtonListener implementation.
233 virtual void OnMenuButtonClicked(views::View* source,
234 const gfx::Point& point) OVERRIDE {
235 gfx::Point screen_location;
236 views::View::ConvertPointToScreen(source, &screen_location);
237 gfx::Rect bounds(screen_location, source->size());
238 ignore_result(menu_runner_->RunMenuAt(
239 source->GetWidget(),
240 button_,
241 bounds,
242 views::MenuItemView::TOPLEFT,
243 ui::MENU_SOURCE_NONE,
244 views::MenuRunner::HAS_MNEMONICS));
247 // ViewEventTestBase implementation
248 virtual void DoTestOnMessageLoop() OVERRIDE {
249 Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1));
252 // Open the submenu.
253 void Step1() {
254 views::SubmenuView* topmenu = menu_->GetSubmenu();
255 ASSERT_TRUE(topmenu);
256 ASSERT_TRUE(topmenu->IsShowing());
257 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());
259 // Click the first item to open the submenu.
260 views::MenuItemView* item = topmenu->GetMenuItemAt(0);
261 ASSERT_TRUE(item);
262 Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2));
265 // Rebuild the menu which should close the submenu.
266 void Step2() {
267 views::SubmenuView* topmenu = menu_->GetSubmenu();
268 ASSERT_TRUE(topmenu);
269 ASSERT_TRUE(topmenu->IsShowing());
270 ASSERT_TRUE(top_menu_model_.IsSubmenuShowing());
272 menu_model_adapter_.BuildMenu(menu_);
274 base::MessageLoopForUI::current()->PostTask(
275 FROM_HERE, CreateEventTask(this, &MenuModelAdapterTest::Step3));
278 // Verify that the submenu MenuModel received the close callback
279 // and close the menu.
280 void Step3() {
281 views::SubmenuView* topmenu = menu_->GetSubmenu();
282 ASSERT_TRUE(topmenu);
283 ASSERT_TRUE(topmenu->IsShowing());
284 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());
286 // Click the button to exit the menu.
287 Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4));
290 // All done.
291 void Step4() {
292 views::SubmenuView* topmenu = menu_->GetSubmenu();
293 ASSERT_TRUE(topmenu);
294 ASSERT_FALSE(topmenu->IsShowing());
295 ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());
297 Done();
300 private:
301 // Generate a mouse click on the specified view and post a new task.
302 virtual void Click(views::View* view, const base::Closure& next) {
303 ui_test_utils::MoveMouseToCenterAndPress(
304 view,
305 ui_controls::LEFT,
306 ui_controls::DOWN | ui_controls::UP,
307 next);
310 views::ViewsDelegate* old_views_delegate_;
311 views::TestViewsDelegate views_delegate_;
313 views::MenuButton* button_;
314 TopMenuModel top_menu_model_;
315 views::MenuModelAdapter menu_model_adapter_;
316 views::MenuItemView* menu_;
317 scoped_ptr<views::MenuRunner> menu_runner_;
320 #if defined(OS_WIN)
321 #define MAYBE_RebuildMenu DISABLED_RebuildMenu
322 #else
323 #define MAYBE_RebuildMenu RebuildMenu
324 #endif
325 VIEW_TEST(MenuModelAdapterTest, MAYBE_RebuildMenu)