Use normal event loop in GUI test program.

Don't create an event loop manually, let the port-specific code do it and run
it as usual in the GUI unit tests.

This has several advantages:
 - No need to manage the event loop manually in the test.
 - No need for Mac-specific code in the test itself.
 - Code being tested runs in the same context as in a normal GUI program,
   which is especially important for event-loop related tests under wxOSX as
   the main event loop is special there.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74334 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2013-07-03 00:25:46 +00:00
parent c738d187e9
commit e77dc839af

View File

@@ -296,7 +296,6 @@ public:
virtual void OnInitCmdLine(wxCmdLineParser& parser); virtual void OnInitCmdLine(wxCmdLineParser& parser);
virtual bool OnCmdLineParsed(wxCmdLineParser& parser); virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
virtual bool OnInit(); virtual bool OnInit();
virtual int OnRun();
virtual int OnExit(); virtual int OnExit();
// used by events propagation test // used by events propagation test
@@ -306,6 +305,46 @@ public:
void SetFilterEventFunc(FilterEventFunc f) { m_filterEventFunc = f; } void SetFilterEventFunc(FilterEventFunc f) { m_filterEventFunc = f; }
void SetProcessEventFunc(ProcessEventFunc f) { m_processEventFunc = f; } void SetProcessEventFunc(ProcessEventFunc f) { m_processEventFunc = f; }
// In console applications we run the tests directly from the overridden
// OnRun(), but in the GUI ones we run them when we get the first call to
// our EVT_IDLE handler to ensure that we do everything from inside the
// main event loop. This is especially important under wxOSX/Cocoa where
// the main event loop is different from the others but it's also safer to
// do it like this in the other ports as we test the GUI code in the same
// context as it's used usually, in normal programs, and it might behave
// differently without the event loop.
#if wxUSE_GUI
void OnIdle(wxIdleEvent& event)
{
if ( m_runTests )
{
m_runTests = false;
#ifdef __WXOSX__
// we need to wait until the window is activated and fully ready
// otherwise no events can be posted
wxEventLoopBase* const loop = wxEventLoop::GetActive();
if ( loop )
{
loop->DispatchTimeout(1000);
loop->Yield();
}
#endif // __WXOSX__
m_exitcode = RunTests();
ExitMainLoop();
}
event.Skip();
}
#else // !wxUSE_GUI
virtual int OnRun()
{
m_exitcode = RunTests();
return m_exitcode;
}
#endif // wxUSE_GUI/!wxUSE_GUI
private: private:
void List(Test *test, const string& parent = "") const; void List(Test *test, const string& parent = "") const;
@@ -318,6 +357,11 @@ private:
runner.addTest(test); runner.addTest(test);
} }
int RunTests();
// flag telling us whether we should run tests from our EVT_IDLE handler
bool m_runTests;
// command lines options/parameters // command lines options/parameters
bool m_list; bool m_list;
bool m_longlist; bool m_longlist;
@@ -326,12 +370,12 @@ private:
wxArrayString m_registries; wxArrayString m_registries;
wxLocale *m_locale; wxLocale *m_locale;
// event loop for GUI tests
wxEventLoop* m_eventloop;
// event handling hooks // event handling hooks
FilterEventFunc m_filterEventFunc; FilterEventFunc m_filterEventFunc;
ProcessEventFunc m_processEventFunc; ProcessEventFunc m_processEventFunc;
// the program exit code
int m_exitcode;
}; };
IMPLEMENT_APP_NO_MAIN(TestApp) IMPLEMENT_APP_NO_MAIN(TestApp)
@@ -431,7 +475,7 @@ extern bool IsAutomaticTest()
return s_isAutomatic == 1; return s_isAutomatic == 1;
} }
// helper of OnRun(): gets the test with the given name, returning NULL (and // helper of RunTests(): gets the test with the given name, returning NULL (and
// not an empty test suite) if there is no such test // not an empty test suite) if there is no such test
static Test *GetTestByName(const wxString& name) static Test *GetTestByName(const wxString& name)
{ {
@@ -460,11 +504,14 @@ TestApp::TestApp()
: m_list(false), : m_list(false),
m_longlist(false) m_longlist(false)
{ {
m_runTests = true;
m_filterEventFunc = NULL; m_filterEventFunc = NULL;
m_processEventFunc = NULL; m_processEventFunc = NULL;
m_locale = NULL; m_locale = NULL;
m_eventloop = NULL;
m_exitcode = EXIT_SUCCESS;
} }
// Init // Init
@@ -495,16 +542,7 @@ bool TestApp::OnInit()
wxTestableFrame* frame = new wxTestableFrame(); wxTestableFrame* frame = new wxTestableFrame();
frame->Show(); frame->Show();
m_eventloop = new wxEventLoop; Connect(wxEVT_IDLE, wxIdleEventHandler(TestApp::OnIdle));
wxEventLoop::SetActive(m_eventloop);
#ifdef __WXOSX__
// we need to wait until the window is activated and fully ready
// otherwise no events can be posted
m_eventloop->DispatchTimeout(1000);
m_eventloop->Yield();
#endif
#endif // wxUSE_GUI #endif // wxUSE_GUI
return true; return true;
@@ -595,15 +633,8 @@ bool TestApp::ProcessEvent(wxEvent& event)
// Run // Run
// //
int TestApp::OnRun() int TestApp::RunTests()
{ {
#if wxUSE_GUI
#ifdef __WXOSX__
// make sure there's always an autorelease pool ready
wxMacAutoreleasePool autoreleasepool;
#endif
#endif
#if wxUSE_LOG #if wxUSE_LOG
// Switch off logging unless --verbose // Switch off logging unless --verbose
bool verbose = wxLog::GetVerbose(); bool verbose = wxLog::GetVerbose();
@@ -683,11 +714,9 @@ int TestApp::OnExit()
#if wxUSE_GUI #if wxUSE_GUI
delete GetTopWindow(); delete GetTopWindow();
wxEventLoop::SetActive(NULL);
delete m_eventloop;
#endif // wxUSE_GUI #endif // wxUSE_GUI
return 0; return m_exitcode;
} }
// List the tests // List the tests