1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/weakref/weakref.cpp
3 // Purpose: wxWeakRef<T> unit test
4 // Author: Arne Steinarson
7 // Copyright: (c) 2007 Arne Steinarson
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
25 #include "wx/weakref.h"
27 // A statically trackable derived wxObject
28 class wxObjectTrackable
: public wxObject
, public wxTrackable
34 // Make sure this does not clash with wxTrackableBase method
35 int GetFirst() { return 0; }
38 // --------------------------------------------------------------------------
40 // --------------------------------------------------------------------------
42 class WeakRefTestCase
: public CppUnit
::TestCase
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
);
58 CPPUNIT_TEST_SUITE_END();
62 void AssignWeakRefTest();
63 void MultiAssignTest();
66 #ifdef HAVE_DYNAMIC_CAST
67 void DynamicRefTest();
70 DECLARE_NO_COPY_CLASS(WeakRefTestCase
)
73 // register in the unnamed registry so that these tests are run by default
74 CPPUNIT_TEST_SUITE_REGISTRATION( WeakRefTestCase
);
76 // also include in it's own registry so that these tests can be run alone
77 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( WeakRefTestCase
, "WeakRefTestCase" );
79 void WeakRefTestCase
::DeclareTest()
82 // Not initializing or initializing with NULL should work too
84 // FIXME-VC6: but it doesn't with VC6, see comment in wx/weakref.h
86 wxWeakRef
<wxEvtHandler
> wroDef
;
87 wxWeakRef
<wxEvtHandler
> wro0(NULL
);
88 #endif // __VISUALC6__
90 wxObject o
; // Should not work
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
);
99 CPPUNIT_ASSERT( wro2
.get() == &eh
);
100 CPPUNIT_ASSERT( wro3
.get() == &ot
);
102 // Test accessing wxObject members
103 CPPUNIT_ASSERT( !wro2
->GetRefData() );
104 CPPUNIT_ASSERT( !wro3
->GetRefData() );
107 wxWeakRef
<wxEvtHandler
> wreh(&eh
);
108 wxWeakRef
<wxObjectTrackable
> wrot(&ot
);
110 CPPUNIT_ASSERT( wreh
.get() == &eh
);
111 CPPUNIT_ASSERT( wrot
.get() == &ot
);
115 void WeakRefTestCase
::AssignTest()
117 wxWeakRef
<wxEvtHandler
> wro1
;
118 wxWeakRef
<wxObjectTrackable
> wro2
;
120 { // Scope for object destruction
122 wxObjectTrackable ot
;
127 CPPUNIT_ASSERT( wro1
.get() == &eh
);
128 CPPUNIT_ASSERT( wro2
.get() == &ot
);
131 // Should be reset now
132 CPPUNIT_ASSERT( !wro1
);
133 CPPUNIT_ASSERT( !wro2
);
135 // Explicitly resetting should work too
137 // FIXME-VC6: as above, it doesn't work with VC6, see wx/weakref.h
140 wxObjectTrackable ot
;
148 CPPUNIT_ASSERT( !wro1
);
149 CPPUNIT_ASSERT( !wro2
);
150 #endif // __VISUALC6__
153 void WeakRefTestCase
::AssignWeakRefTest()
155 // Test declare when T is wxObject
156 wxWeakRef
<wxEvtHandler
> wro1
;
157 wxWeakRef
<wxObjectTrackable
> wro2
;
159 { // Scope for object destruction
161 wxObjectTrackable ot
;
162 wxWeakRef
<wxEvtHandler
> wro3
;
163 wxWeakRef
<wxObjectTrackable
> wro4
;
170 CPPUNIT_ASSERT( wro1
.get() == &eh
);
171 CPPUNIT_ASSERT( wro2
.get() == &ot
);
172 CPPUNIT_ASSERT( wro3
.get() == &eh
);
173 CPPUNIT_ASSERT( wro4
.get() == &ot
);
176 CPPUNIT_ASSERT( !wro4
.get() );
179 // Should be reset now
180 CPPUNIT_ASSERT( !wro1
);
181 CPPUNIT_ASSERT( !wro2
);
184 void WeakRefTestCase
::MultiAssignTest()
186 // Object is tracked by several refs
187 wxEvtHandler
*peh
= new wxEvtHandler
;
189 // Test declare when T is wxObject
190 wxWeakRef
<wxEvtHandler
> wro1(peh
);
191 wxWeakRef
<wxEvtHandler
> wro2(peh
);
193 wxObjectTrackable
*pot
= new wxObjectTrackable
;
194 wxWeakRef
<wxObjectTrackable
> wro3
= pot
;
195 wxWeakRef
<wxObjectTrackable
> wro4
= pot
;
197 CPPUNIT_ASSERT( wro1
.get() == peh
);
198 CPPUNIT_ASSERT( wro2
.get() == peh
);
199 CPPUNIT_ASSERT( wro3
.get() == pot
);
200 CPPUNIT_ASSERT( wro4
.get() == pot
);
205 // Should be reset now
206 CPPUNIT_ASSERT( !wro1
);
207 CPPUNIT_ASSERT( !wro2
);
208 CPPUNIT_ASSERT( !wro3
);
209 CPPUNIT_ASSERT( !wro4
);
212 void WeakRefTestCase
::CleanupTest()
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.
217 wxObjectTrackable ots
;
218 wxObjectTrackable otd
;
220 { // Scope for object destruction
221 wxWeakRef
<wxEvtHandler
> wro1
;
222 wxWeakRef
<wxEvtHandler
> wro2
;
223 wxWeakRef
<wxObjectTrackable
> wro3
;
224 wxWeakRef
<wxObjectTrackable
> wro4
;
227 wro2
= &eh
; // Has two tracker nodes now
231 // Access members of reffed object
234 CPPUNIT_ASSERT( eh
.GetFirst()==&wro2
);
235 CPPUNIT_ASSERT( ots
.wxTrackable
::GetFirst()==&wro3
);
236 CPPUNIT_ASSERT( otd
.wxTrackable
::GetFirst()==&wro4
);
239 // Should be reset now
240 CPPUNIT_ASSERT( !eh
.GetFirst() );
241 CPPUNIT_ASSERT( !ots
.wxTrackable
::GetFirst() );
242 CPPUNIT_ASSERT( !otd
.wxTrackable
::GetFirst() );
245 void WeakRefTestCase
::DeleteTest()
247 // Object is tracked by several refs
248 wxEvtHandler
*peh
= new wxEvtHandler
;
250 // Declared derived type of object and test deleting it
251 wxEvtHandlerRef
wre(peh
);
252 wxWeakRef
<wxEvtHandler
> wro(peh
);
254 CPPUNIT_ASSERT( wre
.get() == peh
);
255 CPPUNIT_ASSERT( wro
.get() == peh
);
259 CPPUNIT_ASSERT( !wre
);
260 CPPUNIT_ASSERT( !wro
);
263 #ifdef HAVE_DYNAMIC_CAST
265 void WeakRefTestCase
::DynamicRefTest()
267 wxWeakRefDynamic
<wxEvtHandler
> wro1
;
268 wxWeakRefDynamic
<wxObjectTrackable
> wro2
;
269 wxWeakRefDynamic
<wxObjectTrackable
> wro3
;
271 { // Scope for object destruction
277 CPPUNIT_ASSERT( !wro1
);
279 wxObjectTrackable otd1
;
280 wxObjectTrackable otd2
;
284 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
285 CPPUNIT_ASSERT( wro3
.get() == &otd2
);
288 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
289 CPPUNIT_ASSERT( wro3
.get() == &otd1
);
292 // Should be reset now
293 CPPUNIT_ASSERT( !wro2
);
294 CPPUNIT_ASSERT( !wro3
);
297 #endif // HAVE_DYNAMIC_CAST