Fix menu event handlers calling order.
[wxWidgets.git] / tests / longlong / longlongtest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/longlong/longlong.cpp
3 // Purpose: wxLongLong unit test
4 // Author: Vadim Zeitlin, Wlodzimierz ABX Skiba
5 // Created: 2004-04-01
6 // RCS-ID: $Id$
7 // Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba
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/longlong.h"
25 #include "wx/timer.h"
26
27 #if wxUSE_LONGLONG
28
29 // ----------------------------------------------------------------------------
30 // helpers for testing
31 // ----------------------------------------------------------------------------
32
33 // number of iterations in loops
34 #define ITEMS 1000
35
36 // make a 64 bit number from 4 16 bit ones
37 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
38
39 // get a random 64 bit number
40 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
41
42 static const long testLongs[] =
43 {
44 0,
45 1,
46 -1,
47 LONG_MAX,
48 LONG_MIN,
49 0x1234,
50 -0x1234
51 };
52
53 // ----------------------------------------------------------------------------
54 // test class
55 // ----------------------------------------------------------------------------
56
57 class LongLongTestCase : public CppUnit::TestCase
58 {
59 public:
60 LongLongTestCase();
61
62 private:
63 CPPUNIT_TEST_SUITE( LongLongTestCase );
64 CPPUNIT_TEST( Conversion );
65 CPPUNIT_TEST( Comparison );
66 CPPUNIT_TEST( Addition );
67 CPPUNIT_TEST( Multiplication );
68 CPPUNIT_TEST( Division );
69 CPPUNIT_TEST( BitOperations );
70 CPPUNIT_TEST( ToString );
71 CPPUNIT_TEST( LoHi );
72 CPPUNIT_TEST( Limits );
73 CPPUNIT_TEST_SUITE_END();
74
75 void Conversion();
76 void Comparison();
77 void Addition();
78 void Multiplication();
79 void Division();
80 void BitOperations();
81 void ToString();
82 void LoHi();
83 void Limits();
84
85 DECLARE_NO_COPY_CLASS(LongLongTestCase)
86 };
87
88 // register in the unnamed registry so that these tests are run by default
89 CPPUNIT_TEST_SUITE_REGISTRATION( LongLongTestCase );
90
91 // also include in its own registry so that these tests can be run alone
92 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LongLongTestCase, "LongLongTestCase" );
93
94 LongLongTestCase::LongLongTestCase()
95 {
96 srand((unsigned)time(NULL));
97 }
98
99 void LongLongTestCase::Conversion()
100 {
101 for ( size_t n = 0; n < ITEMS; n++ )
102 {
103 wxLongLong a = RAND_LL();
104
105 wxLongLong b(a.GetHi(), a.GetLo());
106 CPPUNIT_ASSERT( a == b );
107
108 #if wxUSE_LONGLONG_WX
109 wxLongLongWx c(a.GetHi(), a.GetLo());
110 CPPUNIT_ASSERT( a == c );
111 #endif
112
113 #if wxUSE_LONGLONG_NATIVE
114 wxLongLongNative d(a.GetHi(), a.GetLo());
115 CPPUNIT_ASSERT( a == d );
116 #endif
117 }
118 }
119
120 void LongLongTestCase::Comparison()
121 {
122 static const long ls[2] =
123 {
124 0x1234,
125 -0x1234,
126 };
127
128 wxLongLong lls[2];
129 lls[0] = ls[0];
130 lls[1] = ls[1];
131
132 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
133 {
134 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
135 {
136 CPPUNIT_ASSERT( (lls[m] < testLongs[n]) == (ls[m] < testLongs[n]) );
137 CPPUNIT_ASSERT( (lls[m] > testLongs[n]) == (ls[m] > testLongs[n]) );
138 CPPUNIT_ASSERT( (lls[m] <= testLongs[n]) == (ls[m] <= testLongs[n]) );
139 CPPUNIT_ASSERT( (lls[m] >= testLongs[n]) == (ls[m] >= testLongs[n]) );
140 CPPUNIT_ASSERT( (lls[m] != testLongs[n]) == (ls[m] != testLongs[n]) );
141 CPPUNIT_ASSERT( (lls[m] == testLongs[n]) == (ls[m] == testLongs[n]) );
142 }
143 }
144 }
145
146 void LongLongTestCase::Addition()
147 {
148 for ( size_t n = 0; n < ITEMS; n++ )
149 {
150 wxLongLong a = RAND_LL();
151 wxLongLong b = RAND_LL();
152 wxLongLong c = a + b;
153
154 #if wxUSE_LONGLONG_NATIVE
155 wxLongLongNative a1 = a;
156 wxLongLongNative b1 = b;
157 wxLongLongNative c1 = a1 + b1;
158 CPPUNIT_ASSERT( c == c1 );
159 #endif
160
161 #if wxUSE_LONGLONG_WX
162 wxLongLongWx a2 = a;
163 wxLongLongWx b2 = b;
164 wxLongLongWx c2 = a2 + b2;
165 CPPUNIT_ASSERT( c == c2 );
166 #endif
167 }
168 }
169
170 void LongLongTestCase::Multiplication()
171 {
172 for ( size_t n = 0; n < ITEMS; n++ )
173 {
174 wxLongLong a = RAND_LL();
175 wxLongLong b = RAND_LL();
176 wxLongLong c = a*b;
177
178 wxLongLong a1(a.GetHi(), a.GetLo());
179 wxLongLong b1(b.GetHi(), b.GetLo());
180 wxLongLong c1 = a1*b1;
181 CPPUNIT_ASSERT( c1 == c );
182
183 #if wxUSE_LONGLONG_WX
184 wxLongLongWx a2(a.GetHi(), a.GetLo());
185 wxLongLongWx b2(b.GetHi(), b.GetLo());
186 wxLongLongWx c2 = a2*b2;
187 CPPUNIT_ASSERT( c2 == c );
188 #endif
189
190 #if wxUSE_LONGLONG_NATIVE
191 wxLongLongNative a3(a.GetHi(), a.GetLo());
192 wxLongLongNative b3(b.GetHi(), b.GetLo());
193 wxLongLongNative c3 = a3*b3;
194 CPPUNIT_ASSERT( c3 == c );
195 #endif
196 }
197 }
198
199 void LongLongTestCase::Division()
200 {
201 for ( size_t n = 0; n < ITEMS; n++ )
202 {
203 // get a random wxLongLong (shifting by 12 the MSB ensures that the
204 // multiplication will not overflow)
205 wxLongLong a = MAKE_LL((rand() >> 12), rand(), rand(), rand());
206
207 // get a random (but non null) long (not wxLongLong for now) divider
208 long l;
209 do
210 {
211 l = rand();
212 }
213 while ( !l );
214
215 wxLongLong q = a / l;
216 wxLongLong r = a % l;
217
218 CPPUNIT_ASSERT( a == ( q * l + r ) );
219
220 #if wxUSE_LONGLONG_WX
221 wxLongLongWx a1(a.GetHi(), a.GetLo());
222 wxLongLongWx q1 = a1 / l;
223 wxLongLongWx r1 = a1 % l;
224 CPPUNIT_ASSERT( q == q1 );
225 CPPUNIT_ASSERT( r == r1 );
226 CPPUNIT_ASSERT( a1 == ( q1 * l + r1 ) );
227 #endif
228
229 #if wxUSE_LONGLONG_NATIVE
230 wxLongLongNative a2(a.GetHi(), a.GetLo());
231 wxLongLongNative q2 = a2 / l;
232 wxLongLongNative r2 = a2 % l;
233 CPPUNIT_ASSERT( q == q2 );
234 CPPUNIT_ASSERT( r == r2 );
235 CPPUNIT_ASSERT( a2 == ( q2 * l + r2 ) );
236 #endif
237 }
238 }
239
240 void LongLongTestCase::BitOperations()
241 {
242 for ( size_t m = 0; m < ITEMS; m++ )
243 {
244 wxLongLong a = RAND_LL();
245
246 for ( size_t n = 0; n < 33; n++ )
247 {
248 wxLongLong b(a.GetHi(), a.GetLo()), c, d = b, e;
249 d >>= n;
250 c = b >> n;
251 CPPUNIT_ASSERT( c == d );
252 d <<= n;
253 e = c << n;
254 CPPUNIT_ASSERT( d == e );
255
256 #if wxUSE_LONGLONG_WX
257 wxLongLongWx b1(a.GetHi(), a.GetLo()), c1, d1 = b1, e1;
258 d1 >>= n;
259 c1 = b1 >> n;
260 CPPUNIT_ASSERT( c1 == d1 );
261 d1 <<= n;
262 e1 = c1 << n;
263 CPPUNIT_ASSERT( d1 == e1 );
264 #endif
265
266 #if wxUSE_LONGLONG_NATIVE
267 wxLongLongNative b2(a.GetHi(), a.GetLo()), c2, d2 = b2, e2;
268 d2 >>= n;
269 c2 = b2 >> n;
270 CPPUNIT_ASSERT( c2 == d2 );
271 d2 <<= n;
272 e2 = c2 << n;
273 CPPUNIT_ASSERT( d2 == e2 );
274 #endif
275 }
276 }
277 }
278
279 void LongLongTestCase::ToString()
280 {
281 wxString s1, s2;
282
283 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
284 {
285 wxLongLong a = testLongs[n];
286 s1 = wxString::Format(wxT("%ld"), testLongs[n]);
287 s2 = a.ToString();
288 CPPUNIT_ASSERT( s1 == s2 );
289
290 s2 = wxEmptyString;
291 s2 << a;
292 CPPUNIT_ASSERT( s1 == s2 );
293
294 #if wxUSE_LONGLONG_WX
295 wxLongLongWx a1 = testLongs[n];
296 s2 = a1.ToString();
297 CPPUNIT_ASSERT( s1 == s2 );
298 #endif
299
300 #if wxUSE_LONGLONG_NATIVE
301 wxLongLongNative a2 = testLongs[n];
302 s2 = a2.ToString();
303 CPPUNIT_ASSERT( s1 == s2 );
304 #endif
305 }
306
307 wxLongLong a(0x12345678, 0x87654321);
308 CPPUNIT_ASSERT( a.ToString() == wxT("1311768467139281697") );
309 a.Negate();
310 CPPUNIT_ASSERT( a.ToString() == wxT("-1311768467139281697") );
311
312 wxLongLong llMin(-2147483647L - 1L, 0);
313 CPPUNIT_ASSERT( llMin.ToString() == wxT("-9223372036854775808") );
314
315 #if wxUSE_LONGLONG_WX
316 wxLongLongWx a1(a.GetHi(), a.GetLo());
317 CPPUNIT_ASSERT( a1.ToString() == wxT("-1311768467139281697") );
318 a1.Negate();
319 CPPUNIT_ASSERT( a1.ToString() == wxT("1311768467139281697") );
320 #endif
321
322 #if wxUSE_LONGLONG_NATIVE
323 wxLongLongNative a2(a.GetHi(), a.GetLo());
324 CPPUNIT_ASSERT( a2.ToString() == wxT("-1311768467139281697") );
325 a2.Negate();
326 CPPUNIT_ASSERT( a2.ToString() == wxT("1311768467139281697") );
327 #endif
328
329 }
330
331 void LongLongTestCase::LoHi()
332 {
333 wxLongLong ll(123, 456);
334 CPPUNIT_ASSERT_EQUAL( 456u, ll.GetLo() );
335 CPPUNIT_ASSERT_EQUAL( 123, ll.GetHi() );
336
337 wxULongLong ull(987, 654);
338 CPPUNIT_ASSERT_EQUAL( 654u, ull.GetLo() );
339 CPPUNIT_ASSERT_EQUAL( 987u, ull.GetHi() );
340 }
341
342 void LongLongTestCase::Limits()
343 {
344 // VC6 doesn't specialize numeric_limits<> for __int64 so skip this test
345 // for it.
346 #ifndef __VISUALC6__
347 #if wxUSE_LONGLONG_NATIVE
348 CPPUNIT_ASSERT( std::numeric_limits<wxLongLong>::is_specialized );
349 CPPUNIT_ASSERT( std::numeric_limits<wxULongLong>::is_specialized );
350
351 wxULongLong maxval = std::numeric_limits<wxULongLong>::max();
352 CPPUNIT_ASSERT( maxval.ToDouble() > 0 );
353 #endif // wxUSE_LONGLONG_NATIVE
354 #endif // !__VISUALC6__
355 }
356
357 #endif // wxUSE_LONGLONG