]>
Commit | Line | Data |
---|---|---|
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 it's 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 | private: | |
61 | SelfPointingObject *m_self; | |
62 | }; | |
63 | ||
64 | // ---------------------------------------------------------------------------- | |
65 | // test class | |
66 | // ---------------------------------------------------------------------------- | |
67 | ||
68 | class VectorsTestCase : public CppUnit::TestCase | |
69 | { | |
70 | public: | |
71 | VectorsTestCase() {} | |
72 | ||
73 | private: | |
74 | CPPUNIT_TEST_SUITE( VectorsTestCase ); | |
75 | CPPUNIT_TEST( PushPopTest ); | |
76 | CPPUNIT_TEST( Insert ); | |
77 | CPPUNIT_TEST( Erase ); | |
78 | CPPUNIT_TEST( Iterators ); | |
79 | CPPUNIT_TEST( Objects ); | |
80 | CPPUNIT_TEST( NonPODs ); | |
81 | CPPUNIT_TEST_SUITE_END(); | |
82 | ||
83 | void PushPopTest(); | |
84 | void Insert(); | |
85 | void Erase(); | |
86 | void Iterators(); | |
87 | void Objects(); | |
88 | void NonPODs(); | |
89 | ||
90 | DECLARE_NO_COPY_CLASS(VectorsTestCase) | |
91 | }; | |
92 | ||
93 | // register in the unnamed registry so that these tests are run by default | |
94 | CPPUNIT_TEST_SUITE_REGISTRATION( VectorsTestCase ); | |
95 | ||
96 | // also include in it's own registry so that these tests can be run alone | |
97 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VectorsTestCase, "VectorsTestCase" ); | |
98 | ||
99 | void VectorsTestCase::PushPopTest() | |
100 | { | |
101 | wxVector<int> v; | |
102 | ||
103 | CPPUNIT_ASSERT( v.size() == 0 ); | |
104 | v.push_back(1); | |
105 | CPPUNIT_ASSERT( v.size() == 1 ); | |
106 | v.push_back(2); | |
107 | CPPUNIT_ASSERT( v.size() == 2 ); | |
108 | v.push_back(42); | |
109 | CPPUNIT_ASSERT( v.size() == 3 ); | |
110 | ||
111 | CPPUNIT_ASSERT( v[0] == 1 ); | |
112 | CPPUNIT_ASSERT( v[1] == 2 ); | |
113 | CPPUNIT_ASSERT( v[2] == 42 ); | |
114 | ||
115 | v.pop_back(); | |
116 | CPPUNIT_ASSERT( v.size() == 2 ); | |
117 | CPPUNIT_ASSERT( v[0] == 1 ); | |
118 | CPPUNIT_ASSERT( v[1] == 2 ); | |
119 | ||
120 | v.pop_back(); | |
121 | CPPUNIT_ASSERT( v.size() == 1 ); | |
122 | CPPUNIT_ASSERT( v[0] == 1 ); | |
123 | ||
124 | v.pop_back(); | |
125 | CPPUNIT_ASSERT( v.size() == 0 ); | |
126 | CPPUNIT_ASSERT( v.empty() ); | |
127 | ||
128 | wxVector<char> vEmpty; | |
129 | } | |
130 | ||
131 | void VectorsTestCase::Insert() | |
132 | { | |
133 | wxVector<char> v; | |
134 | ||
135 | v.insert(v.end(), 'a'); | |
136 | CPPUNIT_ASSERT( v.size() == 1 ); | |
137 | CPPUNIT_ASSERT( v[0] == 'a' ); | |
138 | ||
139 | v.insert(v.end(), 'b'); | |
140 | CPPUNIT_ASSERT( v.size() == 2 ); | |
141 | CPPUNIT_ASSERT( v[0] == 'a' ); | |
142 | CPPUNIT_ASSERT( v[1] == 'b' ); | |
143 | ||
144 | v.insert(v.begin(), '0'); | |
145 | CPPUNIT_ASSERT( v.size() == 3 ); | |
146 | CPPUNIT_ASSERT( v[0] == '0' ); | |
147 | CPPUNIT_ASSERT( v[1] == 'a' ); | |
148 | CPPUNIT_ASSERT( v[2] == 'b' ); | |
149 | ||
150 | v.insert(v.begin() + 2, 'X'); | |
151 | CPPUNIT_ASSERT( v.size() == 4 ); | |
152 | CPPUNIT_ASSERT( v[0] == '0' ); | |
153 | CPPUNIT_ASSERT( v[1] == 'a' ); | |
154 | CPPUNIT_ASSERT( v[2] == 'X' ); | |
155 | CPPUNIT_ASSERT( v[3] == 'b' ); | |
156 | } | |
157 | ||
158 | void VectorsTestCase::Erase() | |
159 | { | |
160 | wxVector<int> v; | |
161 | ||
162 | v.push_back(1); | |
163 | v.push_back(2); | |
164 | v.push_back(3); | |
165 | v.push_back(4); | |
166 | CPPUNIT_ASSERT( v.size() == 4 ); | |
167 | ||
168 | v.erase(v.begin(), v.end()-1); | |
169 | CPPUNIT_ASSERT( v.size() == 1 ); | |
170 | CPPUNIT_ASSERT( v[0] == 4 ); | |
171 | ||
172 | v.clear(); | |
173 | v.push_back(1); | |
174 | v.push_back(2); | |
175 | v.push_back(3); | |
176 | v.push_back(4); | |
177 | CPPUNIT_ASSERT( v.size() == 4 ); | |
178 | ||
179 | v.erase(v.begin()); | |
180 | CPPUNIT_ASSERT( v.size() == 3 ); | |
181 | CPPUNIT_ASSERT( v[0] == 2 ); | |
182 | CPPUNIT_ASSERT( v[1] == 3 ); | |
183 | CPPUNIT_ASSERT( v[2] == 4 ); | |
184 | } | |
185 | ||
186 | void VectorsTestCase::Iterators() | |
187 | { | |
188 | wxVector<int> v; | |
189 | v.push_back(1); | |
190 | v.push_back(2); | |
191 | v.push_back(3); | |
192 | v.push_back(4); | |
193 | ||
194 | int value = 1; | |
195 | for ( wxVector<int>::iterator i = v.begin(); i != v.end(); ++i, ++value ) | |
196 | { | |
197 | CPPUNIT_ASSERT_EQUAL( value, *i ); | |
198 | } | |
199 | } | |
200 | ||
201 | void VectorsTestCase::Objects() | |
202 | { | |
203 | wxVector<CountedObject> v; | |
204 | v.push_back(CountedObject(1)); | |
205 | v.push_back(CountedObject(2)); | |
206 | v.push_back(CountedObject(3)); | |
207 | ||
208 | v.erase(v.begin()); | |
209 | WX_ASSERT_SIZET_EQUAL( 2, v.size() ); | |
210 | CPPUNIT_ASSERT_EQUAL( 2, CountedObject::GetCount() ); | |
211 | ||
212 | v.clear(); | |
213 | CPPUNIT_ASSERT_EQUAL( 0, CountedObject::GetCount() ); | |
214 | } | |
215 | ||
216 | void VectorsTestCase::NonPODs() | |
217 | { | |
218 | wxVector<SelfPointingObject> v; | |
219 | v.push_back(SelfPointingObject()); | |
220 | v.push_back(SelfPointingObject()); | |
221 | v.push_back(SelfPointingObject()); | |
222 | ||
223 | v.erase(v.begin()); | |
224 | v.clear(); | |
225 | ||
226 | // try the same with wxString, which is not POD, but is implemented in | |
227 | // a movable way (this won't assert, but would crash or show some memory | |
228 | // problems under Valgrind if wxString couldn't be safely moved with | |
229 | // memmove()): | |
230 | wxVector<wxString> vs; | |
231 | vs.push_back("one"); | |
232 | vs.push_back("two"); | |
233 | vs.push_back("three"); | |
234 | ||
235 | vs.erase(vs.begin()); | |
236 | vs.clear(); | |
237 | } |