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