1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/xlocale/xlocale.cpp
3 // Purpose: wxXLocale & related unit test
4 // Author: Brian Vanderburg II, Vadim Zeitlin
7 // Copyright: (c) 2008 Brian Vanderburg II
8 // 2008 Vadim Zeitlin <vadim@wxwidgets.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ----------------------------------------------------------------------------
14 // ----------------------------------------------------------------------------
28 #include "wx/xlocale.h"
30 // --------------------------------------------------------------------------
32 // --------------------------------------------------------------------------
34 class XLocaleTestCase
: public CppUnit::TestCase
40 CPPUNIT_TEST_SUITE( XLocaleTestCase
);
41 CPPUNIT_TEST( TestCtor
);
42 CPPUNIT_TEST( PreserveLocale
);
43 CPPUNIT_TEST( TestCtypeFunctions
);
44 CPPUNIT_TEST( TestStdlibFunctions
);
45 CPPUNIT_TEST_SUITE_END();
48 void PreserveLocale();
49 void TestCtypeFunctions();
50 void TestStdlibFunctions();
52 void TestCtypeFunctionsWith(const wxXLocale
& loc
);
53 void TestStdlibFunctionsWith(const wxXLocale
& loc
);
55 DECLARE_NO_COPY_CLASS(XLocaleTestCase
)
58 // register in the unnamed registry so that these tests are run by default
59 CPPUNIT_TEST_SUITE_REGISTRATION( XLocaleTestCase
);
61 // also include in its own registry so that these tests can be run alone
62 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XLocaleTestCase
, "XLocaleTestCase" );
65 // test the different wxXLocale ctors
66 void XLocaleTestCase::TestCtor()
68 CPPUNIT_ASSERT( !wxXLocale().IsOk() );
69 CPPUNIT_ASSERT( wxCLocale
.IsOk() );
70 CPPUNIT_ASSERT( wxXLocale("C").IsOk() );
71 CPPUNIT_ASSERT( !wxXLocale("bloordyblop").IsOk() );
73 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH
))
74 return; // you should have french support installed to continue this test!
76 #ifdef wxHAS_XLOCALE_SUPPORT
77 CPPUNIT_ASSERT( wxXLocale(wxLANGUAGE_FRENCH
).IsOk() );
79 CPPUNIT_ASSERT( wxXLocale("french").IsOk() );
81 CPPUNIT_ASSERT( wxXLocale("fr_FR").IsOk() );
86 void XLocaleTestCase::PreserveLocale()
88 // Test that using locale functions doesn't change the global C locale.
89 const wxString
origLocale(setlocale(LC_ALL
, NULL
));
91 wxStrtod_l(wxT("1.234"), NULL
, wxCLocale
);
93 CPPUNIT_ASSERT_EQUAL( origLocale
, setlocale(LC_ALL
, NULL
) );
96 // test the ctype functions with the given locale
97 void XLocaleTestCase::TestCtypeFunctionsWith(const wxXLocale
& loc
)
99 // NOTE: here go the checks which must pass under _any_ locale "loc";
100 // checks for specific locales are in TestCtypeFunctions()
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
) );
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
) );
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
) );
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
) );
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
) );
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
) );
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
) );
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
) );
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
) );
193 // test the stdlib functions with the given locale
194 void XLocaleTestCase::TestStdlibFunctionsWith(const wxXLocale
& loc
)
196 // NOTE: here go the checks which must pass under _any_ locale "loc";
197 // checks for specific locales are in TestStdlibFunctions()
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
) );
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
) );
219 // NOTE: 3147483647 and 0xEE6B2800 are greater than LONG_MAX (on 32bit machines) but
220 // smaller than ULONG_MAX
221 CPPUNIT_ASSERT_EQUAL( 3147483647ul, wxStrtoul_l(wxT("3147483647"), NULL
, 0, loc
) );
222 CPPUNIT_ASSERT_EQUAL( 0xEE6B2800ul
, wxStrtoul_l(wxT("0xEE6B2800"), NULL
, 0, loc
) );
224 // TODO: test for "failure" behaviour of the functions above
227 void XLocaleTestCase::TestCtypeFunctions()
229 TestCtypeFunctionsWith(wxCLocale
);
231 #ifdef wxHAS_XLOCALE_SUPPORT
235 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH
))
236 return; // you should have french support installed to continue this test!
238 wxXLocale
locFR(wxLANGUAGE_FRENCH
);
239 CPPUNIT_ASSERT( locFR
.IsOk() ); // doesn't make sense to continue otherwise
241 TestCtypeFunctionsWith(locFR
);
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
) );
254 if (!wxLocale::IsAvailable(wxLANGUAGE_ITALIAN
))
255 return; // you should have italian support installed to continue this test!
257 wxXLocale
locIT(wxLANGUAGE_ITALIAN
);
258 CPPUNIT_ASSERT( locIT
.IsOk() ); // doesn't make sense to continue otherwise
260 TestCtypeFunctionsWith(locIT
);
262 CPPUNIT_ASSERT( wxIsalpha_l(wxT('\xe1'), locIT
) );
263 CPPUNIT_ASSERT( wxIslower_l(wxT('\xe1'), locIT
) );
267 void XLocaleTestCase::TestStdlibFunctions()
269 TestStdlibFunctionsWith(wxCLocale
);
277 // strtod checks specific for C locale
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
) );
285 #ifdef wxHAS_XLOCALE_SUPPORT
289 if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH
))
290 return; // you should have french support installed to continue this test!
292 wxXLocale
locFR(wxLANGUAGE_FRENCH
);
293 CPPUNIT_ASSERT( locFR
.IsOk() ); // doesn't make sense to continue otherwise
295 TestCtypeFunctionsWith(locFR
);
297 // comma as decimal point:
298 CPPUNIT_ASSERT_EQUAL( 1.234, wxStrtod_l(wxT("1,234"), NULL
, locFR
) );
300 // space as thousands separator is not recognized by wxStrtod_l():
301 CPPUNIT_ASSERT( 1234.5 != wxStrtod_l(wxT("1 234,5"), NULL
, locFR
) );
306 if (!wxLocale::IsAvailable(wxLANGUAGE_ITALIAN
))
307 return; // you should have italian support installed to continue this test!
309 wxXLocale
locIT(wxLANGUAGE_ITALIAN
);
310 CPPUNIT_ASSERT( locIT
.IsOk() ); // doesn't make sense to continue otherwise
312 TestStdlibFunctionsWith(locIT
);
314 // comma as decimal point:
315 CPPUNIT_ASSERT_EQUAL( 1.234, wxStrtod_l(wxT("1,234"), NULL
, locIT
) );
317 // dot as thousands separator is not recognized by wxStrtod_l():
318 CPPUNIT_ASSERT( 1234.5 != wxStrtod_l(wxT("1.234,5"), NULL
, locIT
) );
322 #endif // wxUSE_XLOCALE