1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/any/anytest.cpp
3 // Purpose: Test the wxAny classes
4 // Author: Jaakko Salli
6 // Copyright: (c) the wxWidgets team
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
19 #include "wx/datetime.h"
20 #include "wx/object.h"
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
28 class wxAnyTestCase
: public CppUnit::TestCase
34 CPPUNIT_TEST_SUITE( wxAnyTestCase
);
35 CPPUNIT_TEST( Equality
);
37 CPPUNIT_TEST( GetAs
);
39 CPPUNIT_TEST( CustomTemplateSpecialization
);
40 CPPUNIT_TEST_SUITE_END();
46 void CustomTemplateSpecialization();
48 wxDateTime m_testDateTime
;
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
;
64 wxAny m_anyFloatDouble1
;
65 wxAny m_anyDoubleDouble1
;
66 wxAny m_anyWxObjectPtr1
;
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
;
84 wxAny m_anyFloatDouble2
;
85 wxAny m_anyDoubleDouble2
;
86 wxAny m_anyWxObjectPtr2
;
90 DECLARE_NO_COPY_CLASS(wxAnyTestCase
)
93 // register in the unnamed registry so that these tests are run by default
94 CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase
);
96 // also include in it's own registry so that these tests can be run alone
97 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase
, "wxAnyTestCase" );
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;
104 const double FEQ_DELTA
= 0.001;
106 wxObject
* dummyWxObjectPointer
= reinterpret_cast<wxObject
*>(1234);
107 void* dummyVoidPointer
= reinterpret_cast<void*>(1234);
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),
118 m_anySignedLongLong1((wxLongLong_t
)15),
120 m_anyUnsignedChar1((unsigned char)15),
121 m_anyUnsignedShort1((unsigned short)15),
122 m_anyUnsignedInt1((unsigned int)15),
123 m_anyUnsignedLong1((unsigned long)15),
125 m_anyUnsignedLongLong1((wxULongLong_t
)15),
127 m_anyStringString1(wxString("abc")),
128 m_anyCharString1("abc"),
129 m_anyWcharString1(L
"abc"),
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())
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;
143 m_anySignedLongLong2
= (wxLongLong_t
)15;
145 m_anyUnsignedChar2
= (unsigned char)15;
146 m_anyUnsignedShort2
= (unsigned short)15;
147 m_anyUnsignedInt2
= (unsigned int)15;
148 m_anyUnsignedLong2
= (unsigned long)15;
150 m_anyUnsignedLongLong2
= (wxULongLong_t
)15;
152 m_anyStringString2
= wxString("abc");
153 m_anyCharString2
= "abc";
154 m_anyWcharString2
= L
"abc";
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
;
163 void wxAnyTestCase::Equality()
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),
182 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1
, double),
185 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1
, wxObject
*)
186 == dummyWxObjectPointer
);
187 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1
, void*) == dummyVoidPointer
);
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),
197 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2
, double),
200 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2
, wxObject
*)
201 == dummyWxObjectPointer
);
202 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2
, void*) == dummyVoidPointer
);
205 void wxAnyTestCase::As()
208 // Test getting C++ data from wxAny without dynamic conversion
209 signed char a
= wxANY_AS(m_anySignedChar1
, signed char);
210 CPPUNIT_ASSERT(a
== (signed int)15);
211 signed short b
= wxANY_AS(m_anySignedShort1
, signed short);
212 CPPUNIT_ASSERT(b
== (signed int)15);
213 signed int c
= wxANY_AS(m_anySignedInt1
, signed int);
214 CPPUNIT_ASSERT(c
== (signed int)15);
215 signed long d
= wxANY_AS(m_anySignedLong1
, signed long);
216 CPPUNIT_ASSERT(d
== (signed int)15);
218 wxLongLong_t e
= wxANY_AS(m_anySignedLongLong1
, wxLongLong_t
);
219 CPPUNIT_ASSERT(e
== (signed int)15);
221 unsigned char f
= wxANY_AS(m_anyUnsignedChar1
, unsigned char);
222 CPPUNIT_ASSERT(f
== (unsigned int)15);
223 unsigned short g
= wxANY_AS(m_anyUnsignedShort1
, unsigned short);
224 CPPUNIT_ASSERT(g
== (unsigned int)15);
225 unsigned int h
= wxANY_AS(m_anyUnsignedInt1
, unsigned int);
226 CPPUNIT_ASSERT(h
== (unsigned int)15);
227 unsigned long i
= wxANY_AS(m_anyUnsignedLong1
, unsigned long);
228 CPPUNIT_ASSERT(i
== (unsigned int)15);
230 wxULongLong_t j
= wxANY_AS(m_anyUnsignedLongLong1
, wxULongLong_t
);
231 CPPUNIT_ASSERT(j
== (unsigned int)15);
233 wxString k
= wxANY_AS(m_anyStringString1
, wxString
);
234 CPPUNIT_ASSERT(k
== "abc");
235 wxString l
= wxANY_AS(m_anyCharString1
, wxString
);
236 CPPUNIT_ASSERT(l
== "abc");
237 wxString m
= wxANY_AS(m_anyWcharString1
, wxString
);
238 CPPUNIT_ASSERT(m
== "abc");
239 bool n
= wxANY_AS(m_anyBool1
, bool);
241 float o
= wxANY_AS(m_anyFloatDouble1
, float);
242 CPPUNIT_ASSERT_DOUBLES_EQUAL(o
, TEST_FLOAT_CONST
, FEQ_DELTA
);
243 double p
= wxANY_AS(m_anyDoubleDouble1
, double);
244 CPPUNIT_ASSERT_DOUBLES_EQUAL(p
, TEST_FLOAT_CONST
, FEQ_DELTA
);
245 wxDateTime q
= wxANY_AS(m_anyDateTime1
, wxDateTime
);
246 CPPUNIT_ASSERT(q
== m_testDateTime
);
247 wxObject
* r
= wxANY_AS(m_anyWxObjectPtr1
, wxObject
*);
248 CPPUNIT_ASSERT(r
== dummyWxObjectPointer
);
249 void* s
= wxANY_AS(m_anyVoidPtr1
, void*);
250 CPPUNIT_ASSERT(s
== dummyVoidPointer
);
253 void wxAnyTestCase::Null()
256 CPPUNIT_ASSERT(a
.IsNull());
258 CPPUNIT_ASSERT(a
== -127);
260 CPPUNIT_ASSERT(a
.IsNull());
263 void wxAnyTestCase::GetAs()
266 // Test dynamic conversion
269 unsigned long ul
= 0;
271 // Let's test against float instead of double, since the former
272 // is not the native underlying type the code converts to, but
273 // should still work, all the same.
277 // Conversions from signed long type
278 res
= m_anySignedLong1
.GetAs(&ul
);
280 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(15));
281 res
= m_anySignedLong1
.GetAs(&s
);
283 CPPUNIT_ASSERT(s
== "15");
284 res
= m_anySignedLong1
.GetAs(&f
);
286 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
287 res
= m_anySignedLong1
.GetAs(&b
);
289 CPPUNIT_ASSERT(b
== true);
291 // Conversions from unsigned long type
292 res
= m_anyUnsignedLong1
.GetAs(&l
);
294 CPPUNIT_ASSERT(l
== static_cast<signed long>(15));
295 res
= m_anyUnsignedLong1
.GetAs(&s
);
297 CPPUNIT_ASSERT(s
== "15");
298 res
= m_anyUnsignedLong1
.GetAs(&f
);
300 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
301 res
= m_anyUnsignedLong1
.GetAs(&b
);
303 CPPUNIT_ASSERT(b
== true);
305 // Conversions from default "abc" string to other types
307 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&l
));
308 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&ul
));
309 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&f
));
310 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&b
));
312 // Let's test some other conversions from string that should work.
316 res
= anyString
.GetAs(&l
);
318 CPPUNIT_ASSERT(l
== static_cast<signed long>(15));
319 res
= anyString
.GetAs(&ul
);
321 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(15));
322 res
= anyString
.GetAs(&f
);
324 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
326 res
= anyString
.GetAs(&b
);
328 CPPUNIT_ASSERT(b
== true);
330 res
= anyString
.GetAs(&b
);
332 CPPUNIT_ASSERT(b
== false);
334 // Conversions from bool type
335 res
= m_anyBool1
.GetAs(&l
);
337 CPPUNIT_ASSERT(l
== static_cast<signed long>(1));
338 res
= m_anyBool1
.GetAs(&ul
);
340 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(1));
341 res
= m_anyBool1
.GetAs(&s
);
343 CPPUNIT_ASSERT(s
== "true");
344 CPPUNIT_ASSERT(!m_anyBool1
.GetAs(&f
));
346 // Conversions from floating point type
347 res
= m_anyDoubleDouble1
.GetAs(&l
);
349 CPPUNIT_ASSERT(l
== static_cast<signed long>(123));
350 res
= m_anyDoubleDouble1
.GetAs(&ul
);
352 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(123));
353 res
= m_anyDoubleDouble1
.GetAs(&s
);
356 res
= s
.ToDouble(&d2
);
358 CPPUNIT_ASSERT_DOUBLES_EQUAL(d2
, TEST_FLOAT_CONST
, FEQ_DELTA
);
362 // Test user data type specialization of wxAnyValueTypeImpl
368 MyClass( int someValue
= 32768 )
370 m_someValue
= someValue
;
375 return wxString::Format("%i", m_someValue
);
384 class wxAnyValueTypeImpl
<MyClass
> :
385 public wxAnyValueTypeImplBase
<MyClass
>
387 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<MyClass
>)
389 wxAnyValueTypeImpl() :
390 wxAnyValueTypeImplBase
<MyClass
>() { }
391 virtual ~wxAnyValueTypeImpl() { }
393 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
394 wxAnyValueType
* dstType
,
395 wxAnyValueBuffer
& dst
) const
397 MyClass value
= GetValue(src
);
399 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
401 wxString s
= value
.ToString();
402 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
412 // Following must be placed somewhere in your source code
413 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<MyClass
>)
415 void wxAnyTestCase::CustomTemplateSpecialization()
417 // Do only a minimal CheckType() test, as dynamic type conversion already
421 wxAny any
= myObject
;
423 CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any
, MyClass
) );
424 MyClass myObject2
= wxANY_AS(any
, MyClass
);
425 wxUnusedVar(myObject2
);
428 res
= any
.GetAs(&str
);
430 CPPUNIT_ASSERT_EQUAL(str
, myObject
.ToString());