Exclude wxWeakRef tests not compiling with VC6 from compilation.
[wxWidgets.git] / tests / weakref / weakref.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/weakref/weakref.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 // A statically trackable derived wxObject
28 class wxObjectTrackable : public wxObject, public wxTrackable
29 {
30 public:
31 // Test member access
32 void TestFunc(){ }
33
34 // Make sure this does not clash with wxTrackableBase method
35 int GetFirst() { return 0; }
36 };
37
38 // --------------------------------------------------------------------------
39 // test class
40 // --------------------------------------------------------------------------
41
42 class WeakRefTestCase : public CppUnit::TestCase
43 {
44 public:
45 WeakRefTestCase() {}
46
47 private:
48 CPPUNIT_TEST_SUITE( WeakRefTestCase );
49 CPPUNIT_TEST( DeclareTest );
50 CPPUNIT_TEST( AssignTest );
51 CPPUNIT_TEST( AssignWeakRefTest );
52 CPPUNIT_TEST( MultiAssignTest );
53 CPPUNIT_TEST( CleanupTest );
54 CPPUNIT_TEST( DeleteTest );
55 #ifdef HAVE_DYNAMIC_CAST
56 CPPUNIT_TEST( DynamicRefTest );
57 #endif
58 CPPUNIT_TEST_SUITE_END();
59
60 void DeclareTest();
61 void AssignTest();
62 void AssignWeakRefTest();
63 void MultiAssignTest();
64 void CleanupTest();
65 void DeleteTest();
66 #ifdef HAVE_DYNAMIC_CAST
67 void DynamicRefTest();
68 #endif
69
70 DECLARE_NO_COPY_CLASS(WeakRefTestCase)
71 };
72
73 // register in the unnamed registry so that these tests are run by default
74 CPPUNIT_TEST_SUITE_REGISTRATION( WeakRefTestCase );
75
76 // also include in it's own registry so that these tests can be run alone
77 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( WeakRefTestCase, "WeakRefTestCase" );
78
79 void WeakRefTestCase::DeclareTest()
80 {
81 {
82 // Not initializing or initializing with NULL should work too
83 //
84 // FIXME-VC6: but it doesn't with VC6, see comment in wx/weakref.h
85 #ifndef __VISUALC6__
86 wxWeakRef<wxEvtHandler> wroDef;
87 wxWeakRef<wxEvtHandler> wro0(NULL);
88 #endif // __VISUALC6__
89
90 wxObject o; // Should not work
91 wxEvtHandler eh;
92 wxObjectTrackable ot;
93
94 // Test declare when T is wxObject
95 // wxWeakRef<wxObject> wro1(&o); // Gives compile time failure
96 wxWeakRef<wxEvtHandler> wro2(&eh);
97 wxWeakRef<wxObjectTrackable> wro3(&ot);
98
99 CPPUNIT_ASSERT( wro2.get() == &eh );
100 CPPUNIT_ASSERT( wro3.get() == &ot );
101
102 // Test accessing wxObject members
103 CPPUNIT_ASSERT( !wro2->GetRefData() );
104 CPPUNIT_ASSERT( !wro3->GetRefData() );
105
106
107 wxWeakRef<wxEvtHandler> wreh(&eh);
108 wxWeakRef<wxObjectTrackable> wrot(&ot);
109
110 CPPUNIT_ASSERT( wreh.get() == &eh );
111 CPPUNIT_ASSERT( wrot.get() == &ot );
112 }
113 }
114
115 void WeakRefTestCase::AssignTest()
116 {
117 wxWeakRef<wxEvtHandler> wro1;
118 wxWeakRef<wxObjectTrackable> wro2;
119
120 { // Scope for object destruction
121 wxEvtHandler eh;
122 wxObjectTrackable ot;
123
124 wro1 = &eh;
125 wro2 = &ot;
126
127 CPPUNIT_ASSERT( wro1.get() == &eh );
128 CPPUNIT_ASSERT( wro2.get() == &ot );
129 }
130
131 // Should be reset now
132 CPPUNIT_ASSERT( !wro1 );
133 CPPUNIT_ASSERT( !wro2 );
134
135 // Explicitly resetting should work too
136 //
137 // FIXME-VC6: as above, it doesn't work with VC6, see wx/weakref.h
138 #ifndef __VISUALC6__
139 wxEvtHandler eh;
140 wxObjectTrackable ot;
141
142 wro1 = &eh;
143 wro2 = &ot;
144
145 wro1 = NULL;
146 wro2 = NULL;
147
148 CPPUNIT_ASSERT( !wro1 );
149 CPPUNIT_ASSERT( !wro2 );
150 #endif // __VISUALC6__
151 }
152
153 void WeakRefTestCase::AssignWeakRefTest()
154 {
155 // Test declare when T is wxObject
156 wxWeakRef<wxEvtHandler> wro1;
157 wxWeakRef<wxObjectTrackable> wro2;
158
159 { // Scope for object destruction
160 wxEvtHandler eh;
161 wxObjectTrackable ot;
162 wxWeakRef<wxEvtHandler> wro3;
163 wxWeakRef<wxObjectTrackable> wro4;
164
165 wro1 = &eh;
166 wro2 = &ot;
167 wro3 = wro1;
168 wro4 = wro2;
169
170 CPPUNIT_ASSERT( wro1.get() == &eh );
171 CPPUNIT_ASSERT( wro2.get() == &ot );
172 CPPUNIT_ASSERT( wro3.get() == &eh );
173 CPPUNIT_ASSERT( wro4.get() == &ot );
174
175 wro4.Release();
176 CPPUNIT_ASSERT( !wro4.get() );
177 }
178
179 // Should be reset now
180 CPPUNIT_ASSERT( !wro1 );
181 CPPUNIT_ASSERT( !wro2 );
182 }
183
184 void WeakRefTestCase::MultiAssignTest()
185 {
186 // Object is tracked by several refs
187 wxEvtHandler *peh = new wxEvtHandler;
188
189 // Test declare when T is wxObject
190 wxWeakRef<wxEvtHandler> wro1(peh);
191 wxWeakRef<wxEvtHandler> wro2(peh);
192
193 wxObjectTrackable *pot = new wxObjectTrackable;
194 wxWeakRef<wxObjectTrackable> wro3 = pot;
195 wxWeakRef<wxObjectTrackable> wro4 = pot;
196
197 CPPUNIT_ASSERT( wro1.get() == peh );
198 CPPUNIT_ASSERT( wro2.get() == peh );
199 CPPUNIT_ASSERT( wro3.get() == pot );
200 CPPUNIT_ASSERT( wro4.get() == pot );
201
202 delete peh;
203 delete pot;
204
205 // Should be reset now
206 CPPUNIT_ASSERT( !wro1 );
207 CPPUNIT_ASSERT( !wro2 );
208 CPPUNIT_ASSERT( !wro3 );
209 CPPUNIT_ASSERT( !wro4 );
210 }
211
212 void WeakRefTestCase::CleanupTest()
213 {
214 // Make sure that trackable objects have no left over tracker nodes after use.
215 // This time the references goes out of scope before the objects.
216 wxEvtHandler eh;
217 wxObjectTrackable ots;
218 wxObjectTrackable otd;
219
220 { // Scope for object destruction
221 wxWeakRef<wxEvtHandler> wro1;
222 wxWeakRef<wxEvtHandler> wro2;
223 wxWeakRef<wxObjectTrackable> wro3;
224 wxWeakRef<wxObjectTrackable> wro4;
225
226 wro1 = &eh;
227 wro2 = &eh; // Has two tracker nodes now
228 wro3 = &ots;
229 wro4 = &otd;
230
231 // Access members of reffed object
232 wro3->TestFunc();
233
234 CPPUNIT_ASSERT( eh.GetFirst()==&wro2 );
235 CPPUNIT_ASSERT( ots.wxTrackable::GetFirst()==&wro3 );
236 CPPUNIT_ASSERT( otd.wxTrackable::GetFirst()==&wro4 );
237 }
238
239 // Should be reset now
240 CPPUNIT_ASSERT( !eh.GetFirst() );
241 CPPUNIT_ASSERT( !ots.wxTrackable::GetFirst() );
242 CPPUNIT_ASSERT( !otd.wxTrackable::GetFirst() );
243 }
244
245 void WeakRefTestCase::DeleteTest()
246 {
247 // Object is tracked by several refs
248 wxEvtHandler *peh = new wxEvtHandler;
249
250 // Declared derived type of object and test deleting it
251 wxEvtHandlerRef wre(peh);
252 wxWeakRef<wxEvtHandler> wro(peh);
253
254 CPPUNIT_ASSERT( wre.get() == peh );
255 CPPUNIT_ASSERT( wro.get() == peh );
256
257 delete wre.get();
258
259 CPPUNIT_ASSERT( !wre );
260 CPPUNIT_ASSERT( !wro );
261 }
262
263 #ifdef HAVE_DYNAMIC_CAST
264
265 void WeakRefTestCase::DynamicRefTest()
266 {
267 wxWeakRefDynamic<wxEvtHandler> wro1;
268 wxWeakRefDynamic<wxObjectTrackable> wro2;
269 wxWeakRefDynamic<wxObjectTrackable> wro3;
270
271 { // Scope for object destruction
272 {
273 wxEvtHandler eh;
274 wro1 = &eh;
275 }
276
277 CPPUNIT_ASSERT( !wro1 );
278
279 wxObjectTrackable otd1;
280 wxObjectTrackable otd2;
281 wro2 = &otd1;
282 wro3 = &otd2;
283
284 CPPUNIT_ASSERT( wro2.get() == &otd1 );
285 CPPUNIT_ASSERT( wro3.get() == &otd2 );
286
287 wro3 = wro2;
288 CPPUNIT_ASSERT( wro2.get() == &otd1 );
289 CPPUNIT_ASSERT( wro3.get() == &otd1 );
290 }
291
292 // Should be reset now
293 CPPUNIT_ASSERT( !wro2 );
294 CPPUNIT_ASSERT( !wro3 );
295 }
296
297 #endif // HAVE_DYNAMIC_CAST