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