fix bug in the test in STL build (where std::vector uses operator=() and not copy...
[wxWidgets.git] / tests / vectors / vectors.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/vectors/vectors.cpp
3 // Purpose: wxVector<T> unit test
4 // Author: Vaclav Slavik
5 // Created: 2007-07-07
6 // RCS-ID: $Id$
7 // Copyright: (c) 2007 Vaclav Slavik
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/vector.h"
25
26 // ----------------------------------------------------------------------------
27 // simple class capable of detecting leaks of its objects
28 // ----------------------------------------------------------------------------
29
30 class CountedObject
31 {
32 public:
33 CountedObject(int n = 0) : m_n(n) { ms_count++; }
34 CountedObject(const CountedObject& co) : m_n(co.m_n) { ms_count++; }
35 ~CountedObject() { ms_count--; }
36
37 int GetValue() const { return m_n; }
38
39 static int GetCount() { return ms_count; }
40
41 private:
42 static int ms_count;
43
44 int m_n;
45 };
46
47 int CountedObject::ms_count = 0;
48
49 // ----------------------------------------------------------------------------
50 // simple class capable of checking its "this" pointer validity
51 // ----------------------------------------------------------------------------
52
53 class SelfPointingObject
54 {
55 public:
56 SelfPointingObject() { m_self = this; }
57 SelfPointingObject(const SelfPointingObject&) { m_self = this; }
58 ~SelfPointingObject() { CPPUNIT_ASSERT( this == m_self ); }
59
60 // the assignment operator should not modify our "this" pointer so
61 // implement it just to prevent the default version from doing it
62 SelfPointingObject& operator=(const SelfPointingObject&) { return *this; }
63
64 private:
65 SelfPointingObject *m_self;
66 };
67
68 // ----------------------------------------------------------------------------
69 // test class
70 // ----------------------------------------------------------------------------
71
72 class VectorsTestCase : public CppUnit::TestCase
73 {
74 public:
75 VectorsTestCase() {}
76
77 private:
78 CPPUNIT_TEST_SUITE( VectorsTestCase );
79 CPPUNIT_TEST( PushPopTest );
80 CPPUNIT_TEST( Insert );
81 CPPUNIT_TEST( Erase );
82 CPPUNIT_TEST( Iterators );
83 CPPUNIT_TEST( Objects );
84 CPPUNIT_TEST( NonPODs );
85 CPPUNIT_TEST_SUITE_END();
86
87 void PushPopTest();
88 void Insert();
89 void Erase();
90 void Iterators();
91 void Objects();
92 void NonPODs();
93
94 DECLARE_NO_COPY_CLASS(VectorsTestCase)
95 };
96
97 // register in the unnamed registry so that these tests are run by default
98 CPPUNIT_TEST_SUITE_REGISTRATION( VectorsTestCase );
99
100 // also include in it's own registry so that these tests can be run alone
101 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VectorsTestCase, "VectorsTestCase" );
102
103 void VectorsTestCase::PushPopTest()
104 {
105 wxVector<int> v;
106
107 CPPUNIT_ASSERT( v.size() == 0 );
108 v.push_back(1);
109 CPPUNIT_ASSERT( v.size() == 1 );
110 v.push_back(2);
111 CPPUNIT_ASSERT( v.size() == 2 );
112 v.push_back(42);
113 CPPUNIT_ASSERT( v.size() == 3 );
114
115 CPPUNIT_ASSERT( v[0] == 1 );
116 CPPUNIT_ASSERT( v[1] == 2 );
117 CPPUNIT_ASSERT( v[2] == 42 );
118
119 v.pop_back();
120 CPPUNIT_ASSERT( v.size() == 2 );
121 CPPUNIT_ASSERT( v[0] == 1 );
122 CPPUNIT_ASSERT( v[1] == 2 );
123
124 v.pop_back();
125 CPPUNIT_ASSERT( v.size() == 1 );
126 CPPUNIT_ASSERT( v[0] == 1 );
127
128 v.pop_back();
129 CPPUNIT_ASSERT( v.size() == 0 );
130 CPPUNIT_ASSERT( v.empty() );
131
132 wxVector<char> vEmpty;
133 }
134
135 void VectorsTestCase::Insert()
136 {
137 wxVector<char> v;
138
139 v.insert(v.end(), 'a');
140 CPPUNIT_ASSERT( v.size() == 1 );
141 CPPUNIT_ASSERT( v[0] == 'a' );
142
143 v.insert(v.end(), 'b');
144 CPPUNIT_ASSERT( v.size() == 2 );
145 CPPUNIT_ASSERT( v[0] == 'a' );
146 CPPUNIT_ASSERT( v[1] == 'b' );
147
148 v.insert(v.begin(), '0');
149 CPPUNIT_ASSERT( v.size() == 3 );
150 CPPUNIT_ASSERT( v[0] == '0' );
151 CPPUNIT_ASSERT( v[1] == 'a' );
152 CPPUNIT_ASSERT( v[2] == 'b' );
153
154 v.insert(v.begin() + 2, 'X');
155 CPPUNIT_ASSERT( v.size() == 4 );
156 CPPUNIT_ASSERT( v[0] == '0' );
157 CPPUNIT_ASSERT( v[1] == 'a' );
158 CPPUNIT_ASSERT( v[2] == 'X' );
159 CPPUNIT_ASSERT( v[3] == 'b' );
160 }
161
162 void VectorsTestCase::Erase()
163 {
164 wxVector<int> v;
165
166 v.push_back(1);
167 v.push_back(2);
168 v.push_back(3);
169 v.push_back(4);
170 CPPUNIT_ASSERT( v.size() == 4 );
171
172 v.erase(v.begin(), v.end()-1);
173 CPPUNIT_ASSERT( v.size() == 1 );
174 CPPUNIT_ASSERT( v[0] == 4 );
175
176 v.clear();
177 v.push_back(1);
178 v.push_back(2);
179 v.push_back(3);
180 v.push_back(4);
181 CPPUNIT_ASSERT( v.size() == 4 );
182
183 v.erase(v.begin());
184 CPPUNIT_ASSERT( v.size() == 3 );
185 CPPUNIT_ASSERT( v[0] == 2 );
186 CPPUNIT_ASSERT( v[1] == 3 );
187 CPPUNIT_ASSERT( v[2] == 4 );
188 }
189
190 void VectorsTestCase::Iterators()
191 {
192 wxVector<int> v;
193 v.push_back(1);
194 v.push_back(2);
195 v.push_back(3);
196 v.push_back(4);
197
198 int value = 1;
199 for ( wxVector<int>::iterator i = v.begin(); i != v.end(); ++i, ++value )
200 {
201 CPPUNIT_ASSERT_EQUAL( value, *i );
202 }
203 }
204
205 void VectorsTestCase::Objects()
206 {
207 wxVector<CountedObject> v;
208 v.push_back(CountedObject(1));
209 v.push_back(CountedObject(2));
210 v.push_back(CountedObject(3));
211
212 v.erase(v.begin());
213 CPPUNIT_ASSERT_EQUAL( 2, v.size() );
214 CPPUNIT_ASSERT_EQUAL( 2, CountedObject::GetCount() );
215
216 v.clear();
217 CPPUNIT_ASSERT_EQUAL( 0, CountedObject::GetCount() );
218 }
219
220 void VectorsTestCase::NonPODs()
221 {
222 wxVector<SelfPointingObject> v;
223 v.push_back(SelfPointingObject());
224 v.push_back(SelfPointingObject());
225 v.push_back(SelfPointingObject());
226
227 v.erase(v.begin());
228 v.clear();
229
230 // try the same with wxString, which is not POD, but is implemented in
231 // a movable way (this won't assert, but would crash or show some memory
232 // problems under Valgrind if wxString couldn't be safely moved with
233 // memmove()):
234 wxVector<wxString> vs;
235 vs.push_back("one");
236 vs.push_back("two");
237 vs.push_back("three");
238
239 vs.erase(vs.begin());
240 vs.clear();
241 }