Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / tests / xlocale / xlocale.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/xlocale/xlocale.cpp
3 // Purpose: wxXLocale & related unit test
4 // Author: Brian Vanderburg II, Vadim Zeitlin
5 // Created: 2008-01-16
6 // Copyright: (c) 2008 Brian Vanderburg II
7 // 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ----------------------------------------------------------------------------
12 // headers
13 // ----------------------------------------------------------------------------
14
15 #include "testprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #if wxUSE_XLOCALE
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif // WX_PRECOMP
26
27 #include "wx/xlocale.h"
28
29 // --------------------------------------------------------------------------
30 // test class
31 // --------------------------------------------------------------------------
32
33 class XLocaleTestCase : public CppUnit::TestCase
34 {
35 public:
36 XLocaleTestCase() { }
37
38 private:
39 CPPUNIT_TEST_SUITE( XLocaleTestCase );
40 CPPUNIT_TEST( TestCtor );
41 CPPUNIT_TEST( PreserveLocale );
42 CPPUNIT_TEST( TestCtypeFunctions );
43 CPPUNIT_TEST( TestStdlibFunctions );
44 CPPUNIT_TEST_SUITE_END();
45
46 void TestCtor();
47 void PreserveLocale();
48 void TestCtypeFunctions();
49 void TestStdlibFunctions();
50
51 void TestCtypeFunctionsWith(const wxXLocale& loc);
52 void TestStdlibFunctionsWith(const wxXLocale& loc);
53
54 DECLARE_NO_COPY_CLASS(XLocaleTestCase)
55 };
56
57 // register in the unnamed registry so that these tests are run by default
58 CPPUNIT_TEST_SUITE_REGISTRATION( XLocaleTestCase );
59
60 // also include in its own registry so that these tests can be run alone
61 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XLocaleTestCase, "XLocaleTestCase" );
62
63
64 // test the different wxXLocale ctors
65 void XLocaleTestCase::TestCtor()
66 {
67 CPPUNIT_ASSERT( !wxXLocale().IsOk() );
68 CPPUNIT_ASSERT( wxCLocale.IsOk() );
69 CPPUNIT_ASSERT( wxXLocale("C").IsOk() );
70 CPPUNIT_ASSERT( !wxXLocale("bloordyblop").IsOk() );
71
72 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
73 return; // you should have french support installed to continue this test!
74
75 #ifdef wxHAS_XLOCALE_SUPPORT
76 CPPUNIT_ASSERT( wxXLocale(wxLANGUAGE_FRENCH).IsOk() );
77 #ifdef __WINDOWS__
78 CPPUNIT_ASSERT( wxXLocale("french").IsOk() );
79 #else
80 CPPUNIT_ASSERT( wxXLocale("fr_FR").IsOk() );
81 #endif
82 #endif
83 }
84
85 void XLocaleTestCase::PreserveLocale()
86 {
87 // Test that using locale functions doesn't change the global C locale.
88 const wxString origLocale(setlocale(LC_ALL, NULL));
89
90 wxStrtod_l(wxT("1.234"), NULL, wxCLocale);
91
92 CPPUNIT_ASSERT_EQUAL( origLocale, setlocale(LC_ALL, NULL) );
93 }
94
95 // test the ctype functions with the given locale
96 void XLocaleTestCase::TestCtypeFunctionsWith(const wxXLocale& loc)
97 {
98 // NOTE: here go the checks which must pass under _any_ locale "loc";
99 // checks for specific locales are in TestCtypeFunctions()
100
101
102 // isalnum
103 CPPUNIT_ASSERT( wxIsalnum_l('0', loc) );
104 CPPUNIT_ASSERT( wxIsalnum_l('9', loc) );
105 CPPUNIT_ASSERT( wxIsalnum_l('A', loc) );
106 CPPUNIT_ASSERT( wxIsalnum_l('Z', loc) );
107 CPPUNIT_ASSERT( wxIsalnum_l('a', loc) );
108 CPPUNIT_ASSERT( wxIsalnum_l('z', loc) );
109 CPPUNIT_ASSERT( !wxIsalnum_l('*', loc) );
110 CPPUNIT_ASSERT( !wxIsalnum_l('@', loc) );
111 CPPUNIT_ASSERT( !wxIsalnum_l('+', loc) );
112
113 // isalpha
114 CPPUNIT_ASSERT( !wxIsalpha_l('0', loc) );
115 CPPUNIT_ASSERT( !wxIsalpha_l('9', loc) );
116 CPPUNIT_ASSERT( wxIsalpha_l('A', loc) );
117 CPPUNIT_ASSERT( wxIsalpha_l('Z', loc) );
118 CPPUNIT_ASSERT( wxIsalpha_l('a', loc) );
119 CPPUNIT_ASSERT( wxIsalpha_l('z', loc) );
120 CPPUNIT_ASSERT( !wxIsalpha_l('*', loc) );
121 CPPUNIT_ASSERT( !wxIsalpha_l('@', loc) );
122 CPPUNIT_ASSERT( !wxIsalpha_l('+', loc) );
123
124 // TODO: iscntrl
125
126 // isdigit
127 CPPUNIT_ASSERT( wxIsdigit_l('0', loc) );
128 CPPUNIT_ASSERT( wxIsdigit_l('9', loc) );
129 CPPUNIT_ASSERT( !wxIsdigit_l('A', loc) );
130 CPPUNIT_ASSERT( !wxIsdigit_l('Z', loc) );
131 CPPUNIT_ASSERT( !wxIsdigit_l('a', loc) );
132 CPPUNIT_ASSERT( !wxIsdigit_l('z', loc) );
133
134 // TODO: isgraph
135
136 // islower
137 CPPUNIT_ASSERT( !wxIslower_l('A', loc) );
138 CPPUNIT_ASSERT( !wxIslower_l('Z', loc) );
139 CPPUNIT_ASSERT( wxIslower_l('a', loc) );
140 CPPUNIT_ASSERT( wxIslower_l('z', loc) );
141 CPPUNIT_ASSERT( !wxIslower_l('0', loc) );
142 CPPUNIT_ASSERT( !wxIslower_l('9', loc) );
143
144
145 // TODO: isprint
146 // TODO: ispunct
147
148 // isspace
149 CPPUNIT_ASSERT( wxIsspace_l(' ', loc) );
150 CPPUNIT_ASSERT( wxIsspace_l('\t', loc) );
151 CPPUNIT_ASSERT( wxIsspace_l('\r', loc) );
152 CPPUNIT_ASSERT( wxIsspace_l('\n', loc) );
153 CPPUNIT_ASSERT( !wxIsspace_l('0', loc) );
154 CPPUNIT_ASSERT( !wxIsspace_l('a', loc) );
155 CPPUNIT_ASSERT( !wxIsspace_l('A', loc) );
156
157 // isupper
158 CPPUNIT_ASSERT( !wxIsupper_l('0', loc) );
159 CPPUNIT_ASSERT( !wxIsupper_l('9', loc) );
160 CPPUNIT_ASSERT( wxIsupper_l('A', loc) );
161 CPPUNIT_ASSERT( wxIsupper_l('Z', loc) );
162 CPPUNIT_ASSERT( !wxIsupper_l('a', loc) );
163 CPPUNIT_ASSERT( !wxIsupper_l('z', loc) );
164
165 // isxdigit
166 CPPUNIT_ASSERT( wxIsxdigit_l('0', loc) );
167 CPPUNIT_ASSERT( wxIsxdigit_l('9', loc) );
168 CPPUNIT_ASSERT( wxIsxdigit_l('A', loc) );
169 CPPUNIT_ASSERT( wxIsxdigit_l('F', loc) );
170 CPPUNIT_ASSERT( !wxIsxdigit_l('Z', loc) );
171 CPPUNIT_ASSERT( wxIsxdigit_l('a', loc) );
172 CPPUNIT_ASSERT( wxIsxdigit_l('f', loc) );
173 CPPUNIT_ASSERT( !wxIsxdigit_l('z', loc) );
174
175 // tolower
176 CPPUNIT_ASSERT_EQUAL( 'a', (char)wxTolower_l('A', loc) );
177 CPPUNIT_ASSERT_EQUAL( 'a', (char)wxTolower_l('a', loc) );
178 CPPUNIT_ASSERT_EQUAL( 'z', (char)wxTolower_l('Z', loc) );
179 CPPUNIT_ASSERT_EQUAL( 'z', (char)wxTolower_l('z', loc) );
180 CPPUNIT_ASSERT_EQUAL( '0', (char)wxTolower_l('0', loc) );
181 CPPUNIT_ASSERT_EQUAL( '9', (char)wxTolower_l('9', loc) );
182
183 // toupper
184 CPPUNIT_ASSERT_EQUAL( 'A', (char)wxToupper_l('A', loc) );
185 CPPUNIT_ASSERT_EQUAL( 'A', (char)wxToupper_l('a', loc) );
186 CPPUNIT_ASSERT_EQUAL( 'Z', (char)wxToupper_l('Z', loc) );
187 CPPUNIT_ASSERT_EQUAL( 'Z', (char)wxToupper_l('z', loc) );
188 CPPUNIT_ASSERT_EQUAL( '0', (char)wxToupper_l('0', loc) );
189 CPPUNIT_ASSERT_EQUAL( '9', (char)wxToupper_l('9', loc) );
190 }
191
192 // test the stdlib functions with the given locale
193 void XLocaleTestCase::TestStdlibFunctionsWith(const wxXLocale& loc)
194 {
195 // NOTE: here go the checks which must pass under _any_ locale "loc";
196 // checks for specific locales are in TestStdlibFunctions()
197
198 #if wxUSE_UNICODE
199 wchar_t* endptr;
200 #else
201 char* endptr;
202 #endif
203
204 // strtod (don't use decimal separator as it's locale-specific)
205 CPPUNIT_ASSERT_EQUAL( 0.0, wxStrtod_l(wxT("0"), NULL, loc) );
206 CPPUNIT_ASSERT_EQUAL( 1234.0, wxStrtod_l(wxT("1234"), NULL, loc) );
207
208 // strtol
209 endptr = NULL;
210 CPPUNIT_ASSERT_EQUAL( 100, wxStrtol_l(wxT("100"), NULL, 0, loc) );
211 CPPUNIT_ASSERT_EQUAL( 0xFF, wxStrtol_l(wxT("0xFF"), NULL, 0, loc) );
212 CPPUNIT_ASSERT_EQUAL( 2001, wxStrtol_l(wxT("2001 60c0c0 -1101110100110100100000 0x6fffff"), &endptr, 10, loc) );
213 CPPUNIT_ASSERT_EQUAL( 0x60c0c0, wxStrtol_l(endptr, &endptr, 16, loc) );
214 CPPUNIT_ASSERT_EQUAL( -0x374D20, wxStrtol_l(endptr, &endptr, 2, loc) );
215 CPPUNIT_ASSERT_EQUAL( 0x6fffff, wxStrtol_l(endptr, NULL, 0, loc) );
216
217 // strtoul
218 // NOTE: 3147483647 and 0xEE6B2800 are greater than LONG_MAX (on 32bit machines) but
219 // smaller than ULONG_MAX
220 CPPUNIT_ASSERT_EQUAL( 3147483647ul, wxStrtoul_l(wxT("3147483647"), NULL, 0, loc) );
221 CPPUNIT_ASSERT_EQUAL( 0xEE6B2800ul, wxStrtoul_l(wxT("0xEE6B2800"), NULL, 0, loc) );
222
223 // TODO: test for "failure" behaviour of the functions above
224 }
225
226 void XLocaleTestCase::TestCtypeFunctions()
227 {
228 TestCtypeFunctionsWith(wxCLocale);
229
230 #ifdef wxHAS_XLOCALE_SUPPORT
231
232 // french
233
234 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
235 return; // you should have french support installed to continue this test!
236
237 wxXLocale locFR(wxLANGUAGE_FRENCH);
238 CPPUNIT_ASSERT( locFR.IsOk() ); // doesn't make sense to continue otherwise
239
240 TestCtypeFunctionsWith(locFR);
241
242 CPPUNIT_ASSERT( wxIsalpha_l(wxT('\xe9'), locFR) );
243 CPPUNIT_ASSERT( wxIslower_l(wxT('\xe9'), locFR) );
244 CPPUNIT_ASSERT( !wxIslower_l(wxT('\xc9'), locFR) );
245 CPPUNIT_ASSERT( wxIsupper_l(wxT('\xc9'), locFR) );
246 CPPUNIT_ASSERT( wxIsalpha_l(wxT('\xe7'), locFR) );
247 CPPUNIT_ASSERT( wxIslower_l(wxT('\xe7'), locFR) );
248 CPPUNIT_ASSERT( wxIsupper_l(wxT('\xc7'), locFR) );
249
250
251 // italian
252
253 if (!wxLocale::IsAvailable(wxLANGUAGE_ITALIAN))
254 return; // you should have italian support installed to continue this test!
255
256 wxXLocale locIT(wxLANGUAGE_ITALIAN);
257 CPPUNIT_ASSERT( locIT.IsOk() ); // doesn't make sense to continue otherwise
258
259 TestCtypeFunctionsWith(locIT);
260
261 CPPUNIT_ASSERT( wxIsalpha_l(wxT('\xe1'), locIT) );
262 CPPUNIT_ASSERT( wxIslower_l(wxT('\xe1'), locIT) );
263 #endif
264 }
265
266 void XLocaleTestCase::TestStdlibFunctions()
267 {
268 TestStdlibFunctionsWith(wxCLocale);
269
270 #if wxUSE_UNICODE
271 wchar_t* endptr;
272 #else
273 char* endptr;
274 #endif
275
276 // strtod checks specific for C locale
277 endptr = NULL;
278 CPPUNIT_ASSERT_EQUAL( 0.0, wxStrtod_l(wxT("0.000"), NULL, wxCLocale) );
279 CPPUNIT_ASSERT_EQUAL( 1.234, wxStrtod_l(wxT("1.234"), NULL, wxCLocale) );
280 CPPUNIT_ASSERT_EQUAL( -1.234E-5, wxStrtod_l(wxT("-1.234E-5"), NULL, wxCLocale) );
281 CPPUNIT_ASSERT_EQUAL( 365.24, wxStrtod_l(wxT("365.24 29.53"), &endptr, wxCLocale) );
282 CPPUNIT_ASSERT_EQUAL( 29.53, wxStrtod_l(endptr, NULL, wxCLocale) );
283
284 #ifdef wxHAS_XLOCALE_SUPPORT
285
286 // french
287
288 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
289 return; // you should have french support installed to continue this test!
290
291 wxXLocale locFR(wxLANGUAGE_FRENCH);
292 CPPUNIT_ASSERT( locFR.IsOk() ); // doesn't make sense to continue otherwise
293
294 TestCtypeFunctionsWith(locFR);
295
296 // comma as decimal point:
297 CPPUNIT_ASSERT_EQUAL( 1.234, wxStrtod_l(wxT("1,234"), NULL, locFR) );
298
299 // space as thousands separator is not recognized by wxStrtod_l():
300 CPPUNIT_ASSERT( 1234.5 != wxStrtod_l(wxT("1 234,5"), NULL, locFR) );
301
302
303 // italian
304
305 if (!wxLocale::IsAvailable(wxLANGUAGE_ITALIAN))
306 return; // you should have italian support installed to continue this test!
307
308 wxXLocale locIT(wxLANGUAGE_ITALIAN);
309 CPPUNIT_ASSERT( locIT.IsOk() ); // doesn't make sense to continue otherwise
310
311 TestStdlibFunctionsWith(locIT);
312
313 // comma as decimal point:
314 CPPUNIT_ASSERT_EQUAL( 1.234, wxStrtod_l(wxT("1,234"), NULL, locIT) );
315
316 // dot as thousands separator is not recognized by wxStrtod_l():
317 CPPUNIT_ASSERT( 1234.5 != wxStrtod_l(wxT("1.234,5"), NULL, locIT) );
318 #endif
319 }
320
321 #endif // wxUSE_XLOCALE