]>
git.saurik.com Git - wxWidgets.git/blob - tests/weakref/weakref.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/weakref/weakref.cpp
3 // Purpose: wxWeakRef<T> unit test
4 // Author: Arne Steinarson
6 // Copyright: (c) 2007 Arne Steinarson
7 ///////////////////////////////////////////////////////////////////////////////
9 // ----------------------------------------------------------------------------
11 // ----------------------------------------------------------------------------
24 #include "wx/weakref.h"
26 // A statically trackable derived wxObject
27 class wxObjectTrackable
: public wxObject
, public wxTrackable
33 // Make sure this does not clash with wxTrackableBase method
34 int GetFirst() { return 0; }
37 // --------------------------------------------------------------------------
39 // --------------------------------------------------------------------------
41 class WeakRefTestCase
: public CppUnit::TestCase
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
);
57 CPPUNIT_TEST_SUITE_END();
61 void AssignWeakRefTest();
62 void MultiAssignTest();
65 #ifdef HAVE_DYNAMIC_CAST
66 void DynamicRefTest();
69 DECLARE_NO_COPY_CLASS(WeakRefTestCase
)
72 // register in the unnamed registry so that these tests are run by default
73 CPPUNIT_TEST_SUITE_REGISTRATION( WeakRefTestCase
);
75 // also include in its own registry so that these tests can be run alone
76 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( WeakRefTestCase
, "WeakRefTestCase" );
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)
81 struct ForwardDeclaredClass
;
82 wxWeakRef
<ForwardDeclaredClass
> g_incompleteWeakRef
;
84 struct ForwardDeclaredClass
: wxEvtHandler
{ };
86 void WeakRefTestCase::DeclareTest()
89 // Not initializing or initializing with NULL should work too
91 // FIXME-VC6: but it doesn't with VC6, see comment in wx/weakref.h
93 wxWeakRef
<wxEvtHandler
> wroDef
;
94 wxWeakRef
<wxEvtHandler
> wro0(NULL
);
95 #endif // __VISUALC6__
97 wxObject o
; // Should not work
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
);
106 CPPUNIT_ASSERT( wro2
.get() == &eh
);
107 CPPUNIT_ASSERT( wro3
.get() == &ot
);
109 // Test accessing wxObject members
110 CPPUNIT_ASSERT( !wro2
->GetRefData() );
111 CPPUNIT_ASSERT( !wro3
->GetRefData() );
114 wxWeakRef
<wxEvtHandler
> wreh(&eh
);
115 wxWeakRef
<wxObjectTrackable
> wrot(&ot
);
117 CPPUNIT_ASSERT( wreh
.get() == &eh
);
118 CPPUNIT_ASSERT( wrot
.get() == &ot
);
121 // This test requires a working dynamic_cast<>
124 ForwardDeclaredClass fdc
;
125 g_incompleteWeakRef
= &fdc
;
126 CPPUNIT_ASSERT( g_incompleteWeakRef
);
129 CPPUNIT_ASSERT( !g_incompleteWeakRef
);
130 #endif // RTTI enabled
133 void WeakRefTestCase::AssignTest()
135 wxWeakRef
<wxEvtHandler
> wro1
;
136 wxWeakRef
<wxObjectTrackable
> wro2
;
138 { // Scope for object destruction
140 wxObjectTrackable ot
;
145 CPPUNIT_ASSERT( wro1
.get() == &eh
);
146 CPPUNIT_ASSERT( wro2
.get() == &ot
);
149 // Should be reset now
150 CPPUNIT_ASSERT( !wro1
);
151 CPPUNIT_ASSERT( !wro2
);
153 // Explicitly resetting should work too
155 // FIXME-VC6: as above, it doesn't work with VC6, see wx/weakref.h
158 wxObjectTrackable ot
;
166 CPPUNIT_ASSERT( !wro1
);
167 CPPUNIT_ASSERT( !wro2
);
168 #endif // __VISUALC6__
171 void WeakRefTestCase::AssignWeakRefTest()
173 // Test declare when T is wxObject
174 wxWeakRef
<wxEvtHandler
> wro1
;
175 wxWeakRef
<wxObjectTrackable
> wro2
;
177 { // Scope for object destruction
179 wxObjectTrackable ot
;
180 wxWeakRef
<wxEvtHandler
> wro3
;
181 wxWeakRef
<wxObjectTrackable
> wro4
;
188 CPPUNIT_ASSERT( wro1
.get() == &eh
);
189 CPPUNIT_ASSERT( wro2
.get() == &ot
);
190 CPPUNIT_ASSERT( wro3
.get() == &eh
);
191 CPPUNIT_ASSERT( wro4
.get() == &ot
);
194 CPPUNIT_ASSERT( !wro4
.get() );
197 // Should be reset now
198 CPPUNIT_ASSERT( !wro1
);
199 CPPUNIT_ASSERT( !wro2
);
202 void WeakRefTestCase::MultiAssignTest()
204 // Object is tracked by several refs
205 wxEvtHandler
*peh
= new wxEvtHandler
;
207 // Test declare when T is wxObject
208 wxWeakRef
<wxEvtHandler
> wro1(peh
);
209 wxWeakRef
<wxEvtHandler
> wro2(peh
);
211 wxObjectTrackable
*pot
= new wxObjectTrackable
;
212 wxWeakRef
<wxObjectTrackable
> wro3
= pot
;
213 wxWeakRef
<wxObjectTrackable
> wro4
= pot
;
215 CPPUNIT_ASSERT( wro1
.get() == peh
);
216 CPPUNIT_ASSERT( wro2
.get() == peh
);
217 CPPUNIT_ASSERT( wro3
.get() == pot
);
218 CPPUNIT_ASSERT( wro4
.get() == pot
);
223 // Should be reset now
224 CPPUNIT_ASSERT( !wro1
);
225 CPPUNIT_ASSERT( !wro2
);
226 CPPUNIT_ASSERT( !wro3
);
227 CPPUNIT_ASSERT( !wro4
);
230 void WeakRefTestCase::CleanupTest()
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.
235 wxObjectTrackable ots
;
236 wxObjectTrackable otd
;
238 { // Scope for object destruction
239 wxWeakRef
<wxEvtHandler
> wro1
;
240 wxWeakRef
<wxEvtHandler
> wro2
;
241 wxWeakRef
<wxObjectTrackable
> wro3
;
242 wxWeakRef
<wxObjectTrackable
> wro4
;
245 wro2
= &eh
; // Has two tracker nodes now
249 // Access members of reffed object
252 CPPUNIT_ASSERT( eh
.GetFirst()==&wro2
);
253 CPPUNIT_ASSERT( ots
.wxTrackable::GetFirst()==&wro3
);
254 CPPUNIT_ASSERT( otd
.wxTrackable::GetFirst()==&wro4
);
257 // Should be reset now
258 CPPUNIT_ASSERT( !eh
.GetFirst() );
259 CPPUNIT_ASSERT( !ots
.wxTrackable::GetFirst() );
260 CPPUNIT_ASSERT( !otd
.wxTrackable::GetFirst() );
263 void WeakRefTestCase::DeleteTest()
265 // Object is tracked by several refs
266 wxEvtHandler
*peh
= new wxEvtHandler
;
268 // Declared derived type of object and test deleting it
269 wxEvtHandlerRef
wre(peh
);
270 wxWeakRef
<wxEvtHandler
> wro(peh
);
272 CPPUNIT_ASSERT( wre
.get() == peh
);
273 CPPUNIT_ASSERT( wro
.get() == peh
);
277 CPPUNIT_ASSERT( !wre
);
278 CPPUNIT_ASSERT( !wro
);
281 #ifdef HAVE_DYNAMIC_CAST
283 void WeakRefTestCase::DynamicRefTest()
285 wxWeakRefDynamic
<wxEvtHandler
> wro1
;
286 wxWeakRefDynamic
<wxObjectTrackable
> wro2
;
287 wxWeakRefDynamic
<wxObjectTrackable
> wro3
;
289 { // Scope for object destruction
295 CPPUNIT_ASSERT( !wro1
);
297 wxObjectTrackable otd1
;
298 wxObjectTrackable otd2
;
302 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
303 CPPUNIT_ASSERT( wro3
.get() == &otd2
);
306 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
307 CPPUNIT_ASSERT( wro3
.get() == &otd1
);
310 // Should be reset now
311 CPPUNIT_ASSERT( !wro2
);
312 CPPUNIT_ASSERT( !wro3
);
315 #endif // HAVE_DYNAMIC_CAST