1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/menu/menu.cpp
3 // Purpose: wxMenu unit test
4 // Author: wxWidgets team
7 // Copyright: (c) 2010 wxWidgets team
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
36 MenuTestCase_Foo
= 10000,
41 void PopulateMenu(wxMenu
* menu
, const wxString
& name
, size_t& itemcount
)
43 // Start at item 1 to make it human-readable ;)
44 for (int n
=1; n
<6; ++n
, ++itemcount
)
46 wxString label
= name
; label
<< n
;
47 menu
->Append(MenuTestCase_First
+ itemcount
, label
, label
+ " help string");
51 void RecursivelyCountMenuItems(const wxMenu
* menu
, size_t& count
)
53 CPPUNIT_ASSERT( menu
);
55 count
+= menu
->GetMenuItemCount();
56 for (size_t n
=0; n
< menu
->GetMenuItemCount(); ++n
)
58 wxMenuItem
* item
= menu
->FindItemByPosition(n
);
59 if (item
->IsSubMenu())
61 RecursivelyCountMenuItems(item
->GetSubMenu(), count
);
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 class MenuTestCase
: public CppUnit::TestCase
78 virtual void setUp() { CreateFrame(); }
79 virtual void tearDown() { m_frame
->Destroy(); }
82 CPPUNIT_TEST_SUITE( MenuTestCase
);
83 CPPUNIT_TEST( FindInMenubar
);
84 CPPUNIT_TEST( FindInMenu
);
85 CPPUNIT_TEST( EnableTop
);
86 CPPUNIT_TEST( Count
);
87 CPPUNIT_TEST( Labels
);
88 CPPUNIT_TEST( RadioItems
);
89 CPPUNIT_TEST( RemoveAdd
);
90 CPPUNIT_TEST_SUITE_END();
104 // Holds the number of menuitems contained in all the menus
107 // Store here the id of a known submenu item, to be searched for later
110 // and a sub-submenu item
111 int m_subsubmenuItemId
;
113 wxArrayString m_menuLabels
;
115 DECLARE_NO_COPY_CLASS(MenuTestCase
)
118 // register in the unnamed registry so that these tests are run by default
119 CPPUNIT_TEST_SUITE_REGISTRATION( MenuTestCase
);
121 // also include in its own registry so that these tests can be run alone
122 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MenuTestCase
, "MenuTestCase" );
124 void MenuTestCase::CreateFrame()
126 m_frame
= new wxFrame(NULL
, wxID_ANY
, "test frame");
128 wxMenu
*fileMenu
= new wxMenu
;
129 wxMenu
*helpMenu
= new wxMenu
;
130 wxMenu
*subMenu
= new wxMenu
;
131 wxMenu
*subsubMenu
= new wxMenu
;
133 size_t itemcount
= 0;
135 PopulateMenu(subsubMenu
, "Subsubmenu item ", itemcount
);
137 // Store one of its IDs for later
138 m_subsubmenuItemId
= MenuTestCase_First
+ itemcount
- 2;
140 PopulateMenu(subMenu
, "Submenu item ", itemcount
);
142 // Store one of its IDs for later
143 m_submenuItemId
= MenuTestCase_First
+ itemcount
- 2;
145 subMenu
->AppendSubMenu(subsubMenu
, "Subsubmen&u", "Test a subsubmenu");
147 PopulateMenu(fileMenu
, "Filemenu item ", itemcount
);
149 fileMenu
->Append(MenuTestCase_Foo
, "&Foo\tCtrl-F", "Test item to be found");
152 PopulateMenu(helpMenu
, "Helpmenu item ", itemcount
);
153 helpMenu
->Append(MenuTestCase_Bar
, "Bar");
154 helpMenu
->AppendSubMenu(subMenu
, "Sub&menu", "Test a submenu");
156 // +2 for "Foo" and "Bar", +2 for the 2 submenus
157 m_itemCount
= itemcount
+ 4;
159 // Use an arraystring here, to help with future tests
160 m_menuLabels
.Add("&File");
161 m_menuLabels
.Add("&Help");
163 wxMenuBar
*menuBar
= new wxMenuBar();
164 menuBar
->Append(fileMenu
, m_menuLabels
[0]);
165 menuBar
->Append(helpMenu
, m_menuLabels
[1]);
166 m_frame
->SetMenuBar(menuBar
);
169 void MenuTestCase::FindInMenubar()
171 wxMenuBar
* bar
= m_frame
->GetMenuBar();
174 CPPUNIT_ASSERT( bar
->FindMenu("File") != wxNOT_FOUND
);
175 CPPUNIT_ASSERT( bar
->FindMenu("&File") != wxNOT_FOUND
);
176 CPPUNIT_ASSERT( bar
->FindMenu("&Fail") == wxNOT_FOUND
);
178 // Find by menu name plus item name:
179 CPPUNIT_ASSERT( bar
->FindMenuItem("File", "Foo") != wxNOT_FOUND
);
180 CPPUNIT_ASSERT( bar
->FindMenuItem("&File", "&Foo") != wxNOT_FOUND
);
181 // and using the menu label
182 int index
= bar
->FindMenu("&File");
183 CPPUNIT_ASSERT( index
!= wxNOT_FOUND
);
184 wxString menulabel
= bar
->GetMenuLabel(index
);
185 CPPUNIT_ASSERT( bar
->FindMenuItem(menulabel
, "&Foo") != wxNOT_FOUND
);
187 wxString menutitle
= bar
->GetMenu(index
)->GetTitle();
188 CPPUNIT_ASSERT( bar
->FindMenuItem(menutitle
, "&Foo") != wxNOT_FOUND
);
191 for (size_t n
=0; n
< bar
->GetMenuCount(); ++n
)
193 CPPUNIT_ASSERT( bar
->GetMenu(n
) );
198 wxMenuItem
* item
= NULL
;
199 item
= bar
->FindItem(MenuTestCase_Foo
, &menu
);
200 CPPUNIT_ASSERT( item
);
201 CPPUNIT_ASSERT( menu
);
202 // Check that the correct menu was found
203 CPPUNIT_ASSERT( menu
->FindChildItem(MenuTestCase_Foo
) );
205 // Find submenu item:
206 item
= bar
->FindItem(m_submenuItemId
, &menu
);
207 CPPUNIT_ASSERT( item
);
208 CPPUNIT_ASSERT( menu
);
209 // and, for completeness, a subsubmenu one:
210 item
= bar
->FindItem(m_subsubmenuItemId
, &menu
);
211 CPPUNIT_ASSERT( item
);
212 CPPUNIT_ASSERT( menu
);
215 void MenuTestCase::FindInMenu()
217 wxMenuBar
* bar
= m_frame
->GetMenuBar();
220 wxMenu
* menuFind
= bar
->GetMenu(0);
221 CPPUNIT_ASSERT( menuFind
->FindItem("Foo") != wxNOT_FOUND
);
222 CPPUNIT_ASSERT( menuFind
->FindItem("&Foo") != wxNOT_FOUND
);
224 wxMenu
* menuHelp
= bar
->GetMenu(1);
225 CPPUNIT_ASSERT( menuHelp
->FindItem("Submenu") != wxNOT_FOUND
);
226 CPPUNIT_ASSERT( menuHelp
->FindItem("Sub&menu") != wxNOT_FOUND
);
230 for (n
=0; n
< menuHelp
->GetMenuItemCount(); ++n
)
232 CPPUNIT_ASSERT( menuHelp
->FindItemByPosition(n
) );
236 CPPUNIT_ASSERT( menuHelp
->FindItem(MenuTestCase_Bar
) );
237 CPPUNIT_ASSERT( menuHelp
->FindItem(MenuTestCase_Foo
) == NULL
);
239 for (n
=0; n
< menuHelp
->GetMenuItemCount(); ++n
)
242 wxMenuItem
* itemByPos
= menuHelp
->FindItemByPosition(n
);
243 CPPUNIT_ASSERT( itemByPos
);
244 wxMenuItem
* itemById
= menuHelp
->FindChildItem(itemByPos
->GetId(), &locatedAt
);
245 CPPUNIT_ASSERT_EQUAL( itemByPos
, itemById
);
246 CPPUNIT_ASSERT_EQUAL( locatedAt
, n
);
249 // Find submenu item:
250 for (n
=0; n
< menuHelp
->GetMenuItemCount(); ++n
)
252 wxMenuItem
* item
= menuHelp
->FindItemByPosition(n
);
253 if (item
->IsSubMenu())
256 wxMenuItem
* submenuItem
= menuHelp
->FindItem(m_submenuItemId
, &submenu
);
257 CPPUNIT_ASSERT( submenuItem
);
258 CPPUNIT_ASSERT( item
->GetSubMenu() == submenu
);
263 void MenuTestCase::EnableTop()
265 wxMenuBar
* const bar
= m_frame
->GetMenuBar();
266 CPPUNIT_ASSERT( bar
->IsEnabledTop(0) );
267 bar
->EnableTop( 0, false );
268 CPPUNIT_ASSERT( !bar
->IsEnabledTop(0) );
269 bar
->EnableTop( 0, true );
270 CPPUNIT_ASSERT( bar
->IsEnabledTop(0) );
273 void MenuTestCase::Count()
275 wxMenuBar
* bar
= m_frame
->GetMenuBar();
276 // I suppose you could call this "counting menubars" :)
277 CPPUNIT_ASSERT( bar
);
279 CPPUNIT_ASSERT_EQUAL( bar
->GetMenuCount(), 2 );
282 for (size_t n
=0; n
< bar
->GetMenuCount(); ++n
)
284 RecursivelyCountMenuItems(bar
->GetMenu(n
), count
);
286 CPPUNIT_ASSERT_EQUAL( count
, m_itemCount
);
289 void MenuTestCase::Labels()
291 wxMenuBar
* bar
= m_frame
->GetMenuBar();
292 CPPUNIT_ASSERT( bar
);
294 wxMenuItem
* itemFoo
= bar
->FindItem(MenuTestCase_Foo
, &filemenu
);
295 CPPUNIT_ASSERT( itemFoo
);
296 CPPUNIT_ASSERT( filemenu
);
298 // These return labels including mnemonics/accelerators:
301 CPPUNIT_ASSERT_EQUAL( "&File", bar
->GetMenuLabel(0) );
302 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", bar
->GetLabel(MenuTestCase_Foo
) );
305 CPPUNIT_ASSERT_EQUAL( "&File", filemenu
->GetTitle() );
306 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", filemenu
->GetLabel(MenuTestCase_Foo
) );
309 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", itemFoo
->GetItemLabel() );
311 // These return labels stripped of mnemonics/accelerators:
314 CPPUNIT_ASSERT_EQUAL( "File", bar
->GetMenuLabelText(0) );
317 CPPUNIT_ASSERT_EQUAL( "Foo", filemenu
->GetLabelText(MenuTestCase_Foo
) );
320 CPPUNIT_ASSERT_EQUAL( "Foo", itemFoo
->GetItemLabelText() );
321 CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") );
324 void MenuTestCase::RadioItems()
326 wxMenuBar
* const bar
= m_frame
->GetMenuBar();
327 wxMenu
* const menu
= new wxMenu
;
328 bar
->Append(menu
, "&Radio");
330 // Adding consecutive radio items creates a radio group.
331 menu
->AppendRadioItem(MenuTestCase_First
, "Radio 0");
332 menu
->AppendRadioItem(MenuTestCase_First
+ 1, "Radio 1");
334 // First item of a radio group is checked by default.
335 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
) );
337 // Checking the second one make the first one unchecked however.
338 menu
->Check(MenuTestCase_First
+ 1, true);
339 CPPUNIT_ASSERT( !menu
->IsChecked(MenuTestCase_First
) );
340 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
+ 1) );
342 // Adding more radio items after a separator creates another radio group...
343 menu
->AppendSeparator();
344 menu
->AppendRadioItem(MenuTestCase_First
+ 2, "Radio 2");
345 menu
->AppendRadioItem(MenuTestCase_First
+ 3, "Radio 3");
346 menu
->AppendRadioItem(MenuTestCase_First
+ 4, "Radio 4");
348 // ... which is independent from the first one.
349 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
+ 2) );
351 menu
->Check(MenuTestCase_First
+ 3, true);
352 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
+ 3) );
353 CPPUNIT_ASSERT( !menu
->IsChecked(MenuTestCase_First
+ 2) );
354 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
+ 1) );
357 // Insert an item in the middle of an existing radio group.
358 menu
->InsertRadioItem(4, MenuTestCase_First
+ 5, "Radio 5");
359 CPPUNIT_ASSERT( menu
->IsChecked(MenuTestCase_First
+ 3) );
361 menu
->Check( MenuTestCase_First
+ 5, true );
362 CPPUNIT_ASSERT( !menu
->IsChecked(MenuTestCase_First
+ 3) );
365 // Prepend a couple of items before the first group.
366 menu
->PrependRadioItem(MenuTestCase_First
+ 6, "Radio 6");
367 menu
->PrependRadioItem(MenuTestCase_First
+ 7, "Radio 7");
368 menu
->Check(MenuTestCase_First
+ 7, true);
369 CPPUNIT_ASSERT( !menu
->IsChecked(MenuTestCase_First
+ 1) );
372 // Check that the last radio group still works as expected.
373 menu
->Check(MenuTestCase_First
+ 4, true);
374 CPPUNIT_ASSERT( !menu
->IsChecked(MenuTestCase_First
+ 5) );
377 void MenuTestCase::RemoveAdd()
379 wxMenuBar
* bar
= m_frame
->GetMenuBar();
381 wxMenu
* menu0
= bar
->GetMenu(0);
382 wxMenu
* menu1
= bar
->GetMenu(1);
383 wxMenuItem
* item
= new wxMenuItem(menu0
, MenuTestCase_Foo
+ 100, "t&ext\tCtrl-E");
384 menu0
->Insert(0, item
);
385 CPPUNIT_ASSERT( menu0
->FindItemByPosition(0) == item
);
387 CPPUNIT_ASSERT( menu0
->FindItemByPosition(0) != item
);
388 menu1
->Insert(0, item
);
389 CPPUNIT_ASSERT( menu1
->FindItemByPosition(0) == item
);
391 CPPUNIT_ASSERT( menu1
->FindItemByPosition(0) != item
);
392 menu0
->Insert(0, item
);
393 CPPUNIT_ASSERT( menu0
->FindItemByPosition(0) == item
);