diff options
Diffstat (limited to 'chrome/browser/ui/views/menu_model_adapter_test.cc')
-rw-r--r-- | chrome/browser/ui/views/menu_model_adapter_test.cc | 372 |
1 files changed, 372 insertions, 0 deletions
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 0000000..ff7c0a4 --- /dev/null +++ b/chrome/browser/ui/views/menu_model_adapter_test.cc @@ -0,0 +1,372 @@ +// 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 { + public: + TestViewsDelegate() { + } + + ~TestViewsDelegate() { + } + + // 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; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestViewsDelegate); +}; + +// 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 { + public: + CommonMenuModel() { + } + + virtual ~CommonMenuModel() { + } + + 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 { + } + + private: + DISALLOW_COPY_AND_ASSIGN(CommonMenuModel); +}; + +class SubMenuModel : public CommonMenuModel { + public: + SubMenuModel() + : showing_(false) { + } + + ~SubMenuModel() { + } + + 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_; + + DISALLOW_COPY_AND_ASSIGN(SubMenuModel); +}; + +class TopMenuModel : public CommonMenuModel { + public: + TopMenuModel() { + } + + ~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_; + + DISALLOW_COPY_AND_ASSIGN(TopMenuModel); +}; + +} // 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); + } + + // 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) |