remove the test of weak references classes size, it's implementation-dependent
[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 wxObject o; // Should not work
83 wxEvtHandler eh;
84 wxObjectTrackable ot;
85
86 // Test declare when T is wxObject
87 // wxWeakRef<wxObject> wro1(&o); // Gives compile time failure
88 wxWeakRef<wxEvtHandler> wro2(&eh);
89 wxWeakRef<wxObjectTrackable> wro3(&ot);
90
91 CPPUNIT_ASSERT( wro2.get() == &eh );
92 CPPUNIT_ASSERT( wro3.get() == &ot );
93
94 // Test accessing wxObject members
95 CPPUNIT_ASSERT( !wro2->GetRefData() );
96 CPPUNIT_ASSERT( !wro3->GetRefData() );
97
98
99 wxWeakRef<wxEvtHandler> wreh(&eh);
100 wxWeakRef<wxObjectTrackable> wrot(&ot);
101
102 CPPUNIT_ASSERT( wreh.get() == &eh );
103 CPPUNIT_ASSERT( wrot.get() == &ot );
104 }
105 }
106
107 void WeakRefTestCase::AssignTest()
108 {
109 wxWeakRef<wxEvtHandler> wro1;
110 wxWeakRef<wxObjectTrackable> wro2;
111
112 { // Scope for object destruction
113 wxEvtHandler eh;
114 wxObjectTrackable ot;
115
116 wro1 = &eh;
117 wro2 = &ot;
118
119 CPPUNIT_ASSERT( wro1.get() == &eh );
120 CPPUNIT_ASSERT( wro2.get() == &ot );
121 }
122
123 // Should be reset now
124 CPPUNIT_ASSERT( !wro1 );
125 CPPUNIT_ASSERT( !wro2 );
126 }
127
128 void WeakRefTestCase::AssignWeakRefTest()
129 {
130 // Test declare when T is wxObject
131 wxWeakRef<wxEvtHandler> wro1;
132 wxWeakRef<wxObjectTrackable> wro2;
133
134 { // Scope for object destruction
135 wxEvtHandler eh;
136 wxObjectTrackable ot;
137 wxWeakRef<wxEvtHandler> wro3;
138 wxWeakRef<wxObjectTrackable> wro4;
139
140 wro1 = &eh;
141 wro2 = &ot;
142 wro3 = wro1;
143 wro4 = wro2;
144
145 CPPUNIT_ASSERT( wro1.get() == &eh );
146 CPPUNIT_ASSERT( wro2.get() == &ot );
147 CPPUNIT_ASSERT( wro3.get() == &eh );
148 CPPUNIT_ASSERT( wro4.get() == &ot );
149
150 wro4.Release();
151 CPPUNIT_ASSERT( !wro4.get() );
152 }
153
154 // Should be reset now
155 CPPUNIT_ASSERT( !wro1 );
156 CPPUNIT_ASSERT( !wro2 );
157 }
158
159 void WeakRefTestCase::MultiAssignTest()
160 {
161 // Object is tracked by several refs
162 wxEvtHandler *peh = new wxEvtHandler;
163
164 // Test declare when T is wxObject
165 wxWeakRef<wxEvtHandler> wro1(peh);
166 wxWeakRef<wxEvtHandler> wro2(peh);
167
168 wxObjectTrackable *pot = new wxObjectTrackable;
169 wxWeakRef<wxObjectTrackable> wro3 = pot;
170 wxWeakRef<wxObjectTrackable> wro4 = pot;
171
172 CPPUNIT_ASSERT( wro1.get() == peh );
173 CPPUNIT_ASSERT( wro2.get() == peh );
174 CPPUNIT_ASSERT( wro3.get() == pot );
175 CPPUNIT_ASSERT( wro4.get() == pot );
176
177 delete peh;
178 delete pot;
179
180 // Should be reset now
181 CPPUNIT_ASSERT( !wro1 );
182 CPPUNIT_ASSERT( !wro2 );
183 CPPUNIT_ASSERT( !wro3 );
184 CPPUNIT_ASSERT( !wro4 );
185 }
186
187 void WeakRefTestCase::CleanupTest()
188 {
189 // Make sure that trackable objects have no left over tracker nodes after use.
190 // This time the references goes out of scope before the objects.
191 wxEvtHandler eh;
192 wxObjectTrackable ots;
193 wxObjectTrackable otd;
194
195 { // Scope for object destruction
196 wxWeakRef<wxEvtHandler> wro1;
197 wxWeakRef<wxEvtHandler> wro2;
198 wxWeakRef<wxObjectTrackable> wro3;
199 wxWeakRef<wxObjectTrackable> wro4;
200
201 wro1 = &eh;
202 wro2 = &eh; // Has two tracker nodes now
203 wro3 = &ots;
204 wro4 = &otd;
205
206 // Access members of reffed object
207 wro3->TestFunc();
208
209 CPPUNIT_ASSERT( eh.GetFirst()==&wro2 );
210 CPPUNIT_ASSERT( ots.wxTrackable::GetFirst()==&wro3 );
211 CPPUNIT_ASSERT( otd.wxTrackable::GetFirst()==&wro4 );
212 }
213
214 // Should be reset now
215 CPPUNIT_ASSERT( !eh.GetFirst() );
216 CPPUNIT_ASSERT( !ots.wxTrackable::GetFirst() );
217 CPPUNIT_ASSERT( !otd.wxTrackable::GetFirst() );
218 }
219
220 void WeakRefTestCase::DeleteTest()
221 {
222 // Object is tracked by several refs
223 wxEvtHandler *peh = new wxEvtHandler;
224
225 // Declared derived type of object and test deleting it
226 wxEvtHandlerRef wre(peh);
227 wxWeakRef<wxEvtHandler> wro(peh);
228
229 CPPUNIT_ASSERT( wre.get() == peh );
230 CPPUNIT_ASSERT( wro.get() == peh );
231
232 delete wre.get();
233
234 CPPUNIT_ASSERT( !wre );
235 CPPUNIT_ASSERT( !wro );
236 }
237
238 #ifdef HAVE_DYNAMIC_CAST
239
240 void WeakRefTestCase::DynamicRefTest()
241 {
242 wxWeakRefDynamic<wxEvtHandler> wro1;
243 wxWeakRefDynamic<wxObjectTrackable> wro2;
244 wxWeakRefDynamic<wxObjectTrackable> wro3;
245
246 { // Scope for object destruction
247 {
248 wxEvtHandler eh;
249 wro1 = &eh;
250 }
251
252 CPPUNIT_ASSERT( !wro1 );
253
254 wxObjectTrackable otd1;
255 wxObjectTrackable otd2;
256 wro2 = &otd1;
257 wro3 = &otd2;
258
259 CPPUNIT_ASSERT( wro2.get() == &otd1 );
260 CPPUNIT_ASSERT( wro3.get() == &otd2 );
261
262 wro3 = wro2;
263 CPPUNIT_ASSERT( wro2.get() == &otd1 );
264 CPPUNIT_ASSERT( wro3.get() == &otd1 );
265 }
266
267 // Should be reset now
268 CPPUNIT_ASSERT( !wro2 );
269 CPPUNIT_ASSERT( !wro3 );
270 }
271
272 #endif // HAVE_DYNAMIC_CAST