| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- ///////////////////////////////////////////////////////////////////////////////
- // Name: tests/menu/menu.cpp
- // Purpose: wxMenu unit test
- // Author: wxWidgets team
- // Created: 2010-11-10
- // Copyright: (c) 2010 wxWidgets team
- ///////////////////////////////////////////////////////////////////////////////
- // ----------------------------------------------------------------------------
- // headers
- // ----------------------------------------------------------------------------
- #include "testprec.h"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- #ifndef WX_PRECOMP
- #include "wx/wx.h"
- #endif // WX_PRECOMP
- #include "wx/menu.h"
- #include "wx/uiaction.h"
- #include <stdarg.h>
- // ----------------------------------------------------------------------------
- // helper
- // ----------------------------------------------------------------------------
- namespace
- {
- enum
- {
- MenuTestCase_Foo = 10000,
- MenuTestCase_Bar,
- MenuTestCase_First
- };
- void PopulateMenu(wxMenu* menu, const wxString& name, size_t& itemcount)
- {
- // Start at item 1 to make it human-readable ;)
- for (int n=1; n<6; ++n, ++itemcount)
- {
- wxString label = name; label << n;
- menu->Append(MenuTestCase_First + itemcount, label, label + " help string");
- }
- }
- void RecursivelyCountMenuItems(const wxMenu* menu, size_t& count)
- {
- CPPUNIT_ASSERT( menu );
- count += menu->GetMenuItemCount();
- for (size_t n=0; n < menu->GetMenuItemCount(); ++n)
- {
- wxMenuItem* item = menu->FindItemByPosition(n);
- if (item->IsSubMenu())
- {
- RecursivelyCountMenuItems(item->GetSubMenu(), count);
- }
- }
- }
- } // anon namespace
- // ----------------------------------------------------------------------------
- // test class
- // ----------------------------------------------------------------------------
- class MenuTestCase : public CppUnit::TestCase
- {
- public:
- MenuTestCase() {}
- virtual void setUp() { CreateFrame(); }
- virtual void tearDown() { m_frame->Destroy(); }
- private:
- CPPUNIT_TEST_SUITE( MenuTestCase );
- CPPUNIT_TEST( FindInMenubar );
- CPPUNIT_TEST( FindInMenu );
- CPPUNIT_TEST( EnableTop );
- CPPUNIT_TEST( Count );
- CPPUNIT_TEST( Labels );
- CPPUNIT_TEST( RadioItems );
- CPPUNIT_TEST( RemoveAdd );
- WXUISIM_TEST( Events );
- CPPUNIT_TEST_SUITE_END();
- void CreateFrame();
- void FindInMenubar();
- void FindInMenu();
- void EnableTop();
- void Count();
- void Labels();
- void RadioItems();
- void RemoveAdd();
- void Events();
- wxFrame* m_frame;
- // Holds the number of menuitems contained in all the menus
- size_t m_itemCount;
- // Store here the id of a known submenu item, to be searched for later
- int m_submenuItemId;
- // and a sub-submenu item
- int m_subsubmenuItemId;
- wxArrayString m_menuLabels;
- // The menu containing the item with MenuTestCase_Bar id.
- wxMenu* m_menuWithBar;
- DECLARE_NO_COPY_CLASS(MenuTestCase)
- };
- // register in the unnamed registry so that these tests are run by default
- CPPUNIT_TEST_SUITE_REGISTRATION( MenuTestCase );
- // also include in its own registry so that these tests can be run alone
- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MenuTestCase, "MenuTestCase" );
- void MenuTestCase::CreateFrame()
- {
- m_frame = new wxFrame(NULL, wxID_ANY, "test frame");
- wxMenu *fileMenu = new wxMenu;
- wxMenu *helpMenu = new wxMenu;
- wxMenu *subMenu = new wxMenu;
- wxMenu *subsubMenu = new wxMenu;
- size_t itemcount = 0;
- PopulateMenu(subsubMenu, "Subsubmenu item ", itemcount);
- // Store one of its IDs for later
- m_subsubmenuItemId = MenuTestCase_First + itemcount - 2;
- PopulateMenu(subMenu, "Submenu item ", itemcount);
- // Store one of its IDs for later
- m_submenuItemId = MenuTestCase_First + itemcount - 2;
- subMenu->AppendSubMenu(subsubMenu, "Subsubmen&u", "Test a subsubmenu");
- // Check GetTitle() returns the correct string _before_ appending to the bar
- fileMenu->SetTitle("&Foo\tCtrl-F");
- CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", fileMenu->GetTitle() );
- PopulateMenu(fileMenu, "Filemenu item ", itemcount);
- fileMenu->Append(MenuTestCase_Foo, "&Foo\tCtrl-F", "Test item to be found");
- PopulateMenu(helpMenu, "Helpmenu item ", itemcount);
- helpMenu->Append(MenuTestCase_Bar, "Bar\tF1");
- m_menuWithBar = helpMenu;
- helpMenu->AppendSubMenu(subMenu, "Sub&menu", "Test a submenu");
- // +2 for "Foo" and "Bar", +2 for the 2 submenus
- m_itemCount = itemcount + 4;
- // Use an arraystring here, to help with future tests
- m_menuLabels.Add("&File");
- m_menuLabels.Add("&Help");
- wxMenuBar *menuBar = new wxMenuBar();
- menuBar->Append(fileMenu, m_menuLabels[0]);
- menuBar->Append(helpMenu, m_menuLabels[1]);
- m_frame->SetMenuBar(menuBar);
- }
- void MenuTestCase::FindInMenubar()
- {
- wxMenuBar* bar = m_frame->GetMenuBar();
- // Find by name:
- CPPUNIT_ASSERT( bar->FindMenu("File") != wxNOT_FOUND );
- CPPUNIT_ASSERT( bar->FindMenu("&File") != wxNOT_FOUND );
- CPPUNIT_ASSERT( bar->FindMenu("&Fail") == wxNOT_FOUND );
- // Find by menu name plus item name:
- CPPUNIT_ASSERT( bar->FindMenuItem("File", "Foo") != wxNOT_FOUND );
- CPPUNIT_ASSERT( bar->FindMenuItem("&File", "&Foo") != wxNOT_FOUND );
- // and using the menu label
- int index = bar->FindMenu("&File");
- CPPUNIT_ASSERT( index != wxNOT_FOUND );
- wxString menulabel = bar->GetMenuLabel(index);
- CPPUNIT_ASSERT( bar->FindMenuItem(menulabel, "&Foo") != wxNOT_FOUND );
- // and title
- wxString menutitle = bar->GetMenu(index)->GetTitle();
- CPPUNIT_ASSERT( bar->FindMenuItem(menutitle, "&Foo") != wxNOT_FOUND );
- // Find by position:
- for (size_t n=0; n < bar->GetMenuCount(); ++n)
- {
- CPPUNIT_ASSERT( bar->GetMenu(n) );
- }
- // Find by id:
- wxMenu* menu = NULL;
- wxMenuItem* item = NULL;
- item = bar->FindItem(MenuTestCase_Foo, &menu);
- CPPUNIT_ASSERT( item );
- CPPUNIT_ASSERT( menu );
- // Check that the correct menu was found
- CPPUNIT_ASSERT( menu->FindChildItem(MenuTestCase_Foo) );
- // Find submenu item:
- item = bar->FindItem(m_submenuItemId, &menu);
- CPPUNIT_ASSERT( item );
- CPPUNIT_ASSERT( menu );
- // and, for completeness, a subsubmenu one:
- item = bar->FindItem(m_subsubmenuItemId, &menu);
- CPPUNIT_ASSERT( item );
- CPPUNIT_ASSERT( menu );
- }
- void MenuTestCase::FindInMenu()
- {
- wxMenuBar* bar = m_frame->GetMenuBar();
- // Find by name:
- wxMenu* menuFind = bar->GetMenu(0);
- CPPUNIT_ASSERT( menuFind->FindItem("Foo") != wxNOT_FOUND );
- CPPUNIT_ASSERT( menuFind->FindItem("&Foo") != wxNOT_FOUND );
- // and for submenus
- wxMenu* menuHelp = bar->GetMenu(1);
- CPPUNIT_ASSERT( menuHelp->FindItem("Submenu") != wxNOT_FOUND );
- CPPUNIT_ASSERT( menuHelp->FindItem("Sub&menu") != wxNOT_FOUND );
- // Find by position:
- size_t n;
- for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
- {
- CPPUNIT_ASSERT( menuHelp->FindItemByPosition(n) );
- }
- // Find by id:
- CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Bar) );
- CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Foo) == NULL );
- for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
- {
- size_t locatedAt;
- wxMenuItem* itemByPos = menuHelp->FindItemByPosition(n);
- CPPUNIT_ASSERT( itemByPos );
- wxMenuItem* itemById = menuHelp->FindChildItem(itemByPos->GetId(), &locatedAt);
- CPPUNIT_ASSERT_EQUAL( itemByPos, itemById );
- CPPUNIT_ASSERT_EQUAL( locatedAt, n );
- }
- // Find submenu item:
- for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
- {
- wxMenuItem* item = menuHelp->FindItemByPosition(n);
- if (item->IsSubMenu())
- {
- wxMenu* submenu;
- wxMenuItem* submenuItem = menuHelp->FindItem(m_submenuItemId, &submenu);
- CPPUNIT_ASSERT( submenuItem );
- CPPUNIT_ASSERT( item->GetSubMenu() == submenu );
- }
- }
- }
- void MenuTestCase::EnableTop()
- {
- wxMenuBar* const bar = m_frame->GetMenuBar();
- CPPUNIT_ASSERT( bar->IsEnabledTop(0) );
- bar->EnableTop( 0, false );
- CPPUNIT_ASSERT( !bar->IsEnabledTop(0) );
- bar->EnableTop( 0, true );
- CPPUNIT_ASSERT( bar->IsEnabledTop(0) );
- }
- void MenuTestCase::Count()
- {
- wxMenuBar* bar = m_frame->GetMenuBar();
- // I suppose you could call this "counting menubars" :)
- CPPUNIT_ASSERT( bar );
- CPPUNIT_ASSERT_EQUAL( bar->GetMenuCount(), 2 );
- size_t count = 0;
- for (size_t n=0; n < bar->GetMenuCount(); ++n)
- {
- RecursivelyCountMenuItems(bar->GetMenu(n), count);
- }
- CPPUNIT_ASSERT_EQUAL( count, m_itemCount );
- }
- void MenuTestCase::Labels()
- {
- wxMenuBar* bar = m_frame->GetMenuBar();
- CPPUNIT_ASSERT( bar );
- wxMenu* filemenu;
- wxMenuItem* itemFoo = bar->FindItem(MenuTestCase_Foo, &filemenu);
- CPPUNIT_ASSERT( itemFoo );
- CPPUNIT_ASSERT( filemenu );
- // These return labels including mnemonics/accelerators:
- // wxMenuBar
- CPPUNIT_ASSERT_EQUAL( "&File", bar->GetMenuLabel(0) );
- CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", bar->GetLabel(MenuTestCase_Foo) );
- // wxMenu
- CPPUNIT_ASSERT_EQUAL( "&File", filemenu->GetTitle() );
- CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", filemenu->GetLabel(MenuTestCase_Foo) );
- // wxMenuItem
- CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", itemFoo->GetItemLabel() );
- // These return labels stripped of mnemonics/accelerators:
- // wxMenuBar
- CPPUNIT_ASSERT_EQUAL( "File", bar->GetMenuLabelText(0) );
- // wxMenu
- CPPUNIT_ASSERT_EQUAL( "Foo", filemenu->GetLabelText(MenuTestCase_Foo) );
- // wxMenuItem
- CPPUNIT_ASSERT_EQUAL( "Foo", itemFoo->GetItemLabelText() );
- CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") );
- }
- void MenuTestCase::RadioItems()
- {
- wxMenuBar * const bar = m_frame->GetMenuBar();
- wxMenu * const menu = new wxMenu;
- bar->Append(menu, "&Radio");
- // Adding consecutive radio items creates a radio group.
- menu->AppendRadioItem(MenuTestCase_First, "Radio 0");
- menu->AppendRadioItem(MenuTestCase_First + 1, "Radio 1");
- // First item of a radio group is checked by default.
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First) );
- // Checking the second one make the first one unchecked however.
- menu->Check(MenuTestCase_First + 1, true);
- CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First) );
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
- // Adding more radio items after a separator creates another radio group...
- menu->AppendSeparator();
- menu->AppendRadioItem(MenuTestCase_First + 2, "Radio 2");
- menu->AppendRadioItem(MenuTestCase_First + 3, "Radio 3");
- menu->AppendRadioItem(MenuTestCase_First + 4, "Radio 4");
- // ... which is independent from the first one.
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 2) );
- menu->Check(MenuTestCase_First + 3, true);
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
- CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 2) );
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
- // Insert an item in the middle of an existing radio group.
- menu->InsertRadioItem(4, MenuTestCase_First + 5, "Radio 5");
- CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
- menu->Check( MenuTestCase_First + 5, true );
- CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 3) );
- // Prepend a couple of items before the first group.
- menu->PrependRadioItem(MenuTestCase_First + 6, "Radio 6");
- menu->PrependRadioItem(MenuTestCase_First + 7, "Radio 7");
- menu->Check(MenuTestCase_First + 7, true);
- CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 1) );
- // Check that the last radio group still works as expected.
- menu->Check(MenuTestCase_First + 4, true);
- CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 5) );
- }
- void MenuTestCase::RemoveAdd()
- {
- wxMenuBar* bar = m_frame->GetMenuBar();
- wxMenu* menu0 = bar->GetMenu(0);
- wxMenu* menu1 = bar->GetMenu(1);
- wxMenuItem* item = new wxMenuItem(menu0, MenuTestCase_Foo + 100, "t&ext\tCtrl-E");
- menu0->Insert(0, item);
- CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
- menu0->Remove(item);
- CPPUNIT_ASSERT( menu0->FindItemByPosition(0) != item );
- menu1->Insert(0, item);
- CPPUNIT_ASSERT( menu1->FindItemByPosition(0) == item );
- menu1->Remove(item);
- CPPUNIT_ASSERT( menu1->FindItemByPosition(0) != item );
- menu0->Insert(0, item);
- CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
- menu0->Delete(item);
- }
- void MenuTestCase::Events()
- {
- #ifdef __WXGTK__
- // FIXME: For some reason, we sporadically fail to get the event in
- // buildbot slave builds even though the test always passes locally.
- // There is undoubtedly something wrong here but without being able
- // to debug it, I have no idea what is it, so let's just disable
- // this test when running under buildbot to let the entire test
- // suite pass.
- if ( IsAutomaticTest() )
- return;
- #endif // __WXGTK__
- #if wxUSE_UIACTIONSIMULATOR
- class MenuEventHandler : public wxEvtHandler
- {
- public:
- MenuEventHandler(wxWindow* win)
- : m_win(win)
- {
- m_win->Connect(wxEVT_MENU,
- wxCommandEventHandler(MenuEventHandler::OnMenu),
- NULL,
- this);
- m_gotEvent = false;
- m_event = NULL;
- }
- virtual ~MenuEventHandler()
- {
- m_win->Disconnect(wxEVT_MENU,
- wxCommandEventHandler(MenuEventHandler::OnMenu),
- NULL,
- this);
- delete m_event;
- }
- const wxCommandEvent& GetEvent()
- {
- CPPUNIT_ASSERT( m_gotEvent );
- m_gotEvent = false;
- return *m_event;
- }
- private:
- void OnMenu(wxCommandEvent& event)
- {
- CPPUNIT_ASSERT( !m_gotEvent );
- delete m_event;
- m_event = static_cast<wxCommandEvent*>(event.Clone());
- m_gotEvent = true;
- }
- wxWindow* const m_win;
- wxCommandEvent* m_event;
- bool m_gotEvent;
- };
- MenuEventHandler handler(m_frame);
- // Invoke the accelerator.
- m_frame->Show();
- m_frame->SetFocus();
- wxYield();
- wxUIActionSimulator sim;
- sim.KeyDown(WXK_F1);
- sim.KeyUp(WXK_F1);
- wxYield();
- const wxCommandEvent& ev = handler.GetEvent();
- CPPUNIT_ASSERT_EQUAL( static_cast<int>(MenuTestCase_Bar), ev.GetId() );
- wxObject* const src = ev.GetEventObject();
- CPPUNIT_ASSERT( src );
- CPPUNIT_ASSERT_EQUAL( "wxMenu",
- wxString(src->GetClassInfo()->GetClassName()) );
- CPPUNIT_ASSERT_EQUAL( static_cast<wxObject*>(m_menuWithBar),
- src );
- #endif // wxUSE_UIACTIONSIMULATOR
- }
|