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