+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/arrays/arrays.cpp
+// Purpose: wxArray unit test
+// Author: Wlodzimierz ABX Skiba
+// Created: 2004-04-01
+// RCS-ID: $Id$
+// Copyright: (c) 2004 Wlodzimierz Skiba
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/wx.h"
+#endif // WX_PRECOMP
+
+#include "wx/dynarray.h"
+
+#include "wx/cppunit.h"
+
+// ----------------------------------------------------------------------------
+// helpers for testing values and sizes
+// ----------------------------------------------------------------------------
+
+#define COMPARE_VALUE( array , index , value ) ( array.Item( index ) == value )
+
+#define COMPARE_2_VALUES( array , p0 , p1 ) \
+ COMPARE_VALUE( array , 0 , p0 ) && \
+ COMPARE_VALUE( array , 1 , p1 )
+
+#define COMPARE_3_VALUES( array , p0 , p1 , p2 ) \
+ COMPARE_2_VALUES( array , p0 , p1 ) && \
+ COMPARE_VALUE( array , 2 , p2 )
+
+#define COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) \
+ COMPARE_3_VALUES( array , p0 , p1 , p2 ) && \
+ COMPARE_VALUE( array , 3 , p3 )
+
+#define COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) \
+ COMPARE_4_VALUES( array , p0 , p1 , p2 , p3 ) && \
+ COMPARE_VALUE( array , 4 , p4 )
+
+#define COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) \
+ COMPARE_5_VALUES( array , p0 , p1 , p2 , p3 , p4 ) && \
+ COMPARE_VALUE( array , 5 , p5 )
+
+#define COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) \
+ COMPARE_6_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 ) && \
+ COMPARE_VALUE( array , 6 , p6 )
+
+#define COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) \
+ COMPARE_7_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 ) && \
+ COMPARE_VALUE( array , 7 , p7 )
+
+#define COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) \
+ COMPARE_8_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 ) && \
+ COMPARE_VALUE( array , 8 , p8 )
+
+#define COMPARE_10_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 , p9 ) \
+ COMPARE_9_VALUES( array , p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ) && \
+ COMPARE_VALUE( array , 9 , p9 )
+
+#define COMPARE_COUNT( array , n ) \
+ ( array.GetCount() == n ) && \
+ ( array.Last() == array.Item( n - 1 ) )
+
+// ----------------------------------------------------------------------------
+// helpers for testing wxObjArray
+// ----------------------------------------------------------------------------
+
+class Bar
+{
+public:
+ Bar(const wxString& name) : m_name(name) { ms_bars++; }
+ Bar(const Bar& bar) : m_name(bar.m_name) { ms_bars++; }
+ ~Bar() { ms_bars--; }
+
+ static size_t GetNumber() { return ms_bars; }
+
+ const wxChar *GetName() const { return m_name; }
+
+private:
+ wxString m_name;
+
+ static size_t ms_bars;
+};
+
+size_t Bar::ms_bars = 0;
+
+WX_DECLARE_OBJARRAY(Bar, ArrayBars);
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(ArrayBars);
+
+// ----------------------------------------------------------------------------
+// helpers for sorting arrays and comparing items
+// ----------------------------------------------------------------------------
+
+int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
+ const wxString& second)
+{
+ return first.length() - second.length();
+}
+
+#define DEFINE_COMPARE(name, T) \
+ \
+int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
+{ \
+ return first - second; \
+} \
+ \
+int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
+{ \
+ return *first - *second; \
+} \
+ \
+int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
+{ \
+ return *second - *first; \
+} \
+
+typedef unsigned short ushort;
+
+DEFINE_COMPARE(UShort, ushort);
+DEFINE_COMPARE(Int, int);
+
+WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
+WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
+WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
+WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
+
+// ----------------------------------------------------------------------------
+// test class
+// ----------------------------------------------------------------------------
+
+class ArraysTestCase : public CppUnit::TestCase
+{
+public:
+ ArraysTestCase() { }
+
+private:
+ CPPUNIT_TEST_SUITE( ArraysTestCase );
+ CPPUNIT_TEST( wxStringArrayTest );
+ CPPUNIT_TEST( wxObjArrayTest );
+ CPPUNIT_TEST( wxArrayUShortTest );
+ CPPUNIT_TEST( wxArrayIntTest );
+ CPPUNIT_TEST( TestSTL );
+ CPPUNIT_TEST_SUITE_END();
+
+ void wxStringArrayTest();
+ void wxObjArrayTest();
+ void wxArrayUShortTest();
+ void wxArrayIntTest();
+ void TestSTL();
+
+ DECLARE_NO_COPY_CLASS(ArraysTestCase)
+};
+
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( ArraysTestCase );
+
+// also include in it's own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ArraysTestCase, "ArraysTestCase" );
+
+void ArraysTestCase::wxStringArrayTest()
+{
+ wxArrayString a1;
+ a1.Add(_T("thermit"));
+ a1.Add(_T("condor"));
+ a1.Add(_T("lion"), 3);
+ a1.Add(_T("dog"));
+ a1.Add(_T("human"));
+ a1.Add(_T("alligator"));
+
+ CPPUNIT_ASSERT( COMPARE_8_VALUES( a1 , _T("thermit") ,
+ _T("condor") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 8 ) );
+
+ wxArrayString a2(a1);
+
+ CPPUNIT_ASSERT( COMPARE_8_VALUES( a2 , _T("thermit") ,
+ _T("condor") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 8 ) );
+
+ wxSortedArrayString a3(a1);
+
+ CPPUNIT_ASSERT( COMPARE_8_VALUES( a3 , _T("alligator") ,
+ _T("condor") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("thermit") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a3 , 8 ) );
+
+ wxSortedArrayString a4;
+ for (wxArrayString::iterator it = a1.begin(), en = a1.end(); it != en; ++it)
+ a4.Add(*it);
+
+ CPPUNIT_ASSERT( COMPARE_8_VALUES( a4 , _T("alligator") ,
+ _T("condor") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("lion") ,
+ _T("thermit") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a4 , 8 ) );
+
+ a1.RemoveAt(2,3);
+
+ CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("thermit") ,
+ _T("condor") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
+
+ a2 = a1;
+
+ CPPUNIT_ASSERT( COMPARE_5_VALUES( a2 , _T("thermit") ,
+ _T("condor") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 5 ) );
+
+ a1.Sort(false);
+
+ CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("alligator") ,
+ _T("condor") ,
+ _T("dog") ,
+ _T("human") ,
+ _T("thermit") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
+
+ a1.Sort(true);
+
+ CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("thermit") ,
+ _T("human") ,
+ _T("dog") ,
+ _T("condor") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
+
+ a1.Sort(&StringLenCompare);
+
+ CPPUNIT_ASSERT( COMPARE_5_VALUES( a1 , _T("dog") ,
+ _T("human") ,
+ _T("condor") ,
+ _T("thermit") ,
+ _T("alligator") ) );
+ CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) );
+}
+
+void ArraysTestCase::wxObjArrayTest()
+{
+ {
+ ArrayBars bars;
+ Bar bar(_T("first bar in general, second bar in array (two copies!)"));
+
+ CPPUNIT_ASSERT( bars.GetCount() == 0 );
+ CPPUNIT_ASSERT( Bar::GetNumber() == 1 );
+
+ bars.Add(new Bar(_T("first bar in array")));
+ bars.Add(bar,2);
+
+ CPPUNIT_ASSERT( bars.GetCount() == 3 );
+ CPPUNIT_ASSERT( Bar::GetNumber() == 4 );
+
+ bars.RemoveAt(1, bars.GetCount() - 1);
+
+ CPPUNIT_ASSERT( bars.GetCount() == 1 );
+ CPPUNIT_ASSERT( Bar::GetNumber() == 2 );
+
+ bars.Empty();
+
+ CPPUNIT_ASSERT( bars.GetCount() == 0 );
+ CPPUNIT_ASSERT( Bar::GetNumber() == 1 );
+ }
+ CPPUNIT_ASSERT( Bar::GetNumber() == 0 );
+}
+
+#define TestArrayOf(name) \
+ \
+void ArraysTestCase::wxArray ## name ## Test() \
+{ \
+ wxArray##name a; \
+ a.Add(1); \
+ a.Add(17,2); \
+ a.Add(5,3); \
+ a.Add(3,4); \
+ \
+ CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,17,17,5,5,5,3,3,3,3) ); \
+ CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
+ \
+ a.Sort(name ## Compare); \
+ \
+ CPPUNIT_ASSERT( COMPARE_10_VALUES(a,1,3,3,3,3,5,5,5,17,17) ); \
+ CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
+ \
+ a.Sort(name ## RevCompare); \
+ \
+ CPPUNIT_ASSERT( COMPARE_10_VALUES(a,17,17,5,5,5,3,3,3,3,1) ); \
+ CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \
+ \
+ wxSortedArray##name b; \
+ \
+ b.Add(1); \
+ b.Add(17); \
+ b.Add(5); \
+ b.Add(3); \
+ \
+ CPPUNIT_ASSERT( COMPARE_4_VALUES(b,1,3,5,17) ); \
+ CPPUNIT_ASSERT( COMPARE_COUNT( b , 4 ) ); \
+}
+
+TestArrayOf(UShort);
+
+TestArrayOf(Int);
+
+void ArraysTestCase::TestSTL()
+{
+ wxArrayInt list1;
+ wxArrayInt::iterator it, en;
+ wxArrayInt::reverse_iterator rit, ren;
+ int i;
+ for ( i = 0; i < 5; ++i )
+ list1.push_back(i);
+
+ for ( it = list1.begin(), en = list1.end(), i = 0;
+ it != en; ++it, ++i )
+ {
+ CPPUNIT_ASSERT( *it == i );
+ }
+
+ for ( rit = list1.rbegin(), ren = list1.rend(), i = 4;
+ rit != ren; ++rit, --i )
+ {
+ CPPUNIT_ASSERT( *rit == i );
+ }
+
+ CPPUNIT_ASSERT( *list1.rbegin() == *(list1.end()-1) &&
+ *list1.begin() == *(list1.rend()-1) );
+
+ it = list1.begin()+1;
+ rit = list1.rbegin()+1;
+ CPPUNIT_ASSERT( *list1.begin() == *(it-1) &&
+ *list1.rbegin() == *(rit-1) );
+
+ CPPUNIT_ASSERT( ( list1.front() == 0 ) && ( list1.back() == 4 ) );
+
+ list1.erase(list1.begin());
+ list1.erase(list1.end()-1);
+
+ for ( it = list1.begin(), en = list1.end(), i = 1;
+ it != en; ++it, ++i )
+ {
+ CPPUNIT_ASSERT( *it == i );
+ }
+}