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