]> git.saurik.com Git - wxWidgets.git/blob - tests/arrays/arrays.cpp
fixed memory leak in Submit(cmd, false) (bug 1037115)
[wxWidgets.git] / tests / arrays / arrays.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/arrays/arrays.cpp
3 // Purpose: wxArray 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 "wx/wxprec.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/dynarray.h"
25
26 #include "wx/cppunit.h"
27
28 // ----------------------------------------------------------------------------
29 // helpers for testing values and sizes
30 // ----------------------------------------------------------------------------
31
32 #define COMPARE_VALUE( array , index , value ) ( array.Item( index ) == value )
33
34 #define COMPARE_2_VALUES( array , p0 , p1 ) \
35 COMPARE_VALUE( array , 0 , p0 ) && \
36 COMPARE_VALUE( array , 1 , p1 )
37
38 #define COMPARE_3_VALUES( array , p0 , p1 , p2 ) \
39 COMPARE_2_VALUES( array , p0 , p1 ) && \
40 COMPARE_VALUE( array , 2 , p2 )
41
42 #define COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) \
43 COMPARE_3_VALUES( array , p0 , p1 , p2 ) && \
44 COMPARE_VALUE( array , 3 , p3 )
45
46 #define COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) \
47 COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) && \
48 COMPARE_VALUE( array , 4 , p4 )
49
50 #define COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) \
51 COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) && \
52 COMPARE_VALUE( array , 5 , p5 )
53
54 #define COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) \
55 COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) && \
56 COMPARE_VALUE( array , 6 , p6 )
57
58 #define COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) \
59 COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) && \
60 COMPARE_VALUE( array , 7 , p7 )
61
62 #define COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) \
63 COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) && \
64 COMPARE_VALUE( array , 8 , p8 )
65
66 #define COMPARE_10_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 , p9 ) \
67 COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) && \
68 COMPARE_VALUE( array , 9 , p9 )
69
70 #define COMPARE_COUNT( array , n ) \
71 ( array.GetCount() == n ) && \
72 ( array.Last() == array.Item( n - 1 ) )
73
74 // ----------------------------------------------------------------------------
75 // helpers for testing wxObjArray
76 // ----------------------------------------------------------------------------
77
78 class Bar
79 {
80 public:
81 Bar(const wxString& name) : m_name(name) { ms_bars++; }
82 Bar(const Bar& bar) : m_name(bar.m_name) { ms_bars++; }
83 ~Bar() { ms_bars--; }
84
85 static size_t GetNumber() { return ms_bars; }
86
87 const wxChar *GetName() const { return m_name; }
88
89 private:
90 wxString m_name;
91
92 static size_t ms_bars;
93 };
94
95 size_t Bar::ms_bars = 0;
96
97 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
98 #include "wx/arrimpl.cpp"
99 WX_DEFINE_OBJARRAY(ArrayBars);
100
101 // ----------------------------------------------------------------------------
102 // helpers for sorting arrays and comparing items
103 // ----------------------------------------------------------------------------
104
105 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
106 const wxString& second)
107 {
108 return first.length() - second.length();
109 }
110
111 #define DEFINE_COMPARE(name, T) \
112 \
113 int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
114 { \
115 return first - second; \
116 } \
117 \
118 int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
119 { \
120 return *first - *second; \
121 } \
122 \
123 int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
124 { \
125 return *second - *first; \
126 } \
127
128 typedef unsigned short ushort;
129
130 DEFINE_COMPARE(UShort, ushort);
131 DEFINE_COMPARE(Int, int);
132
133 WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
134 WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
135 WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
136 WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
137
138 // ----------------------------------------------------------------------------
139 // test class
140 // ----------------------------------------------------------------------------
141
142 class ArraysTestCase : public CppUnit::TestCase
143 {
144 public:
145 ArraysTestCase() { }
146
147 private:
148 CPPUNIT_TEST_SUITE( ArraysTestCase );
149 CPPUNIT_TEST( wxStringArrayTest );
150 CPPUNIT_TEST( wxObjArrayTest );
151 CPPUNIT_TEST( wxArrayUShortTest );
152 CPPUNIT_TEST( wxArrayIntTest );
153 CPPUNIT_TEST( TestSTL );
154 CPPUNIT_TEST_SUITE_END();
155
156 void wxStringArrayTest();
157 void wxObjArrayTest();
158 void wxArrayUShortTest();
159 void wxArrayIntTest();
160 void TestSTL();
161
162 DECLARE_NO_COPY_CLASS(ArraysTestCase)
163 };
164
165 // register in the unnamed registry so that these tests are run by default
166 CPPUNIT_TEST_SUITE_REGISTRATION( ArraysTestCase );
167
168 // also include in it's own registry so that these tests can be run alone
169 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ArraysTestCase, "ArraysTestCase" );
170
171 void ArraysTestCase::wxStringArrayTest()
172 {
173 wxArrayString a1;
174 a1.Add(_T("thermit"));
175 a1.Add(_T("condor"));
176 a1.Add(_T("lion"), 3);
177 a1.Add(_T("dog"));
178 a1.Add(_T("human"));
179 a1.Add(_T("alligator"));
180
181 CPPUNIT_ASSERT( COMPARE_8_VALUES( a1 , _T("thermit") ,
182 _T("condor") ,
183 _T("lion") ,
184 _T("lion") ,
185 _T("lion") ,
186 _T("dog") ,
187 _T("human") ,
188 _T("alligator") ) );
189 CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 8 ) );
190
191 wxArrayString a2(a1);
192
193 CPPUNIT_ASSERT( COMPARE_8_VALUES( a2 , _T("thermit") ,
194 _T("condor") ,
195 _T("lion") ,
196 _T("lion") ,
197 _T("lion") ,
198 _T("dog") ,
199 _T("human") ,
200 _T("alligator") ) );
201 CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 8 ) );
202
203 wxSortedArrayString a3(a1);
204
205 CPPUNIT_ASSERT( COMPARE_8_VALUES( a3 , _T("alligator") ,
206 _T("condor") ,
207 _T("dog") ,
208 _T("human") ,
209 _T("lion") ,
210 _T("lion") ,
211 _T("lion") ,
212 _T("thermit") ) );
213 CPPUNIT_ASSERT( COMPARE_COUNT( a3 , 8 ) );
214
215 wxSortedArrayString a4;
216 for (wxArrayString::iterator it = a1.begin(), en = a1.end(); it != en; ++it)
217 a4.Add(*it);
218
219 CPPUNIT_ASSERT( COMPARE_8_VALUES( a4 , _T("alligator") ,
220 _T("condor") ,
221 _T("dog") ,
222 _T("human") ,
223 _T("lion") ,
224 _T("lion") ,
225 _T("lion") ,
226 _T("thermit") ) );
227 CPPUNIT_ASSERT( COMPARE_COUNT( a4 , 8 ) );
228
229 a1.RemoveAt(2,3);
230
231 CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("thermit") ,
232 _T("condor") ,
233 _T("dog") ,
234 _T("human") ,
235 _T("alligator") ) );
236 CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
237
238 a2 = a1;
239
240 CPPUNIT_ASSERT( COMPARE_5_VALUES( a2 , _T("thermit") ,
241 _T("condor") ,
242 _T("dog") ,
243 _T("human") ,
244 _T("alligator") ) );
245 CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 5 ) );
246
247 a1.Sort(false);
248
249 CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("alligator") ,
250 _T("condor") ,
251 _T("dog") ,
252 _T("human") ,
253 _T("thermit") ) );
254 CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
255
256 a1.Sort(true);
257
258 CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("thermit") ,
259 _T("human") ,
260 _T("dog") ,
261 _T("condor") ,
262 _T("alligator") ) );
263 CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
264
265 a1.Sort(&StringLenCompare);
266
267 CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("dog") ,
268 _T("human") ,
269 _T("condor") ,
270 _T("thermit") ,
271 _T("alligator") ) );
272 CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
273 }
274
275 void ArraysTestCase::wxObjArrayTest()
276 {
277 {
278 ArrayBars bars;
279 Bar bar(_T("first bar in general, second bar in array (two copies!)"));
280
281 CPPUNIT_ASSERT( bars.GetCount() == 0 );
282 CPPUNIT_ASSERT( Bar::GetNumber() == 1 );
283
284 bars.Add(new Bar(_T("first bar in array")));
285 bars.Add(bar,2);
286
287 CPPUNIT_ASSERT( bars.GetCount() == 3 );
288 CPPUNIT_ASSERT( Bar::GetNumber() == 4 );
289
290 bars.RemoveAt(1, bars.GetCount() - 1);
291
292 CPPUNIT_ASSERT( bars.GetCount() == 1 );
293 CPPUNIT_ASSERT( Bar::GetNumber() == 2 );
294
295 bars.Empty();
296
297 CPPUNIT_ASSERT( bars.GetCount() == 0 );
298 CPPUNIT_ASSERT( Bar::GetNumber() == 1 );
299 }
300 CPPUNIT_ASSERT( Bar::GetNumber() == 0 );
301 }
302
303 #define TestArrayOf(name) \
304 \
305 void ArraysTestCase::wxArray ## name ## Test() \
306 { \
307 wxArray##name a; \
308 a.Add(1); \
309 a.Add(17,2); \
310 a.Add(5,3); \
311 a.Add(3,4); \
312 \
313 CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,17,17,5,5,5,3,3,3,3) ); \
314 CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
315 \
316 a.Sort(name ## Compare); \
317 \
318 CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,3,3,3,3,5,5,5,17,17) ); \
319 CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
320 \
321 a.Sort(name ## RevCompare); \
322 \
323 CPPUNIT_ASSERT( COMPARE_10_VALUES(a,17,17,5,5,5,3,3,3,3,1) ); \
324 CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
325 \
326 wxSortedArray##name b; \
327 \
328 b.Add(1); \
329 b.Add(17); \
330 b.Add(5); \
331 b.Add(3); \
332 \
333 CPPUNIT_ASSERT( COMPARE_4_VALUES(b,1,3,5,17) ); \
334 CPPUNIT_ASSERT( COMPARE_COUNT( b , 4 ) ); \
335 }
336
337 TestArrayOf(UShort);
338
339 TestArrayOf(Int);
340
341 void ArraysTestCase::TestSTL()
342 {
343 wxArrayInt list1;
344 wxArrayInt::iterator it, en;
345 wxArrayInt::reverse_iterator rit, ren;
346 int i;
347 for ( i = 0; i < 5; ++i )
348 list1.push_back(i);
349
350 for ( it = list1.begin(), en = list1.end(), i = 0;
351 it != en; ++it, ++i )
352 {
353 CPPUNIT_ASSERT( *it == i );
354 }
355
356 for ( rit = list1.rbegin(), ren = list1.rend(), i = 4;
357 rit != ren; ++rit, --i )
358 {
359 CPPUNIT_ASSERT( *rit == i );
360 }
361
362 CPPUNIT_ASSERT( *list1.rbegin() == *(list1.end()-1) &&
363 *list1.begin() == *(list1.rend()-1) );
364
365 it = list1.begin()+1;
366 rit = list1.rbegin()+1;
367 CPPUNIT_ASSERT( *list1.begin() == *(it-1) &&
368 *list1.rbegin() == *(rit-1) );
369
370 CPPUNIT_ASSERT( ( list1.front() == 0 ) && ( list1.back() == 4 ) );
371
372 list1.erase(list1.begin());
373 list1.erase(list1.end()-1);
374
375 for ( it = list1.begin(), en = list1.end(), i = 1;
376 it != en; ++it, ++i )
377 {
378 CPPUNIT_ASSERT( *it == i );
379 }
380 }