Don't use GetThreadId() in wxMSW code.
[wxWidgets.git] / tests / strings / tokenizer.cpp
0 / 272 (  0%)
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/strings/strings.cpp
3// Purpose: wxStringTokenizer unit test
4// Author: Vadim Zeitlin
5// Created: 2005-12-20 (extacted from strings.cpp)
6// RCS-ID: $Id$
7// Copyright: (c) 2004-2005 Vadim Zeitlin
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/tokenzr.h"
25
26// ----------------------------------------------------------------------------
27// test class
28// ----------------------------------------------------------------------------
29
30class TokenizerTestCase : public CppUnit::TestCase
31{
32public:
33 TokenizerTestCase() { }
34
35private:
36 CPPUNIT_TEST_SUITE( TokenizerTestCase );
37 CPPUNIT_TEST( GetCount );
38 CPPUNIT_TEST( GetPosition );
39 CPPUNIT_TEST( GetString );
40 CPPUNIT_TEST( LastDelimiter );
41 CPPUNIT_TEST( StrtokCompat );
42 CPPUNIT_TEST_SUITE_END();
43
44 void GetCount();
45 void GetPosition();
46 void GetString();
47 void LastDelimiter();
48 void StrtokCompat();
49
50 DECLARE_NO_COPY_CLASS(TokenizerTestCase)
51};
52
53// register in the unnamed registry so that these tests are run by default
54CPPUNIT_TEST_SUITE_REGISTRATION( TokenizerTestCase );
55
56// also include in its own registry so that these tests can be run alone
57CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TokenizerTestCase, "TokenizerTestCase" );
58
59// ----------------------------------------------------------------------------
60// test data
61// ----------------------------------------------------------------------------
62
63static const struct TokenizerTestData
64{
65 // the string to tokenize
66 const wxChar *str;
67
68 // the delimiters to use
69 const wxChar *delims;
70
71 // the tokenizer mode
72 wxStringTokenizerMode mode;
73
74 // expected number of tokens
75 size_t count;
76}
77gs_testData[] =
78{
79 { wxT(""), wxT(" "), wxTOKEN_DEFAULT, 0 },
80 { wxT(""), wxT(" "), wxTOKEN_RET_EMPTY, 0 },
81 { wxT(""), wxT(" "), wxTOKEN_RET_EMPTY_ALL, 0 },
82 { wxT(""), wxT(" "), wxTOKEN_RET_DELIMS, 0 },
83 { wxT(":"), wxT(":"), wxTOKEN_RET_EMPTY, 1 },
84 { wxT(":"), wxT(":"), wxTOKEN_RET_DELIMS, 1 },
85 { wxT(":"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 2 },
86 { wxT("::"), wxT(":"), wxTOKEN_RET_EMPTY, 1 },
87 { wxT("::"), wxT(":"), wxTOKEN_RET_DELIMS, 1 },
88 { wxT("::"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 3 },
89
90 { wxT("Hello, world"), wxT(" "), wxTOKEN_DEFAULT, 2 },
91 { wxT("Hello, world "), wxT(" "), wxTOKEN_DEFAULT, 2 },
92 { wxT("Hello, world"), wxT(","), wxTOKEN_DEFAULT, 2 },
93 { wxT("Hello, world!"), wxT(",!"), wxTOKEN_DEFAULT, 2 },
94 { wxT("Hello,, world!"), wxT(",!"), wxTOKEN_DEFAULT, 3 },
95 { wxT("Hello,, world!"), wxT(",!"), wxTOKEN_STRTOK, 2 },
96 { wxT("Hello, world!"), wxT(",!"), wxTOKEN_RET_EMPTY_ALL, 3 },
97
98 { wxT("username:password:uid:gid:gecos:home:shell"),
99 wxT(":"), wxTOKEN_DEFAULT, 7 },
100
101 { wxT("1:2::3:"), wxT(":"), wxTOKEN_DEFAULT, 4 },
102 { wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_EMPTY, 4 },
103 { wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 5 },
104 { wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_DELIMS, 4 },
105 { wxT("1:2::3:"), wxT(":"), wxTOKEN_STRTOK, 3 },
106
107 { wxT("1:2::3::"), wxT(":"), wxTOKEN_DEFAULT, 4 },
108 { wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_EMPTY, 4 },
109 { wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 6 },
110 { wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_DELIMS, 4 },
111 { wxT("1:2::3::"), wxT(":"), wxTOKEN_STRTOK, 3 },
112
113 { wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_DEFAULT, 4 },
114 { wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_STRTOK, 4 },
115 { wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_RET_EMPTY, 6 },
116 { wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_RET_EMPTY_ALL, 9 },
117
118 { wxT("01/02/99"), wxT("/-"), wxTOKEN_DEFAULT, 3 },
119 { wxT("01-02/99"), wxT("/-"), wxTOKEN_RET_DELIMS, 3 },
120};
121
122// helper function returning the string showing the index for which the test
123// fails in the diagnostic message
124static std::string Nth(size_t n)
125{
126 return std::string(wxString::Format(wxT("for loop index %lu"),
127 (unsigned long)n).mb_str());
128}
129
130// ----------------------------------------------------------------------------
131// the tests
132// ----------------------------------------------------------------------------
133
134void TokenizerTestCase::GetCount()
135{
136 for ( size_t n = 0; n < WXSIZEOF(gs_testData); n++ )
137 {
138 const TokenizerTestData& ttd = gs_testData[n];
139
140 wxStringTokenizer tkz(ttd.str, ttd.delims, ttd.mode);
141 CPPUNIT_ASSERT_EQUAL_MESSAGE( Nth(n), ttd.count, tkz.CountTokens() );
142
143 size_t count = 0;
144 while ( tkz.HasMoreTokens() )
145 {
146 tkz.GetNextToken();
147 count++;
148 }
149
150 CPPUNIT_ASSERT_EQUAL_MESSAGE( Nth(n), ttd.count, count );
151 }
152}
153
154// call this with the string to tokenize, delimeters to use and the expected
155// positions (i.e. results of GetPosition()) after each GetNextToken() call,
156// terminate positions with 0
157static void
158DoTestGetPosition(const wxChar *s, const wxChar *delims, int pos, ...)
159{
160 wxStringTokenizer tkz(s, delims);
161
162 CPPUNIT_ASSERT_EQUAL( (size_t)0, tkz.GetPosition() );
163
164 va_list ap;
165 va_start(ap, pos);
166
167 for ( ;; )
168 {
169 if ( !pos )
170 {
171 CPPUNIT_ASSERT( !tkz.HasMoreTokens() );
172 break;
173 }
174
175 tkz.GetNextToken();
176
177 CPPUNIT_ASSERT_EQUAL( (size_t)pos, tkz.GetPosition() );
178
179 pos = va_arg(ap, int);
180 }
181
182 va_end(ap);
183}
184
185void TokenizerTestCase::GetPosition()
186{
187 DoTestGetPosition(wxT("foo"), wxT("_"), 3, 0);
188 DoTestGetPosition(wxT("foo_bar"), wxT("_"), 4, 7, 0);
189 DoTestGetPosition(wxT("foo_bar_"), wxT("_"), 4, 8, 0);
190}
191
192// helper for GetString(): the parameters are the same as for DoTestGetPosition
193// but it checks GetString() return value instead of GetPosition()
194static void
195DoTestGetString(const wxChar *s, const wxChar *delims, int pos, ...)
196{
197 wxStringTokenizer tkz(s, delims);
198
199 CPPUNIT_ASSERT_EQUAL( wxString(s), tkz.GetString() );
200
201 va_list ap;
202 va_start(ap, pos);
203
204 for ( ;; )
205 {
206 if ( !pos )
207 {
208 CPPUNIT_ASSERT( tkz.GetString().empty() ) ;
209 break;
210 }
211
212 tkz.GetNextToken();
213
214 CPPUNIT_ASSERT_EQUAL( wxString(s + pos), tkz.GetString() );
215
216 pos = va_arg(ap, int);
217 }
218
219 va_end(ap);
220}
221
222void TokenizerTestCase::GetString()
223{
224 DoTestGetString(wxT("foo"), wxT("_"), 3, 0);
225 DoTestGetString(wxT("foo_bar"), wxT("_"), 4, 7, 0);
226 DoTestGetString(wxT("foo_bar_"), wxT("_"), 4, 8, 0);
227}
228
229void TokenizerTestCase::LastDelimiter()
230{
231 wxStringTokenizer tkz(wxT("a+-b=c"), wxT("+-="));
232
233 tkz.GetNextToken();
234 CPPUNIT_ASSERT_EQUAL( wxT('+'), tkz.GetLastDelimiter() );
235
236 tkz.GetNextToken();
237 CPPUNIT_ASSERT_EQUAL( wxT('-'), tkz.GetLastDelimiter() );
238
239 tkz.GetNextToken();
240 CPPUNIT_ASSERT_EQUAL( wxT('='), tkz.GetLastDelimiter() );
241
242 tkz.GetNextToken();
243 CPPUNIT_ASSERT_EQUAL( wxT('\0'), tkz.GetLastDelimiter() );
244}
245
246void TokenizerTestCase::StrtokCompat()
247{
248 for ( size_t n = 0; n < WXSIZEOF(gs_testData); n++ )
249 {
250 const TokenizerTestData& ttd = gs_testData[n];
251 if ( ttd.mode != wxTOKEN_STRTOK )
252 continue;
253
254#if wxUSE_UNICODE
255 wxWCharBuffer
256#else
257 wxCharBuffer
258#endif
259 buf(ttd.str);
260 wxChar *last;
261 wxChar *s = wxStrtok(buf.data(), ttd.delims, &last);
262
263 wxStringTokenizer tkz(ttd.str, ttd.delims, ttd.mode);
264 while ( tkz.HasMoreTokens() )
265 {
266 CPPUNIT_ASSERT_EQUAL( wxString(s), tkz.GetNextToken() );
267 s = wxStrtok(NULL, ttd.delims, &last);
268 }
269 }
270}
271
272