]>
Commit | Line | Data |
---|---|---|
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 |