arrays.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  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. // Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ----------------------------------------------------------------------------
  9. // headers
  10. // ----------------------------------------------------------------------------
  11. #include "testprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #ifndef WX_PRECOMP
  16. #include "wx/wx.h"
  17. #endif // WX_PRECOMP
  18. #include "wx/dynarray.h"
  19. // ----------------------------------------------------------------------------
  20. // helpers for testing values and sizes
  21. // ----------------------------------------------------------------------------
  22. #define COMPARE_VALUE( array , index , value ) ( array.Item( index ) == value )
  23. #define COMPARE_2_VALUES( array , p0 , p1 ) \
  24. COMPARE_VALUE( array , 0 , p0 ) && \
  25. COMPARE_VALUE( array , 1 , p1 )
  26. #define COMPARE_3_VALUES( array , p0 , p1 , p2 ) \
  27. COMPARE_2_VALUES( array , p0 , p1 ) && \
  28. COMPARE_VALUE( array , 2 , p2 )
  29. #define COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) \
  30. COMPARE_3_VALUES( array , p0 , p1 , p2 ) && \
  31. COMPARE_VALUE( array , 3 , p3 )
  32. #define COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) \
  33. COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) && \
  34. COMPARE_VALUE( array , 4 , p4 )
  35. #define COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) \
  36. COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) && \
  37. COMPARE_VALUE( array , 5 , p5 )
  38. #define COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) \
  39. COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) && \
  40. COMPARE_VALUE( array , 6 , p6 )
  41. #define COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) \
  42. COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) && \
  43. COMPARE_VALUE( array , 7 , p7 )
  44. #define COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) \
  45. COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) && \
  46. COMPARE_VALUE( array , 8 , p8 )
  47. #define COMPARE_10_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 , p9 ) \
  48. COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) && \
  49. COMPARE_VALUE( array , 9 , p9 )
  50. #define COMPARE_COUNT( array , n ) \
  51. ( array.GetCount() == n ) && \
  52. ( array.Last() == array.Item( n - 1 ) )
  53. // ----------------------------------------------------------------------------
  54. // helpers for testing wxObjArray
  55. // ----------------------------------------------------------------------------
  56. class Bar
  57. {
  58. public:
  59. Bar(const wxString& name) : m_name(name) { ms_bars++; }
  60. Bar(const Bar& bar) : m_name(bar.m_name) { ms_bars++; }
  61. ~Bar() { ms_bars--; }
  62. static size_t GetNumber() { return ms_bars; }
  63. const wxChar *GetName() const { return m_name.c_str(); }
  64. private:
  65. wxString m_name;
  66. static size_t ms_bars;
  67. };
  68. size_t Bar::ms_bars = 0;
  69. WX_DECLARE_OBJARRAY(Bar, ArrayBars);
  70. #include "wx/arrimpl.cpp"
  71. WX_DEFINE_OBJARRAY(ArrayBars)
  72. // ----------------------------------------------------------------------------
  73. // helpers for sorting arrays and comparing items
  74. // ----------------------------------------------------------------------------
  75. int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
  76. const wxString& second)
  77. {
  78. return first.length() - second.length();
  79. }
  80. #define DEFINE_COMPARE(name, T) \
  81. \
  82. int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
  83. { \
  84. return first - second; \
  85. } \
  86. \
  87. int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
  88. { \
  89. return *first - *second; \
  90. } \
  91. \
  92. int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
  93. { \
  94. return *second - *first; \
  95. } \
  96. typedef unsigned short ushort;
  97. DEFINE_COMPARE(Char, char)
  98. DEFINE_COMPARE(UShort, ushort)
  99. DEFINE_COMPARE(Int, int)
  100. WX_DEFINE_ARRAY_CHAR(char, wxArrayChar);
  101. WX_DEFINE_SORTED_ARRAY_CHAR(char, wxSortedArrayCharNoCmp);
  102. WX_DEFINE_SORTED_ARRAY_CMP_CHAR(char, CharCompareValues, wxSortedArrayChar);
  103. WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
  104. WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
  105. WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
  106. WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
  107. struct Item
  108. {
  109. Item(int n_ = 0) : n(n_) { }
  110. int n;
  111. };
  112. WX_DEFINE_ARRAY_PTR(Item *, ItemPtrArray);
  113. // ----------------------------------------------------------------------------
  114. // test class
  115. // ----------------------------------------------------------------------------
  116. class ArraysTestCase : public CppUnit::TestCase
  117. {
  118. public:
  119. ArraysTestCase() { }
  120. private:
  121. CPPUNIT_TEST_SUITE( ArraysTestCase );
  122. CPPUNIT_TEST( wxStringArrayTest );
  123. CPPUNIT_TEST( SortedArray );
  124. CPPUNIT_TEST( wxStringArraySplitTest );
  125. CPPUNIT_TEST( wxStringArrayJoinTest );
  126. CPPUNIT_TEST( wxStringArraySplitJoinTest );
  127. CPPUNIT_TEST( wxObjArrayTest );
  128. CPPUNIT_TEST( wxArrayUShortTest );
  129. CPPUNIT_TEST( wxArrayIntTest );
  130. CPPUNIT_TEST( wxArrayCharTest );
  131. CPPUNIT_TEST( TestSTL );
  132. CPPUNIT_TEST( Alloc );
  133. CPPUNIT_TEST( Clear );
  134. CPPUNIT_TEST( Swap );
  135. CPPUNIT_TEST( IndexFromEnd );
  136. CPPUNIT_TEST_SUITE_END();
  137. void wxStringArrayTest();
  138. void SortedArray();
  139. void wxStringArraySplitTest();
  140. void wxStringArrayJoinTest();
  141. void wxStringArraySplitJoinTest();
  142. void wxObjArrayTest();
  143. void wxArrayUShortTest();
  144. void wxArrayIntTest();
  145. void wxArrayCharTest();
  146. void TestSTL();
  147. void Alloc();
  148. void Clear();
  149. void Swap();
  150. void IndexFromEnd();
  151. DECLARE_NO_COPY_CLASS(ArraysTestCase)
  152. };
  153. // register in the unnamed registry so that these tests are run by default
  154. CPPUNIT_TEST_SUITE_REGISTRATION( ArraysTestCase );
  155. // also include in its own registry so that these tests can be run alone
  156. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ArraysTestCase, "ArraysTestCase" );
  157. void ArraysTestCase::wxStringArrayTest()
  158. {
  159. wxArrayString a1;
  160. a1.Add(wxT("thermit"));
  161. a1.Add(wxT("condor"));
  162. a1.Add(wxT("lion"), 3);
  163. a1.Add(wxT("dog"));
  164. a1.Add(wxT("human"));
  165. a1.Add(wxT("alligator"));
  166. CPPUNIT_ASSERT( COMPARE_8_VALUES( a1 , wxT("thermit") ,
  167. wxT("condor") ,
  168. wxT("lion") ,
  169. wxT("lion") ,
  170. wxT("lion") ,
  171. wxT("dog") ,
  172. wxT("human") ,
  173. wxT("alligator") ) );
  174. CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 8 ) );
  175. wxArrayString a2(a1);
  176. CPPUNIT_ASSERT( COMPARE_8_VALUES( a2 , wxT("thermit") ,
  177. wxT("condor") ,
  178. wxT("lion") ,
  179. wxT("lion") ,
  180. wxT("lion") ,
  181. wxT("dog") ,
  182. wxT("human") ,
  183. wxT("alligator") ) );
  184. CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 8 ) );
  185. wxSortedArrayString a3(a1);
  186. CPPUNIT_ASSERT( COMPARE_8_VALUES( a3 , wxT("alligator") ,
  187. wxT("condor") ,
  188. wxT("dog") ,
  189. wxT("human") ,
  190. wxT("lion") ,
  191. wxT("lion") ,
  192. wxT("lion") ,
  193. wxT("thermit") ) );
  194. CPPUNIT_ASSERT( COMPARE_COUNT( a3 , 8 ) );
  195. wxSortedArrayString a4;
  196. for (wxArrayString::iterator it = a1.begin(), en = a1.end(); it != en; ++it)
  197. a4.Add(*it);
  198. CPPUNIT_ASSERT( COMPARE_8_VALUES( a4 , wxT("alligator") ,
  199. wxT("condor") ,
  200. wxT("dog") ,
  201. wxT("human") ,
  202. wxT("lion") ,
  203. wxT("lion") ,
  204. wxT("lion") ,
  205. wxT("thermit") ) );
  206. CPPUNIT_ASSERT( COMPARE_COUNT( a4 , 8 ) );
  207. a1.RemoveAt(2,3);
  208. CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , wxT("thermit") ,
  209. wxT("condor") ,
  210. wxT("dog") ,
  211. wxT("human") ,
  212. wxT("alligator") ) );
  213. CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
  214. a2 = a1;
  215. CPPUNIT_ASSERT( COMPARE_5_VALUES( a2 , wxT("thermit") ,
  216. wxT("condor") ,
  217. wxT("dog") ,
  218. wxT("human") ,
  219. wxT("alligator") ) );
  220. CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 5 ) );
  221. a1.Sort(false);
  222. CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , wxT("alligator") ,
  223. wxT("condor") ,
  224. wxT("dog") ,
  225. wxT("human") ,
  226. wxT("thermit") ) );
  227. CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
  228. a1.Sort(true);
  229. CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , wxT("thermit") ,
  230. wxT("human") ,
  231. wxT("dog") ,
  232. wxT("condor") ,
  233. wxT("alligator") ) );
  234. CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
  235. a1.Sort(&StringLenCompare);
  236. CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , wxT("dog") ,
  237. wxT("human") ,
  238. wxT("condor") ,
  239. wxT("thermit") ,
  240. wxT("alligator") ) );
  241. CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
  242. CPPUNIT_ASSERT( a1.Index( wxT("dog") ) == 0 );
  243. CPPUNIT_ASSERT( a1.Index( wxT("human") ) == 1 );
  244. CPPUNIT_ASSERT( a1.Index( wxT("humann") ) == wxNOT_FOUND );
  245. CPPUNIT_ASSERT( a1.Index( wxT("condor") ) == 2 );
  246. CPPUNIT_ASSERT( a1.Index( wxT("thermit") ) == 3 );
  247. CPPUNIT_ASSERT( a1.Index( wxT("alligator") ) == 4 );
  248. CPPUNIT_ASSERT( a1.Index( wxT("dog"), /*bCase=*/true, /*fromEnd=*/true ) == 0 );
  249. CPPUNIT_ASSERT( a1.Index( wxT("human"), /*bCase=*/true, /*fromEnd=*/true ) == 1 );
  250. CPPUNIT_ASSERT( a1.Index( wxT("humann"), /*bCase=*/true, /*fromEnd=*/true ) == wxNOT_FOUND );
  251. CPPUNIT_ASSERT( a1.Index( wxT("condor"), /*bCase=*/true, /*fromEnd=*/true ) == 2 );
  252. CPPUNIT_ASSERT( a1.Index( wxT("thermit"), /*bCase=*/true, /*fromEnd=*/true ) == 3 );
  253. CPPUNIT_ASSERT( a1.Index( wxT("alligator"), /*bCase=*/true, /*fromEnd=*/true ) == 4 );
  254. wxArrayString a5;
  255. CPPUNIT_ASSERT( a5.Add( wxT("x"), 1 ) == 0 );
  256. CPPUNIT_ASSERT( a5.Add( wxT("a"), 3 ) == 1 );
  257. CPPUNIT_ASSERT( COMPARE_4_VALUES( a5, wxT("x") ,
  258. wxT("a") ,
  259. wxT("a") ,
  260. wxT("a") ) );
  261. a5.assign(a1.end(), a1.end());
  262. CPPUNIT_ASSERT( a5.empty() );
  263. a5.assign(a1.begin(), a1.end());
  264. CPPUNIT_ASSERT( a5 == a1 );
  265. #ifdef wxHAS_VECTOR_TEMPLATE_ASSIGN
  266. const wxString months[] = { "Jan", "Feb", "Mar" };
  267. a5.assign(months, months + WXSIZEOF(months));
  268. CPPUNIT_ASSERT_EQUAL( WXSIZEOF(months), a5.size() );
  269. CPPUNIT_ASSERT( COMPARE_3_VALUES(a5, "Jan", "Feb", "Mar") );
  270. #endif // wxHAS_VECTOR_TEMPLATE_ASSIGN
  271. a5.clear();
  272. CPPUNIT_ASSERT_EQUAL( 0, a5.size() );
  273. a5.resize(7, "Foo");
  274. CPPUNIT_ASSERT_EQUAL( 7, a5.size() );
  275. CPPUNIT_ASSERT_EQUAL( "Foo", a5[3] );
  276. a5.resize(3);
  277. CPPUNIT_ASSERT_EQUAL( 3, a5.size() );
  278. CPPUNIT_ASSERT_EQUAL( "Foo", a5[2] );
  279. }
  280. void ArraysTestCase::SortedArray()
  281. {
  282. wxSortedArrayString a;
  283. a.Add("d");
  284. a.Add("c");
  285. CPPUNIT_ASSERT_EQUAL( 0, a.Index("c") );
  286. a.push_back("b");
  287. a.push_back("a");
  288. CPPUNIT_ASSERT_EQUAL( 0, a.Index("a") );
  289. }
  290. void ArraysTestCase::wxStringArraySplitTest()
  291. {
  292. // test wxSplit:
  293. {
  294. wxString str = wxT(",,,,first,second,third,,");
  295. const wxChar *expected[] =
  296. { wxT(""), wxT(""), wxT(""), wxT(""), wxT("first"),
  297. wxT("second"), wxT("third"), wxT(""), wxT("") };
  298. wxArrayString exparr(WXSIZEOF(expected), expected);
  299. wxArrayString realarr(wxSplit(str, wxT(',')));
  300. CPPUNIT_ASSERT( exparr == realarr );
  301. }
  302. {
  303. wxString str = wxT(",\\,first,second,third,");
  304. const wxChar *expected[] =
  305. { wxT(""), wxT(",first"), wxT("second"), wxT("third"), wxT("") };
  306. const wxChar *expected2[] =
  307. { wxT(""), wxT("\\"), wxT("first"), wxT("second"), wxT("third"), wxT("") };
  308. // escaping on:
  309. wxArrayString exparr(WXSIZEOF(expected), expected);
  310. wxArrayString realarr(wxSplit(str, wxT(','), wxT('\\')));
  311. CPPUNIT_ASSERT( exparr == realarr );
  312. // escaping turned off:
  313. wxArrayString exparr2(WXSIZEOF(expected2), expected2);
  314. wxArrayString realarr2(wxSplit(str, wxT(','), wxT('\0')));
  315. CPPUNIT_ASSERT( exparr2 == realarr2 );
  316. }
  317. {
  318. // test is escape characters placed before non-separator character are
  319. // just ignored as they should:
  320. wxString str = wxT(",\\,,fir\\st,se\\cond\\,,\\third");
  321. const wxChar *expected[] =
  322. { wxT(""), wxT(","), wxT("fir\\st"), wxT("se\\cond,"), wxT("\\third") };
  323. const wxChar *expected2[] =
  324. { wxT(""), wxT("\\"), wxT(""), wxT("fir\\st"), wxT("se\\cond\\"),
  325. wxT(""), wxT("\\third") };
  326. // escaping on:
  327. wxArrayString exparr(WXSIZEOF(expected), expected);
  328. wxArrayString realarr(wxSplit(str, wxT(','), wxT('\\')));
  329. CPPUNIT_ASSERT( exparr == realarr );
  330. // escaping turned off:
  331. wxArrayString exparr2(WXSIZEOF(expected2), expected2);
  332. wxArrayString realarr2(wxSplit(str, wxT(','), wxT('\0')));
  333. CPPUNIT_ASSERT( exparr2 == realarr2 );
  334. }
  335. }
  336. void ArraysTestCase::wxStringArrayJoinTest()
  337. {
  338. // test wxJoin:
  339. {
  340. const wxChar *arr[] = { wxT("first"), wxT(""), wxT("second"), wxT("third") };
  341. wxString expected = wxT("first,,second,third");
  342. wxArrayString arrstr(WXSIZEOF(arr), arr);
  343. wxString result = wxJoin(arrstr, wxT(','));
  344. CPPUNIT_ASSERT( expected == result );
  345. }
  346. {
  347. const wxChar *arr[] = { wxT("first, word"), wxT(",,second"), wxT("third,,") };
  348. wxString expected = wxT("first\\, word,\\,\\,second,third\\,\\,");
  349. wxString expected2 = wxT("first, word,,,second,third,,");
  350. // escaping on:
  351. wxArrayString arrstr(WXSIZEOF(arr), arr);
  352. wxString result = wxJoin(arrstr, wxT(','), wxT('\\'));
  353. CPPUNIT_ASSERT( expected == result );
  354. // escaping turned off:
  355. wxString result2 = wxJoin(arrstr, wxT(','), wxT('\0'));
  356. CPPUNIT_ASSERT( expected2 == result2 );
  357. }
  358. {
  359. // test is escape characters placed in the original array are just ignored as they should:
  360. const wxChar *arr[] = { wxT("first\\, wo\\rd"), wxT("seco\\nd"), wxT("\\third\\") };
  361. wxString expected = wxT("first\\\\, wo\\rd,seco\\nd,\\third\\");
  362. wxString expected2 = wxT("first\\, wo\\rd,seco\\nd,\\third\\");
  363. // escaping on:
  364. wxArrayString arrstr(WXSIZEOF(arr), arr);
  365. wxString result = wxJoin(arrstr, wxT(','), wxT('\\'));
  366. CPPUNIT_ASSERT( expected == result );
  367. // escaping turned off:
  368. wxString result2 = wxJoin(arrstr, wxT(','), wxT('\0'));
  369. CPPUNIT_ASSERT( expected2 == result2 );
  370. }
  371. }
  372. void ArraysTestCase::wxStringArraySplitJoinTest()
  373. {
  374. wxChar separators[] = { wxT('a'), wxT(','), wxT('_'), wxT(' '), wxT('\\'),
  375. wxT('&'), wxT('{'), wxT('A'), wxT('<'), wxT('>'),
  376. wxT('\''), wxT('\n'), wxT('!'), wxT('-') };
  377. // test with a string: split it and then rejoin it:
  378. wxString str = wxT("This is a long, long test; if wxSplit and wxJoin do work ")
  379. wxT("correctly, then splitting and joining this 'text' _multiple_ ")
  380. wxT("times shouldn't cause any loss of content.\n")
  381. wxT("This is some latex code: ")
  382. wxT("\\func{wxString}{wxJoin}{")
  383. wxT("\\param{const wxArray String\\&}{ arr}, ")
  384. wxT("\\param{const wxChar}{ sep}, ")
  385. wxT("\\param{const wxChar}{ escape = '\\'}}.\n")
  386. wxT("This is some HTML code: ")
  387. wxT("<html><head><meta http-equiv=\"content-type\">")
  388. wxT("<title>Initial page of Mozilla Firefox</title>")
  389. wxT("</meta></head></html>");
  390. size_t i;
  391. for (i = 0; i < WXSIZEOF(separators); i++)
  392. {
  393. wxArrayString arr = wxSplit(str, separators[i]);
  394. CPPUNIT_ASSERT( str == wxJoin(arr, separators[i]) );
  395. }
  396. // test with an array: join it and then resplit it:
  397. const wxChar *arr[] =
  398. {
  399. wxT("first, second!"), wxT("this is the third!!"),
  400. wxT("\nThat's the fourth token\n\n"), wxT(" - fifth\ndummy\ntoken - "),
  401. wxT("_sixth__token__with_underscores"), wxT("The! Last! One!")
  402. };
  403. wxArrayString theArr(WXSIZEOF(arr), arr);
  404. for (i = 0; i < WXSIZEOF(separators); i++)
  405. {
  406. wxString string = wxJoin(theArr, separators[i]);
  407. CPPUNIT_ASSERT( theArr == wxSplit(string, separators[i]) );
  408. }
  409. wxArrayString emptyArray;
  410. wxString string = wxJoin(emptyArray, wxT(';'));
  411. CPPUNIT_ASSERT( string.empty() );
  412. CPPUNIT_ASSERT( wxSplit(string, wxT(';')).empty() );
  413. CPPUNIT_ASSERT_EQUAL( 2, wxSplit(wxT(";"), wxT(';')).size() );
  414. }
  415. void ArraysTestCase::wxObjArrayTest()
  416. {
  417. {
  418. ArrayBars bars;
  419. Bar bar(wxT("first bar in general, second bar in array (two copies!)"));
  420. CPPUNIT_ASSERT_EQUAL( 0, bars.GetCount() );
  421. CPPUNIT_ASSERT_EQUAL( 1, Bar::GetNumber() );
  422. bars.Add(new Bar(wxT("first bar in array")));
  423. bars.Add(bar, 2);
  424. CPPUNIT_ASSERT_EQUAL( 3, bars.GetCount() );
  425. CPPUNIT_ASSERT_EQUAL( 4, Bar::GetNumber() );
  426. bars.RemoveAt(1, bars.GetCount() - 1);
  427. CPPUNIT_ASSERT_EQUAL( 1, bars.GetCount() );
  428. CPPUNIT_ASSERT_EQUAL( 2, Bar::GetNumber() );
  429. bars.Empty();
  430. CPPUNIT_ASSERT_EQUAL( 0, bars.GetCount() );
  431. CPPUNIT_ASSERT_EQUAL( 1, Bar::GetNumber() );
  432. }
  433. CPPUNIT_ASSERT_EQUAL( 0, Bar::GetNumber() );
  434. }
  435. #define TestArrayOf(name) \
  436. \
  437. void ArraysTestCase::wxArray ## name ## Test() \
  438. { \
  439. wxArray##name a; \
  440. a.Add(1); \
  441. a.Add(17,2); \
  442. a.Add(5,3); \
  443. a.Add(3,4); \
  444. \
  445. CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,17,17,5,5,5,3,3,3,3) ); \
  446. CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
  447. \
  448. a.Sort(name ## Compare); \
  449. \
  450. CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,3,3,3,3,5,5,5,17,17) ); \
  451. CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
  452. \
  453. a.Sort(name ## RevCompare); \
  454. \
  455. CPPUNIT_ASSERT( COMPARE_10_VALUES(a,17,17,5,5,5,3,3,3,3,1) ); \
  456. CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
  457. \
  458. wxSortedArray##name b; \
  459. \
  460. b.Add(1); \
  461. b.Add(17); \
  462. b.Add(5); \
  463. b.Add(3); \
  464. \
  465. CPPUNIT_ASSERT( COMPARE_4_VALUES(b,1,3,5,17) ); \
  466. CPPUNIT_ASSERT( COMPARE_COUNT( b , 4 ) ); \
  467. CPPUNIT_ASSERT( b.Index( 0 ) == wxNOT_FOUND ); \
  468. CPPUNIT_ASSERT( b.Index( 1 ) == 0 ); \
  469. CPPUNIT_ASSERT( b.Index( 3 ) == 1 ); \
  470. CPPUNIT_ASSERT( b.Index( 4 ) == wxNOT_FOUND ); \
  471. CPPUNIT_ASSERT( b.Index( 5 ) == 2 ); \
  472. CPPUNIT_ASSERT( b.Index( 6 ) == wxNOT_FOUND ); \
  473. CPPUNIT_ASSERT( b.Index( 17 ) == 3 ); \
  474. }
  475. TestArrayOf(UShort)
  476. TestArrayOf(Char)
  477. TestArrayOf(Int)
  478. void ArraysTestCase::Alloc()
  479. {
  480. wxArrayInt a;
  481. a.Add(17);
  482. a.Add(9);
  483. CPPUNIT_ASSERT_EQUAL( 2, a.GetCount() );
  484. a.Alloc(1000);
  485. CPPUNIT_ASSERT_EQUAL( 2, a.GetCount() );
  486. CPPUNIT_ASSERT_EQUAL( 17, a[0] );
  487. CPPUNIT_ASSERT_EQUAL( 9, a[1] );
  488. }
  489. void ArraysTestCase::Clear()
  490. {
  491. ItemPtrArray items;
  492. WX_CLEAR_ARRAY(items);
  493. CPPUNIT_ASSERT_EQUAL( 0, items.size() );
  494. items.push_back(new Item(17));
  495. items.push_back(new Item(71));
  496. CPPUNIT_ASSERT_EQUAL( 2, items.size() );
  497. WX_CLEAR_ARRAY(items);
  498. CPPUNIT_ASSERT_EQUAL( 0, items.size() );
  499. }
  500. namespace
  501. {
  502. template <typename A, typename T>
  503. void DoTestSwap(T v1, T v2, T v3,
  504. A * WXUNUSED(dummyUglyVC6Workaround))
  505. {
  506. A a1, a2;
  507. a1.swap(a2);
  508. CPPUNIT_ASSERT( a1.empty() && a2.empty() );
  509. a1.push_back(v1);
  510. a1.swap(a2);
  511. CPPUNIT_ASSERT( a1.empty() );
  512. CPPUNIT_ASSERT_EQUAL( 1, a2.size() );
  513. a1.push_back(v2);
  514. a1.push_back(v3);
  515. a2.swap(a1);
  516. CPPUNIT_ASSERT_EQUAL( 1, a1.size() );
  517. CPPUNIT_ASSERT_EQUAL( 2, a2.size() );
  518. CPPUNIT_ASSERT_EQUAL( v1, a1[0] );
  519. CPPUNIT_ASSERT_EQUAL( v3, a2[1] );
  520. a1.swap(a2);
  521. CPPUNIT_ASSERT_EQUAL( 2, a1.size() );
  522. CPPUNIT_ASSERT_EQUAL( 1, a2.size() );
  523. }
  524. } // anonymous namespace
  525. void ArraysTestCase::Swap()
  526. {
  527. DoTestSwap("Foo", "Bar", "Baz", (wxArrayString *)NULL);
  528. DoTestSwap(1, 10, 100, (wxArrayInt *)NULL);
  529. DoTestSwap(6, 28, 496, (wxArrayLong *)NULL);
  530. }
  531. void ArraysTestCase::TestSTL()
  532. {
  533. wxArrayInt list1;
  534. wxArrayInt::iterator it, en;
  535. wxArrayInt::reverse_iterator rit, ren;
  536. int i;
  537. static const int COUNT = 5;
  538. for ( i = 0; i < COUNT; ++i )
  539. list1.push_back(i);
  540. CPPUNIT_ASSERT( list1.capacity() >= (size_t)COUNT );
  541. CPPUNIT_ASSERT_EQUAL( COUNT, list1.size() );
  542. for ( it = list1.begin(), en = list1.end(), i = 0;
  543. it != en; ++it, ++i )
  544. {
  545. CPPUNIT_ASSERT( *it == i );
  546. }
  547. CPPUNIT_ASSERT_EQUAL( COUNT, i );
  548. for ( rit = list1.rbegin(), ren = list1.rend(), i = COUNT;
  549. rit != ren; ++rit, --i )
  550. {
  551. CPPUNIT_ASSERT( *rit == i-1 );
  552. }
  553. CPPUNIT_ASSERT_EQUAL( 0, i );
  554. CPPUNIT_ASSERT( *list1.rbegin() == *(list1.end()-1) &&
  555. *list1.begin() == *(list1.rend()-1) );
  556. it = list1.begin()+1;
  557. rit = list1.rbegin()+1;
  558. CPPUNIT_ASSERT( *list1.begin() == *(it-1) &&
  559. *list1.rbegin() == *(rit-1) );
  560. CPPUNIT_ASSERT( ( list1.front() == 0 ) && ( list1.back() == COUNT - 1 ) );
  561. list1.erase(list1.begin());
  562. list1.erase(list1.end()-1);
  563. for ( it = list1.begin(), en = list1.end(), i = 1;
  564. it != en; ++it, ++i )
  565. {
  566. CPPUNIT_ASSERT( *it == i );
  567. }
  568. ItemPtrArray items;
  569. items.push_back(new Item(17));
  570. CPPUNIT_ASSERT_EQUAL( 17, (*(items.rbegin()))->n );
  571. CPPUNIT_ASSERT_EQUAL( 17, (**items.begin()).n );
  572. }
  573. void ArraysTestCase::IndexFromEnd()
  574. {
  575. wxArrayInt a;
  576. a.push_back(10);
  577. a.push_back(1);
  578. a.push_back(42);
  579. CPPUNIT_ASSERT_EQUAL( 0, a.Index(10) );
  580. CPPUNIT_ASSERT_EQUAL( 1, a.Index(1) );
  581. CPPUNIT_ASSERT_EQUAL( 2, a.Index(42) );
  582. CPPUNIT_ASSERT_EQUAL( 0, a.Index(10, /*bFromEnd=*/true) );
  583. CPPUNIT_ASSERT_EQUAL( 1, a.Index(1, /*bFromEnd=*/true) );
  584. CPPUNIT_ASSERT_EQUAL( 2, a.Index(42, /*bFromEnd=*/true) );
  585. }