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