draghino explicitly
[wxWidgets.git] / tests / weakref / evtconnection.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/weakref/evtconnection.cpp
3 // Purpose: wxWeakRef<T> unit test
4 // Author: Arne Steinarson
5 // Created: 2008-01-10
6 // RCS-ID: $Id$
7 // Copyright: (c) 2007 Arne Steinarson
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifndef WX_PRECOMP
21 #include "wx/wx.h"
22 #endif // WX_PRECOMP
23
24 #include "wx/event.h"
25 #include "wx/weakref.h"
26
27 static int gs_value = 0; // Increased by 1 by first object and 0x10000 by 2nd object
28
29 static wxObject *gs_psrc1;
30 static wxObject *gs_psrc2;
31
32 // We need some event types
33 const wxEventType wxEVT_TEST = wxNewEventType(),
34 wxEVT_TEST1 = wxNewEventType(),
35 wxEVT_TEST2 = wxNewEventType();
36
37 class wxTestEvent : public wxEvent
38 {
39 public:
40 wxTestEvent(wxEventType type = wxEVT_TEST) : wxEvent(0, type) { }
41 virtual wxEvent *Clone() const { return new wxTestEvent(GetEventType()); }
42 };
43
44 class wxTestSink : public wxEvtHandler
45 {
46 public:
47 void OnTestEvent(wxEvent& evt)
48 {
49 if ( evt.GetEventObject() == gs_psrc1 )
50 gs_value += 1;
51 else if ( evt.GetEventObject() == gs_psrc2 )
52 gs_value += 0x10000;
53 }
54
55 void OnTestEvent1(wxEvent& )
56 {
57 gs_value += 0x00100;
58 }
59
60 void OnTestEvent2(wxEvent&)
61 {
62 gs_value += 0x01000000;
63 }
64 };
65
66
67
68 // --------------------------------------------------------------------------
69 // test class
70 // --------------------------------------------------------------------------
71
72 class EvtConnectionTestCase : public CppUnit::TestCase
73 {
74 public:
75 EvtConnectionTestCase() {}
76
77 private:
78 CPPUNIT_TEST_SUITE( EvtConnectionTestCase );
79 CPPUNIT_TEST( SinkTest );
80 CPPUNIT_TEST( SourceDestroyTest );
81 CPPUNIT_TEST( MultiConnectionTest );
82 CPPUNIT_TEST_SUITE_END();
83
84 void SinkTest();
85 void SourceDestroyTest();
86 void MultiConnectionTest();
87
88 DECLARE_NO_COPY_CLASS(EvtConnectionTestCase)
89 };
90
91 // register in the unnamed registry so that these tests are run by default
92 CPPUNIT_TEST_SUITE_REGISTRATION( EvtConnectionTestCase );
93
94 // also include in its own registry so that these tests can be run alone
95 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtConnectionTestCase, "EvtConnectionTestCase" );
96
97
98 // Helpers
99 void DoConnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
100 eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
101 NULL, &ts);
102 eh2.Connect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
103 NULL, &ts);
104 }
105
106 void DoDisconnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
107 eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
108 NULL, &ts);
109 eh2.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
110 NULL, &ts);
111 }
112
113
114 void EvtConnectionTestCase::SinkTest()
115 {
116 // Let the sink be destroyed before the sources
117
118 // An event used below
119 wxTestEvent evt;
120
121 // Connect two event handlers to one sink
122 wxEvtHandler eh1, eh2;
123 gs_psrc1 = &eh1;
124 gs_psrc2 = &eh2;
125
126 {
127 wxTestSink ts;
128 CPPUNIT_ASSERT( !ts.GetFirst() );
129 DoConnect(eh1, eh2, ts);
130
131 DoDisconnect(eh1, eh2, ts);
132
133 DoConnect(eh1, eh2, ts);
134
135 // Fire events
136 evt.SetEventObject(&eh1);
137 eh1.ProcessEvent(evt);
138 evt.SetEventObject(&eh2);
139 eh2.ProcessEvent(evt);
140
141 // Make sure they were processed correctly
142 CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
143 }
144
145 // Fire events again, should be no sink connected now
146 gs_value = 0;
147 evt.SetEventObject(&eh1);
148 eh1.ProcessEvent( evt );
149 evt.SetEventObject(&eh2);
150 eh2.ProcessEvent( evt );
151
152 // Make sure no processing happened
153 CPPUNIT_ASSERT_EQUAL( 0, gs_value );
154 }
155
156 void EvtConnectionTestCase::SourceDestroyTest()
157 {
158 // Let the sources be destroyed before the sink
159 wxTestSink ts;
160 wxTestEvent evt;
161 {
162 wxEvtHandler eh1;
163 {
164 CPPUNIT_ASSERT( !ts.GetFirst() );
165
166 // Connect two event handlers to one sink
167 wxEvtHandler eh2;
168 gs_psrc1 = &eh1;
169 gs_psrc2 = &eh2;
170 DoConnect( eh1, eh2, ts );
171
172 // Fire events
173 gs_value = 0;
174 evt.SetEventObject(&eh1);
175 eh1.ProcessEvent( evt );
176 evt.SetEventObject(&eh2);
177 eh2.ProcessEvent( evt );
178
179 // Make sure they were processed correctly
180 CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
181 }
182
183 gs_value = 0;
184 evt.SetEventObject(&eh1);
185 eh1.ProcessEvent( evt );
186
187 // Make sure still connected
188 CPPUNIT_ASSERT_EQUAL( 0x00000001, gs_value );
189 }
190 CPPUNIT_ASSERT( !ts.GetFirst() );
191 }
192
193 void EvtConnectionTestCase::MultiConnectionTest()
194 {
195 // events used below
196 wxTestEvent evt;
197 wxTestEvent evt1(wxEVT_TEST1);
198 wxTestEvent evt2(wxEVT_TEST2);
199
200 // One source
201 wxEvtHandler eh1;
202 evt.SetEventObject(&eh1);
203 gs_psrc1 = NULL;
204 gs_psrc2 = &eh1;
205
206 {
207 // ...and one sink
208 wxTestSink ts;
209
210 eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
211 NULL, &ts);
212 eh1.Connect(wxEVT_TEST1, (wxObjectEventFunction)&wxTestSink::OnTestEvent1,
213 NULL, &ts);
214 eh1.Connect(wxEVT_TEST2, (wxObjectEventFunction)&wxTestSink::OnTestEvent2,
215 NULL, &ts);
216
217 // Generate events
218 gs_value = 0;
219 eh1.ProcessEvent(evt);
220 eh1.ProcessEvent(evt1);
221 eh1.ProcessEvent(evt2);
222 CPPUNIT_ASSERT( gs_value==0x01010100 );
223
224 {
225 // Declare weak references to the objects (using same list)
226 wxEvtHandlerRef re(&eh1), rs(&ts);
227 }
228 // And now destroyed
229
230 eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
231 NULL, &ts);
232 eh1.ProcessEvent(evt);
233 eh1.ProcessEvent(evt1);
234 eh1.ProcessEvent(evt2);
235 CPPUNIT_ASSERT_EQUAL( 0x02010200, gs_value );
236 }
237
238 // No connection should be left now
239 gs_value = 0;
240 eh1.ProcessEvent(evt);
241 eh1.ProcessEvent(evt1);
242 eh1.ProcessEvent(evt2);
243
244 // Nothing should have been done
245 CPPUNIT_ASSERT_EQUAL( 0, gs_value );
246 }
247