Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: chrome/test/menu_item_view_test.cc

Issue 6931039: Add MenuItemView API to add and remove items at a particular index. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to trunk. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "chrome/browser/automation/ui_controls.h"
6 #include "chrome/test/interactive_ui/view_event_test_base.h"
7 #include "views/controls/button/menu_button.h"
8 #include "views/controls/menu/menu_controller.h"
9 #include "views/controls/menu/menu_item_view.h"
10 #include "views/controls/menu/submenu_view.h"
11 #include "views/controls/menu/view_menu_delegate.h"
12 #include "views/widget/root_view.h"
13 #include "views/window/window.h"
14
15 // This is a convenience base class for all tests to provide some
16 // common functionality. It sets up a MenuButton and a MenuItemView
17 // and clicks the MenuButton.
18 //
19 // Subclasses should implement:
20 // BuildMenu() populate the menu
21 // DoTestOnMessageLoop() initiate the test
22 //
23 // Subclasses can call:
24 // Click() to post a mouse click on a View
25 //
26 // Although it should be possible to post a menu multiple times,
27 // MenuItemView prevents repeated activation of a menu by clicks too
28 // close in time.
29 class MenuItemViewTestBase : public ViewEventTestBase,
30 public views::ViewMenuDelegate,
31 public views::MenuDelegate {
32 public:
33 MenuItemViewTestBase() : ViewEventTestBase(),
sky 2011/05/11 14:26:10 wrap to next line and indent 4.
rhashimoto 2011/05/11 19:41:07 Done.
34 button_(NULL),
35 menu_(NULL) {
36 }
37
38 virtual ~MenuItemViewTestBase() {
39 }
40
41 // ViewEventTestBase implementation.
42
43 virtual void SetUp() OVERRIDE {
44 button_ = new views::MenuButton(NULL, L"Menu Test", this, true);
45 menu_.reset(new views::MenuItemView(this));
46 BuildMenu(menu_.get());
47
48 ViewEventTestBase::SetUp();
49 }
50
51 virtual void TearDown() OVERRIDE {
52 menu_.reset(NULL);
53 ViewEventTestBase::TearDown();
54 }
55
56 virtual views::View* CreateContentsView() OVERRIDE {
57 return button_;
58 }
59
60 virtual gfx::Size GetPreferredSize() OVERRIDE {
61 return button_->GetPreferredSize();
62 }
63
64 // views::ViewMenuDelegate implementation.
65 virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE {
66 gfx::Point screen_location;
67 views::View::ConvertPointToScreen(source, &screen_location);
68 gfx::Rect bounds(screen_location, source->size());
69 menu_->RunMenuAt(
70 source->GetWindow()->GetNativeWindow(),
71 button_,
72 bounds,
73 views::MenuItemView::TOPLEFT,
74 true);
75 }
76
77 protected:
78 // Generate a mouse click on the specified view and post a new task.
79 virtual void Click(views::View* view, Task* next) {
80 ui_controls::MoveMouseToCenterAndPress(
81 view,
82 ui_controls::LEFT,
83 ui_controls::DOWN | ui_controls::UP,
84 next);
85 }
86
87 virtual void BuildMenu(views::MenuItemView* menu) {
88 }
89
90 #if defined(TOOLKIT_USES_GTK)
91 // GTK processes widget size changes with an idle task so RootView
92 // sizes are not updated reliably before an automation mouse click.
93 // This can result in the event being marked outside the menu
94 // bounds. To work around this issue for testing, this code short
95 // circuits the RootView size update by setting it directly.
96 void WorkaroundGTKRace() {
97 views::Widget* widget = menu_->GetSubmenu()->GetWidget();
98 if (widget) {
99 widget->GetRootView()->SetSize(
100 widget->GetClientAreaScreenBounds().size());
101 }
102 }
103 #endif
104
105 views::MenuButton* button_;
106 scoped_ptr<views::MenuItemView> menu_;
107 };
108
109 // Simple test for clicking a menu item. This template class clicks on an
110 // item and checks that the returned id matches. The index of the item
111 // is the template argument.
112 template<int INDEX>
113 class MenuItemViewTestBasic : public MenuItemViewTestBase {
114 public:
115 MenuItemViewTestBasic() : last_command_(0) {
116 }
117
118 virtual ~MenuItemViewTestBasic() {
119 }
120
121 // views::MenuDelegate implementation
122 virtual void ExecuteCommand(int id) OVERRIDE {
123 last_command_ = id;
124 }
125
126 // MenuItemViewTestBase implementation
127 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
128 menu->AppendMenuItemWithLabel(1, L"item 1");
129 menu->AppendMenuItemWithLabel(2, L"item 2");
130 menu->AppendSeparator();
131 menu->AppendMenuItemWithLabel(3, L"item 3");
132 }
133
134 // ViewEventTestBase implementation
135 virtual void DoTestOnMessageLoop() OVERRIDE {
136 Click(button_, CreateEventTask(this, &MenuItemViewTestBasic::Step1));
137 }
138
139 // Click on item INDEX.
140 void Step1() {
141 ASSERT_TRUE(menu_.get());
142
143 views::SubmenuView* submenu = menu_->GetSubmenu();
144 ASSERT_TRUE(submenu);
145 ASSERT_TRUE(submenu->IsShowing());
146 ASSERT_EQ(3, submenu->GetMenuItemCount());
147
148 // click an item and pass control to the next step
149 views::MenuItemView* item = submenu->GetMenuItemAt(INDEX);
150 ASSERT_TRUE(item);
151 Click(item, CreateEventTask(this, &MenuItemViewTestBasic::Step2));
152 }
153
154 // Check the clicked item and complete the test.
155 void Step2() {
156 ASSERT_FALSE(menu_->GetSubmenu()->IsShowing());
157 ASSERT_EQ(INDEX + 1,last_command_);
158 Done();
159 }
160
161 private:
162 int last_command_;
163 };
164
165 // Click each item of a 3-item menu (with separator).
166 typedef MenuItemViewTestBasic<0> MenuItemViewTestBasic0;
167 typedef MenuItemViewTestBasic<1> MenuItemViewTestBasic1;
168 typedef MenuItemViewTestBasic<2> MenuItemViewTestBasic2;
169 VIEW_TEST(MenuItemViewTestBasic0, SelectItem0)
170 VIEW_TEST(MenuItemViewTestBasic1, SelectItem1)
171 VIEW_TEST(MenuItemViewTestBasic2, SelectItem2)
172
173 // Test class for inserting a menu item while the menu is open.
174 template<int INSERT_INDEX, int SELECT_INDEX>
175 class MenuItemViewTestInsert : public MenuItemViewTestBase {
176 public:
177 MenuItemViewTestInsert() : last_command_(0),
sky 2011/05/11 14:26:10 wrap and indent 4.
rhashimoto 2011/05/11 19:41:07 Done.
178 inserted_item_(NULL) {
179 }
180
181 virtual ~MenuItemViewTestInsert() {
182 }
183
184 // views::MenuDelegate implementation
185 virtual void ExecuteCommand(int id) OVERRIDE {
186 last_command_ = id;
187 }
188
189 // MenuItemViewTestBase implementation
190 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
191 menu->AppendMenuItemWithLabel(1, L"item 1");
192 menu->AppendMenuItemWithLabel(2, L"item 2");
193 }
194
195 // ViewEventTestBase implementation
196 virtual void DoTestOnMessageLoop() OVERRIDE {
197 Click(button_, CreateEventTask(this, &MenuItemViewTestInsert::Step1));
198 }
199
200 // Insert item at INSERT_INDEX and click item at SELECT_INDEX.
201 void Step1() {
202 ASSERT_TRUE(menu_.get());
203
204 views::SubmenuView* submenu = menu_->GetSubmenu();
205 ASSERT_TRUE(submenu);
206 ASSERT_TRUE(submenu->IsShowing());
207 ASSERT_EQ(2, submenu->GetMenuItemCount());
208
209 inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX, 1000,
210 L"inserted item", SkBitmap(),
211 views::MenuItemView::NORMAL);
212 ASSERT_TRUE(inserted_item_);
213 menu_->ChildrenChanged();
214 #if defined(TOOLKIT_USES_GTK)
215 WorkaroundGTKRace();
216 #endif
217
218 // click an item and pass control to the next step
219 views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
220 ASSERT_TRUE(item);
221 Click(item, CreateEventTask(this, &MenuItemViewTestInsert::Step2));
222 }
223
224 // Check clicked item and complete test.
225 void Step2() {
226 ASSERT_TRUE(menu_.get());
227
228 views::SubmenuView* submenu = menu_->GetSubmenu();
229 ASSERT_TRUE(submenu);
230 ASSERT_FALSE(submenu->IsShowing());
231 ASSERT_EQ(3, submenu->GetMenuItemCount());
232
233 if (SELECT_INDEX == INSERT_INDEX)
234 ASSERT_EQ(1000, last_command_);
235 else if (SELECT_INDEX < INSERT_INDEX)
236 ASSERT_EQ(SELECT_INDEX + 1, last_command_);
237 else
238 ASSERT_EQ(SELECT_INDEX, last_command_);
239
240 Done();
241 }
242
243 private:
244 int last_command_;
245 views::MenuItemView* inserted_item_;
246 };
247
248 // MenuItemViewTestInsertXY inserts an item at index X and selects the
249 // item at index Y (after the insertion). The tests here cover
250 // inserting at the beginning, middle, and end, crossbarred with
251 // selecting the first and last item.
252 typedef MenuItemViewTestInsert<0,0> MenuItemViewTestInsert00;
253 typedef MenuItemViewTestInsert<0,2> MenuItemViewTestInsert02;
254 typedef MenuItemViewTestInsert<1,0> MenuItemViewTestInsert10;
255 typedef MenuItemViewTestInsert<1,2> MenuItemViewTestInsert12;
256 typedef MenuItemViewTestInsert<2,0> MenuItemViewTestInsert20;
257 typedef MenuItemViewTestInsert<2,2> MenuItemViewTestInsert22;
258 VIEW_TEST(MenuItemViewTestInsert00, InsertItem00)
259 VIEW_TEST(MenuItemViewTestInsert02, InsertItem02)
260 VIEW_TEST(MenuItemViewTestInsert10, InsertItem10)
261 VIEW_TEST(MenuItemViewTestInsert12, InsertItem12)
262 VIEW_TEST(MenuItemViewTestInsert20, InsertItem20)
263 VIEW_TEST(MenuItemViewTestInsert22, InsertItem22)
264
265 // Test class for inserting a menu item while a submenu is open.
266 template<int INSERT_INDEX>
267 class MenuItemViewTestInsertWithSubmenu : public MenuItemViewTestBase {
268 public:
269 MenuItemViewTestInsertWithSubmenu() : last_command_(0),
270 submenu_(NULL),
271 inserted_item_(NULL) {
272 }
273
274 virtual ~MenuItemViewTestInsertWithSubmenu() {
275 }
276
277 // views::MenuDelegate implementation
278 virtual void ExecuteCommand(int id) OVERRIDE {
279 last_command_ = id;
280 }
281
282 // MenuItemViewTestBase implementation
283 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
284 submenu_ = menu->AppendSubMenu(1, L"My Submenu");
285 submenu_->AppendMenuItemWithLabel(101, L"submenu item 1");
286 submenu_->AppendMenuItemWithLabel(101, L"submenu item 2");
287 menu->AppendMenuItemWithLabel(2, L"item 2");
288 }
289
290 // ViewEventTestBase implementation
291 virtual void DoTestOnMessageLoop() OVERRIDE {
292 Click(button_,
293 CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step1));
294 }
295
296 // Post submenu.
297 void Step1() {
298 Click(submenu_,
299 CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step2));
300 }
301
302 // Insert item at INSERT_INDEX.
303 void Step2() {
304 inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX, 1000,
305 L"inserted item", SkBitmap(),
306 views::MenuItemView::NORMAL);
307 ASSERT_TRUE(inserted_item_);
308 menu_->ChildrenChanged();
309 #if defined(TOOLKIT_USES_GTK)
310 WorkaroundGTKRace();
311 #endif
312
313 Click(inserted_item_,
314 CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step3));
315 }
316
317 void Step3() {
318 Done();
319 }
320
321 private:
sky 2011/05/11 14:26:10 indentation is off.
rhashimoto 2011/05/11 19:41:07 Done.
322 int last_command_;
323 views::MenuItemView* submenu_;
324 views::MenuItemView* inserted_item_;
325 };
326
327 // MenuItemViewTestInsertWithSubmenuX posts a menu and its submenu,
328 // then inserts an item in the top-level menu at X.
329 typedef MenuItemViewTestInsertWithSubmenu<0> MenuItemViewTestInsertWithSubmenu0;
330 typedef MenuItemViewTestInsertWithSubmenu<1> MenuItemViewTestInsertWithSubmenu1;
331 VIEW_TEST(MenuItemViewTestInsertWithSubmenu0, InsertItemWithSubmenu0)
332 VIEW_TEST(MenuItemViewTestInsertWithSubmenu1, InsertItemWithSubmenu1)
333
334 // Test class for removing a menu item while the menu is open.
335 template<int REMOVE_INDEX, int SELECT_INDEX>
336 class MenuItemViewTestRemove : public MenuItemViewTestBase {
337 public:
338 MenuItemViewTestRemove() : last_command_(0) {
339 }
340
341 virtual ~MenuItemViewTestRemove() {
342 }
343
344 // views::MenuDelegate implementation
345 virtual void ExecuteCommand(int id) OVERRIDE {
346 last_command_ = id;
347 }
348
349 // MenuItemViewTestBase implementation
350 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
351 menu->AppendMenuItemWithLabel(1, L"item 1");
352 menu->AppendMenuItemWithLabel(2, L"item 2");
353 menu->AppendMenuItemWithLabel(3, L"item 3");
354 }
355
356 // ViewEventTestBase implementation
357 virtual void DoTestOnMessageLoop() OVERRIDE {
358 Click(button_, CreateEventTask(this, &MenuItemViewTestRemove::Step1));
359 }
360
361 // Remove item at REMOVE_INDEX and click item at SELECT_INDEX.
362 void Step1() {
363 ASSERT_TRUE(menu_.get());
364
365 views::SubmenuView* submenu = menu_->GetSubmenu();
366 ASSERT_TRUE(submenu);
367 ASSERT_TRUE(submenu->IsShowing());
368 ASSERT_EQ(3, submenu->GetMenuItemCount());
369
370 // remove
371 menu_->RemoveMenuItemAt(REMOVE_INDEX);
372 menu_->ChildrenChanged();
373 #if defined(TOOLKIT_USES_GTK)
374 WorkaroundGTKRace();
375 #endif
376
377 // click
378 views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
379 ASSERT_TRUE(item);
380 Click(item, CreateEventTask(this, &MenuItemViewTestRemove::Step2));
381 }
382
383 // Check clicked item and complete test.
384 void Step2() {
385 ASSERT_TRUE(menu_.get());
386
387 views::SubmenuView* submenu = menu_->GetSubmenu();
388 ASSERT_TRUE(submenu);
389 ASSERT_FALSE(submenu->IsShowing());
390 ASSERT_EQ(2, submenu->GetMenuItemCount());
391
392 if (SELECT_INDEX < REMOVE_INDEX)
393 ASSERT_EQ(SELECT_INDEX + 1, last_command_);
394 else
395 ASSERT_EQ(SELECT_INDEX + 2, last_command_);
396
397 Done();
398 }
399
400 private:
401 int last_command_;
402 };
403
404 typedef MenuItemViewTestRemove<0,0> MenuItemViewTestRemove00;
405 typedef MenuItemViewTestRemove<0,1> MenuItemViewTestRemove01;
406 typedef MenuItemViewTestRemove<1,0> MenuItemViewTestRemove10;
407 typedef MenuItemViewTestRemove<1,1> MenuItemViewTestRemove11;
408 typedef MenuItemViewTestRemove<2,0> MenuItemViewTestRemove20;
409 typedef MenuItemViewTestRemove<2,1> MenuItemViewTestRemove21;
410 VIEW_TEST(MenuItemViewTestRemove00, RemoveItem00)
411 VIEW_TEST(MenuItemViewTestRemove01, RemoveItem01)
412 VIEW_TEST(MenuItemViewTestRemove10, RemoveItem10)
413 VIEW_TEST(MenuItemViewTestRemove11, RemoveItem11)
414 VIEW_TEST(MenuItemViewTestRemove20, RemoveItem20)
415 VIEW_TEST(MenuItemViewTestRemove21, RemoveItem21)
416
417 // Test class for removing a menu item while a submenu is open.
418 template<int REMOVE_INDEX>
419 class MenuItemViewTestRemoveWithSubmenu : public MenuItemViewTestBase {
420 public:
421 MenuItemViewTestRemoveWithSubmenu() : last_command_(0),
422 submenu_(NULL) {
423 }
424
425 virtual ~MenuItemViewTestRemoveWithSubmenu() {
426 }
427
428 // views::MenuDelegate implementation
429 virtual void ExecuteCommand(int id) OVERRIDE {
430 last_command_ = id;
431 }
432
433 // MenuItemViewTestBase implementation
434 virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
435 menu->AppendMenuItemWithLabel(1, L"item 1");
436 submenu_ = menu->AppendSubMenu(2, L"My Submenu");
437 submenu_->AppendMenuItemWithLabel(101, L"submenu item 1");
438 submenu_->AppendMenuItemWithLabel(102, L"submenu item 2");
439 }
440
441 // ViewEventTestBase implementation
442 virtual void DoTestOnMessageLoop() OVERRIDE {
443 Click(button_,
444 CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step1));
445 }
446
447 // Post submenu.
448 void Step1() {
449 ASSERT_TRUE(menu_.get());
450
451 views::SubmenuView* submenu = menu_->GetSubmenu();
452 ASSERT_TRUE(submenu);
453 ASSERT_TRUE(submenu->IsShowing());
454
455 Click(submenu_,
456 CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step2));
457 }
458
459 // Remove item at REMOVE_INDEX and select it to exit the menu loop.
460 void Step2() {
461 ASSERT_TRUE(menu_.get());
462
463 views::SubmenuView* submenu = menu_->GetSubmenu();
464 ASSERT_TRUE(submenu);
465 ASSERT_TRUE(submenu->IsShowing());
466 ASSERT_EQ(2, submenu->GetMenuItemCount());
467
468 // remove
469 menu_->RemoveMenuItemAt(REMOVE_INDEX);
470 menu_->ChildrenChanged();
471 #if defined(TOOLKIT_USES_GTK)
472 WorkaroundGTKRace();
473 #endif
474
475 // click
476 Click(button_,
477 CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step3));
478 }
479
480 void Step3() {
481 ASSERT_TRUE(menu_.get());
482
483 views::SubmenuView* submenu = menu_->GetSubmenu();
484 ASSERT_TRUE(submenu);
485 ASSERT_FALSE(submenu->IsShowing());
486 ASSERT_EQ(1, submenu->GetMenuItemCount());
487
488 Done();
489 }
490
491 private:
sky 2011/05/11 14:26:10 indentation is off.
rhashimoto 2011/05/11 19:41:07 Done.
492 int last_command_;
493 views::MenuItemView* submenu_;
494 };
495
496 typedef MenuItemViewTestRemoveWithSubmenu<0> MenuItemViewTestRemoveWithSubmenu0;
497 typedef MenuItemViewTestRemoveWithSubmenu<1> MenuItemViewTestRemoveWithSubmenu1;
498 VIEW_TEST(MenuItemViewTestRemoveWithSubmenu0, RemoveItemWithSubmenu0)
499 VIEW_TEST(MenuItemViewTestRemoveWithSubmenu1, RemoveItemWithSubmenu1)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698