xlocale.cpp 11 KB

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