]> git.saurik.com Git - wxWidgets.git/blame - tests/hashes/hashes.cpp
wxMax instead of max, former is always around
[wxWidgets.git] / tests / hashes / hashes.cpp
CommitLineData
cbca1e08
MB
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/hashes/hashes.cpp
3// Purpose: wxArray unit test
4// Author: Vadim Zeitlin, Mattia Barbon
5// Created: 2004-05-16
6// RCS-ID: $Id$
7// Copyright: (c) 2004 Vadim Zeitlin, Mattia Barbon
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/hash.h"
25#include "wx/hashmap.h"
26#include "wx/hashset.h"
27
28#include "wx/cppunit.h"
29
30// --------------------------------------------------------------------------
31// helper class for typed/untyped wxHashTable
32// --------------------------------------------------------------------------
33
34struct Foo
35{
36 Foo(int n_) { n = n_; count++; }
37 ~Foo() { count--; }
38
39 int n;
40
41 static size_t count;
42};
43
44size_t Foo::count = 0;
45
46struct FooObject : public wxObject
47{
48 FooObject(int n_) { n = n_; count++; }
49 ~FooObject() { count--; }
50
51 int n;
52
53 static size_t count;
54};
55
56size_t FooObject::count = 0;
57
58// --------------------------------------------------------------------------
59// test class
60// --------------------------------------------------------------------------
61
62class HashesTestCase : public CppUnit::TestCase
63{
64public:
65 HashesTestCase() { }
66
67private:
68 CPPUNIT_TEST_SUITE( HashesTestCase );
69 CPPUNIT_TEST( wxHashTableTest );
70 CPPUNIT_TEST( wxUntypedHashTableDeleteContents );
71 CPPUNIT_TEST( wxTypedHashTableTest );
72 CPPUNIT_TEST( wxHashMapTest );
73 CPPUNIT_TEST( wxHashSetTest );
74 CPPUNIT_TEST_SUITE_END();
75
76 void wxHashTableTest();
77 void wxUntypedHashTableDeleteContents();
78 void wxTypedHashTableTest();
79 void wxHashMapTest();
80 void wxHashSetTest();
81
82 DECLARE_NO_COPY_CLASS(HashesTestCase)
83};
84
85// register in the unnamed registry so that these tests are run by default
86CPPUNIT_TEST_SUITE_REGISTRATION( HashesTestCase );
87
88// also include in it's own registry so that these tests can be run alone
89CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( HashesTestCase, "HashesTestCase" );
90
91void HashesTestCase::wxHashTableTest()
92{
93 const int COUNT = 100;
94
95 {
96 wxHashTable hash(wxKEY_INTEGER, 10), hash2(wxKEY_STRING);
97 wxObject o;
98 int i;
99
100 for ( i = 0; i < COUNT; ++i )
101 hash.Put(i, &o + i);
102
103 hash.BeginFind();
104 wxHashTable::compatibility_iterator it = hash.Next();
105 i = 0;
106
107 while (it)
108 {
109 ++i;
110 it = hash.Next();
111 }
112
113 CPPUNIT_ASSERT( i == COUNT );
114
115 for ( i = 99; i >= 0; --i )
116 CPPUNIT_ASSERT( hash.Get(i) == &o + i );
117
118 for ( i = 0; i < COUNT; ++i )
119 hash.Put(i, &o + i + 20);
120
121 for ( i = 99; i >= 0; --i )
122 CPPUNIT_ASSERT( hash.Get(i) == &o + i);
123
124 for ( i = 0; i < COUNT/2; ++i )
125 CPPUNIT_ASSERT( hash.Delete(i) == &o + i);
126
127 for ( i = COUNT/2; i < COUNT; ++i )
128 CPPUNIT_ASSERT( hash.Get(i) == &o + i);
129
130 for ( i = 0; i < COUNT/2; ++i )
131 CPPUNIT_ASSERT( hash.Get(i) == &o + i + 20);
132
133 for ( i = 0; i < COUNT/2; ++i )
134 CPPUNIT_ASSERT( hash.Delete(i) == &o + i + 20);
135
136 for ( i = 0; i < COUNT/2; ++i )
137 CPPUNIT_ASSERT( hash.Get(i) == NULL);
138
139 hash2.Put(_T("foo"), &o + 1);
140 hash2.Put(_T("bar"), &o + 2);
141 hash2.Put(_T("baz"), &o + 3);
142
143 CPPUNIT_ASSERT(hash2.Get(_T("moo")) == NULL);
144 CPPUNIT_ASSERT(hash2.Get(_T("bar")) == &o + 2);
145
146 hash2.Put(_T("bar"), &o + 0);
147
148 CPPUNIT_ASSERT(hash2.Get(_T("bar")) == &o + 2);
149 }
150
151 // and now some corner-case testing; 3 and 13 hash to the same bucket
152 {
153 wxHashTable hash(wxKEY_INTEGER, 10);
154 wxObject dummy;
155
156 hash.Put(3, &dummy);
157 hash.Delete(3);
158
159 CPPUNIT_ASSERT(hash.Get(3) == NULL);
160
161 hash.Put(3, &dummy);
162 hash.Put(13, &dummy);
163 hash.Delete(3);
164
165 CPPUNIT_ASSERT(hash.Get(3) == NULL);
166
167 hash.Delete(13);
168
169 CPPUNIT_ASSERT(hash.Get(13) == NULL);
170
171 hash.Put(3, &dummy);
172 hash.Put(13, &dummy);
173 hash.Delete(13);
174
175 CPPUNIT_ASSERT(hash.Get(13) == NULL);
176
177 hash.Delete(3);
178
179 CPPUNIT_ASSERT(hash.Get(3) == NULL);
180 }
181
182 // test for key + value access (specifically that supplying either
183 // wrong key or wrong value returns NULL)
184 {
185 wxHashTable hash(wxKEY_INTEGER, 10);
186 wxObject dummy;
187
188 hash.Put(3, 7, &dummy + 7);
189 hash.Put(4, 8, &dummy + 8);
190
191 CPPUNIT_ASSERT(hash.Get(7) == NULL);
192 CPPUNIT_ASSERT(hash.Get(3, 7) == &dummy + 7);
193 CPPUNIT_ASSERT(hash.Get(4) == NULL);
194 CPPUNIT_ASSERT(hash.Get(3) == NULL);
195 CPPUNIT_ASSERT(hash.Get(8) == NULL);
196 CPPUNIT_ASSERT(hash.Get(8, 4) == NULL);
197
198 CPPUNIT_ASSERT(hash.Delete(7) == NULL);
199 CPPUNIT_ASSERT(hash.Delete(3) == NULL);
200 CPPUNIT_ASSERT(hash.Delete(3, 7) == &dummy + 7);
201 }
202
203}
204
205void HashesTestCase::wxUntypedHashTableDeleteContents()
206{
207 // need a nested scope for destruction
208 {
209 wxHashTable hash;
210 hash.DeleteContents(true);
211
212 CPPUNIT_ASSERT( hash.GetCount() == 0 );
213 CPPUNIT_ASSERT( FooObject::count == 0 );
214
215 static const int hashTestData[] =
216 {
217 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
218 };
219
220 size_t n;
221 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
222 {
223 hash.Put(hashTestData[n], n, new FooObject(n));
224 }
225
226 CPPUNIT_ASSERT( hash.GetCount() == WXSIZEOF(hashTestData) );
227 CPPUNIT_ASSERT( FooObject::count == WXSIZEOF(hashTestData) );
228
229 // delete from hash without deleting object
230 FooObject* foo = (FooObject*)hash.Delete(0l);
231
232 CPPUNIT_ASSERT( FooObject::count == WXSIZEOF(hashTestData) );
233 delete foo;
234 CPPUNIT_ASSERT( FooObject::count == WXSIZEOF(hashTestData) - 1 );
235 }
236
237 // hash destroyed
238 CPPUNIT_ASSERT( FooObject::count == 0 );
239}
240
241#if WXWIN_COMPATIBILITY_2_4
242WX_DECLARE_LIST(Foo, wxListFoos);
243#endif
244
245WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
246
247#if WXWIN_COMPATIBILITY_2_4
248#include "wx/listimpl.cpp"
249WX_DEFINE_LIST(wxListFoos);
250#endif
251
252void HashesTestCase::wxTypedHashTableTest()
253{
254 // need a nested scope for destruction
255 {
256 wxHashFoos hash;
257 hash.DeleteContents(true);
258
259 CPPUNIT_ASSERT( hash.GetCount() == 0 );
260 CPPUNIT_ASSERT( Foo::count == 0 );
261
262 static const int hashTestData[] =
263 {
264 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
265 };
266
267 size_t n;
268 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
269 {
270 hash.Put(hashTestData[n], n, new Foo(n));
271 }
272
273 CPPUNIT_ASSERT( hash.GetCount() == WXSIZEOF(hashTestData) );
274 CPPUNIT_ASSERT( Foo::count == WXSIZEOF(hashTestData) );
275
276 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
277 {
278 Foo *foo = hash.Get(hashTestData[n], n);
279
280 CPPUNIT_ASSERT( foo != NULL );
281 CPPUNIT_ASSERT( foo->n == (int)n );
282 }
283
284 // element not in hash
285 CPPUNIT_ASSERT( hash.Get(1234) == NULL );
286 CPPUNIT_ASSERT( hash.Get(1, 0) == NULL );
287
288 // delete from hash without deleting object
289 Foo* foo = hash.Delete(0);
290
291 CPPUNIT_ASSERT( Foo::count == WXSIZEOF(hashTestData) );
292 delete foo;
293 CPPUNIT_ASSERT( Foo::count == WXSIZEOF(hashTestData) - 1 );
294 }
295
296 // hash destroyed
297 CPPUNIT_ASSERT( Foo::count == 0 );
298}
299
300void HashesTestCase::wxHashMapTest()
301{
302}
303
304void HashesTestCase::wxHashSetTest()
305{
306}