1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/events/evthandler.cpp
3 // Purpose: Test the new event types and wxEvtHandler-methods
7 // Copyright: (c) 2009 Peter Most
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
23 // test events and their handlers
24 // ----------------------------------------------------------------------------
26 const wxEventType LegacyEventType
= wxNewEventType();
29 wxDEFINE_EVENT( MyEventType
, MyEvent
)
31 class MyEvent
: public wxEvent
34 MyEvent() : wxEvent(0, MyEventType
) { }
36 virtual wxEvent
*Clone() const { return new MyEvent
; }
39 #define EVT_MYEVENT(func) wx__DECLARE_EVT0(MyEventType, &func)
41 class AnotherEvent
: public wxEvent
66 void GlobalOnMyEvent(MyEvent
&)
68 g_called
.function
= true;
71 void GlobalOnAnotherEvent(AnotherEvent
&);
73 void GlobalOnIdle(wxIdleEvent
&)
75 g_called
.function
= true;
80 void operator()(MyEvent
&) { g_called
.functor
= true; }
85 void operator()(wxIdleEvent
&) { g_called
.functor
= true; }
88 class MyHandler
: public wxEvtHandler
91 static void StaticOnMyEvent(MyEvent
&) { g_called
.smethod
= true; }
92 static void StaticOnAnotherEvent(AnotherEvent
&);
93 static void StaticOnIdle(wxIdleEvent
&) { g_called
.smethod
= true; }
95 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
96 void OnEvent(wxEvent
&) { g_called
.method
= true; }
97 void OnAnotherEvent(AnotherEvent
&);
98 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
101 // we can also handle events in classes not deriving from wxEvtHandler
104 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
105 void OnEvent(wxEvent
&) { g_called
.method
= true; }
106 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
109 // also test event table compilation
110 class MyClassWithEventTable
: public wxEvtHandler
113 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
114 void OnEvent(wxEvent
&) { g_called
.method
= true; }
115 void OnAnotherEvent(AnotherEvent
&);
116 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
119 DECLARE_EVENT_TABLE()
122 BEGIN_EVENT_TABLE(MyClassWithEventTable
, wxEvtHandler
)
123 EVT_IDLE(MyClassWithEventTable::OnIdle
)
125 EVT_MYEVENT(MyClassWithEventTable::OnMyEvent
)
126 EVT_MYEVENT(MyClassWithEventTable::OnEvent
)
128 // this shouldn't compile:
129 //EVT_MYEVENT(MyClassWithEventTable::OnIdle)
130 //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
133 } // anonymous namespace
136 // --------------------------------------------------------------------------
138 // --------------------------------------------------------------------------
140 class EvtHandlerTestCase
: public CppUnit::TestCase
143 EvtHandlerTestCase() {}
146 CPPUNIT_TEST_SUITE( EvtHandlerTestCase
);
147 CPPUNIT_TEST( BuiltinConnect
);
148 CPPUNIT_TEST( LegacyConnect
);
149 #if !wxEVENTS_COMPATIBILITY_2_8
150 CPPUNIT_TEST( ConnectFunction
);
151 CPPUNIT_TEST( ConnectStaticMethod
);
152 CPPUNIT_TEST( ConnectFunctor
);
153 CPPUNIT_TEST( ConnectMethod
);
154 CPPUNIT_TEST( ConnectMethodUsingBaseEvent
);
155 CPPUNIT_TEST( ConnectMethodWithSink
);
156 CPPUNIT_TEST( ConnectNonHandler
);
157 CPPUNIT_TEST( StaticConnect
);
158 CPPUNIT_TEST( InvalidConnect
);
159 #endif // !wxEVENTS_COMPATIBILITY_2_8
160 CPPUNIT_TEST_SUITE_END();
162 void BuiltinConnect();
163 void LegacyConnect();
164 #if !wxEVENTS_COMPATIBILITY_2_8
165 void ConnectFunction();
166 void ConnectStaticMethod();
167 void ConnectFunctor();
168 void ConnectMethod();
169 void ConnectMethodUsingBaseEvent();
170 void ConnectMethodWithSink();
171 void ConnectNonHandler();
172 void StaticConnect();
173 void InvalidConnect();
174 #endif // !wxEVENTS_COMPATIBILITY_2_8
177 // these member variables exceptionally don't use "m_" prefix because
178 // they're used so many times
182 DECLARE_NO_COPY_CLASS(EvtHandlerTestCase
)
185 // register in the unnamed registry so that these tests are run by default
186 CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase
);
188 // also include in it's own registry so that these tests can be run alone
189 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase
, "EvtHandlerTestCase" );
191 void EvtHandlerTestCase::BuiltinConnect()
193 handler
.Connect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
));
194 handler
.Disconnect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
));
196 handler
.Connect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
), NULL
, &handler
);
197 handler
.Disconnect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
), NULL
, &handler
);
199 // using casts like this is even uglier than using wxIdleEventHandler but
200 // it should still continue to work for compatibility
201 handler
.Connect(wxEVT_IDLE
, (wxObjectEventFunction
)(wxEventFunction
)&MyHandler::OnIdle
);
202 handler
.Disconnect(wxEVT_IDLE
, (wxObjectEventFunction
)(wxEventFunction
)&MyHandler::OnIdle
);
204 #if !wxEVENTS_COMPATIBILITY_2_8
205 handler
.Connect(wxEVT_IDLE
, GlobalOnIdle
);
206 handler
.Disconnect(wxEVT_IDLE
, GlobalOnIdle
);
209 handler
.Connect(wxEVT_IDLE
, f
);
210 handler
.Disconnect(wxEVT_IDLE
, f
);
212 handler
.Connect(wxEVT_IDLE
, &MyHandler::OnIdle
);
213 handler
.Disconnect(wxEVT_IDLE
, &MyHandler::OnIdle
);
215 handler
.Connect(wxEVT_IDLE
, &MyHandler::StaticOnIdle
);
216 handler
.Disconnect(wxEVT_IDLE
, &MyHandler::StaticOnIdle
);
217 #endif // !wxEVENTS_COMPATIBILITY_2_8
220 void EvtHandlerTestCase::LegacyConnect()
222 handler
.Connect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
223 handler
.Connect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
224 handler
.Connect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
226 handler
.Disconnect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
227 handler
.Disconnect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
228 handler
.Disconnect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
231 handler
.Connect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
232 handler
.Connect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
233 handler
.Connect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
235 handler
.Disconnect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
236 handler
.Disconnect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
237 handler
.Disconnect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
240 #if !wxEVENTS_COMPATIBILITY_2_8
242 void EvtHandlerTestCase::ConnectFunction()
245 handler
.Connect( MyEventType
, GlobalOnMyEvent
);
247 handler
.ProcessEvent(e
);
248 CPPUNIT_ASSERT( g_called
.function
);
249 handler
.Disconnect( MyEventType
, GlobalOnMyEvent
);
251 handler
.ProcessEvent(e
);
252 CPPUNIT_ASSERT( !g_called
.function
); // check that it was disconnected
254 handler
.Connect( 0, MyEventType
, GlobalOnMyEvent
);
255 handler
.Disconnect( 0, MyEventType
, GlobalOnMyEvent
);
257 handler
.Connect( 0, 0, MyEventType
, GlobalOnMyEvent
);
258 handler
.Disconnect( 0, 0, MyEventType
, GlobalOnMyEvent
);
261 void EvtHandlerTestCase::ConnectStaticMethod()
263 // static method tests (this is same as functions but still test it just in
264 // case we hit some strange compiler bugs)
265 handler
.Connect( MyEventType
, &MyHandler::StaticOnMyEvent
);
267 handler
.ProcessEvent(e
);
268 CPPUNIT_ASSERT( g_called
.smethod
);
269 handler
.Disconnect( MyEventType
, &MyHandler::StaticOnMyEvent
);
271 handler
.ProcessEvent(e
);
272 CPPUNIT_ASSERT( !g_called
.smethod
);
274 handler
.Connect( 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
275 handler
.Disconnect( 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
277 handler
.Connect( 0, 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
278 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
281 void EvtHandlerTestCase::ConnectFunctor()
283 // generalized functor tests
286 handler
.Connect( MyEventType
, functor
);
288 handler
.ProcessEvent(e
);
289 CPPUNIT_ASSERT( g_called
.functor
);
290 handler
.Disconnect( MyEventType
, functor
);
292 handler
.ProcessEvent(e
);
293 CPPUNIT_ASSERT( !g_called
.functor
);
295 handler
.Connect( 0, MyEventType
, functor
);
296 handler
.Disconnect( 0, MyEventType
, functor
);
298 handler
.Connect( 0, 0, MyEventType
, functor
);
299 handler
.Disconnect( 0, 0, MyEventType
, functor
);
302 void EvtHandlerTestCase::ConnectMethod()
304 // class method tests
305 handler
.Connect( MyEventType
, &MyHandler::OnMyEvent
);
307 handler
.ProcessEvent(e
);
308 CPPUNIT_ASSERT( g_called
.method
);
309 handler
.Disconnect( MyEventType
, &MyHandler::OnMyEvent
);
311 handler
.ProcessEvent(e
);
312 CPPUNIT_ASSERT( !g_called
.method
);
314 handler
.Connect( 0, MyEventType
, &MyHandler::OnMyEvent
);
315 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnMyEvent
);
317 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
);
318 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
);
321 void EvtHandlerTestCase::ConnectMethodUsingBaseEvent()
323 // test connecting a method taking just wxEvent and not MyEvent: this
324 // should work too if we don't need any MyEvent-specific information in the
326 handler
.Connect( MyEventType
, &MyHandler::OnEvent
);
328 handler
.ProcessEvent(e
);
329 CPPUNIT_ASSERT( g_called
.method
);
330 handler
.Disconnect( MyEventType
, &MyHandler::OnEvent
);
332 handler
.ProcessEvent(e
);
333 CPPUNIT_ASSERT( !g_called
.method
);
335 handler
.Connect( 0, MyEventType
, &MyHandler::OnEvent
);
336 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnEvent
);
338 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnEvent
);
339 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnEvent
);
342 void EvtHandlerTestCase::ConnectMethodWithSink()
344 handler
.Connect( MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
345 handler
.Connect( 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
346 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
348 handler
.Disconnect( MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
349 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
350 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
353 void EvtHandlerTestCase::ConnectNonHandler()
355 // class method tests for class not derived from wxEvtHandler
358 handler
.Connect( MyEventType
, &MySink::OnMyEvent
, NULL
, &sink
);
360 handler
.ProcessEvent(e
);
361 CPPUNIT_ASSERT( g_called
.method
);
362 handler
.Disconnect( MyEventType
, &MySink::OnMyEvent
, NULL
, &sink
);
364 handler
.ProcessEvent(e
);
365 CPPUNIT_ASSERT( !g_called
.method
);
368 void EvtHandlerTestCase::StaticConnect()
370 wxEvtHandler::Connect( &handler
, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
371 wxEvtHandler::Connect( &handler
, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
372 wxEvtHandler::Connect( &handler
, 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
374 wxEvtHandler::Disconnect( &handler
, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
375 wxEvtHandler::Disconnect( &handler
, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
376 wxEvtHandler::Disconnect( &handler
, 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
379 void EvtHandlerTestCase::InvalidConnect()
381 // these calls shouldn't compile but we unfortunately can't check this
382 // automatically, you need to uncomment them manually and test that
383 // compilation does indeed fail
384 //handler.Connect(MyEventType, GlobalOnAnotherEvent);
385 //IdleFunctor f; handler.Connect(MyEventType, f);
386 //handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent);
387 //handler.Connect(MyEventType, &MyHandler::OnAnotherEvent);
390 #endif // !wxEVENTS_COMPATIBILITY_2_8