1// Copyright 2014 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. 4 5#include "base/strings/utf_string_conversions.h" 6#include "chrome/browser/ui/views/menu_test_base.h" 7#include "ui/views/controls/menu/menu_item_view.h" 8#include "ui/views/controls/menu/submenu_view.h" 9 10using base::ASCIIToUTF16; 11 12// Simple test for clicking a menu item. This template class clicks on an 13// item and checks that the returned id matches. The index of the item 14// is the template argument. 15template<int INDEX> 16class MenuItemViewTestBasic : public MenuTestBase { 17 public: 18 MenuItemViewTestBasic() { 19 } 20 21 virtual ~MenuItemViewTestBasic() { 22 } 23 24 // MenuTestBase implementation 25 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE { 26 menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1")); 27 menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2")); 28 menu->AppendSeparator(); 29 menu->AppendMenuItemWithLabel(3, ASCIIToUTF16("item 3")); 30 } 31 32 // Click on item INDEX. 33 virtual void DoTestWithMenuOpen() OVERRIDE { 34 views::SubmenuView* submenu = menu()->GetSubmenu(); 35 ASSERT_TRUE(submenu); 36 ASSERT_TRUE(submenu->IsShowing()); 37 ASSERT_EQ(3, submenu->GetMenuItemCount()); 38 39 // click an item and pass control to the next step 40 views::MenuItemView* item = submenu->GetMenuItemAt(INDEX); 41 ASSERT_TRUE(item); 42 Click(item, CreateEventTask(this, &MenuItemViewTestBasic::Step2)); 43 } 44 45 // Check the clicked item and complete the test. 46 void Step2() { 47 ASSERT_FALSE(menu()->GetSubmenu()->IsShowing()); 48 ASSERT_EQ(INDEX + 1, last_command()); 49 Done(); 50 } 51 52 private: 53 DISALLOW_COPY_AND_ASSIGN(MenuItemViewTestBasic); 54}; 55 56// Click each item of a 3-item menu (with separator). 57typedef MenuItemViewTestBasic<0> MenuItemViewTestBasic0; 58typedef MenuItemViewTestBasic<1> MenuItemViewTestBasic1; 59typedef MenuItemViewTestBasic<2> MenuItemViewTestBasic2; 60VIEW_TEST(MenuItemViewTestBasic0, SelectItem0) 61VIEW_TEST(MenuItemViewTestBasic1, SelectItem1) 62VIEW_TEST(MenuItemViewTestBasic2, SelectItem2) 63 64// Test class for inserting a menu item while the menu is open. 65template<int INSERT_INDEX, int SELECT_INDEX> 66class MenuItemViewTestInsert : public MenuTestBase { 67 public: 68 MenuItemViewTestInsert() : inserted_item_(NULL) { 69 } 70 71 virtual ~MenuItemViewTestInsert() { 72 } 73 74 // MenuTestBase implementation 75 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE { 76 menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1")); 77 menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2")); 78 } 79 80 // Insert item at INSERT_INDEX and click item at SELECT_INDEX. 81 virtual void DoTestWithMenuOpen() OVERRIDE { 82 views::SubmenuView* submenu = menu()->GetSubmenu(); 83 ASSERT_TRUE(submenu); 84 ASSERT_TRUE(submenu->IsShowing()); 85 ASSERT_EQ(2, submenu->GetMenuItemCount()); 86 87 inserted_item_ = menu()->AddMenuItemAt(INSERT_INDEX, 88 1000, 89 ASCIIToUTF16("inserted item"), 90 base::string16(), 91 base::string16(), 92 gfx::ImageSkia(), 93 views::MenuItemView::NORMAL, 94 ui::NORMAL_SEPARATOR); 95 ASSERT_TRUE(inserted_item_); 96 menu()->ChildrenChanged(); 97 98 // click an item and pass control to the next step 99 views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX); 100 ASSERT_TRUE(item); 101 Click(item, CreateEventTask(this, &MenuItemViewTestInsert::Step2)); 102 } 103 104 // Check clicked item and complete test. 105 void Step2() { 106 views::SubmenuView* submenu = menu()->GetSubmenu(); 107 ASSERT_TRUE(submenu); 108 ASSERT_FALSE(submenu->IsShowing()); 109 ASSERT_EQ(3, submenu->GetMenuItemCount()); 110 111 if (SELECT_INDEX == INSERT_INDEX) 112 ASSERT_EQ(1000, last_command()); 113 else if (SELECT_INDEX < INSERT_INDEX) 114 ASSERT_EQ(SELECT_INDEX + 1, last_command()); 115 else 116 ASSERT_EQ(SELECT_INDEX, last_command()); 117 118 Done(); 119 } 120 121 private: 122 views::MenuItemView* inserted_item_; 123 124 DISALLOW_COPY_AND_ASSIGN(MenuItemViewTestInsert); 125}; 126 127// MenuItemViewTestInsertXY inserts an item at index X and selects the 128// item at index Y (after the insertion). The tests here cover 129// inserting at the beginning, middle, and end, crossbarred with 130// selecting the first and last item. 131typedef MenuItemViewTestInsert<0,0> MenuItemViewTestInsert00; 132typedef MenuItemViewTestInsert<0,2> MenuItemViewTestInsert02; 133typedef MenuItemViewTestInsert<1,0> MenuItemViewTestInsert10; 134typedef MenuItemViewTestInsert<1,2> MenuItemViewTestInsert12; 135typedef MenuItemViewTestInsert<2,0> MenuItemViewTestInsert20; 136typedef MenuItemViewTestInsert<2,2> MenuItemViewTestInsert22; 137VIEW_TEST(MenuItemViewTestInsert00, InsertItem00) 138VIEW_TEST(MenuItemViewTestInsert02, InsertItem02) 139VIEW_TEST(MenuItemViewTestInsert10, InsertItem10) 140VIEW_TEST(MenuItemViewTestInsert12, InsertItem12) 141VIEW_TEST(MenuItemViewTestInsert20, InsertItem20) 142VIEW_TEST(MenuItemViewTestInsert22, InsertItem22) 143 144// Test class for inserting a menu item while a submenu is open. 145template<int INSERT_INDEX> 146class MenuItemViewTestInsertWithSubmenu : public MenuTestBase { 147 public: 148 MenuItemViewTestInsertWithSubmenu() : 149 submenu_(NULL), 150 inserted_item_(NULL) { 151 } 152 153 virtual ~MenuItemViewTestInsertWithSubmenu() { 154 } 155 156 // MenuTestBase implementation 157 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE { 158 submenu_ = menu->AppendSubMenu(1, ASCIIToUTF16("My Submenu")); 159 submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 1")); 160 submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 2")); 161 menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2")); 162 } 163 164 // Post submenu. 165 virtual void DoTestWithMenuOpen() OVERRIDE { 166 Click(submenu_, 167 CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step2)); 168 } 169 170 // Insert item at INSERT_INDEX. 171 void Step2() { 172 inserted_item_ = menu()->AddMenuItemAt(INSERT_INDEX, 173 1000, 174 ASCIIToUTF16("inserted item"), 175 base::string16(), 176 base::string16(), 177 gfx::ImageSkia(), 178 views::MenuItemView::NORMAL, 179 ui::NORMAL_SEPARATOR); 180 ASSERT_TRUE(inserted_item_); 181 menu()->ChildrenChanged(); 182 183 Click(inserted_item_, 184 CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step3)); 185 } 186 187 void Step3() { 188 Done(); 189 } 190 191 private: 192 views::MenuItemView* submenu_; 193 views::MenuItemView* inserted_item_; 194 195 DISALLOW_COPY_AND_ASSIGN(MenuItemViewTestInsertWithSubmenu); 196}; 197 198// MenuItemViewTestInsertWithSubmenuX posts a menu and its submenu, 199// then inserts an item in the top-level menu at X. 200typedef MenuItemViewTestInsertWithSubmenu<0> MenuItemViewTestInsertWithSubmenu0; 201typedef MenuItemViewTestInsertWithSubmenu<1> MenuItemViewTestInsertWithSubmenu1; 202VIEW_TEST(MenuItemViewTestInsertWithSubmenu0, InsertItemWithSubmenu0) 203VIEW_TEST(MenuItemViewTestInsertWithSubmenu1, InsertItemWithSubmenu1) 204 205// Test class for removing a menu item while the menu is open. 206template<int REMOVE_INDEX, int SELECT_INDEX> 207class MenuItemViewTestRemove : public MenuTestBase { 208 public: 209 MenuItemViewTestRemove() { 210 } 211 212 virtual ~MenuItemViewTestRemove() { 213 } 214 215 // MenuTestBase implementation 216 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE { 217 menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1")); 218 menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2")); 219 menu->AppendMenuItemWithLabel(3, ASCIIToUTF16("item 3")); 220 } 221 222 // Remove item at REMOVE_INDEX and click item at SELECT_INDEX. 223 virtual void DoTestWithMenuOpen() OVERRIDE { 224 views::SubmenuView* submenu = menu()->GetSubmenu(); 225 ASSERT_TRUE(submenu); 226 ASSERT_TRUE(submenu->IsShowing()); 227 ASSERT_EQ(3, submenu->GetMenuItemCount()); 228 229 // remove 230 menu()->RemoveMenuItemAt(REMOVE_INDEX); 231 menu()->ChildrenChanged(); 232 233 // click 234 views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX); 235 ASSERT_TRUE(item); 236 Click(item, CreateEventTask(this, &MenuItemViewTestRemove::Step2)); 237 } 238 239 // Check clicked item and complete test. 240 void Step2() { 241 views::SubmenuView* submenu = menu()->GetSubmenu(); 242 ASSERT_TRUE(submenu); 243 ASSERT_FALSE(submenu->IsShowing()); 244 ASSERT_EQ(2, submenu->GetMenuItemCount()); 245 246 if (SELECT_INDEX < REMOVE_INDEX) 247 ASSERT_EQ(SELECT_INDEX + 1, last_command()); 248 else 249 ASSERT_EQ(SELECT_INDEX + 2, last_command()); 250 251 Done(); 252 } 253 254 private: 255 DISALLOW_COPY_AND_ASSIGN(MenuItemViewTestRemove); 256}; 257 258typedef MenuItemViewTestRemove<0,0> MenuItemViewTestRemove00; 259typedef MenuItemViewTestRemove<0,1> MenuItemViewTestRemove01; 260typedef MenuItemViewTestRemove<1,0> MenuItemViewTestRemove10; 261typedef MenuItemViewTestRemove<1,1> MenuItemViewTestRemove11; 262typedef MenuItemViewTestRemove<2,0> MenuItemViewTestRemove20; 263typedef MenuItemViewTestRemove<2,1> MenuItemViewTestRemove21; 264VIEW_TEST(MenuItemViewTestRemove00, RemoveItem00) 265VIEW_TEST(MenuItemViewTestRemove01, RemoveItem01) 266VIEW_TEST(MenuItemViewTestRemove10, RemoveItem10) 267VIEW_TEST(MenuItemViewTestRemove11, RemoveItem11) 268VIEW_TEST(MenuItemViewTestRemove20, RemoveItem20) 269VIEW_TEST(MenuItemViewTestRemove21, RemoveItem21) 270 271// Test class for removing a menu item while a submenu is open. 272template<int REMOVE_INDEX> 273class MenuItemViewTestRemoveWithSubmenu : public MenuTestBase { 274 public: 275 MenuItemViewTestRemoveWithSubmenu() : submenu_(NULL) { 276 } 277 278 virtual ~MenuItemViewTestRemoveWithSubmenu() { 279 } 280 281 // MenuTestBase implementation 282 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE { 283 menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1")); 284 submenu_ = menu->AppendSubMenu(2, ASCIIToUTF16("My Submenu")); 285 submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 1")); 286 submenu_->AppendMenuItemWithLabel(102, ASCIIToUTF16("submenu item 2")); 287 } 288 289 // Post submenu. 290 virtual void DoTestWithMenuOpen() OVERRIDE { 291 views::SubmenuView* submenu = menu()->GetSubmenu(); 292 ASSERT_TRUE(submenu); 293 ASSERT_TRUE(submenu->IsShowing()); 294 295 Click(submenu_, 296 CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step2)); 297 } 298 299 // Remove item at REMOVE_INDEX and press escape to exit the menu loop. 300 void Step2() { 301 views::SubmenuView* submenu = menu()->GetSubmenu(); 302 ASSERT_TRUE(submenu); 303 ASSERT_TRUE(submenu->IsShowing()); 304 ASSERT_EQ(2, submenu->GetMenuItemCount()); 305 306 // remove 307 menu()->RemoveMenuItemAt(REMOVE_INDEX); 308 menu()->ChildrenChanged(); 309 310 // click 311 KeyPress(ui::VKEY_ESCAPE, 312 CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step3)); 313 } 314 315 void Step3() { 316 views::SubmenuView* submenu = menu()->GetSubmenu(); 317 ASSERT_TRUE(submenu); 318 ASSERT_FALSE(submenu->IsShowing()); 319 ASSERT_EQ(1, submenu->GetMenuItemCount()); 320 321 Done(); 322 } 323 324 private: 325 views::MenuItemView* submenu_; 326 327 DISALLOW_COPY_AND_ASSIGN(MenuItemViewTestRemoveWithSubmenu); 328}; 329 330typedef MenuItemViewTestRemoveWithSubmenu<0> MenuItemViewTestRemoveWithSubmenu0; 331typedef MenuItemViewTestRemoveWithSubmenu<1> MenuItemViewTestRemoveWithSubmenu1; 332 333#if defined(USE_OZONE) 334// ozone bringup - http://crbug.com/401304 335#define MAYBE_RemoveItemWithSubmenu0 DISABLED_RemoveItemWithSubmenu0 336#define MAYBE_RemoveItemWithSubmenu1 DISABLED_RemoveItemWithSubmenu1 337#else 338#define MAYBE_RemoveItemWithSubmenu0 RemoveItemWithSubmenu0 339#define MAYBE_RemoveItemWithSubmenu1 RemoveItemWithSubmenu1 340#endif 341 342VIEW_TEST(MenuItemViewTestRemoveWithSubmenu0, MAYBE_RemoveItemWithSubmenu0) 343VIEW_TEST(MenuItemViewTestRemoveWithSubmenu1, MAYBE_RemoveItemWithSubmenu1) 344