blob: c818536bb078000c44757659b9d6a22733170867 [file] [log] [blame]
// Copyright 2018 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 "ash/public/cpp/menu_utils.h"
#include <utility>
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/models/menu_separator_types.h"
#include "ui/base/models/simple_menu_model.h"
using base::ASCIIToUTF16;
namespace ash {
namespace menu_utils {
using MenuModelList = std::vector<std::unique_ptr<ui::SimpleMenuModel>>;
class MenuUtilsTest : public testing::Test,
public ui::SimpleMenuModel::Delegate {
public:
MenuUtilsTest() {}
~MenuUtilsTest() override {}
// testing::Test overrides:
void SetUp() override {
menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
}
protected:
ui::SimpleMenuModel* root_menu() { return menu_model_.get(); }
MenuModelList* submenus() { return &submenu_models_; }
ui::SimpleMenuModel* CreateSubmenu() {
std::unique_ptr<ui::SimpleMenuModel> submenu =
std::make_unique<ui::SimpleMenuModel>(this);
ui::SimpleMenuModel* submenu_ptr = submenu.get();
submenu_models_.push_back(std::move(submenu));
return submenu_ptr;
}
bool IsCommandIdChecked(int command_id) const override {
// Assume that we have a checked item in every 3 items.
return command_id % 3 == 0;
}
bool IsCommandIdEnabled(int command_id) const override {
// Assume that we have a enabled item in every 4 items.
return command_id % 4 == 0;
}
void ExecuteCommand(int command_id, int event_flags) override {}
void CheckMenuItemsMatched(const MenuItemList& mojo_menu,
const ui::MenuModel* menu) {
EXPECT_EQ(mojo_menu.size(), static_cast<size_t>(menu->GetItemCount()));
for (size_t i = 0; i < mojo_menu.size(); i++) {
VLOG(1) << "Checking item at " << i;
mojom::MenuItem* mojo_item = mojo_menu[i].get();
EXPECT_EQ(mojo_item->type, menu->GetTypeAt(i));
EXPECT_EQ(mojo_item->command_id, menu->GetCommandIdAt(i));
EXPECT_EQ(mojo_item->label, menu->GetLabelAt(i));
if (mojo_item->type == ui::MenuModel::TYPE_SUBMENU) {
VLOG(1) << "It's a submenu, let's do a recursion.";
CheckMenuItemsMatched(mojo_item->submenu.value(),
menu->GetSubmenuModelAt(i));
continue;
}
EXPECT_EQ(mojo_item->enabled, menu->IsEnabledAt(i));
EXPECT_EQ(mojo_item->checked, menu->IsItemCheckedAt(i));
EXPECT_EQ(mojo_item->radio_group_id, menu->GetGroupIdAt(i));
}
}
private:
std::unique_ptr<ui::SimpleMenuModel> menu_model_;
MenuModelList submenu_models_;
DISALLOW_COPY_AND_ASSIGN(MenuUtilsTest);
};
TEST_F(MenuUtilsTest, Basic) {
ui::SimpleMenuModel* menu = root_menu();
// Populates items into |menu| for testing.
int command_id = 0;
menu->AddItem(command_id++, ASCIIToUTF16("Item0"));
menu->AddItem(command_id++, ASCIIToUTF16("Item1"));
menu->AddSeparator(ui::NORMAL_SEPARATOR);
menu->AddCheckItem(command_id++, ASCIIToUTF16("CheckItem0"));
menu->AddCheckItem(command_id++, ASCIIToUTF16("CheckItem1"));
menu->AddRadioItem(command_id++, ASCIIToUTF16("RadioItem0"),
0 /* group_id */);
menu->AddRadioItem(command_id++, ASCIIToUTF16("RadioItem1"),
0 /* group_id */);
// Creates a submenu.
ui::SimpleMenuModel* submenu = CreateSubmenu();
submenu->AddItem(command_id++, ASCIIToUTF16("SubMenu-Item0"));
submenu->AddItem(command_id++, ASCIIToUTF16("SubMenu-Item1"));
submenu->AddSeparator(ui::NORMAL_SEPARATOR);
submenu->AddCheckItem(command_id++, ASCIIToUTF16("SubMenu-CheckItem0"));
submenu->AddCheckItem(command_id++, ASCIIToUTF16("SubMenu-CheckItem1"));
submenu->AddRadioItem(command_id++, ASCIIToUTF16("SubMenu-RadioItem0"),
1 /* group_id */);
submenu->AddRadioItem(command_id++, ASCIIToUTF16("SubMenu-RadioItem1"),
1 /* group_id */);
menu->AddSubMenu(command_id++, ASCIIToUTF16("SubMenu"), submenu);
// Converts the menu into mojo format.
MenuItemList mojo_menu_items = GetMojoMenuItemsFromModel(menu);
CheckMenuItemsMatched(mojo_menu_items, menu);
// Converts backwards.
ui::SimpleMenuModel new_menu(this);
SubmenuList new_submenus;
PopulateMenuFromMojoMenuItems(&new_menu, this, mojo_menu_items,
&new_submenus);
CheckMenuItemsMatched(mojo_menu_items, &new_menu);
// Tests |GetMenuItemByCommandId|.
for (int command_to_find = 0; command_to_find < command_id;
command_to_find++) {
// Gets the mojo item.
const mojom::MenuItemPtr& mojo_item =
GetMenuItemByCommandId(mojo_menu_items, command_to_find);
// Gets the item index with this command from the original root menu.
int index = menu->GetIndexOfCommandId(command_to_find);
ui::MenuModel* menu_to_find = menu;
if (index < 0) {
// We cannot find it from the original root menu. Then it should be in the
// submenu.
index = submenu->GetIndexOfCommandId(command_to_find);
EXPECT_LE(0, index);
menu_to_find = submenu;
}
// Checks whether they match.
EXPECT_EQ(mojo_item->type, menu_to_find->GetTypeAt(index));
EXPECT_EQ(mojo_item->command_id, menu_to_find->GetCommandIdAt(index));
EXPECT_EQ(mojo_item->label, menu_to_find->GetLabelAt(index));
EXPECT_EQ(mojo_item->enabled, menu_to_find->IsEnabledAt(index));
EXPECT_EQ(mojo_item->checked, menu_to_find->IsItemCheckedAt(index));
EXPECT_EQ(mojo_item->radio_group_id, menu_to_find->GetGroupIdAt(index));
}
// For unknown command ids, we'll get a singleton stub item.
const mojom::MenuItemPtr& item_not_found_1 =
GetMenuItemByCommandId(mojo_menu_items, command_id + 1);
const mojom::MenuItemPtr& item_not_found_2 =
GetMenuItemByCommandId(mojo_menu_items, command_id + 2);
EXPECT_EQ(item_not_found_1.get(), item_not_found_2.get());
}
} // namespace menu_utils
} // namespace ash