Demonstrate the basic functionality of the File System
[chromium-blink-merge.git] / ui / views / controls / menu / menu_model_adapter_unittest.cc
blobcba4d2fa7fb2d85dcf7a1f794bf761c6c40ff9ee
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/l10n/l10n_util.h"
9 #include "ui/base/models/menu_model.h"
10 #include "ui/base/models/menu_model_delegate.h"
11 #include "ui/views/controls/menu/menu_item_view.h"
12 #include "ui/views/controls/menu/menu_runner.h"
13 #include "ui/views/controls/menu/submenu_view.h"
14 #include "ui/views/test/views_test_base.h"
16 namespace {
18 // Base command id for test menu and its submenu.
19 const int kRootIdBase = 100;
20 const int kSubmenuIdBase = 200;
22 class MenuModelBase : public ui::MenuModel {
23 public:
24 explicit MenuModelBase(int command_id_base)
25 : command_id_base_(command_id_base),
26 last_activation_(-1) {
29 virtual ~MenuModelBase() {
32 // ui::MenuModel implementation:
34 virtual bool HasIcons() const OVERRIDE {
35 return false;
38 virtual int GetItemCount() const OVERRIDE {
39 return static_cast<int>(items_.size());
42 virtual ItemType GetTypeAt(int index) const OVERRIDE {
43 return items_[index].type;
46 virtual ui::MenuSeparatorType GetSeparatorTypeAt(
47 int index) const OVERRIDE {
48 return ui::NORMAL_SEPARATOR;
51 virtual int GetCommandIdAt(int index) const OVERRIDE {
52 return index + command_id_base_;
55 virtual base::string16 GetLabelAt(int index) const OVERRIDE {
56 return items_[index].label;
59 virtual bool IsItemDynamicAt(int index) const OVERRIDE {
60 return false;
63 virtual const gfx::FontList* GetLabelFontListAt(int index) const OVERRIDE {
64 return NULL;
67 virtual bool GetAcceleratorAt(int index,
68 ui::Accelerator* accelerator) const OVERRIDE {
69 return false;
72 virtual bool IsItemCheckedAt(int index) const OVERRIDE {
73 return false;
76 virtual int GetGroupIdAt(int index) const OVERRIDE {
77 return 0;
80 virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE {
81 return false;
84 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(
85 int index) const OVERRIDE {
86 return NULL;
89 virtual bool IsEnabledAt(int index) const OVERRIDE {
90 return true;
93 virtual bool IsVisibleAt(int index) const OVERRIDE {
94 return true;
97 virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
98 return items_[index].submenu;
101 virtual void HighlightChangedTo(int index) OVERRIDE {
104 virtual void ActivatedAt(int index) OVERRIDE {
105 set_last_activation(index);
108 virtual void ActivatedAt(int index, int event_flags) OVERRIDE {
109 ActivatedAt(index);
112 virtual void MenuWillShow() OVERRIDE {
115 virtual void MenuClosed() OVERRIDE {
118 virtual void SetMenuModelDelegate(
119 ui::MenuModelDelegate* delegate) OVERRIDE {
122 virtual ui::MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE {
123 return NULL;
126 // Item definition.
127 struct Item {
128 Item(ItemType item_type,
129 const std::string& item_label,
130 ui::MenuModel* item_submenu)
131 : type(item_type),
132 label(base::ASCIIToUTF16(item_label)),
133 submenu(item_submenu) {
136 ItemType type;
137 base::string16 label;
138 ui::MenuModel* submenu;
141 const Item& GetItemDefinition(int index) {
142 return items_[index];
145 // Access index argument to ActivatedAt().
146 int last_activation() const { return last_activation_; }
147 void set_last_activation(int last_activation) {
148 last_activation_ = last_activation;
151 protected:
152 std::vector<Item> items_;
154 private:
155 int command_id_base_;
156 int last_activation_;
158 DISALLOW_COPY_AND_ASSIGN(MenuModelBase);
161 class SubmenuModel : public MenuModelBase {
162 public:
163 SubmenuModel() : MenuModelBase(kSubmenuIdBase) {
164 items_.push_back(Item(TYPE_COMMAND, "submenu item 0", NULL));
165 items_.push_back(Item(TYPE_COMMAND, "submenu item 1", NULL));
168 virtual ~SubmenuModel() {
171 private:
172 DISALLOW_COPY_AND_ASSIGN(SubmenuModel);
175 class RootModel : public MenuModelBase {
176 public:
177 RootModel() : MenuModelBase(kRootIdBase) {
178 submenu_model_.reset(new SubmenuModel);
180 items_.push_back(Item(TYPE_COMMAND, "command 0", NULL));
181 items_.push_back(Item(TYPE_CHECK, "check 1", NULL));
182 items_.push_back(Item(TYPE_SEPARATOR, "", NULL));
183 items_.push_back(Item(TYPE_SUBMENU, "submenu 3", submenu_model_.get()));
184 items_.push_back(Item(TYPE_RADIO, "radio 4", NULL));
187 virtual ~RootModel() {
190 private:
191 scoped_ptr<MenuModel> submenu_model_;
193 DISALLOW_COPY_AND_ASSIGN(RootModel);
196 } // namespace
198 namespace views {
200 typedef ViewsTestBase MenuModelAdapterTest;
202 TEST_F(MenuModelAdapterTest, BasicTest) {
203 // Build model and adapter.
204 RootModel model;
205 views::MenuModelAdapter delegate(&model);
207 // Create menu. Build menu twice to check that rebuilding works properly.
208 MenuItemView* menu = new views::MenuItemView(&delegate);
209 // MenuRunner takes ownership of menu.
210 scoped_ptr<MenuRunner> menu_runner(new MenuRunner(menu));
211 delegate.BuildMenu(menu);
212 delegate.BuildMenu(menu);
213 EXPECT_TRUE(menu->HasSubmenu());
215 // Check top level menu items.
216 views::SubmenuView* item_container = menu->GetSubmenu();
217 EXPECT_EQ(5, item_container->child_count());
219 for (int i = 0; i < item_container->child_count(); ++i) {
220 const MenuModelBase::Item& model_item = model.GetItemDefinition(i);
222 const int id = i + kRootIdBase;
223 MenuItemView* item = menu->GetMenuItemByID(id);
224 if (!item) {
225 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type);
226 continue;
229 // Check placement.
230 EXPECT_EQ(i, menu->GetSubmenu()->GetIndexOf(item));
232 // Check type.
233 switch (model_item.type) {
234 case ui::MenuModel::TYPE_COMMAND:
235 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
236 break;
237 case ui::MenuModel::TYPE_CHECK:
238 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
239 break;
240 case ui::MenuModel::TYPE_RADIO:
241 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
242 break;
243 case ui::MenuModel::TYPE_SEPARATOR:
244 case ui::MenuModel::TYPE_BUTTON_ITEM:
245 break;
246 case ui::MenuModel::TYPE_SUBMENU:
247 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
248 break;
251 // Check activation.
252 static_cast<views::MenuDelegate*>(&delegate)->ExecuteCommand(id);
253 EXPECT_EQ(i, model.last_activation());
254 model.set_last_activation(-1);
257 // Check submenu items.
258 views::MenuItemView* submenu = menu->GetMenuItemByID(103);
259 views::SubmenuView* subitem_container = submenu->GetSubmenu();
260 EXPECT_EQ(2, subitem_container->child_count());
262 for (int i = 0; i < subitem_container->child_count(); ++i) {
263 MenuModelBase* submodel = static_cast<MenuModelBase*>(
264 model.GetSubmenuModelAt(3));
265 EXPECT_TRUE(submodel);
267 const MenuModelBase::Item& model_item = submodel->GetItemDefinition(i);
269 const int id = i + kSubmenuIdBase;
270 MenuItemView* item = menu->GetMenuItemByID(id);
271 if (!item) {
272 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type);
273 continue;
276 // Check placement.
277 EXPECT_EQ(i, submenu->GetSubmenu()->GetIndexOf(item));
279 // Check type.
280 switch (model_item.type) {
281 case ui::MenuModel::TYPE_COMMAND:
282 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
283 break;
284 case ui::MenuModel::TYPE_CHECK:
285 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
286 break;
287 case ui::MenuModel::TYPE_RADIO:
288 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
289 break;
290 case ui::MenuModel::TYPE_SEPARATOR:
291 case ui::MenuModel::TYPE_BUTTON_ITEM:
292 break;
293 case ui::MenuModel::TYPE_SUBMENU:
294 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
295 break;
298 // Check activation.
299 static_cast<views::MenuDelegate*>(&delegate)->ExecuteCommand(id);
300 EXPECT_EQ(i, submodel->last_activation());
301 submodel->set_last_activation(-1);
304 // Check that selecting the root item is safe. The MenuModel does
305 // not care about the root so MenuModelAdapter should do nothing
306 // (not hit the NOTREACHED check) when the root is selected.
307 static_cast<views::MenuDelegate*>(&delegate)->SelectionChanged(menu);
310 } // namespace views