]> git.saurik.com Git - wxWidgets.git/blame - tests/any/anytest.cpp
Fix wxRichTextCtrl test compilation.
[wxWidgets.git] / tests / any / anytest.cpp
CommitLineData
39601a7f
VZ
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"
97051666 20#include "wx/object.h"
85615340 21#include "wx/vector.h"
39601a7f
VZ
22
23#include <math.h>
24
25// ----------------------------------------------------------------------------
26// test class
27// ----------------------------------------------------------------------------
28
29class wxAnyTestCase : public CppUnit::TestCase
30{
31public:
32 wxAnyTestCase();
33
34private:
35 CPPUNIT_TEST_SUITE( wxAnyTestCase );
153107b4 36 CPPUNIT_TEST( CheckType );
39601a7f
VZ
37 CPPUNIT_TEST( Equality );
38 CPPUNIT_TEST( As );
39 CPPUNIT_TEST( GetAs );
62b88de2
VZ
40 // FIXME: One of these tests might result in heap corruption under PPC
41 // OS X, disable them to at least allow the subsequent tests to
42 // run as otherwise the test program just crashes.
29bdcf09 43#ifndef __WXOSX__
39601a7f 44 CPPUNIT_TEST( Null );
0bf14ab8 45 CPPUNIT_TEST( wxVariantConversions );
39601a7f 46 CPPUNIT_TEST( CustomTemplateSpecialization );
85615340 47 CPPUNIT_TEST( Misc );
62b88de2 48#endif // __WXOSX__
39601a7f
VZ
49 CPPUNIT_TEST_SUITE_END();
50
153107b4 51 void CheckType();
39601a7f
VZ
52 void Equality();
53 void As();
54 void GetAs();
55 void Null();
0bf14ab8 56 void wxVariantConversions();
39601a7f 57 void CustomTemplateSpecialization();
85615340 58 void Misc();
39601a7f
VZ
59
60 wxDateTime m_testDateTime;
61
62 wxAny m_anySignedChar1;
63 wxAny m_anySignedShort1;
64 wxAny m_anySignedInt1;
65 wxAny m_anySignedLong1;
66 wxAny m_anySignedLongLong1;
67 wxAny m_anyUnsignedChar1;
68 wxAny m_anyUnsignedShort1;
69 wxAny m_anyUnsignedInt1;
70 wxAny m_anyUnsignedLong1;
71 wxAny m_anyUnsignedLongLong1;
72 wxAny m_anyStringString1;
73 wxAny m_anyCharString1;
74 wxAny m_anyWcharString1;
75 wxAny m_anyBool1;
76 wxAny m_anyFloatDouble1;
77 wxAny m_anyDoubleDouble1;
78 wxAny m_anyWxObjectPtr1;
79 wxAny m_anyVoidPtr1;
80 wxAny m_anyDateTime1;
0bf14ab8 81 wxAny m_anyUniChar1;
39601a7f
VZ
82
83 wxAny m_anySignedChar2;
84 wxAny m_anySignedShort2;
85 wxAny m_anySignedInt2;
86 wxAny m_anySignedLong2;
87 wxAny m_anySignedLongLong2;
88 wxAny m_anyUnsignedChar2;
89 wxAny m_anyUnsignedShort2;
90 wxAny m_anyUnsignedInt2;
91 wxAny m_anyUnsignedLong2;
92 wxAny m_anyUnsignedLongLong2;
93 wxAny m_anyStringString2;
94 wxAny m_anyCharString2;
95 wxAny m_anyWcharString2;
96 wxAny m_anyBool2;
97 wxAny m_anyFloatDouble2;
98 wxAny m_anyDoubleDouble2;
99 wxAny m_anyWxObjectPtr2;
100 wxAny m_anyVoidPtr2;
101 wxAny m_anyDateTime2;
102
103 DECLARE_NO_COPY_CLASS(wxAnyTestCase)
104};
105
106// register in the unnamed registry so that these tests are run by default
107CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );
108
e3778b4d 109// also include in its own registry so that these tests can be run alone
39601a7f
VZ
110CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );
111
112// Let's use a number with first digit after decimal dot less than 5,
113// so that we don't have to worry about whether conversion from float
114// to int truncates or rounds.
d517b606
JS
115const float TEST_FLOAT_CONST = 123.456f;
116const double TEST_DOUBLE_CONST = 123.456;
39601a7f
VZ
117
118const double FEQ_DELTA = 0.001;
119
120wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);
121void* dummyVoidPointer = reinterpret_cast<void*>(1234);
122
123
124//
125// Test both 'creation' methods
126wxAnyTestCase::wxAnyTestCase()
127 : m_anySignedChar1((signed char)15),
128 m_anySignedShort1((signed short)15),
129 m_anySignedInt1((signed int)15),
130 m_anySignedLong1((signed long)15),
131#ifdef wxLongLong_t
132 m_anySignedLongLong1((wxLongLong_t)15),
133#endif
134 m_anyUnsignedChar1((unsigned char)15),
135 m_anyUnsignedShort1((unsigned short)15),
136 m_anyUnsignedInt1((unsigned int)15),
137 m_anyUnsignedLong1((unsigned long)15),
138#ifdef wxLongLong_t
139 m_anyUnsignedLongLong1((wxULongLong_t)15),
140#endif
141 m_anyStringString1(wxString("abc")),
142 m_anyCharString1("abc"),
143 m_anyWcharString1(L"abc"),
144 m_anyBool1(true),
d517b606
JS
145 m_anyFloatDouble1(TEST_FLOAT_CONST),
146 m_anyDoubleDouble1(TEST_DOUBLE_CONST),
39601a7f
VZ
147 m_anyWxObjectPtr1(dummyWxObjectPointer),
148 m_anyVoidPtr1(dummyVoidPointer),
149 m_anyDateTime1(wxDateTime::Now())
150{
151 m_testDateTime = wxDateTime::Now();
152 m_anySignedChar2 = (signed char)15;
153 m_anySignedShort2 = (signed short)15;
154 m_anySignedInt2 = (signed int)15;
155 m_anySignedLong2 = (signed long)15;
156#ifdef wxLongLong_t
157 m_anySignedLongLong2 = (wxLongLong_t)15;
158#endif
159 m_anyUnsignedChar2 = (unsigned char)15;
160 m_anyUnsignedShort2 = (unsigned short)15;
161 m_anyUnsignedInt2 = (unsigned int)15;
162 m_anyUnsignedLong2 = (unsigned long)15;
163#ifdef wxLongLong_t
164 m_anyUnsignedLongLong2 = (wxULongLong_t)15;
165#endif
166 m_anyStringString2 = wxString("abc");
167 m_anyCharString2 = "abc";
168 m_anyWcharString2 = L"abc";
169 m_anyBool2 = true;
d517b606
JS
170 m_anyFloatDouble2 = TEST_FLOAT_CONST;
171 m_anyDoubleDouble2 = TEST_DOUBLE_CONST;
39601a7f 172 m_anyDateTime2 = m_testDateTime;
0bf14ab8 173 m_anyUniChar1 = wxUniChar('A');
39601a7f
VZ
174 m_anyWxObjectPtr2 = dummyWxObjectPointer;
175 m_anyVoidPtr2 = dummyVoidPointer;
176}
177
153107b4
JS
178void wxAnyTestCase::CheckType()
179{
180 wxAny nullAny;
181 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(nullAny, wxString));
182
183 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyCharString2, const char*));
184 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2, wxString));
185 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2, const wchar_t*));
186 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyWcharString2, const wchar_t*));
187 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2, wxString));
188 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2, const char*));
f1156cbb
JS
189
190 // HasSameType()
191 CPPUNIT_ASSERT( m_anyWcharString1.HasSameType(m_anyWcharString2) );
192 CPPUNIT_ASSERT( !m_anyWcharString1.HasSameType(m_anyBool1) );
153107b4
JS
193}
194
39601a7f
VZ
195void wxAnyTestCase::Equality()
196{
197 //
198 // Currently this should work
199 CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);
200 CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);
201 CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);
202 CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);
203 CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));
204 CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));
205 CPPUNIT_ASSERT(m_anyStringString1 == "abc");
206 CPPUNIT_ASSERT(m_anyStringString1 != "ABC");
207 CPPUNIT_ASSERT(m_anyStringString1 == L"abc");
208 CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");
209 CPPUNIT_ASSERT(m_anyBool1 == true);
210 CPPUNIT_ASSERT(m_anyBool1 != false);
211 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
212 wxANY_AS(m_anyDoubleDouble1, double),
213 FEQ_DELTA);
214 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
215 TEST_FLOAT_CONST,
216 FEQ_DELTA);
217 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)
218 == dummyWxObjectPointer);
219 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);
220
221 CPPUNIT_ASSERT(m_anySignedLong2 == 15);
222 CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));
223 CPPUNIT_ASSERT(m_anyStringString2 == "abc");
224 CPPUNIT_ASSERT(m_anyStringString2 == L"abc");
225 CPPUNIT_ASSERT(m_anyBool2 == true);
226 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
227 wxANY_AS(m_anyDoubleDouble2, double),
228 FEQ_DELTA);
229 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
230 TEST_FLOAT_CONST,
231 FEQ_DELTA);
232 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)
233 == dummyWxObjectPointer);
234 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);
7db064f6
JS
235
236 // Test sub-type system type compatibility
237 CPPUNIT_ASSERT(m_anySignedShort1.GetType()->
238 IsSameType(m_anySignedLongLong1.GetType()));
239 CPPUNIT_ASSERT(m_anyUnsignedShort1.GetType()->
240 IsSameType(m_anyUnsignedLongLong1.GetType()));
39601a7f
VZ
241}
242
243void wxAnyTestCase::As()
244{
245 //
246 // Test getting C++ data from wxAny without dynamic conversion
247 signed char a = wxANY_AS(m_anySignedChar1, signed char);
248 CPPUNIT_ASSERT(a == (signed int)15);
249 signed short b = wxANY_AS(m_anySignedShort1, signed short);
250 CPPUNIT_ASSERT(b == (signed int)15);
251 signed int c = wxANY_AS(m_anySignedInt1, signed int);
252 CPPUNIT_ASSERT(c == (signed int)15);
253 signed long d = wxANY_AS(m_anySignedLong1, signed long);
254 CPPUNIT_ASSERT(d == (signed int)15);
255#ifdef wxLongLong_t
256 wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);
257 CPPUNIT_ASSERT(e == (signed int)15);
258#endif
259 unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);
260 CPPUNIT_ASSERT(f == (unsigned int)15);
261 unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);
262 CPPUNIT_ASSERT(g == (unsigned int)15);
263 unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);
264 CPPUNIT_ASSERT(h == (unsigned int)15);
265 unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);
266 CPPUNIT_ASSERT(i == (unsigned int)15);
267#ifdef wxLongLong_t
268 wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);
269 CPPUNIT_ASSERT(j == (unsigned int)15);
270#endif
271 wxString k = wxANY_AS(m_anyStringString1, wxString);
272 CPPUNIT_ASSERT(k == "abc");
273 wxString l = wxANY_AS(m_anyCharString1, wxString);
153107b4 274 const char* cptr = wxANY_AS(m_anyCharString1, const char*);
39601a7f 275 CPPUNIT_ASSERT(l == "abc");
153107b4 276 CPPUNIT_ASSERT(cptr);
39601a7f 277 wxString m = wxANY_AS(m_anyWcharString1, wxString);
153107b4
JS
278 const wchar_t* wcptr = wxANY_AS(m_anyWcharString1, const wchar_t*);
279 CPPUNIT_ASSERT(wcptr);
39601a7f
VZ
280 CPPUNIT_ASSERT(m == "abc");
281 bool n = wxANY_AS(m_anyBool1, bool);
282 CPPUNIT_ASSERT(n);
d517b606
JS
283
284 // Make sure the stored float that comes back is -identical-.
285 // So do not use delta comparison here.
39601a7f 286 float o = wxANY_AS(m_anyFloatDouble1, float);
d517b606
JS
287 CPPUNIT_ASSERT_EQUAL(o, TEST_FLOAT_CONST);
288
39601a7f 289 double p = wxANY_AS(m_anyDoubleDouble1, double);
d517b606
JS
290 CPPUNIT_ASSERT_EQUAL(p, TEST_DOUBLE_CONST);
291
0bf14ab8
JS
292 wxUniChar chr = wxANY_AS(m_anyUniChar1, wxUniChar);
293 CPPUNIT_ASSERT(chr == 'A');
39601a7f
VZ
294 wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);
295 CPPUNIT_ASSERT(q == m_testDateTime);
296 wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);
297 CPPUNIT_ASSERT(r == dummyWxObjectPointer);
298 void* s = wxANY_AS(m_anyVoidPtr1, void*);
299 CPPUNIT_ASSERT(s == dummyVoidPointer);
300}
301
302void wxAnyTestCase::Null()
303{
304 wxAny a;
305 CPPUNIT_ASSERT(a.IsNull());
306 a = -127;
307 CPPUNIT_ASSERT(a == -127);
308 a.MakeNull();
309 CPPUNIT_ASSERT(a.IsNull());
310}
311
312void wxAnyTestCase::GetAs()
313{
314 //
315 // Test dynamic conversion
316 bool res;
317 long l = 0;
7db064f6 318 short int si = 0;
39601a7f
VZ
319 unsigned long ul = 0;
320 wxString s;
321 // Let's test against float instead of double, since the former
322 // is not the native underlying type the code converts to, but
323 // should still work, all the same.
324 float f = 0.0;
325 bool b = false;
326
327 // Conversions from signed long type
7db064f6
JS
328 // The first check should be enough to make sure that the sub-type system
329 // has not failed.
330 res = m_anySignedLong1.GetAs(&si);
331 CPPUNIT_ASSERT(res);
332 CPPUNIT_ASSERT_EQUAL(si, 15);
39601a7f
VZ
333 res = m_anySignedLong1.GetAs(&ul);
334 CPPUNIT_ASSERT(res);
7db064f6 335 CPPUNIT_ASSERT_EQUAL(ul, 15UL);
39601a7f
VZ
336 res = m_anySignedLong1.GetAs(&s);
337 CPPUNIT_ASSERT(res);
338 CPPUNIT_ASSERT(s == "15");
339 res = m_anySignedLong1.GetAs(&f);
340 CPPUNIT_ASSERT(res);
341 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
342 res = m_anySignedLong1.GetAs(&b);
343 CPPUNIT_ASSERT(res);
344 CPPUNIT_ASSERT(b == true);
345
346 // Conversions from unsigned long type
347 res = m_anyUnsignedLong1.GetAs(&l);
348 CPPUNIT_ASSERT(res);
349 CPPUNIT_ASSERT(l == static_cast<signed long>(15));
350 res = m_anyUnsignedLong1.GetAs(&s);
351 CPPUNIT_ASSERT(res);
352 CPPUNIT_ASSERT(s == "15");
353 res = m_anyUnsignedLong1.GetAs(&f);
354 CPPUNIT_ASSERT(res);
355 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
356 res = m_anyUnsignedLong1.GetAs(&b);
357 CPPUNIT_ASSERT(res);
358 CPPUNIT_ASSERT(b == true);
359
360 // Conversions from default "abc" string to other types
361 // should not work.
362 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));
363 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));
364 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));
365 CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));
366
367 // Let's test some other conversions from string that should work.
368 wxAny anyString;
369
370 anyString = "15";
371 res = anyString.GetAs(&l);
372 CPPUNIT_ASSERT(res);
373 CPPUNIT_ASSERT(l == static_cast<signed long>(15));
374 res = anyString.GetAs(&ul);
375 CPPUNIT_ASSERT(res);
376 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
377 res = anyString.GetAs(&f);
378 CPPUNIT_ASSERT(res);
379 CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
380 anyString = "TRUE";
381 res = anyString.GetAs(&b);
382 CPPUNIT_ASSERT(res);
383 CPPUNIT_ASSERT(b == true);
384 anyString = "0";
385 res = anyString.GetAs(&b);
386 CPPUNIT_ASSERT(res);
387 CPPUNIT_ASSERT(b == false);
388
389 // Conversions from bool type
390 res = m_anyBool1.GetAs(&l);
391 CPPUNIT_ASSERT(res);
392 CPPUNIT_ASSERT(l == static_cast<signed long>(1));
393 res = m_anyBool1.GetAs(&ul);
394 CPPUNIT_ASSERT(res);
395 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));
396 res = m_anyBool1.GetAs(&s);
397 CPPUNIT_ASSERT(res);
398 CPPUNIT_ASSERT(s == "true");
399 CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));
400
401 // Conversions from floating point type
402 res = m_anyDoubleDouble1.GetAs(&l);
403 CPPUNIT_ASSERT(res);
404 CPPUNIT_ASSERT(l == static_cast<signed long>(123));
405 res = m_anyDoubleDouble1.GetAs(&ul);
406 CPPUNIT_ASSERT(res);
407 CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));
408 res = m_anyDoubleDouble1.GetAs(&s);
409 CPPUNIT_ASSERT(res);
410 double d2;
411 res = s.ToDouble(&d2);
412 CPPUNIT_ASSERT(res);
413 CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);
414}
415
0bf14ab8 416
39601a7f 417//
0bf14ab8 418// Test user data type for wxAnyValueTypeImpl specialization
85615340
JS
419// any hand-built wxVariantData. Also for inplace allocation
420// sanity checks.
39601a7f
VZ
421//
422
85615340
JS
423class MyClass;
424
425static wxVector<MyClass*> gs_myClassInstances;
426
39601a7f
VZ
427class MyClass
428{
429public:
430 MyClass( int someValue = 32768 )
431 {
85615340 432 Init();
39601a7f
VZ
433 m_someValue = someValue;
434 }
85615340
JS
435 MyClass( const MyClass& other )
436 {
437 Init();
438 m_someValue = other.m_someValue;
439 }
440 virtual ~MyClass()
441 {
442 for ( size_t i=0; i<gs_myClassInstances.size(); i++ )
443 {
444 if ( gs_myClassInstances[i] == this )
445 {
446 gs_myClassInstances.erase(gs_myClassInstances.begin()+i);
447 }
448 }
449 }
450
451 int GetValue() const
452 {
453 return m_someValue;
454 }
39601a7f
VZ
455
456 wxString ToString()
457 {
458 return wxString::Format("%i", m_someValue);
459 }
460
461private:
85615340
JS
462 void Init()
463 {
464 // We use this for some sanity checking
465 gs_myClassInstances.push_back(this);
466 }
467
39601a7f
VZ
468 int m_someValue;
469};
470
471
0bf14ab8
JS
472#if wxUSE_VARIANT
473
474// For testing purposes, create dummy variant data implementation
475// that does not have wxAny conversion code
476class wxMyVariantData : public wxVariantData
477{
478public:
479 wxMyVariantData(const MyClass& value)
480 {
481 m_value = value;
482 }
483
484 virtual bool Eq(wxVariantData& WXUNUSED(data)) const
485 {
486 return false;
487 }
488
489 // What type is it? Return a string name.
490 virtual wxString GetType() const { return "MyClass"; }
491
492 virtual wxVariantData* Clone() const
493 {
494 return new wxMyVariantData(m_value);
495 }
496
497protected:
498 MyClass m_value;
499};
500
501#endif // wxUSE_VARIANT
502
503
504void wxAnyTestCase::wxVariantConversions()
505{
506#if wxUSE_VARIANT
507 //
508 // Test various conversions to and from wxVariant
509 //
510 bool res;
511
512 // Prepare wxVariants
513 wxVariant vLong(123L);
514 wxVariant vString("ABC");
515 wxVariant vDouble(TEST_FLOAT_CONST);
516 wxVariant vBool((bool)true);
517 wxVariant vChar('A');
518#ifdef wxLongLong_t
fdfd6499 519 wxVariant vLongLong(wxLongLong(wxLL(0xAABBBBCCCC)));
0bf14ab8
JS
520 wxVariant vULongLong(wxULongLong(wxULL(123456)));
521#endif
522 wxArrayString arrstr;
523 arrstr.push_back("test string");
524 wxVariant vArrayString(arrstr);
525 wxVariant vDateTime(m_testDateTime);
526 wxVariant vVoidPtr(dummyVoidPointer);
527 wxVariant vCustomType(new wxMyVariantData(MyClass(101)));
528 wxVariant vList;
529
530 vList.NullList();
531 vList.Append(15);
532 vList.Append("abc");
533
534 // Convert to wxAnys, and then back to wxVariants
535 wxVariant variant;
536
537 wxAny any(vLong);
538 CPPUNIT_ASSERT(any == 123L);
539 res = any.GetAs(&variant);
540 CPPUNIT_ASSERT(res);
541 CPPUNIT_ASSERT(variant == 123L);
542
543 // Make sure integer variant has correct type information
544 CPPUNIT_ASSERT(variant.GetLong() == 123);
545 CPPUNIT_ASSERT(variant.GetType() == "long");
546
547 // Unsigned long wxAny should convert to "ulonglong" wxVariant
548 any = 1000UL;
549 res = any.GetAs(&variant);
550 CPPUNIT_ASSERT(res);
551 CPPUNIT_ASSERT(variant.GetType() == "ulonglong");
552 CPPUNIT_ASSERT(variant.GetLong() == 1000);
553
49efebe2 554 any = vString;
0bf14ab8
JS
555 CPPUNIT_ASSERT(any == "ABC");
556 res = any.GetAs(&variant);
557 CPPUNIT_ASSERT(res);
558 CPPUNIT_ASSERT(variant.GetString() == "ABC");
559
153107b4
JS
560 // Must be able to build string wxVariant from wxAny built from
561 // string literal
562 any = "ABC";
563 res = any.GetAs(&variant);
564 CPPUNIT_ASSERT(res);
565 CPPUNIT_ASSERT(variant.GetType() == "string");
566 CPPUNIT_ASSERT(variant.GetString() == "ABC");
567 any = L"ABC";
568 res = any.GetAs(&variant);
569 CPPUNIT_ASSERT(res);
570 CPPUNIT_ASSERT(variant.GetType() == "string");
486b9734 571#if wxUSE_UNICODE
153107b4 572 CPPUNIT_ASSERT(variant.GetString() == L"ABC");
486b9734 573#endif
153107b4 574
49efebe2 575 any = vDouble;
0bf14ab8
JS
576 double d = wxANY_AS(any, double);
577 CPPUNIT_ASSERT_DOUBLES_EQUAL(d, TEST_FLOAT_CONST, FEQ_DELTA);
578 res = any.GetAs(&variant);
579 CPPUNIT_ASSERT(res);
580 CPPUNIT_ASSERT_DOUBLES_EQUAL(variant.GetDouble(),
581 TEST_FLOAT_CONST,
582 FEQ_DELTA);
583
49efebe2 584 any = vBool;
0bf14ab8
JS
585 CPPUNIT_ASSERT(wxANY_AS(any, bool) == true);
586 res = any.GetAs(&variant);
587 CPPUNIT_ASSERT(res);
588 CPPUNIT_ASSERT(variant.GetBool() == true);
589
0aaed451 590 any = wxAny(vChar);
0bf14ab8
JS
591 //CPPUNIT_ASSERT(wxANY_AS(any, wxUniChar) == 'A');
592 res = any.GetAs(&variant);
593 CPPUNIT_ASSERT(res);
594 CPPUNIT_ASSERT(variant.GetChar() == 'A');
595
596#ifdef wxLongLong_t
0aaed451 597 any = wxAny(vLongLong);
fdfd6499 598 CPPUNIT_ASSERT(any == wxLL(0xAABBBBCCCC));
0bf14ab8
JS
599 res = any.GetAs(&variant);
600 CPPUNIT_ASSERT(res);
0bf14ab8 601 CPPUNIT_ASSERT(variant.GetType() == "longlong");
fdfd6499
JS
602 CPPUNIT_ASSERT(variant.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
603
604#if LONG_MAX == wxINT64_MAX
605 // As a sanity check, test that wxVariant of type 'long' converts
606 // seamlessly to 'longlong' (on some 64-bit systems)
607 any = 0xAABBBBCCCCL;
608 res = any.GetAs(&variant);
609 CPPUNIT_ASSERT(variant.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
610#endif
0bf14ab8 611
0aaed451 612 any = wxAny(vULongLong);
0bf14ab8
JS
613 CPPUNIT_ASSERT(any == wxLL(123456));
614 res = any.GetAs(&variant);
615 CPPUNIT_ASSERT(res);
fdfd6499 616 CPPUNIT_ASSERT(variant.GetType() == "ulonglong");
0bf14ab8
JS
617 CPPUNIT_ASSERT(variant.GetULongLong() == wxULongLong(wxULL(123456)));
618#endif
619
620 // Cannot test equality for the rest, just test that they convert
621 // back correctly.
0aaed451 622 any = wxAny(vArrayString);
0bf14ab8
JS
623 res = any.GetAs(&variant);
624 CPPUNIT_ASSERT(res);
625 wxArrayString arrstr2 = variant.GetArrayString();
626 CPPUNIT_ASSERT(arrstr2 == arrstr);
627
628 any = m_testDateTime;
629 CPPUNIT_ASSERT(wxANY_AS(any, wxDateTime) == m_testDateTime);
0aaed451 630 any = wxAny(vDateTime);
0bf14ab8
JS
631 CPPUNIT_ASSERT(wxANY_AS(any, wxDateTime) == m_testDateTime);
632 res = any.GetAs(&variant);
633 CPPUNIT_ASSERT(res);
634 CPPUNIT_ASSERT(variant == m_testDateTime);
635
0aaed451 636 any = wxAny(vVoidPtr);
0bf14ab8
JS
637 res = any.GetAs(&variant);
638 CPPUNIT_ASSERT(res);
639 CPPUNIT_ASSERT(variant.GetVoidPtr() == dummyVoidPointer);
640
0aaed451 641 any = wxAny(vList);
0bf14ab8
JS
642 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxAnyList));
643 wxAnyList anyList = wxANY_AS(any, wxAnyList);
644 CPPUNIT_ASSERT(anyList.GetCount() == 2);
645 CPPUNIT_ASSERT(wxANY_AS((*anyList[0]), int) == 15);
646 CPPUNIT_ASSERT(wxANY_AS((*anyList[1]), wxString) == "abc");
647 res = any.GetAs(&variant);
648 CPPUNIT_ASSERT(res);
649 CPPUNIT_ASSERT(variant.GetType() == "list");
650 CPPUNIT_ASSERT(variant.GetCount() == 2);
651 CPPUNIT_ASSERT(variant[0].GetLong() == 15);
652 CPPUNIT_ASSERT(variant[1].GetString() == "abc");
653
0aaed451 654 any = wxAny(vCustomType);
0bf14ab8
JS
655 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxVariantData*));
656 res = any.GetAs(&variant);
657 CPPUNIT_ASSERT(res);
658 CPPUNIT_ASSERT(variant.GetType() == "MyClass");
659
660#endif // wxUSE_VARIANT
661}
662
39601a7f
VZ
663template<>
664class wxAnyValueTypeImpl<MyClass> :
665 public wxAnyValueTypeImplBase<MyClass>
666{
667 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
668public:
669 wxAnyValueTypeImpl() :
670 wxAnyValueTypeImplBase<MyClass>() { }
671 virtual ~wxAnyValueTypeImpl() { }
672
673 virtual bool ConvertValue(const wxAnyValueBuffer& src,
674 wxAnyValueType* dstType,
675 wxAnyValueBuffer& dst) const
676 {
677 MyClass value = GetValue(src);
678
679 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
680 {
681 wxString s = value.ToString();
682 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
683 }
684 else
685 return false;
686
687 return true;
688 }
689};
690
691//
692// Following must be placed somewhere in your source code
693WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
694
695void wxAnyTestCase::CustomTemplateSpecialization()
696{
697 // Do only a minimal CheckType() test, as dynamic type conversion already
698 // uses it a lot.
699 bool res;
700 MyClass myObject;
701 wxAny any = myObject;
702
703 CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );
704 MyClass myObject2 = wxANY_AS(any, MyClass);
705 wxUnusedVar(myObject2);
706
707 wxString str;
708 res = any.GetAs(&str);
709 CPPUNIT_ASSERT(res);
710 CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());
711}
712
85615340
JS
713void wxAnyTestCase::Misc()
714{
715 // Do some (inplace) allocation sanity checks
716 {
717
718 // Do it inside a scope so we can easily test instance count
719 // afterwards
720 MyClass myObject(15);
721 wxAny any = myObject;
722
723 // There must be two instances - first in myObject,
724 // and second copied in any.
725 CPPUNIT_ASSERT_EQUAL(gs_myClassInstances.size(), 2);
726
727 // Check that it is allocated in-place, as supposed
728 if ( sizeof(MyClass) <= WX_ANY_VALUE_BUFFER_SIZE )
729 {
730 // Memory block of the instance second must be inside the any
731 size_t anyBegin = reinterpret_cast<size_t>(&any);
732 size_t anyEnd = anyBegin + sizeof(wxAny);
733 size_t pos = reinterpret_cast<size_t>(gs_myClassInstances[1]);
734 CPPUNIT_ASSERT( pos >= anyBegin );
735 CPPUNIT_ASSERT( pos < anyEnd );
736 }
737
738 wxAny any2 = any;
7c225789 739 CPPUNIT_ASSERT( wxANY_AS(any2, MyClass).GetValue() == 15 );
85615340
JS
740 }
741
742 // Make sure allocations and deallocations match
743 CPPUNIT_ASSERT_EQUAL(gs_myClassInstances.size(), 0);
744}
745
39601a7f
VZ
746#endif // wxUSE_ANY
747