]>
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
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" );
80 // Test weak reference to an incomplete type, this should work if the type is
81 // fully defined before it is used (but currently doesn't, see #11916)
82 struct ForwardDeclaredClass
;
83 wxWeakRef
<ForwardDeclaredClass
> g_incompleteWeakRef
;
85 struct ForwardDeclaredClass
: wxEvtHandler
{ };
87 void WeakRefTestCase::DeclareTest()
90 // Not initializing or initializing with NULL should work too
92 // FIXME-VC6: but it doesn't with VC6, see comment in wx/weakref.h
94 wxWeakRef
<wxEvtHandler
> wroDef
;
95 wxWeakRef
<wxEvtHandler
> wro0(NULL
);
96 #endif // __VISUALC6__
98 wxObject o
; // Should not work
100 wxObjectTrackable ot
;
102 // Test declare when T is wxObject
103 // wxWeakRef<wxObject> wro1(&o); // Gives compile time failure
104 wxWeakRef
<wxEvtHandler
> wro2(&eh
);
105 wxWeakRef
<wxObjectTrackable
> wro3(&ot
);
107 CPPUNIT_ASSERT( wro2
.get() == &eh
);
108 CPPUNIT_ASSERT( wro3
.get() == &ot
);
110 // Test accessing wxObject members
111 CPPUNIT_ASSERT( !wro2
->GetRefData() );
112 CPPUNIT_ASSERT( !wro3
->GetRefData() );
115 wxWeakRef
<wxEvtHandler
> wreh(&eh
);
116 wxWeakRef
<wxObjectTrackable
> wrot(&ot
);
118 CPPUNIT_ASSERT( wreh
.get() == &eh
);
119 CPPUNIT_ASSERT( wrot
.get() == &ot
);
122 // This test requires a working dynamic_cast<>
125 ForwardDeclaredClass fdc
;
126 g_incompleteWeakRef
= &fdc
;
127 CPPUNIT_ASSERT( g_incompleteWeakRef
);
130 CPPUNIT_ASSERT( !g_incompleteWeakRef
);
131 #endif // RTTI enabled
134 void WeakRefTestCase::AssignTest()
136 wxWeakRef
<wxEvtHandler
> wro1
;
137 wxWeakRef
<wxObjectTrackable
> wro2
;
139 { // Scope for object destruction
141 wxObjectTrackable ot
;
146 CPPUNIT_ASSERT( wro1
.get() == &eh
);
147 CPPUNIT_ASSERT( wro2
.get() == &ot
);
150 // Should be reset now
151 CPPUNIT_ASSERT( !wro1
);
152 CPPUNIT_ASSERT( !wro2
);
154 // Explicitly resetting should work too
156 // FIXME-VC6: as above, it doesn't work with VC6, see wx/weakref.h
159 wxObjectTrackable ot
;
167 CPPUNIT_ASSERT( !wro1
);
168 CPPUNIT_ASSERT( !wro2
);
169 #endif // __VISUALC6__
172 void WeakRefTestCase::AssignWeakRefTest()
174 // Test declare when T is wxObject
175 wxWeakRef
<wxEvtHandler
> wro1
;
176 wxWeakRef
<wxObjectTrackable
> wro2
;
178 { // Scope for object destruction
180 wxObjectTrackable ot
;
181 wxWeakRef
<wxEvtHandler
> wro3
;
182 wxWeakRef
<wxObjectTrackable
> wro4
;
189 CPPUNIT_ASSERT( wro1
.get() == &eh
);
190 CPPUNIT_ASSERT( wro2
.get() == &ot
);
191 CPPUNIT_ASSERT( wro3
.get() == &eh
);
192 CPPUNIT_ASSERT( wro4
.get() == &ot
);
195 CPPUNIT_ASSERT( !wro4
.get() );
198 // Should be reset now
199 CPPUNIT_ASSERT( !wro1
);
200 CPPUNIT_ASSERT( !wro2
);
203 void WeakRefTestCase::MultiAssignTest()
205 // Object is tracked by several refs
206 wxEvtHandler
*peh
= new wxEvtHandler
;
208 // Test declare when T is wxObject
209 wxWeakRef
<wxEvtHandler
> wro1(peh
);
210 wxWeakRef
<wxEvtHandler
> wro2(peh
);
212 wxObjectTrackable
*pot
= new wxObjectTrackable
;
213 wxWeakRef
<wxObjectTrackable
> wro3
= pot
;
214 wxWeakRef
<wxObjectTrackable
> wro4
= pot
;
216 CPPUNIT_ASSERT( wro1
.get() == peh
);
217 CPPUNIT_ASSERT( wro2
.get() == peh
);
218 CPPUNIT_ASSERT( wro3
.get() == pot
);
219 CPPUNIT_ASSERT( wro4
.get() == pot
);
224 // Should be reset now
225 CPPUNIT_ASSERT( !wro1
);
226 CPPUNIT_ASSERT( !wro2
);
227 CPPUNIT_ASSERT( !wro3
);
228 CPPUNIT_ASSERT( !wro4
);
231 void WeakRefTestCase::CleanupTest()
233 // Make sure that trackable objects have no left over tracker nodes after use.
234 // This time the references goes out of scope before the objects.
236 wxObjectTrackable ots
;
237 wxObjectTrackable otd
;
239 { // Scope for object destruction
240 wxWeakRef
<wxEvtHandler
> wro1
;
241 wxWeakRef
<wxEvtHandler
> wro2
;
242 wxWeakRef
<wxObjectTrackable
> wro3
;
243 wxWeakRef
<wxObjectTrackable
> wro4
;
246 wro2
= &eh
; // Has two tracker nodes now
250 // Access members of reffed object
253 CPPUNIT_ASSERT( eh
.GetFirst()==&wro2
);
254 CPPUNIT_ASSERT( ots
.wxTrackable::GetFirst()==&wro3
);
255 CPPUNIT_ASSERT( otd
.wxTrackable::GetFirst()==&wro4
);
258 // Should be reset now
259 CPPUNIT_ASSERT( !eh
.GetFirst() );
260 CPPUNIT_ASSERT( !ots
.wxTrackable::GetFirst() );
261 CPPUNIT_ASSERT( !otd
.wxTrackable::GetFirst() );
264 void WeakRefTestCase::DeleteTest()
266 // Object is tracked by several refs
267 wxEvtHandler
*peh
= new wxEvtHandler
;
269 // Declared derived type of object and test deleting it
270 wxEvtHandlerRef
wre(peh
);
271 wxWeakRef
<wxEvtHandler
> wro(peh
);
273 CPPUNIT_ASSERT( wre
.get() == peh
);
274 CPPUNIT_ASSERT( wro
.get() == peh
);
278 CPPUNIT_ASSERT( !wre
);
279 CPPUNIT_ASSERT( !wro
);
282 #ifdef HAVE_DYNAMIC_CAST
284 void WeakRefTestCase::DynamicRefTest()
286 wxWeakRefDynamic
<wxEvtHandler
> wro1
;
287 wxWeakRefDynamic
<wxObjectTrackable
> wro2
;
288 wxWeakRefDynamic
<wxObjectTrackable
> wro3
;
290 { // Scope for object destruction
296 CPPUNIT_ASSERT( !wro1
);
298 wxObjectTrackable otd1
;
299 wxObjectTrackable otd2
;
303 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
304 CPPUNIT_ASSERT( wro3
.get() == &otd2
);
307 CPPUNIT_ASSERT( wro2
.get() == &otd1
);
308 CPPUNIT_ASSERT( wro3
.get() == &otd1
);
311 // Should be reset now
312 CPPUNIT_ASSERT( !wro2
);
313 CPPUNIT_ASSERT( !wro3
);
316 #endif // HAVE_DYNAMIC_CAST