Add ICU message format support
[chromium-blink-merge.git] / ui / views / controls / menu / menu_model_adapter_unittest.cc
blobad98a1559f7c99f4eeca5deabc25755393bf7aa6
1 // Copyright (c) 2012 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.
5 #include "ui/views/controls/menu/menu_model_adapter.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/base/models/menu_model.h"
9 #include "ui/base/models/menu_model_delegate.h"
10 #include "ui/views/controls/menu/menu_item_view.h"
11 #include "ui/views/controls/menu/menu_runner.h"
12 #include "ui/views/controls/menu/submenu_view.h"
13 #include "ui/views/test/views_test_base.h"
15 namespace {
17 // Base command id for test menu and its submenu.
18 const int kRootIdBase = 100;
19 const int kSubmenuIdBase = 200;
21 class MenuModelBase : public ui::MenuModel {
22 public:
23 explicit MenuModelBase(int command_id_base)
24 : command_id_base_(command_id_base),
25 last_activation_(-1) {
28 ~MenuModelBase() override {}
30 // ui::MenuModel implementation:
32 bool HasIcons() const override { return false; }
34 int GetItemCount() const override { return static_cast<int>(items_.size()); }
36 ItemType GetTypeAt(int index) const override { return items_[index].type; }
38 ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
39 return ui::NORMAL_SEPARATOR;
42 int GetCommandIdAt(int index) const override {
43 return index + command_id_base_;
46 base::string16 GetLabelAt(int index) const override {
47 return items_[index].label;
50 bool IsItemDynamicAt(int index) const override { return false; }
52 const gfx::FontList* GetLabelFontListAt(int index) const override {
53 return NULL;
56 bool GetAcceleratorAt(int index,
57 ui::Accelerator* accelerator) const override {
58 return false;
61 bool IsItemCheckedAt(int index) const override { return false; }
63 int GetGroupIdAt(int index) const override { return 0; }
65 bool GetIconAt(int index, gfx::Image* icon) override { return false; }
67 ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
68 return NULL;
71 bool IsEnabledAt(int index) const override { return true; }
73 bool IsVisibleAt(int index) const override { return true; }
75 MenuModel* GetSubmenuModelAt(int index) const override {
76 return items_[index].submenu;
79 void HighlightChangedTo(int index) override {}
81 void ActivatedAt(int index) override { set_last_activation(index); }
83 void ActivatedAt(int index, int event_flags) override { ActivatedAt(index); }
85 void MenuWillShow() override {}
87 void MenuClosed() override {}
89 void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) override {}
91 ui::MenuModelDelegate* GetMenuModelDelegate() const override { return NULL; }
93 // Item definition.
94 struct Item {
95 Item(ItemType item_type,
96 const std::string& item_label,
97 ui::MenuModel* item_submenu)
98 : type(item_type),
99 label(base::ASCIIToUTF16(item_label)),
100 submenu(item_submenu) {
103 ItemType type;
104 base::string16 label;
105 ui::MenuModel* submenu;
108 const Item& GetItemDefinition(int index) {
109 return items_[index];
112 // Access index argument to ActivatedAt().
113 int last_activation() const { return last_activation_; }
114 void set_last_activation(int last_activation) {
115 last_activation_ = last_activation;
118 protected:
119 std::vector<Item> items_;
121 private:
122 int command_id_base_;
123 int last_activation_;
125 DISALLOW_COPY_AND_ASSIGN(MenuModelBase);
128 class SubmenuModel : public MenuModelBase {
129 public:
130 SubmenuModel() : MenuModelBase(kSubmenuIdBase) {
131 items_.push_back(Item(TYPE_COMMAND, "submenu item 0", NULL));
132 items_.push_back(Item(TYPE_COMMAND, "submenu item 1", NULL));
135 ~SubmenuModel() override {}
137 private:
138 DISALLOW_COPY_AND_ASSIGN(SubmenuModel);
141 class RootModel : public MenuModelBase {
142 public:
143 RootModel() : MenuModelBase(kRootIdBase) {
144 submenu_model_.reset(new SubmenuModel);
146 items_.push_back(Item(TYPE_COMMAND, "command 0", NULL));
147 items_.push_back(Item(TYPE_CHECK, "check 1", NULL));
148 items_.push_back(Item(TYPE_SEPARATOR, "", NULL));
149 items_.push_back(Item(TYPE_SUBMENU, "submenu 3", submenu_model_.get()));
150 items_.push_back(Item(TYPE_RADIO, "radio 4", NULL));
153 ~RootModel() override {}
155 private:
156 scoped_ptr<MenuModel> submenu_model_;
158 DISALLOW_COPY_AND_ASSIGN(RootModel);
161 } // namespace
163 namespace views {
165 typedef ViewsTestBase MenuModelAdapterTest;
167 TEST_F(MenuModelAdapterTest, BasicTest) {
168 // Build model and adapter.
169 RootModel model;
170 views::MenuModelAdapter delegate(&model);
172 // Create menu. Build menu twice to check that rebuilding works properly.
173 MenuItemView* menu = new views::MenuItemView(&delegate);
174 // MenuRunner takes ownership of menu.
175 scoped_ptr<MenuRunner> menu_runner(new MenuRunner(menu, 0));
176 delegate.BuildMenu(menu);
177 delegate.BuildMenu(menu);
178 EXPECT_TRUE(menu->HasSubmenu());
180 // Check top level menu items.
181 views::SubmenuView* item_container = menu->GetSubmenu();
182 EXPECT_EQ(5, item_container->child_count());
184 for (int i = 0; i < item_container->child_count(); ++i) {
185 const MenuModelBase::Item& model_item = model.GetItemDefinition(i);
187 const int id = i + kRootIdBase;
188 MenuItemView* item = menu->GetMenuItemByID(id);
189 if (!item) {
190 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type);
191 continue;
194 // Check placement.
195 EXPECT_EQ(i, menu->GetSubmenu()->GetIndexOf(item));
197 // Check type.
198 switch (model_item.type) {
199 case ui::MenuModel::TYPE_COMMAND:
200 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
201 break;
202 case ui::MenuModel::TYPE_CHECK:
203 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
204 break;
205 case ui::MenuModel::TYPE_RADIO:
206 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
207 break;
208 case ui::MenuModel::TYPE_SEPARATOR:
209 case ui::MenuModel::TYPE_BUTTON_ITEM:
210 break;
211 case ui::MenuModel::TYPE_SUBMENU:
212 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
213 break;
216 // Check activation.
217 static_cast<views::MenuDelegate*>(&delegate)->ExecuteCommand(id);
218 EXPECT_EQ(i, model.last_activation());
219 model.set_last_activation(-1);
222 // Check submenu items.
223 views::MenuItemView* submenu = menu->GetMenuItemByID(103);
224 views::SubmenuView* subitem_container = submenu->GetSubmenu();
225 EXPECT_EQ(2, subitem_container->child_count());
227 for (int i = 0; i < subitem_container->child_count(); ++i) {
228 MenuModelBase* submodel = static_cast<MenuModelBase*>(
229 model.GetSubmenuModelAt(3));
230 EXPECT_TRUE(submodel);
232 const MenuModelBase::Item& model_item = submodel->GetItemDefinition(i);
234 const int id = i + kSubmenuIdBase;
235 MenuItemView* item = menu->GetMenuItemByID(id);
236 if (!item) {
237 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type);
238 continue;
241 // Check placement.
242 EXPECT_EQ(i, submenu->GetSubmenu()->GetIndexOf(item));
244 // Check type.
245 switch (model_item.type) {
246 case ui::MenuModel::TYPE_COMMAND:
247 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
248 break;
249 case ui::MenuModel::TYPE_CHECK:
250 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
251 break;
252 case ui::MenuModel::TYPE_RADIO:
253 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
254 break;
255 case ui::MenuModel::TYPE_SEPARATOR:
256 case ui::MenuModel::TYPE_BUTTON_ITEM:
257 break;
258 case ui::MenuModel::TYPE_SUBMENU:
259 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
260 break;
263 // Check activation.
264 static_cast<views::MenuDelegate*>(&delegate)->ExecuteCommand(id);
265 EXPECT_EQ(i, submodel->last_activation());
266 submodel->set_last_activation(-1);
269 // Check that selecting the root item is safe. The MenuModel does
270 // not care about the root so MenuModelAdapter should do nothing
271 // (not hit the NOTREACHED check) when the root is selected.
272 static_cast<views::MenuDelegate*>(&delegate)->SelectionChanged(menu);
275 } // namespace views