Index: ui/views/controls/menu/menu_controller_unittest.cc |
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc |
index a25610c50804af4f183b520df4089d0c98c1de71..a2ad7dab99fe2da97a767c555777639d2386af5d 100644 |
--- a/ui/views/controls/menu/menu_controller_unittest.cc |
+++ b/ui/views/controls/menu/menu_controller_unittest.cc |
@@ -407,6 +407,10 @@ class MenuControllerTest : public ViewsTestBase { |
menu_controller_->SetSelectionOnPointerDown(source, event); |
} |
+ void UpdateSelection(View* view) { |
+ menu_controller_->SetSelection(menu_controller_->pending_state_.item, 0); |
+ } |
+ |
void RunMenu() { |
#if defined(USE_AURA) |
scoped_ptr<MenuKeyEventHandler> key_event_handler(new MenuKeyEventHandler); |
@@ -441,6 +445,18 @@ class MenuControllerTest : public ViewsTestBase { |
return menu_controller_->exit_type_; |
} |
+ void AddButtonMenuItems() { |
+ MenuItemView* item_view = |
+ menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five")); |
+ for (int i = 0; i < 3; ++i) { |
+ LabelButton* button = |
+ new LabelButton(nullptr, base::ASCIIToUTF16("Label")); |
+ button->SetFocusable(true); |
+ item_view->AddChildView(button); |
+ } |
+ menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); |
+ } |
+ |
private: |
void DestroyMenuController() { |
if (!menu_controller_) |
@@ -702,6 +718,118 @@ TEST_F(MenuControllerTest, SelectByChar) { |
ResetSelection(); |
} |
+TEST_F(MenuControllerTest, SelectChildButtonView) { |
+ AddButtonMenuItems(); |
+ |
+ // Handle searching for 'f'; should find "Four". |
+ SelectByChar('f'); |
+ EXPECT_EQ(4, pending_state_item()->GetCommand()); |
+ |
+ View* buttons_view = menu_item()->GetSubmenu()->child_at(4); |
+ ASSERT_NE(nullptr, buttons_view); |
+ CustomButton* button1 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(0)); |
+ ASSERT_NE(nullptr, button1); |
+ CustomButton* button2 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(1)); |
+ ASSERT_NE(nullptr, button2); |
+ CustomButton* button3 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(2)); |
+ ASSERT_NE(nullptr, button2); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_FALSE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Move selection to |button1|. |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_TRUE(button1->IsHotTracked()); |
+ EXPECT_FALSE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Move selection to |button2|. |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_TRUE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Move selection to |button3|. |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_FALSE(button2->IsHotTracked()); |
+ EXPECT_TRUE(button3->IsHotTracked()); |
+ |
+ // Externally set hot tracked to the first child button and update. |
+ button1->SetHotTracked(true); |
+ // Emulate a mouse move that would update menu controller selection. |
+ UpdateSelection(buttons_view); |
+ |
+ // Incrementing selection should move hot tracking to the second button (next |
+ // after the first button). |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_TRUE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Increment selection twice to wrap around. |
+ IncrementSelection(); |
+ IncrementSelection(); |
+ EXPECT_EQ(1, pending_state_item()->GetCommand()); |
+ |
+ // Clear references in menu controller to the menu item that is going away. |
+ ResetSelection(); |
+} |
+ |
+TEST_F(MenuControllerTest, DeleteChildButtonView) { |
+ AddButtonMenuItems(); |
+ |
+ // Handle searching for 'f'; should find "Four". |
+ SelectByChar('f'); |
+ EXPECT_EQ(4, pending_state_item()->GetCommand()); |
+ |
+ View* buttons_view = menu_item()->GetSubmenu()->child_at(4); |
+ ASSERT_NE(nullptr, buttons_view); |
+ CustomButton* button1 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(0)); |
+ ASSERT_NE(nullptr, button1); |
+ CustomButton* button2 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(1)); |
+ ASSERT_NE(nullptr, button2); |
+ CustomButton* button3 = |
+ CustomButton::AsCustomButton(buttons_view->child_at(2)); |
+ ASSERT_NE(nullptr, button2); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_FALSE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Increment twice to move selection to |button2|. |
+ IncrementSelection(); |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_TRUE(button2->IsHotTracked()); |
+ EXPECT_FALSE(button3->IsHotTracked()); |
+ |
+ // Externally set hot tracked to the first child button and update. |
+ button1->SetHotTracked(true); |
+ // Delete |button2| while another child button view is hot-tracked. |
+ // This should update MenuController via ViewHierarchyChanged and reset |
+ // |hot_button_|. |
+ delete button2; |
+ // Emulate a mouse move that would update menu controller selection. |
+ // This should not crash. |
+ UpdateSelection(buttons_view); |
+ |
+ // Incrementing selection should now set hot-tracked item to |button3|. |
+ IncrementSelection(); |
+ EXPECT_EQ(5, pending_state_item()->GetCommand()); |
+ EXPECT_FALSE(button1->IsHotTracked()); |
+ EXPECT_TRUE(button3->IsHotTracked()); |
+} |
+ |
// Tests that a menu opened asynchronously, will notify its |
// MenuControllerDelegate when Accept is called. |
TEST_F(MenuControllerTest, AsynchronousAccept) { |
@@ -876,7 +1004,7 @@ TEST_F(MenuControllerTest, AsynchronousRepostEvent) { |
false, false, &mouse_event_flags); |
EXPECT_EQ(run_result, nullptr); |
- // Show a sub menu to targert with a pointer selection. However have the event |
+ // Show a sub menu to target with a pointer selection. However have the event |
// occur outside of the bounds of the entire menu. |
SubmenuView* sub_menu = item->GetSubmenu(); |
sub_menu->ShowAt(owner(), item->bounds(), false); |
@@ -975,7 +1103,7 @@ TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) { |
false, false, &mouse_event_flags); |
EXPECT_EQ(run_result, nullptr); |
- // Show a sub menu to targert with a pointer selection. However have the event |
+ // Show a sub menu to target with a pointer selection. However have the event |
// occur outside of the bounds of the entire menu. |
SubmenuView* sub_menu = item->GetSubmenu(); |
sub_menu->ShowAt(owner(), item->bounds(), true); |