Chromium Code Reviews| Index: chrome/browser/ui/views/menu_model_adapter_test.cc |
| diff --git a/chrome/browser/ui/views/menu_model_adapter_test.cc b/chrome/browser/ui/views/menu_model_adapter_test.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..193c53693b928bbdeae1ca7f1b98bb0fbce2682c |
| --- /dev/null |
| +++ b/chrome/browser/ui/views/menu_model_adapter_test.cc |
| @@ -0,0 +1,362 @@ |
| +// Copyright (c) 2011 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. |
| + |
| +#include "chrome/browser/automation/ui_controls.h" |
| +#include "chrome/test/interactive_ui/view_event_test_base.h" |
| +#include "ui/base/models/menu_model.h" |
| +#include "views/controls/button/menu_button.h" |
| +#include "views/controls/menu/menu_controller.h" |
| +#include "views/controls/menu/menu_item_view.h" |
| +#include "views/controls/menu/menu_model_adapter.h" |
| +#include "views/controls/menu/submenu_view.h" |
| +#include "views/controls/menu/view_menu_delegate.h" |
| +#include "views/test/test_views_delegate.h" |
| +#include "views/views_delegate.h" |
| +#include "views/widget/root_view.h" |
| +#include "views/widget/widget.h" |
| + |
| +namespace { |
| + |
| +const int kTopMenuBaseId = 100; |
| +const int kSubMenuBaseId = 200; |
| + |
| +// ViewsDelegate::GetDispositionForEvent() is used by views::MenuModelAdapter. |
| +class TestViewsDelegate : public views::ViewsDelegate { |
| + // views::ViewsDelegate implementation |
| + virtual ui::Clipboard* GetClipboard() const OVERRIDE { |
| + return NULL; |
| + } |
| + |
| + virtual views::View* GetDefaultParentView() OVERRIDE |
| + { |
| + return NULL; |
| + } |
| + |
| + virtual void SaveWindowPlacement(const views::Widget* widget, |
| + const std::wstring& window_name, |
| + const gfx::Rect& bounds, |
| + bool maximized) OVERRIDE { |
| + } |
| + |
| + virtual bool GetSavedWindowBounds(const std::wstring& window_name, |
| + gfx::Rect* bounds) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual bool GetSavedMaximizedState(const std::wstring& window_name, |
| + bool* maximized) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual void NotifyAccessibilityEvent( |
| + views::View* view, ui::AccessibilityTypes::Event event_type) OVERRIDE { |
| + } |
| + |
| + virtual void NotifyMenuItemFocused( |
| + const std::wstring& menu_name, |
| + const std::wstring& menu_item_name, |
| + int item_index, |
| + int item_count, |
| + bool has_submenu) OVERRIDE { |
| + } |
| + |
| +#if defined(OS_WIN) |
| + virtual HICON GetDefaultWindowIcon() const OVERRIDE |
| + { |
| + return NULL; |
| + } |
| +#endif |
| + |
| + virtual void AddRef() OVERRIDE { |
| + } |
| + |
| + virtual void ReleaseRef() OVERRIDE { |
| + } |
| + |
| + // Converts views::Event::flags to a WindowOpenDisposition. |
| + virtual int GetDispositionForEvent(int event_flags) OVERRIDE { |
| + return 0; |
| + } |
| +}; |
| + |
| +// Implement most of the ui::MenuModel pure virtuals for subclasses |
| +// |
| +// Exceptions: |
| +// virtual int GetItemCount() const = 0; |
| +// virtual ItemType GetTypeAt(int index) const = 0; |
| +// virtual int GetCommandIdAt(int index) const = 0; |
| +// virtual string16 GetLabelAt(int index) const = 0; |
| +class CommonMenuModel : public ui::MenuModel { |
| + protected: |
| + // ui::MenuModel implementation. |
| + virtual bool HasIcons() const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual bool IsItemDynamicAt(int index) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual bool GetAcceleratorAt(int index, |
| + ui::Accelerator* accelerator) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual bool IsItemCheckedAt(int index) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual int GetGroupIdAt(int index) const OVERRIDE { |
| + return 0; |
| + } |
| + |
| + virtual bool GetIconAt(int index, SkBitmap* icon) OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt( |
| + int index) const OVERRIDE { |
| + return NULL; |
| + } |
| + |
| + virtual bool IsEnabledAt(int index) const OVERRIDE { |
| + return true; |
| + } |
| + |
| + virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { |
| + return NULL; |
| + } |
| + |
| + virtual void HighlightChangedTo(int index) OVERRIDE { |
| + } |
| + |
| + virtual void ActivatedAt(int index) OVERRIDE { |
| + } |
| + |
| + virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE { |
| + } |
| +}; |
| + |
| +class SubMenuModel : public CommonMenuModel { |
| + public: |
| + SubMenuModel() : |
|
sky
2011/08/02 23:08:12
: on next line.
rhashimoto
2011/08/02 23:53:37
Done.
|
| + showing_(false) { |
| + } |
| + |
| + bool showing() const { |
| + return showing_; |
| + } |
| + |
| + private: |
| + // ui::MenuModel implementation. |
| + virtual int GetItemCount() const OVERRIDE { |
| + return 1; |
| + } |
| + |
| + virtual ItemType GetTypeAt(int index) const OVERRIDE { |
| + return TYPE_COMMAND; |
| + } |
| + |
| + virtual int GetCommandIdAt(int index) const OVERRIDE { |
| + return index + kSubMenuBaseId; |
| + } |
| + |
| + virtual string16 GetLabelAt(int index) const OVERRIDE { |
| + return ASCIIToUTF16("Item"); |
| + } |
| + |
| + virtual void MenuWillShow() { |
| + showing_ = true; |
| + } |
| + |
| + // Called when the menu has been closed. |
| + virtual void MenuClosed() { |
| + showing_ = false; |
| + } |
| + |
| + bool showing_; |
| +}; |
|
sky
2011/08/02 23:08:12
DISALLOW_BLAH_BLAH here and in other classes.
rhashimoto
2011/08/02 23:53:37
Done.
|
| + |
| +class TopMenuModel : public CommonMenuModel { |
| + public: |
| + TopMenuModel() { |
| + } |
| + |
| + bool IsSubmenuShowing() { |
| + return sub_menu_model_.showing(); |
| + } |
| + |
| + private: |
| + // ui::MenuModel implementation. |
| + virtual int GetItemCount() const OVERRIDE { |
| + return 1; |
| + } |
| + |
| + virtual ItemType GetTypeAt(int index) const OVERRIDE { |
| + return TYPE_SUBMENU; |
| + } |
| + |
| + virtual int GetCommandIdAt(int index) const OVERRIDE { |
| + return index + kTopMenuBaseId; |
| + } |
| + |
| + virtual string16 GetLabelAt(int index) const OVERRIDE { |
| + return ASCIIToUTF16("submenu"); |
| + } |
| + |
| + virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { |
| + return &sub_menu_model_; |
| + } |
| + |
| + mutable SubMenuModel sub_menu_model_; |
| +}; |
| + |
| +} // namespace |
| + |
| +class MenuModelAdapterTest : public ViewEventTestBase, |
| + public views::ViewMenuDelegate { |
| + public: |
| + MenuModelAdapterTest() : |
| + ViewEventTestBase(), |
| + button_(NULL), |
| + menu_model_adapter_(&top_menu_model_) { |
| + old_views_delegate_ = views::ViewsDelegate::views_delegate; |
| + views::ViewsDelegate::views_delegate = &views_delegate_; |
| + } |
| + |
| + virtual ~MenuModelAdapterTest() { |
| + views::ViewsDelegate::views_delegate = old_views_delegate_; |
| + } |
| + |
| + // ViewEventTestBase implementation. |
| + |
| + virtual void SetUp() OVERRIDE { |
| + button_ = new views::MenuButton(NULL, L"Menu Adapter Test", this, true); |
| + |
| + menu_.reset(new views::MenuItemView(&menu_model_adapter_)); |
| + menu_model_adapter_.BuildMenu(menu_.get()); |
| + |
| + ViewEventTestBase::SetUp(); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + menu_.reset(NULL); |
| + ViewEventTestBase::TearDown(); |
| + } |
| + |
| + virtual views::View* CreateContentsView() OVERRIDE { |
| + return button_; |
| + } |
| + |
| + virtual gfx::Size GetPreferredSize() OVERRIDE { |
| + return button_->GetPreferredSize(); |
| + } |
| + |
| + // views::ViewMenuDelegate implementation. |
| + virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE { |
| + gfx::Point screen_location; |
| + views::View::ConvertPointToScreen(source, &screen_location); |
| + gfx::Rect bounds(screen_location, source->size()); |
| + menu_->RunMenuAt( |
| + source->GetWidget(), |
| + button_, |
| + bounds, |
| + views::MenuItemView::TOPLEFT, |
| + true); |
| + } |
| + |
| + // ui::SimpleMenuModel::Delegate implementation |
| + virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { |
| + return false; |
| + } |
| + |
| + virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { |
| + return true; |
| + } |
| + |
| + virtual bool GetAcceleratorForCommandId( |
| + int command_id, |
| + ui::Accelerator* accelerator) OVERRIDE { |
| + return false; |
| + } |
| + |
| + // Performs the action associated with the specified command id. |
| + virtual void ExecuteCommand(int command_id) OVERRIDE |
| + { |
| + } |
| + |
| + // ViewEventTestBase implementation |
| + virtual void DoTestOnMessageLoop() OVERRIDE { |
| + Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1)); |
| + } |
| + |
| + // Open the submenu. |
| + void Step1() { |
| + views::SubmenuView* topmenu = menu_->GetSubmenu(); |
| + ASSERT_TRUE(topmenu); |
| + ASSERT_TRUE(topmenu->IsShowing()); |
| + ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); |
| + |
| + // Click the first item to open the submenu. |
| + views::MenuItemView* item = topmenu->GetMenuItemAt(0); |
| + ASSERT_TRUE(item); |
| + Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2)); |
| + } |
| + |
| + // Rebuild the menu which should close the submenu. |
| + void Step2() { |
| + views::SubmenuView* topmenu = menu_->GetSubmenu(); |
| + ASSERT_TRUE(topmenu); |
| + ASSERT_TRUE(topmenu->IsShowing()); |
| + ASSERT_TRUE(top_menu_model_.IsSubmenuShowing()); |
| + |
| + menu_model_adapter_.BuildMenu(menu_.get()); |
| + |
| + MessageLoopForUI::current()->PostTask( |
| + FROM_HERE, |
| + CreateEventTask(this, &MenuModelAdapterTest::Step3)); |
| + } |
| + |
| + // Verify that the submenu MenuModel received the close callback |
| + // and close the menu. |
| + void Step3() { |
| + views::SubmenuView* topmenu = menu_->GetSubmenu(); |
| + ASSERT_TRUE(topmenu); |
| + ASSERT_TRUE(topmenu->IsShowing()); |
| + ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); |
| + |
| + // Click the button to exit the menu. |
| + Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4)); |
| + } |
| + |
| + // All done. |
| + void Step4() { |
| + views::SubmenuView* topmenu = menu_->GetSubmenu(); |
| + ASSERT_TRUE(topmenu); |
| + ASSERT_FALSE(topmenu->IsShowing()); |
| + ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); |
| + |
| + Done(); |
| + } |
| + |
| + private: |
| + // Generate a mouse click on the specified view and post a new task. |
| + virtual void Click(views::View* view, Task* next) { |
| + ui_controls::MoveMouseToCenterAndPress( |
| + view, |
| + ui_controls::LEFT, |
| + ui_controls::DOWN | ui_controls::UP, |
| + next); |
| + } |
| + |
| + views::ViewsDelegate* old_views_delegate_; |
| + TestViewsDelegate views_delegate_; |
| + |
| + views::MenuButton* button_; |
| + TopMenuModel top_menu_model_; |
| + views::MenuModelAdapter menu_model_adapter_; |
| + scoped_ptr<views::MenuItemView> menu_; |
| +}; |
| + |
| +VIEW_TEST(MenuModelAdapterTest, RebuildMenu) |