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 typedef void (wxEvtHandler::*MyEventFunction
)(MyEvent
&);
40 #define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
41 #define EVT_MYEVENT(func) \
42 wx__DECLARE_EVT0(MyEventType, MyEventHandler(func))
44 class AnotherEvent
: public wxEvent
69 void GlobalOnMyEvent(MyEvent
&)
71 g_called
.function
= true;
74 void GlobalOnAnotherEvent(AnotherEvent
&);
76 void GlobalOnIdle(wxIdleEvent
&)
78 g_called
.function
= true;
83 void operator()(MyEvent
&) { g_called
.functor
= true; }
88 void operator()(wxIdleEvent
&) { g_called
.functor
= true; }
91 class MyHandler
: public wxEvtHandler
94 static void StaticOnMyEvent(MyEvent
&) { g_called
.smethod
= true; }
95 static void StaticOnAnotherEvent(AnotherEvent
&);
96 static void StaticOnIdle(wxIdleEvent
&) { g_called
.smethod
= true; }
98 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
99 void OnEvent(wxEvent
&) { g_called
.method
= true; }
100 void OnAnotherEvent(AnotherEvent
&);
101 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
104 // we can also handle events in classes not deriving from wxEvtHandler
107 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
108 void OnEvent(wxEvent
&) { g_called
.method
= true; }
109 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
112 // also test event table compilation
113 class MyClassWithEventTable
: public wxEvtHandler
116 void OnMyEvent(MyEvent
&) { g_called
.method
= true; }
117 void OnEvent(wxEvent
&) { g_called
.method
= true; }
118 void OnAnotherEvent(AnotherEvent
&);
119 void OnIdle(wxIdleEvent
&) { g_called
.method
= true; }
122 DECLARE_EVENT_TABLE()
125 BEGIN_EVENT_TABLE(MyClassWithEventTable
, wxEvtHandler
)
126 EVT_IDLE(MyClassWithEventTable::OnIdle
)
128 EVT_MYEVENT(MyClassWithEventTable::OnMyEvent
)
129 #if !wxEVENTS_COMPATIBILITY_2_8
130 EVT_MYEVENT(MyClassWithEventTable::OnEvent
)
133 // this shouldn't compile:
134 //EVT_MYEVENT(MyClassWithEventTable::OnIdle)
135 //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
138 } // anonymous namespace
141 // --------------------------------------------------------------------------
143 // --------------------------------------------------------------------------
145 class EvtHandlerTestCase
: public CppUnit::TestCase
148 EvtHandlerTestCase() {}
151 CPPUNIT_TEST_SUITE( EvtHandlerTestCase
);
152 CPPUNIT_TEST( BuiltinConnect
);
153 CPPUNIT_TEST( LegacyConnect
);
154 #if !wxEVENTS_COMPATIBILITY_2_8
155 CPPUNIT_TEST( ConnectFunction
);
156 CPPUNIT_TEST( ConnectStaticMethod
);
157 CPPUNIT_TEST( ConnectFunctor
);
158 CPPUNIT_TEST( ConnectMethod
);
159 CPPUNIT_TEST( ConnectMethodUsingBaseEvent
);
160 CPPUNIT_TEST( ConnectMethodWithSink
);
161 CPPUNIT_TEST( ConnectNonHandler
);
162 CPPUNIT_TEST( StaticConnect
);
163 CPPUNIT_TEST( InvalidConnect
);
164 #endif // !wxEVENTS_COMPATIBILITY_2_8
165 CPPUNIT_TEST_SUITE_END();
167 void BuiltinConnect();
168 void LegacyConnect();
169 #if !wxEVENTS_COMPATIBILITY_2_8
170 void ConnectFunction();
171 void ConnectStaticMethod();
172 void ConnectFunctor();
173 void ConnectMethod();
174 void ConnectMethodUsingBaseEvent();
175 void ConnectMethodWithSink();
176 void ConnectNonHandler();
177 void StaticConnect();
178 void InvalidConnect();
179 #endif // !wxEVENTS_COMPATIBILITY_2_8
182 // these member variables exceptionally don't use "m_" prefix because
183 // they're used so many times
187 DECLARE_NO_COPY_CLASS(EvtHandlerTestCase
)
190 // register in the unnamed registry so that these tests are run by default
191 CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase
);
193 // also include in it's own registry so that these tests can be run alone
194 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase
, "EvtHandlerTestCase" );
196 void EvtHandlerTestCase::BuiltinConnect()
198 handler
.Connect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
));
199 handler
.Disconnect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
));
201 handler
.Connect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
), NULL
, &handler
);
202 handler
.Disconnect(wxEVT_IDLE
, wxIdleEventHandler(MyHandler::OnIdle
), NULL
, &handler
);
204 // using casts like this is even uglier than using wxIdleEventHandler but
205 // it should still continue to work for compatibility
206 handler
.Connect(wxEVT_IDLE
, (wxObjectEventFunction
)(wxEventFunction
)&MyHandler::OnIdle
);
207 handler
.Disconnect(wxEVT_IDLE
, (wxObjectEventFunction
)(wxEventFunction
)&MyHandler::OnIdle
);
209 #if !wxEVENTS_COMPATIBILITY_2_8
210 handler
.Connect(wxEVT_IDLE
, GlobalOnIdle
);
211 handler
.Disconnect(wxEVT_IDLE
, GlobalOnIdle
);
214 handler
.Connect(wxEVT_IDLE
, f
);
215 handler
.Disconnect(wxEVT_IDLE
, f
);
217 handler
.Connect(wxEVT_IDLE
, &MyHandler::OnIdle
);
218 handler
.Disconnect(wxEVT_IDLE
, &MyHandler::OnIdle
);
220 handler
.Connect(wxEVT_IDLE
, &MyHandler::StaticOnIdle
);
221 handler
.Disconnect(wxEVT_IDLE
, &MyHandler::StaticOnIdle
);
222 #endif // !wxEVENTS_COMPATIBILITY_2_8
225 void EvtHandlerTestCase::LegacyConnect()
227 handler
.Connect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
228 handler
.Connect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
229 handler
.Connect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
231 handler
.Disconnect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
232 handler
.Disconnect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
233 handler
.Disconnect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
);
236 handler
.Connect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
237 handler
.Connect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
238 handler
.Connect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
240 handler
.Disconnect( LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
241 handler
.Disconnect( 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
242 handler
.Disconnect( 0, 0, LegacyEventType
, (wxObjectEventFunction
)&MyHandler::OnEvent
, NULL
, &handler
);
245 #if !wxEVENTS_COMPATIBILITY_2_8
247 void EvtHandlerTestCase::ConnectFunction()
250 handler
.Connect( MyEventType
, GlobalOnMyEvent
);
252 handler
.ProcessEvent(e
);
253 CPPUNIT_ASSERT( g_called
.function
);
254 handler
.Disconnect( MyEventType
, GlobalOnMyEvent
);
256 handler
.ProcessEvent(e
);
257 CPPUNIT_ASSERT( !g_called
.function
); // check that it was disconnected
259 handler
.Connect( 0, MyEventType
, GlobalOnMyEvent
);
260 handler
.Disconnect( 0, MyEventType
, GlobalOnMyEvent
);
262 handler
.Connect( 0, 0, MyEventType
, GlobalOnMyEvent
);
263 handler
.Disconnect( 0, 0, MyEventType
, GlobalOnMyEvent
);
266 void EvtHandlerTestCase::ConnectStaticMethod()
268 // static method tests (this is same as functions but still test it just in
269 // case we hit some strange compiler bugs)
270 handler
.Connect( MyEventType
, &MyHandler::StaticOnMyEvent
);
272 handler
.ProcessEvent(e
);
273 CPPUNIT_ASSERT( g_called
.smethod
);
274 handler
.Disconnect( MyEventType
, &MyHandler::StaticOnMyEvent
);
276 handler
.ProcessEvent(e
);
277 CPPUNIT_ASSERT( !g_called
.smethod
);
279 handler
.Connect( 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
280 handler
.Disconnect( 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
282 handler
.Connect( 0, 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
283 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::StaticOnMyEvent
);
286 void EvtHandlerTestCase::ConnectFunctor()
288 // generalized functor tests
291 handler
.Connect( MyEventType
, functor
);
293 handler
.ProcessEvent(e
);
294 CPPUNIT_ASSERT( g_called
.functor
);
295 handler
.Disconnect( MyEventType
, functor
);
297 handler
.ProcessEvent(e
);
298 CPPUNIT_ASSERT( !g_called
.functor
);
300 handler
.Connect( 0, MyEventType
, functor
);
301 handler
.Disconnect( 0, MyEventType
, functor
);
303 handler
.Connect( 0, 0, MyEventType
, functor
);
304 handler
.Disconnect( 0, 0, MyEventType
, functor
);
307 void EvtHandlerTestCase::ConnectMethod()
309 // class method tests
310 handler
.Connect( MyEventType
, &MyHandler::OnMyEvent
);
312 handler
.ProcessEvent(e
);
313 CPPUNIT_ASSERT( g_called
.method
);
314 handler
.Disconnect( MyEventType
, &MyHandler::OnMyEvent
);
316 handler
.ProcessEvent(e
);
317 CPPUNIT_ASSERT( !g_called
.method
);
319 handler
.Connect( 0, MyEventType
, &MyHandler::OnMyEvent
);
320 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnMyEvent
);
322 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
);
323 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
);
326 void EvtHandlerTestCase::ConnectMethodUsingBaseEvent()
328 // test connecting a method taking just wxEvent and not MyEvent: this
329 // should work too if we don't need any MyEvent-specific information in the
331 handler
.Connect( MyEventType
, &MyHandler::OnEvent
);
333 handler
.ProcessEvent(e
);
334 CPPUNIT_ASSERT( g_called
.method
);
335 handler
.Disconnect( MyEventType
, &MyHandler::OnEvent
);
337 handler
.ProcessEvent(e
);
338 CPPUNIT_ASSERT( !g_called
.method
);
340 handler
.Connect( 0, MyEventType
, &MyHandler::OnEvent
);
341 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnEvent
);
343 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnEvent
);
344 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnEvent
);
347 void EvtHandlerTestCase::ConnectMethodWithSink()
349 handler
.Connect( MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
350 handler
.Connect( 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
351 handler
.Connect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
353 handler
.Disconnect( MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
354 handler
.Disconnect( 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
355 handler
.Disconnect( 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
358 void EvtHandlerTestCase::ConnectNonHandler()
360 // class method tests for class not derived from wxEvtHandler
363 handler
.Connect( MyEventType
, &MySink::OnMyEvent
, NULL
, &sink
);
365 handler
.ProcessEvent(e
);
366 CPPUNIT_ASSERT( g_called
.method
);
367 handler
.Disconnect( MyEventType
, &MySink::OnMyEvent
, NULL
, &sink
);
369 handler
.ProcessEvent(e
);
370 CPPUNIT_ASSERT( !g_called
.method
);
373 void EvtHandlerTestCase::StaticConnect()
375 wxEvtHandler::Connect( &handler
, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
376 wxEvtHandler::Connect( &handler
, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
377 wxEvtHandler::Connect( &handler
, 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
379 wxEvtHandler::Disconnect( &handler
, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
380 wxEvtHandler::Disconnect( &handler
, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
381 wxEvtHandler::Disconnect( &handler
, 0, 0, MyEventType
, &MyHandler::OnMyEvent
, NULL
, &handler
);
384 void EvtHandlerTestCase::InvalidConnect()
386 // these calls shouldn't compile but we unfortunately can't check this
387 // automatically, you need to uncomment them manually and test that
388 // compilation does indeed fail
389 //handler.Connect(MyEventType, GlobalOnAnotherEvent);
390 //IdleFunctor f; handler.Connect(MyEventType, f);
391 //handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent);
392 //handler.Connect(MyEventType, &MyHandler::OnAnotherEvent);
395 #endif // !wxEVENTS_COMPATIBILITY_2_8