]> git.saurik.com Git - wxWidgets.git/blob - tests/any/anytest.cpp
Restore the use of the correct brush for toolbar background erasing.
[wxWidgets.git] / tests / any / anytest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/any/anytest.cpp
3 // Purpose: Test the wxAny classes
4 // Author: Jaakko Salli
5 // RCS-ID: $Id$
6 // Copyright: (c) the wxWidgets team
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "testprec.h"
11
12 #ifdef __BORLANDC__
13 # pragma hdrstop
14 #endif
15
16 #if wxUSE_ANY
17
18 #include "wx/any.h"
19 #include "wx/datetime.h"
20 #include "wx/object.h"
21
22 #include <math.h>
23
24 // ----------------------------------------------------------------------------
25 // test class
26 // ----------------------------------------------------------------------------
27
28 class wxAnyTestCase : public CppUnit::TestCase
29 {
30 public:
31 wxAnyTestCase();
32
33 private:
34 CPPUNIT_TEST_SUITE( wxAnyTestCase );
35 CPPUNIT_TEST( Equality );
36 CPPUNIT_TEST( As );
37 CPPUNIT_TEST( GetAs );
38 CPPUNIT_TEST( Null );
39 CPPUNIT_TEST( CustomTemplateSpecialization );
40 CPPUNIT_TEST_SUITE_END();
41
42 void Equality();
43 void As();
44 void GetAs();
45 void Null();
46 void CustomTemplateSpecialization();
47
48 wxDateTime m_testDateTime;
49
50 wxAny m_anySignedChar1;
51 wxAny m_anySignedShort1;
52 wxAny m_anySignedInt1;
53 wxAny m_anySignedLong1;
54 wxAny m_anySignedLongLong1;
55 wxAny m_anyUnsignedChar1;
56 wxAny m_anyUnsignedShort1;
57 wxAny m_anyUnsignedInt1;
58 wxAny m_anyUnsignedLong1;
59 wxAny m_anyUnsignedLongLong1;
60 wxAny m_anyStringString1;
61 wxAny m_anyCharString1;
62 wxAny m_anyWcharString1;
63 wxAny m_anyBool1;
64 wxAny m_anyFloatDouble1;
65 wxAny m_anyDoubleDouble1;
66 wxAny m_anyWxObjectPtr1;
67 wxAny m_anyVoidPtr1;
68 wxAny m_anyDateTime1;
69
70 wxAny m_anySignedChar2;
71 wxAny m_anySignedShort2;
72 wxAny m_anySignedInt2;
73 wxAny m_anySignedLong2;
74 wxAny m_anySignedLongLong2;
75 wxAny m_anyUnsignedChar2;
76 wxAny m_anyUnsignedShort2;
77 wxAny m_anyUnsignedInt2;
78 wxAny m_anyUnsignedLong2;
79 wxAny m_anyUnsignedLongLong2;
80 wxAny m_anyStringString2;
81 wxAny m_anyCharString2;
82 wxAny m_anyWcharString2;
83 wxAny m_anyBool2;
84 wxAny m_anyFloatDouble2;
85 wxAny m_anyDoubleDouble2;
86 wxAny m_anyWxObjectPtr2;
87 wxAny m_anyVoidPtr2;
88 wxAny m_anyDateTime2;
89
90 DECLARE_NO_COPY_CLASS(wxAnyTestCase)
91 };
92
93 // register in the unnamed registry so that these tests are run by default
94 CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );
95
96 // also include in it's own registry so that these tests can be run alone
97 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );
98
99 // Let's use a number with first digit after decimal dot less than 5,
100 // so that we don't have to worry about whether conversion from float
101 // to int truncates or rounds.
102 const double TEST_FLOAT_CONST = 123.456;
103
104 const double FEQ_DELTA = 0.001;
105
106 wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);
107 void* dummyVoidPointer = reinterpret_cast<void*>(1234);
108
109
110 //
111 // Test both 'creation' methods
112 wxAnyTestCase::wxAnyTestCase()
113 : m_anySignedChar1((signed char)15),
114 m_anySignedShort1((signed short)15),
115 m_anySignedInt1((signed int)15),
116 m_anySignedLong1((signed long)15),
117 #ifdef wxLongLong_t
118 m_anySignedLongLong1((wxLongLong_t)15),
119 #endif
120 m_anyUnsignedChar1((unsigned char)15),
121 m_anyUnsignedShort1((unsigned short)15),
122 m_anyUnsignedInt1((unsigned int)15),
123 m_anyUnsignedLong1((unsigned long)15),
124 #ifdef wxLongLong_t
125 m_anyUnsignedLongLong1((wxULongLong_t)15),
126 #endif
127 m_anyStringString1(wxString("abc")),
128 m_anyCharString1("abc"),
129 m_anyWcharString1(L"abc"),
130 m_anyBool1(true),
131 m_anyFloatDouble1((float)TEST_FLOAT_CONST),
132 m_anyDoubleDouble1((double)TEST_FLOAT_CONST),
133 m_anyWxObjectPtr1(dummyWxObjectPointer),
134 m_anyVoidPtr1(dummyVoidPointer),
135 m_anyDateTime1(wxDateTime::Now())
136 {
137 m_testDateTime = wxDateTime::Now();
138 m_anySignedChar2 = (signed char)15;
139 m_anySignedShort2 = (signed short)15;
140 m_anySignedInt2 = (signed int)15;
141 m_anySignedLong2 = (signed long)15;
142 #ifdef wxLongLong_t
143 m_anySignedLongLong2 = (wxLongLong_t)15;
144 #endif
145 m_anyUnsignedChar2 = (unsigned char)15;
146 m_anyUnsignedShort2 = (unsigned short)15;
147 m_anyUnsignedInt2 = (unsigned int)15;
148 m_anyUnsignedLong2 = (unsigned long)15;
149 #ifdef wxLongLong_t
150 m_anyUnsignedLongLong2 = (wxULongLong_t)15;
151 #endif
152 m_anyStringString2 = wxString("abc");
153 m_anyCharString2 = "abc";
154 m_anyWcharString2 = L"abc";
155 m_anyBool2 = true;
156 m_anyFloatDouble2 = (float)TEST_FLOAT_CONST;
157 m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST;
158 m_anyDateTime2 = m_testDateTime;
159 m_anyWxObjectPtr2 = dummyWxObjectPointer;
160 m_anyVoidPtr2 = dummyVoidPointer;
161 }
162
163 void wxAnyTestCase::Equality()
164 {
165 //
166 // Currently this should work
167 CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);
168 CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);
169 CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);
170 CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);
171 CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));
172 CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));
173 CPPUNIT_ASSERT(m_anyStringString1 == "abc");
174 CPPUNIT_ASSERT(m_anyStringString1 != "ABC");
175 CPPUNIT_ASSERT(m_anyStringString1 == L"abc");
176 CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");
177 CPPUNIT_ASSERT(m_anyBool1 == true);
178 CPPUNIT_ASSERT(m_anyBool1 != false);
179 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
180 wxANY_AS(m_anyDoubleDouble1, double),
181 FEQ_DELTA);
182 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
183 TEST_FLOAT_CONST,
184 FEQ_DELTA);
185 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)
186 == dummyWxObjectPointer);
187 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);
188
189 CPPUNIT_ASSERT(m_anySignedLong2 == 15);
190 CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));
191 CPPUNIT_ASSERT(m_anyStringString2 == "abc");
192 CPPUNIT_ASSERT(m_anyStringString2 == L"abc");
193 CPPUNIT_ASSERT(m_anyBool2 == true);
194 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
195 wxANY_AS(m_anyDoubleDouble2, double),
196 FEQ_DELTA);
197 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
198 TEST_FLOAT_CONST,
199 FEQ_DELTA);
200 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)
201 == dummyWxObjectPointer);
202 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);
203
204 // Test sub-type system type compatibility
205 CPPUNIT_ASSERT(m_anySignedShort1.GetType()->
206 IsSameType(m_anySignedLongLong1.GetType()));
207 CPPUNIT_ASSERT(m_anyUnsignedShort1.GetType()->
208 IsSameType(m_anyUnsignedLongLong1.GetType()));
209 }
210
211 void wxAnyTestCase::As()
212 {
213 //
214 // Test getting C++ data from wxAny without dynamic conversion
215 signed char a = wxANY_AS(m_anySignedChar1, signed char);
216 CPPUNIT_ASSERT(a == (signed int)15);
217 signed short b = wxANY_AS(m_anySignedShort1, signed short);
218 CPPUNIT_ASSERT(b == (signed int)15);
219 signed int c = wxANY_AS(m_anySignedInt1, signed int);
220 CPPUNIT_ASSERT(c == (signed int)15);
221 signed long d = wxANY_AS(m_anySignedLong1, signed long);
222 CPPUNIT_ASSERT(d == (signed int)15);
223 #ifdef wxLongLong_t
224 wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);
225 CPPUNIT_ASSERT(e == (signed int)15);
226 #endif
227 unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);
228 CPPUNIT_ASSERT(f == (unsigned int)15);
229 unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);
230 CPPUNIT_ASSERT(g == (unsigned int)15);
231 unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);
232 CPPUNIT_ASSERT(h == (unsigned int)15);
233 unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);
234 CPPUNIT_ASSERT(i == (unsigned int)15);
235 #ifdef wxLongLong_t
236 wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);
237 CPPUNIT_ASSERT(j == (unsigned int)15);
238 #endif
239 wxString k = wxANY_AS(m_anyStringString1, wxString);
240 CPPUNIT_ASSERT(k == "abc");
241 wxString l = wxANY_AS(m_anyCharString1, wxString);
242 CPPUNIT_ASSERT(l == "abc");
243 wxString m = wxANY_AS(m_anyWcharString1, wxString);
244 CPPUNIT_ASSERT(m == "abc");
245 bool n = wxANY_AS(m_anyBool1, bool);
246 CPPUNIT_ASSERT(n);
247 float o = wxANY_AS(m_anyFloatDouble1, float);
248 CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA);
249 double p = wxANY_AS(m_anyDoubleDouble1, double);
250 CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA);
251 wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);
252 CPPUNIT_ASSERT(q == m_testDateTime);
253 wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);
254 CPPUNIT_ASSERT(r == dummyWxObjectPointer);
255 void* s = wxANY_AS(m_anyVoidPtr1, void*);
256 CPPUNIT_ASSERT(s == dummyVoidPointer);
257 }
258
259 void wxAnyTestCase::Null()
260 {
261 wxAny a;
262 CPPUNIT_ASSERT(a.IsNull());
263 a = -127;
264 CPPUNIT_ASSERT(a == -127);
265 a.MakeNull();
266 CPPUNIT_ASSERT(a.IsNull());
267 }
268
269 void wxAnyTestCase::GetAs()
270 {
271 //
272 // Test dynamic conversion
273 bool res;
274 long l = 0;
275 short int si = 0;
276 unsigned long ul = 0;
277 wxString s;
278 // Let's test against float instead of double, since the former
279 // is not the native underlying type the code converts to, but
280 // should still work, all the same.
281 float f = 0.0;
282 bool b = false;
283
284 // Conversions from signed long type
285 // The first check should be enough to make sure that the sub-type system
286 // has not failed.
287 res = m_anySignedLong1.GetAs(&si);
288 CPPUNIT_ASSERT(res);
289 CPPUNIT_ASSERT_EQUAL(si, 15);
290 res = m_anySignedLong1.GetAs(&ul);
291 CPPUNIT_ASSERT(res);
292 CPPUNIT_ASSERT_EQUAL(ul, 15UL);
293 res = m_anySignedLong1.GetAs(&s);
294 CPPUNIT_ASSERT(res);
295 CPPUNIT_ASSERT(s == "15");
296 res = m_anySignedLong1.GetAs(&f);
297 CPPUNIT_ASSERT(res);
298 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
299 res = m_anySignedLong1.GetAs(&b);
300 CPPUNIT_ASSERT(res);
301 CPPUNIT_ASSERT(b == true);
302
303 // Conversions from unsigned long type
304 res = m_anyUnsignedLong1.GetAs(&l);
305 CPPUNIT_ASSERT(res);
306 CPPUNIT_ASSERT(l == static_cast<signed long>(15));
307 res = m_anyUnsignedLong1.GetAs(&s);
308 CPPUNIT_ASSERT(res);
309 CPPUNIT_ASSERT(s == "15");
310 res = m_anyUnsignedLong1.GetAs(&f);
311 CPPUNIT_ASSERT(res);
312 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
313 res = m_anyUnsignedLong1.GetAs(&b);
314 CPPUNIT_ASSERT(res);
315 CPPUNIT_ASSERT(b == true);
316
317 // Conversions from default "abc" string to other types
318 // should not work.
319 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));
320 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));
321 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));
322 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));
323
324 // Let's test some other conversions from string that should work.
325 wxAny anyString;
326
327 anyString = "15";
328 res = anyString.GetAs(&l);
329 CPPUNIT_ASSERT(res);
330 CPPUNIT_ASSERT(l == static_cast<signed long>(15));
331 res = anyString.GetAs(&ul);
332 CPPUNIT_ASSERT(res);
333 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
334 res = anyString.GetAs(&f);
335 CPPUNIT_ASSERT(res);
336 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
337 anyString = "TRUE";
338 res = anyString.GetAs(&b);
339 CPPUNIT_ASSERT(res);
340 CPPUNIT_ASSERT(b == true);
341 anyString = "0";
342 res = anyString.GetAs(&b);
343 CPPUNIT_ASSERT(res);
344 CPPUNIT_ASSERT(b == false);
345
346 // Conversions from bool type
347 res = m_anyBool1.GetAs(&l);
348 CPPUNIT_ASSERT(res);
349 CPPUNIT_ASSERT(l == static_cast<signed long>(1));
350 res = m_anyBool1.GetAs(&ul);
351 CPPUNIT_ASSERT(res);
352 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));
353 res = m_anyBool1.GetAs(&s);
354 CPPUNIT_ASSERT(res);
355 CPPUNIT_ASSERT(s == "true");
356 CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));
357
358 // Conversions from floating point type
359 res = m_anyDoubleDouble1.GetAs(&l);
360 CPPUNIT_ASSERT(res);
361 CPPUNIT_ASSERT(l == static_cast<signed long>(123));
362 res = m_anyDoubleDouble1.GetAs(&ul);
363 CPPUNIT_ASSERT(res);
364 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));
365 res = m_anyDoubleDouble1.GetAs(&s);
366 CPPUNIT_ASSERT(res);
367 double d2;
368 res = s.ToDouble(&d2);
369 CPPUNIT_ASSERT(res);
370 CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);
371 }
372
373 //
374 // Test user data type specialization of wxAnyValueTypeImpl
375 //
376
377 class MyClass
378 {
379 public:
380 MyClass( int someValue = 32768 )
381 {
382 m_someValue = someValue;
383 }
384
385 wxString ToString()
386 {
387 return wxString::Format("%i", m_someValue);
388 }
389
390 private:
391 int m_someValue;
392 };
393
394
395 template<>
396 class wxAnyValueTypeImpl<MyClass> :
397 public wxAnyValueTypeImplBase<MyClass>
398 {
399 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
400 public:
401 wxAnyValueTypeImpl() :
402 wxAnyValueTypeImplBase<MyClass>() { }
403 virtual ~wxAnyValueTypeImpl() { }
404
405 virtual bool ConvertValue(const wxAnyValueBuffer& src,
406 wxAnyValueType* dstType,
407 wxAnyValueBuffer& dst) const
408 {
409 MyClass value = GetValue(src);
410
411 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
412 {
413 wxString s = value.ToString();
414 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
415 }
416 else
417 return false;
418
419 return true;
420 }
421 };
422
423 //
424 // Following must be placed somewhere in your source code
425 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
426
427 void wxAnyTestCase::CustomTemplateSpecialization()
428 {
429 // Do only a minimal CheckType() test, as dynamic type conversion already
430 // uses it a lot.
431 bool res;
432 MyClass myObject;
433 wxAny any = myObject;
434
435 CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );
436 MyClass myObject2 = wxANY_AS(any, MyClass);
437 wxUnusedVar(myObject2);
438
439 wxString str;
440 res = any.GetAs(&str);
441 CPPUNIT_ASSERT(res);
442 CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());
443 }
444
445 #endif // wxUSE_ANY
446