| 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..ff7c0a477bdb7fe74c3f62b0384d39c4d63a127b
|
| --- /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)
|
|
|