| Index: chrome/browser/ui/views/menu_item_view_test.cc
|
| diff --git a/chrome/browser/ui/views/menu_item_view_test.cc b/chrome/browser/ui/views/menu_item_view_test.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6b8bb20c713ce31ad684629666840ea97fb1b403
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/views/menu_item_view_test.cc
|
| @@ -0,0 +1,505 @@
|
| +// 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 "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/submenu_view.h"
|
| +#include "views/controls/menu/view_menu_delegate.h"
|
| +#include "views/widget/root_view.h"
|
| +#include "views/window/window.h"
|
| +
|
| +// This is a convenience base class for all tests to provide some
|
| +// common functionality. It sets up a MenuButton and a MenuItemView
|
| +// and clicks the MenuButton.
|
| +//
|
| +// Subclasses should implement:
|
| +// BuildMenu() populate the menu
|
| +// DoTestOnMessageLoop() initiate the test
|
| +//
|
| +// Subclasses can call:
|
| +// Click() to post a mouse click on a View
|
| +//
|
| +// Although it should be possible to post a menu multiple times,
|
| +// MenuItemView prevents repeated activation of a menu by clicks too
|
| +// close in time.
|
| +class MenuItemViewTestBase : public ViewEventTestBase,
|
| + public views::ViewMenuDelegate,
|
| + public views::MenuDelegate {
|
| + public:
|
| + MenuItemViewTestBase() :
|
| + ViewEventTestBase(),
|
| + button_(NULL),
|
| + menu_(NULL) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestBase() {
|
| + }
|
| +
|
| + // ViewEventTestBase implementation.
|
| +
|
| + virtual void SetUp() OVERRIDE {
|
| + button_ = new views::MenuButton(NULL, L"Menu Test", this, true);
|
| + menu_.reset(new views::MenuItemView(this));
|
| + 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->GetWindow()->GetNativeWindow(),
|
| + button_,
|
| + bounds,
|
| + views::MenuItemView::TOPLEFT,
|
| + true);
|
| + }
|
| +
|
| + protected:
|
| + // 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);
|
| + }
|
| +
|
| + virtual void BuildMenu(views::MenuItemView* menu) {
|
| + }
|
| +
|
| +#if defined(TOOLKIT_USES_GTK)
|
| + // GTK processes widget size changes with an idle task so RootView
|
| + // sizes are not updated reliably before an automation mouse click.
|
| + // This can result in the event being marked outside the menu
|
| + // bounds. To work around this issue for testing, this code short
|
| + // circuits the RootView size update by setting it directly.
|
| + void WorkaroundGTKRace() {
|
| + views::Widget* widget = menu_->GetSubmenu()->GetWidget();
|
| + if (widget) {
|
| + widget->GetRootView()->SetSize(
|
| + widget->GetClientAreaScreenBounds().size());
|
| + }
|
| + }
|
| +#endif
|
| +
|
| + views::MenuButton* button_;
|
| + scoped_ptr<views::MenuItemView> menu_;
|
| +};
|
| +
|
| +// Simple test for clicking a menu item. This template class clicks on an
|
| +// item and checks that the returned id matches. The index of the item
|
| +// is the template argument.
|
| +template<int INDEX>
|
| +class MenuItemViewTestBasic : public MenuItemViewTestBase {
|
| + public:
|
| + MenuItemViewTestBasic() :
|
| + last_command_(0) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestBasic() {
|
| + }
|
| +
|
| + // views::MenuDelegate implementation
|
| + virtual void ExecuteCommand(int id) OVERRIDE {
|
| + last_command_ = id;
|
| + }
|
| +
|
| + // MenuItemViewTestBase implementation
|
| + virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
|
| + menu->AppendMenuItemWithLabel(1, L"item 1");
|
| + menu->AppendMenuItemWithLabel(2, L"item 2");
|
| + menu->AppendSeparator();
|
| + menu->AppendMenuItemWithLabel(3, L"item 3");
|
| + }
|
| +
|
| + // ViewEventTestBase implementation
|
| + virtual void DoTestOnMessageLoop() OVERRIDE {
|
| + Click(button_, CreateEventTask(this, &MenuItemViewTestBasic::Step1));
|
| + }
|
| +
|
| + // Click on item INDEX.
|
| + void Step1() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_TRUE(submenu->IsShowing());
|
| + ASSERT_EQ(3, submenu->GetMenuItemCount());
|
| +
|
| + // click an item and pass control to the next step
|
| + views::MenuItemView* item = submenu->GetMenuItemAt(INDEX);
|
| + ASSERT_TRUE(item);
|
| + Click(item, CreateEventTask(this, &MenuItemViewTestBasic::Step2));
|
| + }
|
| +
|
| + // Check the clicked item and complete the test.
|
| + void Step2() {
|
| + ASSERT_FALSE(menu_->GetSubmenu()->IsShowing());
|
| + ASSERT_EQ(INDEX + 1,last_command_);
|
| + Done();
|
| + }
|
| +
|
| + private:
|
| + int last_command_;
|
| +};
|
| +
|
| +// Click each item of a 3-item menu (with separator).
|
| +typedef MenuItemViewTestBasic<0> MenuItemViewTestBasic0;
|
| +typedef MenuItemViewTestBasic<1> MenuItemViewTestBasic1;
|
| +typedef MenuItemViewTestBasic<2> MenuItemViewTestBasic2;
|
| +VIEW_TEST(MenuItemViewTestBasic0, SelectItem0)
|
| +VIEW_TEST(MenuItemViewTestBasic1, SelectItem1)
|
| +VIEW_TEST(MenuItemViewTestBasic2, SelectItem2)
|
| +
|
| +// Test class for inserting a menu item while the menu is open.
|
| +template<int INSERT_INDEX, int SELECT_INDEX>
|
| +class MenuItemViewTestInsert : public MenuItemViewTestBase {
|
| + public:
|
| + MenuItemViewTestInsert() :
|
| + last_command_(0),
|
| + inserted_item_(NULL) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestInsert() {
|
| + }
|
| +
|
| + // views::MenuDelegate implementation
|
| + virtual void ExecuteCommand(int id) OVERRIDE {
|
| + last_command_ = id;
|
| + }
|
| +
|
| + // MenuItemViewTestBase implementation
|
| + virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
|
| + menu->AppendMenuItemWithLabel(1, L"item 1");
|
| + menu->AppendMenuItemWithLabel(2, L"item 2");
|
| + }
|
| +
|
| + // ViewEventTestBase implementation
|
| + virtual void DoTestOnMessageLoop() OVERRIDE {
|
| + Click(button_, CreateEventTask(this, &MenuItemViewTestInsert::Step1));
|
| + }
|
| +
|
| + // Insert item at INSERT_INDEX and click item at SELECT_INDEX.
|
| + void Step1() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_TRUE(submenu->IsShowing());
|
| + ASSERT_EQ(2, submenu->GetMenuItemCount());
|
| +
|
| + inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX, 1000,
|
| + L"inserted item", SkBitmap(),
|
| + views::MenuItemView::NORMAL);
|
| + ASSERT_TRUE(inserted_item_);
|
| + menu_->ChildrenChanged();
|
| +#if defined(TOOLKIT_USES_GTK)
|
| + WorkaroundGTKRace();
|
| +#endif
|
| +
|
| + // click an item and pass control to the next step
|
| + views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
|
| + ASSERT_TRUE(item);
|
| + Click(item, CreateEventTask(this, &MenuItemViewTestInsert::Step2));
|
| + }
|
| +
|
| + // Check clicked item and complete test.
|
| + void Step2() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_FALSE(submenu->IsShowing());
|
| + ASSERT_EQ(3, submenu->GetMenuItemCount());
|
| +
|
| + if (SELECT_INDEX == INSERT_INDEX)
|
| + ASSERT_EQ(1000, last_command_);
|
| + else if (SELECT_INDEX < INSERT_INDEX)
|
| + ASSERT_EQ(SELECT_INDEX + 1, last_command_);
|
| + else
|
| + ASSERT_EQ(SELECT_INDEX, last_command_);
|
| +
|
| + Done();
|
| + }
|
| +
|
| + private:
|
| + int last_command_;
|
| + views::MenuItemView* inserted_item_;
|
| +};
|
| +
|
| +// MenuItemViewTestInsertXY inserts an item at index X and selects the
|
| +// item at index Y (after the insertion). The tests here cover
|
| +// inserting at the beginning, middle, and end, crossbarred with
|
| +// selecting the first and last item.
|
| +typedef MenuItemViewTestInsert<0,0> MenuItemViewTestInsert00;
|
| +typedef MenuItemViewTestInsert<0,2> MenuItemViewTestInsert02;
|
| +typedef MenuItemViewTestInsert<1,0> MenuItemViewTestInsert10;
|
| +typedef MenuItemViewTestInsert<1,2> MenuItemViewTestInsert12;
|
| +typedef MenuItemViewTestInsert<2,0> MenuItemViewTestInsert20;
|
| +typedef MenuItemViewTestInsert<2,2> MenuItemViewTestInsert22;
|
| +VIEW_TEST(MenuItemViewTestInsert00, InsertItem00)
|
| +VIEW_TEST(MenuItemViewTestInsert02, InsertItem02)
|
| +VIEW_TEST(MenuItemViewTestInsert10, InsertItem10)
|
| +VIEW_TEST(MenuItemViewTestInsert12, InsertItem12)
|
| +VIEW_TEST(MenuItemViewTestInsert20, InsertItem20)
|
| +VIEW_TEST(MenuItemViewTestInsert22, InsertItem22)
|
| +
|
| +// Test class for inserting a menu item while a submenu is open.
|
| +template<int INSERT_INDEX>
|
| +class MenuItemViewTestInsertWithSubmenu : public MenuItemViewTestBase {
|
| + public:
|
| + MenuItemViewTestInsertWithSubmenu() :
|
| + last_command_(0),
|
| + submenu_(NULL),
|
| + inserted_item_(NULL) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestInsertWithSubmenu() {
|
| + }
|
| +
|
| + // views::MenuDelegate implementation
|
| + virtual void ExecuteCommand(int id) OVERRIDE {
|
| + last_command_ = id;
|
| + }
|
| +
|
| + // MenuItemViewTestBase implementation
|
| + virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
|
| + submenu_ = menu->AppendSubMenu(1, L"My Submenu");
|
| + submenu_->AppendMenuItemWithLabel(101, L"submenu item 1");
|
| + submenu_->AppendMenuItemWithLabel(101, L"submenu item 2");
|
| + menu->AppendMenuItemWithLabel(2, L"item 2");
|
| + }
|
| +
|
| + // ViewEventTestBase implementation
|
| + virtual void DoTestOnMessageLoop() OVERRIDE {
|
| + Click(button_,
|
| + CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step1));
|
| + }
|
| +
|
| + // Post submenu.
|
| + void Step1() {
|
| + Click(submenu_,
|
| + CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step2));
|
| + }
|
| +
|
| + // Insert item at INSERT_INDEX.
|
| + void Step2() {
|
| + inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX, 1000,
|
| + L"inserted item", SkBitmap(),
|
| + views::MenuItemView::NORMAL);
|
| + ASSERT_TRUE(inserted_item_);
|
| + menu_->ChildrenChanged();
|
| +#if defined(TOOLKIT_USES_GTK)
|
| + WorkaroundGTKRace();
|
| +#endif
|
| +
|
| + Click(inserted_item_,
|
| + CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step3));
|
| + }
|
| +
|
| + void Step3() {
|
| + Done();
|
| + }
|
| +
|
| + private:
|
| + int last_command_;
|
| + views::MenuItemView* submenu_;
|
| + views::MenuItemView* inserted_item_;
|
| +};
|
| +
|
| +// MenuItemViewTestInsertWithSubmenuX posts a menu and its submenu,
|
| +// then inserts an item in the top-level menu at X.
|
| +typedef MenuItemViewTestInsertWithSubmenu<0> MenuItemViewTestInsertWithSubmenu0;
|
| +typedef MenuItemViewTestInsertWithSubmenu<1> MenuItemViewTestInsertWithSubmenu1;
|
| +VIEW_TEST(MenuItemViewTestInsertWithSubmenu0, InsertItemWithSubmenu0)
|
| +VIEW_TEST(MenuItemViewTestInsertWithSubmenu1, InsertItemWithSubmenu1)
|
| +
|
| +// Test class for removing a menu item while the menu is open.
|
| +template<int REMOVE_INDEX, int SELECT_INDEX>
|
| +class MenuItemViewTestRemove : public MenuItemViewTestBase {
|
| + public:
|
| + MenuItemViewTestRemove() :
|
| + last_command_(0) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestRemove() {
|
| + }
|
| +
|
| + // views::MenuDelegate implementation
|
| + virtual void ExecuteCommand(int id) OVERRIDE {
|
| + last_command_ = id;
|
| + }
|
| +
|
| + // MenuItemViewTestBase implementation
|
| + virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
|
| + menu->AppendMenuItemWithLabel(1, L"item 1");
|
| + menu->AppendMenuItemWithLabel(2, L"item 2");
|
| + menu->AppendMenuItemWithLabel(3, L"item 3");
|
| + }
|
| +
|
| + // ViewEventTestBase implementation
|
| + virtual void DoTestOnMessageLoop() OVERRIDE {
|
| + Click(button_, CreateEventTask(this, &MenuItemViewTestRemove::Step1));
|
| + }
|
| +
|
| + // Remove item at REMOVE_INDEX and click item at SELECT_INDEX.
|
| + void Step1() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_TRUE(submenu->IsShowing());
|
| + ASSERT_EQ(3, submenu->GetMenuItemCount());
|
| +
|
| + // remove
|
| + menu_->RemoveMenuItemAt(REMOVE_INDEX);
|
| + menu_->ChildrenChanged();
|
| +#if defined(TOOLKIT_USES_GTK)
|
| + WorkaroundGTKRace();
|
| +#endif
|
| +
|
| + // click
|
| + views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
|
| + ASSERT_TRUE(item);
|
| + Click(item, CreateEventTask(this, &MenuItemViewTestRemove::Step2));
|
| + }
|
| +
|
| + // Check clicked item and complete test.
|
| + void Step2() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_FALSE(submenu->IsShowing());
|
| + ASSERT_EQ(2, submenu->GetMenuItemCount());
|
| +
|
| + if (SELECT_INDEX < REMOVE_INDEX)
|
| + ASSERT_EQ(SELECT_INDEX + 1, last_command_);
|
| + else
|
| + ASSERT_EQ(SELECT_INDEX + 2, last_command_);
|
| +
|
| + Done();
|
| + }
|
| +
|
| + private:
|
| + int last_command_;
|
| +};
|
| +
|
| +typedef MenuItemViewTestRemove<0,0> MenuItemViewTestRemove00;
|
| +typedef MenuItemViewTestRemove<0,1> MenuItemViewTestRemove01;
|
| +typedef MenuItemViewTestRemove<1,0> MenuItemViewTestRemove10;
|
| +typedef MenuItemViewTestRemove<1,1> MenuItemViewTestRemove11;
|
| +typedef MenuItemViewTestRemove<2,0> MenuItemViewTestRemove20;
|
| +typedef MenuItemViewTestRemove<2,1> MenuItemViewTestRemove21;
|
| +VIEW_TEST(MenuItemViewTestRemove00, RemoveItem00)
|
| +VIEW_TEST(MenuItemViewTestRemove01, RemoveItem01)
|
| +VIEW_TEST(MenuItemViewTestRemove10, RemoveItem10)
|
| +VIEW_TEST(MenuItemViewTestRemove11, RemoveItem11)
|
| +VIEW_TEST(MenuItemViewTestRemove20, RemoveItem20)
|
| +VIEW_TEST(MenuItemViewTestRemove21, RemoveItem21)
|
| +
|
| +// Test class for removing a menu item while a submenu is open.
|
| +template<int REMOVE_INDEX>
|
| +class MenuItemViewTestRemoveWithSubmenu : public MenuItemViewTestBase {
|
| + public:
|
| + MenuItemViewTestRemoveWithSubmenu() :
|
| + last_command_(0),
|
| + submenu_(NULL) {
|
| + }
|
| +
|
| + virtual ~MenuItemViewTestRemoveWithSubmenu() {
|
| + }
|
| +
|
| + // views::MenuDelegate implementation
|
| + virtual void ExecuteCommand(int id) OVERRIDE {
|
| + last_command_ = id;
|
| + }
|
| +
|
| + // MenuItemViewTestBase implementation
|
| + virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
|
| + menu->AppendMenuItemWithLabel(1, L"item 1");
|
| + submenu_ = menu->AppendSubMenu(2, L"My Submenu");
|
| + submenu_->AppendMenuItemWithLabel(101, L"submenu item 1");
|
| + submenu_->AppendMenuItemWithLabel(102, L"submenu item 2");
|
| + }
|
| +
|
| + // ViewEventTestBase implementation
|
| + virtual void DoTestOnMessageLoop() OVERRIDE {
|
| + Click(button_,
|
| + CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step1));
|
| + }
|
| +
|
| + // Post submenu.
|
| + void Step1() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_TRUE(submenu->IsShowing());
|
| +
|
| + Click(submenu_,
|
| + CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step2));
|
| + }
|
| +
|
| + // Remove item at REMOVE_INDEX and select it to exit the menu loop.
|
| + void Step2() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_TRUE(submenu->IsShowing());
|
| + ASSERT_EQ(2, submenu->GetMenuItemCount());
|
| +
|
| + // remove
|
| + menu_->RemoveMenuItemAt(REMOVE_INDEX);
|
| + menu_->ChildrenChanged();
|
| +#if defined(TOOLKIT_USES_GTK)
|
| + WorkaroundGTKRace();
|
| +#endif
|
| +
|
| + // click
|
| + Click(button_,
|
| + CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step3));
|
| + }
|
| +
|
| + void Step3() {
|
| + ASSERT_TRUE(menu_.get());
|
| +
|
| + views::SubmenuView* submenu = menu_->GetSubmenu();
|
| + ASSERT_TRUE(submenu);
|
| + ASSERT_FALSE(submenu->IsShowing());
|
| + ASSERT_EQ(1, submenu->GetMenuItemCount());
|
| +
|
| + Done();
|
| + }
|
| +
|
| + private:
|
| + int last_command_;
|
| + views::MenuItemView* submenu_;
|
| +};
|
| +
|
| +typedef MenuItemViewTestRemoveWithSubmenu<0> MenuItemViewTestRemoveWithSubmenu0;
|
| +typedef MenuItemViewTestRemoveWithSubmenu<1> MenuItemViewTestRemoveWithSubmenu1;
|
| +VIEW_TEST(MenuItemViewTestRemoveWithSubmenu0, RemoveItemWithSubmenu0)
|
| +VIEW_TEST(MenuItemViewTestRemoveWithSubmenu1, RemoveItemWithSubmenu1)
|
|
|