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

Side by Side Diff: views/controls/menu/menu_model_adapter_unittest.cc

Issue 7067032: Add MenuModelAdapter to wrap ui::MenuModel with views::MenuDelegate interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Restore NOTREACHED() in IsCommandEnabled(). 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 "ui/base/l10n/l10n_util.h"
6 #include "ui/base/models/menu_model.h"
7 #include "ui/base/models/menu_model_delegate.h"
8 #include "views/controls/menu/menu_item_view.h"
9 #include "views/controls/menu/menu_model_adapter.h"
10 #include "views/controls/menu/submenu_view.h"
11 #include "views/test/views_test_base.h"
12
13 namespace {
14
15 // Base command id for test menu and its submenu.
16 const int kRootIdBase = 100;
17 const int kSubmenuIdBase = 200;
18
19 // Offset to return for GetFirstItemIndex(). This is an arbitrary
20 // number to ensure that we aren't assuming it is 0.
21 const int kFirstItemIndex = 25;
22
23 class MenuModelBase : public ui::MenuModel {
24 public:
25 MenuModelBase(int command_id_base) : command_id_base_(command_id_base),
26 last_activation_(-1) {
27 }
28
29 // ui::MenuModel implementation:
30
31 virtual bool HasIcons() const OVERRIDE {
32 return false;
33 }
34
35 virtual int GetFirstItemIndex(gfx::NativeMenu native_menu) const {
sky 2011/05/25 15:41:12 OVERRIDE
rhashimoto 2011/05/25 16:24:37 Done.
36 return kFirstItemIndex;
37 }
38
39 virtual int GetItemCount() const OVERRIDE {
40 return static_cast<int>(items_.size());
41 }
42
43 virtual ItemType GetTypeAt(int index) const OVERRIDE {
44 return items_[index - GetFirstItemIndex(NULL)].type_;
45 }
46
47 virtual int GetCommandIdAt(int index) const OVERRIDE {
48 return index - GetFirstItemIndex(NULL) + command_id_base_;
49 }
50
51 string16 GetLabelAt(int index) const OVERRIDE {
52 return items_[index - GetFirstItemIndex(NULL)].label_;
53 }
54
55 virtual bool IsItemDynamicAt(int index) const OVERRIDE {
56 return false;
57 }
58
59 virtual const gfx::Font* GetLabelFontAt(int index) const OVERRIDE {
60 return NULL;
61 }
62
63 virtual bool GetAcceleratorAt(int index,
64 ui::Accelerator* accelerator) const OVERRIDE {
65 return false;
66 }
67
68 virtual bool IsItemCheckedAt(int index) const OVERRIDE {
69 return false;
70 }
71
72 virtual int GetGroupIdAt(int index) const OVERRIDE {
73 return 0;
74 }
75
76 virtual bool GetIconAt(int index, SkBitmap* icon) OVERRIDE {
77 return false;
78 }
79
80 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(
81 int index) const OVERRIDE {
82 return NULL;
83 }
84
85 virtual bool IsEnabledAt(int index) const OVERRIDE {
86 return true;
87 }
88
89 virtual bool IsVisibleAt(int index) const OVERRIDE {
90 return true;
91 }
92
93 virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
94 return items_[index - GetFirstItemIndex(NULL)].submenu_;
95 }
96
97 virtual void HighlightChangedTo(int index) OVERRIDE {
98 }
99
100 virtual void ActivatedAt(int index) OVERRIDE {
101 set_last_activation(index);
102 }
103
104 virtual void ActivatedAtWithDisposition(int index, int disposition) OVERRIDE {
105 ActivatedAt(index);
106 }
107
108 virtual void MenuWillShow() OVERRIDE {
109 }
110
111 virtual void MenuClosed() OVERRIDE {
112 }
113
114 virtual void SetMenuModelDelegate(
115 ui::MenuModelDelegate* delegate) OVERRIDE {
116 }
117
118 // Item definition.
119 struct Item {
120 Item(ItemType type, const std::wstring& label, ui::MenuModel* submenu)
121 : type_(type),
122 label_(WideToUTF16(label)),
123 submenu_(submenu) {
124 }
125
126 ItemType type_;
sky 2011/05/25 15:41:12 don't use underscores for structs. That is, this s
rhashimoto 2011/05/25 16:24:37 Done.
127 string16 label_;
128 ui::MenuModel* submenu_;
129 };
130
131 const Item& GetItemDefinition(int index) {
132 return items_[index];
133 }
134
135 // Access index argument to ActivatedAt() or ActivatedAtWithDisposition().
136 int last_activation() const { return last_activation_; }
137 void set_last_activation(int last_activation) {
138 last_activation_ = last_activation;
139 }
140
141 protected:
142 std::vector<Item> items_;
143
144 private:
145 int command_id_base_;
146 int last_activation_;
147
148 DISALLOW_COPY_AND_ASSIGN(MenuModelBase);
149 };
150
151 class SubmenuModel : public MenuModelBase {
152 public:
153 SubmenuModel() : MenuModelBase(kSubmenuIdBase) {
154 items_.push_back(Item(TYPE_COMMAND, L"submenu item 0", NULL));
sky 2011/05/25 15:41:12 Don't use wide, instead use ascii.
rhashimoto 2011/05/25 16:24:37 Done.
155 items_.push_back(Item(TYPE_COMMAND, L"submenu item 1", NULL));
156 }
157
158 private:
159 DISALLOW_COPY_AND_ASSIGN(SubmenuModel);
160 };
161
162 class RootModel : public MenuModelBase {
163 public:
164 RootModel() : MenuModelBase(kRootIdBase) {
165 submenu_model_.reset(new SubmenuModel);
166
167 items_.push_back(Item(TYPE_COMMAND, L"command 0", NULL));
168 items_.push_back(Item(TYPE_CHECK, L"check 1", NULL));
169 items_.push_back(Item(TYPE_SEPARATOR, L"", NULL));
170 items_.push_back(Item(TYPE_SUBMENU, L"submenu 3", submenu_model_.get()));
171 items_.push_back(Item(TYPE_RADIO, L"radio 4", NULL));
172 }
173
174 private:
175 scoped_ptr<MenuModel> submenu_model_;
176
177 DISALLOW_COPY_AND_ASSIGN(RootModel);
178 };
179
180 } // namespace
181
182 namespace views {
183
184 class MenuModelAdapterTest : public ViewsTestBase {
sky 2011/05/25 15:41:12 use a typedef.
rhashimoto 2011/05/25 16:24:37 Done.
185 public:
186 MenuModelAdapterTest() {
187 }
188 };
189
190 TEST_F(MenuModelAdapterTest, BasicTest) {
191 // Build model and adapter.
192 scoped_ptr<MenuModelBase> model(new RootModel);
sky 2011/05/25 15:41:12 You never reset these, so you may as well declare
rhashimoto 2011/05/25 16:24:37 Done.
193 scoped_ptr<views::MenuModelAdapter> delegate(
194 new views::MenuModelAdapter(model.get()));
195
196 // Create menu. Build menu twice to check that rebuilding works properly.
197 scoped_ptr<views::MenuItemView> menu(new views::MenuItemView(delegate.get()));
198 delegate->BuildMenu(menu.get());
199 delegate->BuildMenu(menu.get());
200 EXPECT_TRUE(menu->HasSubmenu());
201
202 // Check top level menu items.
203 views::SubmenuView* item_container = menu->GetSubmenu();
204 EXPECT_EQ(5, item_container->child_count());
205
206 for (int i = 0; i < item_container->child_count(); ++i) {
207 const MenuModelBase::Item& model_item = model->GetItemDefinition(i);
208
209 const int id = i + kRootIdBase;
210 MenuItemView* item = menu->GetMenuItemByID(id);
211 if (!item) {
212 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type_);
213 continue;
214 }
215
216 // Check placement.
217 EXPECT_EQ(i, menu->GetSubmenu()->GetIndexOf(item));
218
219 // Check type.
220 switch (model_item.type_) {
221 case ui::MenuModel::TYPE_COMMAND:
222 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
223 break;
224 case ui::MenuModel::TYPE_CHECK:
225 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
226 break;
227 case ui::MenuModel::TYPE_RADIO:
228 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
229 break;
230 case ui::MenuModel::TYPE_SEPARATOR:
231 case ui::MenuModel::TYPE_BUTTON_ITEM:
232 break;
233 case ui::MenuModel::TYPE_SUBMENU:
234 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
235 break;
236 }
237
238 // Check activation.
239 static_cast<views::MenuDelegate*>(delegate.get())->ExecuteCommand(id);
240 EXPECT_EQ(i + kFirstItemIndex, model->last_activation());
241 model->set_last_activation(-1);
242 }
243
244 // Check submenu items.
245 views::MenuItemView* submenu = menu->GetMenuItemByID(103);
246 views::SubmenuView* subitem_container = submenu->GetSubmenu();
247 EXPECT_EQ(2, subitem_container->child_count());
248
249 for (int i = 0; i < subitem_container->child_count(); ++i) {
250 MenuModelBase* submodel = static_cast<MenuModelBase*>(
251 model->GetSubmenuModelAt(3 + kFirstItemIndex));
252 EXPECT_TRUE(submodel);
253
254 const MenuModelBase::Item& model_item = submodel->GetItemDefinition(i);
255
256 const int id = i + kSubmenuIdBase;
257 MenuItemView* item = menu->GetMenuItemByID(id);
258 if (!item) {
259 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, model_item.type_);
260 continue;
261 }
262
263 // Check placement.
264 EXPECT_EQ(i, submenu->GetSubmenu()->GetIndexOf(item));
265
266 // Check type.
267 switch (model_item.type_) {
268 case ui::MenuModel::TYPE_COMMAND:
269 EXPECT_EQ(views::MenuItemView::NORMAL, item->GetType());
270 break;
271 case ui::MenuModel::TYPE_CHECK:
272 EXPECT_EQ(views::MenuItemView::CHECKBOX, item->GetType());
273 break;
274 case ui::MenuModel::TYPE_RADIO:
275 EXPECT_EQ(views::MenuItemView::RADIO, item->GetType());
276 break;
277 case ui::MenuModel::TYPE_SEPARATOR:
278 case ui::MenuModel::TYPE_BUTTON_ITEM:
279 break;
280 case ui::MenuModel::TYPE_SUBMENU:
281 EXPECT_EQ(views::MenuItemView::SUBMENU, item->GetType());
282 break;
283 }
284
285 // Check activation.
286 static_cast<views::MenuDelegate*>(delegate.get())->ExecuteCommand(id);
287 EXPECT_EQ(i + kFirstItemIndex, submodel->last_activation());
288 submodel->set_last_activation(-1);
289 }
290 }
291
292 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698