]> git.saurik.com Git - wxWidgets.git/blob - tests/menu/menu.cpp
Add wxListCtrlBase common base class for port-specific wxListCtrl.
[wxWidgets.git] / tests / menu / menu.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/menu/menu.cpp
3 // Purpose: wxMenu unit test
4 // Author: wxWidgets team
5 // Created: 2010-11-10
6 // RCS-ID: $Id$
7 // Copyright: (c) 2010 wxWidgets team
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifndef WX_PRECOMP
21 #include "wx/wx.h"
22 #endif // WX_PRECOMP
23
24 #include "wx/menu.h"
25 #include <stdarg.h>
26
27 // ----------------------------------------------------------------------------
28 // helper
29 // ----------------------------------------------------------------------------
30
31 namespace
32 {
33
34 enum
35 {
36 MenuTestCase_Foo = 10000,
37 MenuTestCase_Bar,
38 MenuTestCase_First
39 };
40
41 void PopulateMenu(wxMenu* menu, const wxString& name, size_t& itemcount)
42 {
43 // Start at item 1 to make it human-readable ;)
44 for (int n=1; n<6; ++n, ++itemcount)
45 {
46 wxString label = name; label << n;
47 menu->Append(MenuTestCase_First + itemcount, label, label + " help string");
48 }
49 }
50
51 void RecursivelyCountMenuItems(const wxMenu* menu, size_t& count)
52 {
53 CPPUNIT_ASSERT( menu );
54
55 count += menu->GetMenuItemCount();
56 for (size_t n=0; n < menu->GetMenuItemCount(); ++n)
57 {
58 wxMenuItem* item = menu->FindItemByPosition(n);
59 if (item->IsSubMenu())
60 {
61 RecursivelyCountMenuItems(item->GetSubMenu(), count);
62 }
63 }
64 }
65
66 } // anon namespace
67
68
69 // ----------------------------------------------------------------------------
70 // test class
71 // ----------------------------------------------------------------------------
72
73 class MenuTestCase : public CppUnit::TestCase
74 {
75 public:
76 MenuTestCase() {}
77
78 virtual void setUp() { CreateFrame(); }
79 virtual void tearDown() { m_frame->Destroy(); }
80
81 private:
82 CPPUNIT_TEST_SUITE( MenuTestCase );
83 CPPUNIT_TEST( FindInMenubar );
84 CPPUNIT_TEST( FindInMenu );
85 CPPUNIT_TEST( Count );
86 CPPUNIT_TEST( Labels );
87 CPPUNIT_TEST( RadioItems );
88 CPPUNIT_TEST( RemoveAdd );
89 CPPUNIT_TEST_SUITE_END();
90
91 void CreateFrame();
92
93 void FindInMenubar();
94 void FindInMenu();
95 void Count();
96 void Labels();
97 void RadioItems();
98 void RemoveAdd();
99
100 wxFrame* m_frame;
101
102 // Holds the number of menuitems contained in all the menus
103 size_t m_itemCount;
104
105 // Store here the id of a known submenu item, to be searched for later
106 int m_submenuItemId;
107
108 // and a sub-submenu item
109 int m_subsubmenuItemId;
110
111 wxArrayString m_menuLabels;
112
113 DECLARE_NO_COPY_CLASS(MenuTestCase)
114 };
115
116 // register in the unnamed registry so that these tests are run by default
117 CPPUNIT_TEST_SUITE_REGISTRATION( MenuTestCase );
118
119 // also include in its own registry so that these tests can be run alone
120 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MenuTestCase, "MenuTestCase" );
121
122 void MenuTestCase::CreateFrame()
123 {
124 m_frame = new wxFrame(NULL, wxID_ANY, "test frame");
125
126 wxMenu *fileMenu = new wxMenu;
127 wxMenu *helpMenu = new wxMenu;
128 wxMenu *subMenu = new wxMenu;
129 wxMenu *subsubMenu = new wxMenu;
130
131 size_t itemcount = 0;
132
133 PopulateMenu(subsubMenu, "Subsubmenu item ", itemcount);
134
135 // Store one of its IDs for later
136 m_subsubmenuItemId = MenuTestCase_First + itemcount - 2;
137
138 PopulateMenu(subMenu, "Submenu item ", itemcount);
139
140 // Store one of its IDs for later
141 m_submenuItemId = MenuTestCase_First + itemcount - 2;
142
143 subMenu->AppendSubMenu(subsubMenu, "Subsubmen&u", "Test a subsubmenu");
144
145 PopulateMenu(fileMenu, "Filemenu item ", itemcount);
146
147 fileMenu->Append(MenuTestCase_Foo, "&Foo\tCtrl-F", "Test item to be found");
148
149
150 PopulateMenu(helpMenu, "Helpmenu item ", itemcount);
151 helpMenu->Append(MenuTestCase_Bar, "Bar");
152 helpMenu->AppendSubMenu(subMenu, "Sub&menu", "Test a submenu");
153
154 // +2 for "Foo" and "Bar", +2 for the 2 submenus
155 m_itemCount = itemcount + 4;
156
157 // Use an arraystring here, to help with future tests
158 m_menuLabels.Add("&File");
159 m_menuLabels.Add("&Help");
160
161 wxMenuBar *menuBar = new wxMenuBar();
162 menuBar->Append(fileMenu, m_menuLabels[0]);
163 menuBar->Append(helpMenu, m_menuLabels[1]);
164 m_frame->SetMenuBar(menuBar);
165 }
166
167 void MenuTestCase::FindInMenubar()
168 {
169 wxMenuBar* bar = m_frame->GetMenuBar();
170
171 // Find by name:
172 CPPUNIT_ASSERT( bar->FindMenu("File") != wxNOT_FOUND );
173 CPPUNIT_ASSERT( bar->FindMenu("&File") != wxNOT_FOUND );
174 CPPUNIT_ASSERT( bar->FindMenu("&Fail") == wxNOT_FOUND );
175
176 // Find by menu name plus item name:
177 CPPUNIT_ASSERT( bar->FindMenuItem("File", "Foo") != wxNOT_FOUND );
178 CPPUNIT_ASSERT( bar->FindMenuItem("&File", "&Foo") != wxNOT_FOUND );
179 // and using the menu label
180 int index = bar->FindMenu("&File");
181 CPPUNIT_ASSERT( index != wxNOT_FOUND );
182 wxString menulabel = bar->GetMenuLabel(index);
183 CPPUNIT_ASSERT( bar->FindMenuItem(menulabel, "&Foo") != wxNOT_FOUND );
184 // and title
185 wxString menutitle = bar->GetMenu(index)->GetTitle();
186 CPPUNIT_ASSERT( bar->FindMenuItem(menutitle, "&Foo") != wxNOT_FOUND );
187
188 // Find by position:
189 for (size_t n=0; n < bar->GetMenuCount(); ++n)
190 {
191 CPPUNIT_ASSERT( bar->GetMenu(n) );
192 }
193
194 // Find by id:
195 wxMenu* menu = NULL;
196 wxMenuItem* item = NULL;
197 item = bar->FindItem(MenuTestCase_Foo, &menu);
198 CPPUNIT_ASSERT( item );
199 CPPUNIT_ASSERT( menu );
200 // Check that the correct menu was found
201 CPPUNIT_ASSERT( menu->FindChildItem(MenuTestCase_Foo) );
202
203 // Find submenu item:
204 item = bar->FindItem(m_submenuItemId, &menu);
205 CPPUNIT_ASSERT( item );
206 CPPUNIT_ASSERT( menu );
207 // and, for completeness, a subsubmenu one:
208 item = bar->FindItem(m_subsubmenuItemId, &menu);
209 CPPUNIT_ASSERT( item );
210 CPPUNIT_ASSERT( menu );
211 }
212
213 void MenuTestCase::FindInMenu()
214 {
215 wxMenuBar* bar = m_frame->GetMenuBar();
216
217 // Find by name:
218 wxMenu* menuFind = bar->GetMenu(0);
219 CPPUNIT_ASSERT( menuFind->FindItem("Foo") != wxNOT_FOUND );
220 CPPUNIT_ASSERT( menuFind->FindItem("&Foo") != wxNOT_FOUND );
221 // and for submenus
222 wxMenu* menuHelp = bar->GetMenu(1);
223 CPPUNIT_ASSERT( menuHelp->FindItem("Submenu") != wxNOT_FOUND );
224 CPPUNIT_ASSERT( menuHelp->FindItem("Sub&menu") != wxNOT_FOUND );
225
226 // Find by position:
227 size_t n;
228 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
229 {
230 CPPUNIT_ASSERT( menuHelp->FindItemByPosition(n) );
231 }
232
233 // Find by id:
234 CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Bar) );
235 CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Foo) == NULL );
236
237 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
238 {
239 size_t locatedAt;
240 wxMenuItem* itemByPos = menuHelp->FindItemByPosition(n);
241 CPPUNIT_ASSERT( itemByPos );
242 wxMenuItem* itemById = menuHelp->FindChildItem(itemByPos->GetId(), &locatedAt);
243 CPPUNIT_ASSERT_EQUAL( itemByPos, itemById );
244 CPPUNIT_ASSERT_EQUAL( locatedAt, n );
245 }
246
247 // Find submenu item:
248 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
249 {
250 wxMenuItem* item = menuHelp->FindItemByPosition(n);
251 if (item->IsSubMenu())
252 {
253 wxMenu* submenu;
254 wxMenuItem* submenuItem = menuHelp->FindItem(m_submenuItemId, &submenu);
255 CPPUNIT_ASSERT( submenuItem );
256 CPPUNIT_ASSERT( item->GetSubMenu() == submenu );
257 }
258 }
259 }
260
261 void MenuTestCase::Count()
262 {
263 wxMenuBar* bar = m_frame->GetMenuBar();
264 // I suppose you could call this "counting menubars" :)
265 CPPUNIT_ASSERT( bar );
266
267 CPPUNIT_ASSERT_EQUAL( bar->GetMenuCount(), 2 );
268
269 size_t count = 0;
270 for (size_t n=0; n < bar->GetMenuCount(); ++n)
271 {
272 RecursivelyCountMenuItems(bar->GetMenu(n), count);
273 }
274 CPPUNIT_ASSERT_EQUAL( count, m_itemCount );
275 }
276
277 void MenuTestCase::Labels()
278 {
279 wxMenuBar* bar = m_frame->GetMenuBar();
280 CPPUNIT_ASSERT( bar );
281 wxMenu* filemenu;
282 wxMenuItem* itemFoo = bar->FindItem(MenuTestCase_Foo, &filemenu);
283 CPPUNIT_ASSERT( itemFoo );
284 CPPUNIT_ASSERT( filemenu );
285
286 // These return labels including mnemonics/accelerators:
287
288 // wxMenuBar
289 CPPUNIT_ASSERT_EQUAL( "&File", bar->GetMenuLabel(0) );
290 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", bar->GetLabel(MenuTestCase_Foo) );
291
292 // wxMenu
293 CPPUNIT_ASSERT_EQUAL( "&File", filemenu->GetTitle() );
294 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", filemenu->GetLabel(MenuTestCase_Foo) );
295
296 // wxMenuItem
297 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", itemFoo->GetItemLabel() );
298
299 // These return labels stripped of mnemonics/accelerators:
300
301 // wxMenuBar
302 CPPUNIT_ASSERT_EQUAL( "File", bar->GetMenuLabelText(0) );
303
304 // wxMenu
305 CPPUNIT_ASSERT_EQUAL( "Foo", filemenu->GetLabelText(MenuTestCase_Foo) );
306
307 // wxMenuItem
308 CPPUNIT_ASSERT_EQUAL( "Foo", itemFoo->GetItemLabelText() );
309 CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") );
310 }
311
312 void MenuTestCase::RadioItems()
313 {
314 wxMenuBar * const bar = m_frame->GetMenuBar();
315 wxMenu * const menu = new wxMenu;
316 bar->Append(menu, "&Radio");
317
318 // Adding consecutive radio items creates a radio group.
319 menu->AppendRadioItem(MenuTestCase_First, "Radio 0");
320 menu->AppendRadioItem(MenuTestCase_First + 1, "Radio 1");
321
322 // First item of a radio group is checked by default.
323 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First) );
324
325 // Checking the second one make the first one unchecked however.
326 menu->Check(MenuTestCase_First + 1, true);
327 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First) );
328 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
329
330 // Adding more radio items after a separator creates another radio group...
331 menu->AppendSeparator();
332 menu->AppendRadioItem(MenuTestCase_First + 2, "Radio 2");
333 menu->AppendRadioItem(MenuTestCase_First + 3, "Radio 3");
334 menu->AppendRadioItem(MenuTestCase_First + 4, "Radio 4");
335
336 // ... which is independent from the first one.
337 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 2) );
338
339 menu->Check(MenuTestCase_First + 3, true);
340 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
341 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 2) );
342 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
343
344
345 // Insert an item in the middle of an existing radio group.
346 menu->InsertRadioItem(4, MenuTestCase_First + 5, "Radio 5");
347 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
348
349 menu->Check( MenuTestCase_First + 5, true );
350 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 3) );
351
352
353 // Prepend a couple of items before the first group.
354 menu->PrependRadioItem(MenuTestCase_First + 6, "Radio 6");
355 menu->PrependRadioItem(MenuTestCase_First + 7, "Radio 7");
356 menu->Check(MenuTestCase_First + 7, true);
357 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 1) );
358
359
360 // Check that the last radio group still works as expected.
361 menu->Check(MenuTestCase_First + 4, true);
362 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 5) );
363 }
364
365 void MenuTestCase::RemoveAdd()
366 {
367 wxMenuBar* bar = m_frame->GetMenuBar();
368
369 wxMenu* menu0 = bar->GetMenu(0);
370 wxMenu* menu1 = bar->GetMenu(1);
371 wxMenuItem* item = new wxMenuItem(menu0, MenuTestCase_Foo + 100, "t&ext\tCtrl-E");
372 menu0->Insert(0, item);
373 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
374 menu0->Remove(item);
375 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) != item );
376 menu1->Insert(0, item);
377 CPPUNIT_ASSERT( menu1->FindItemByPosition(0) == item );
378 menu1->Remove(item);
379 CPPUNIT_ASSERT( menu1->FindItemByPosition(0) != item );
380 menu0->Insert(0, item);
381 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
382 menu0->Delete(item);
383 }