X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/81e9dec6f59b5955d54087e1726098d38a26f03b..4f2511d706e5274a34e1521e11c1b95fed735b42:/tests/strings/unicode.cpp diff --git a/tests/strings/unicode.cpp b/tests/strings/unicode.cpp index 9ddaba42cd..6211e9e489 100644 --- a/tests/strings/unicode.cpp +++ b/tests/strings/unicode.cpp @@ -18,26 +18,108 @@ #endif #ifndef WX_PRECOMP + #include "wx/wx.h" #endif // WX_PRECOMP -// ---------------------------------------------------------------------------- -// local functions -// ---------------------------------------------------------------------------- +// helper class holding the matching MB and WC strings +// +// either str or wcs (but not both) may be NULL, this means that the conversion +// to it should fail +struct StringConversionData +{ + const char *str; + const wchar_t *wcs; + + enum + { + TEST_BOTH = 0, // test both str -> wcs and wcs -> str + ONLY_MB2WC = 1 // only test str -> wcs conversion + }; -#if wxUSE_WCHAR_T && !wxUSE_UNICODE + int flags; -// in case wcscmp is missing -static int wx_wcscmp(const wchar_t *s1, const wchar_t *s2) -{ - while (*s1 == *s2 && *s1 != 0) + // test that the conversion between str and wcs (subject to flags) succeeds + // + // the first argument is the index in the test array and is used solely for + // diagnostics + void Test(size_t n, wxMBConv& conv) const { - s1++; - s2++; + if ( str ) + { + wxWCharBuffer wbuf = conv.cMB2WC(str); + + if ( wcs ) + { + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "MB2WC failed"), + wbuf.data() + ); + + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "MB2WC", wbuf, wcs), + wxStrcmp(wbuf, wcs) == 0 + ); + } + else // conversion is supposed to fail + { + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "MB2WC succeeded"), + !wbuf.data() + ); + } + } + + if ( wcs && !(flags & ONLY_MB2WC) ) + { + wxCharBuffer buf = conv.cWC2MB(wcs); + + if ( str ) + { + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "WC2MB failed"), + buf.data() + ); + + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "WC2MB", buf, str), + strcmp(buf, str) == 0 + ); + } + else + { + CPPUNIT_ASSERT_MESSAGE + ( + Message(n, "WC2MB succeeded"), + !buf.data() + ); + } + } + } + +private: + static std::string + Message(size_t n, const wxString& msg) + { + return std::string(wxString::Format("#%lu: %s", (unsigned long)n, msg)); } - return *s1 - *s2; -} -#endif // wxUSE_WCHAR_T && !wxUSE_UNICODE + template + static std::string + Message(size_t n, + const char *func, + const wxCharTypeBuffer& actual, + const T *expected) + { + return Message(n, + wxString::Format("%s returned \"%s\", expected \"%s\"", + func, actual.data(), expected)); + } +}; // ---------------------------------------------------------------------------- // test class @@ -51,7 +133,6 @@ public: private: CPPUNIT_TEST_SUITE( UnicodeTestCase ); CPPUNIT_TEST( ToFromAscii ); -#if wxUSE_WCHAR_T CPPUNIT_TEST( ConstructorsWithConversion ); CPPUNIT_TEST( ConversionEmpty ); CPPUNIT_TEST( ConversionWithNULs ); @@ -60,14 +141,12 @@ private: CPPUNIT_TEST( ConversionUTF16 ); CPPUNIT_TEST( ConversionUTF32 ); CPPUNIT_TEST( IsConvOk ); -#endif // wxUSE_WCHAR_T #if wxUSE_UNICODE CPPUNIT_TEST( Iteration ); #endif CPPUNIT_TEST_SUITE_END(); void ToFromAscii(); -#if wxUSE_WCHAR_T void ConstructorsWithConversion(); void ConversionEmpty(); void ConversionWithNULs(); @@ -80,14 +159,6 @@ private: void Iteration(); #endif - // test if converting s using the given encoding gives ws and vice versa - // - // if either of the first 2 arguments is NULL, the conversion is supposed - // to fail - void DoTestConversion(const char *s, const wchar_t *w, wxMBConv& conv); -#endif // wxUSE_WCHAR_T - - DECLARE_NO_COPY_CLASS(UnicodeTestCase) }; @@ -115,49 +186,50 @@ void UnicodeTestCase::ToFromAscii() TEST_TO_FROM_ASCII( "additional \" special \t test \\ component \n :-)" ); } -#if wxUSE_WCHAR_T void UnicodeTestCase::ConstructorsWithConversion() { // the string "Déjà" in UTF-8 and wchar_t: const unsigned char utf8Buf[] = {0x44,0xC3,0xA9,0x6A,0xC3,0xA0,0}; - const wchar_t wchar[] = {0x44,0xE9,0x6A,0xE0,0}; const unsigned char utf8subBuf[] = {0x44,0xC3,0xA9,0x6A,0}; // just "Déj" const char *utf8 = (char *)utf8Buf; const char *utf8sub = (char *)utf8subBuf; wxString s1(utf8, wxConvUTF8); - wxString s2(wchar, wxConvUTF8); #if wxUSE_UNICODE - CPPUNIT_ASSERT( s1 == wchar ); - CPPUNIT_ASSERT( s2 == wchar ); + const wchar_t wchar[] = {0x44,0xE9,0x6A,0xE0,0}; + CPPUNIT_ASSERT_EQUAL( wchar, s1 ); + + wxString s2(wchar); + CPPUNIT_ASSERT_EQUAL( wchar, s2 ); + CPPUNIT_ASSERT_EQUAL( utf8, s2 ); #else - CPPUNIT_ASSERT( s1 == utf8 ); - CPPUNIT_ASSERT( s2 == utf8 ); + CPPUNIT_ASSERT_EQUAL( utf8, s1 ); #endif wxString sub(utf8sub, wxConvUTF8); // "Dej" substring wxString s3(utf8, wxConvUTF8, 4); - wxString s4(wchar, wxConvUTF8, 3); - - CPPUNIT_ASSERT( s3 == sub ); - CPPUNIT_ASSERT( s4 == sub ); + CPPUNIT_ASSERT_EQUAL( sub, s3 ); #if wxUSE_UNICODE - CPPUNIT_ASSERT ( wxString("\t[pl]open.format.Sformatuj dyskietkê=gfloppy %f", - wxConvUTF8) == wxT("") ); //should stop at pos 35 -#endif + wxString s4(wchar, wxConvUTF8, 3); + CPPUNIT_ASSERT_EQUAL( sub, s4 ); + + // conversion should stop with failure at pos 35 + wxString s("\t[pl]open.format.Sformatuj dyskietkê=gfloppy %f", wxConvUTF8); + CPPUNIT_ASSERT( s.empty() ); +#endif // wxUSE_UNICODE // test using Unicode strings together with char* strings (this must work // in ANSI mode as well, of course): wxString s5("ascii"); - CPPUNIT_ASSERT( s5 == "ascii" ); + CPPUNIT_ASSERT_EQUAL( "ascii", s5 ); s5 += " value"; CPPUNIT_ASSERT( strcmp(s5.mb_str(), "ascii value") == 0 ); - CPPUNIT_ASSERT( s5 == "ascii value" ); + CPPUNIT_ASSERT_EQUAL( "ascii value", s5 ); CPPUNIT_ASSERT( s5 != "SomethingElse" ); } @@ -190,13 +262,13 @@ void UnicodeTestCase::ConversionWithNULs() CPPUNIT_ASSERT( wxTmemcmp(szTheString2.c_str(), L"The\0String", lenNulString + 1) == 0 ); #else // !wxUSE_UNICODE - wxString szTheString(wxT("TheString")); + wxString szTheString("TheString"); szTheString.insert(3, 1, '\0'); wxWCharBuffer theBuffer = szTheString.wc_str(wxConvLibc); CPPUNIT_ASSERT( memcmp(theBuffer.data(), L"The\0String", 11 * sizeof(wchar_t)) == 0 ); - wxString szLocalTheString(wxT("TheString")); + wxString szLocalTheString("TheString"); szLocalTheString.insert(3, 1, '\0'); wxWCharBuffer theLocalBuffer = szLocalTheString.wc_str(wxConvLocal); @@ -204,60 +276,28 @@ void UnicodeTestCase::ConversionWithNULs() #endif // wxUSE_UNICODE/!wxUSE_UNICODE } -void -UnicodeTestCase::DoTestConversion(const char *s, - const wchar_t *ws, - wxMBConv& conv) -{ -#if wxUSE_UNICODE - if ( ws ) - { - wxCharBuffer buf = conv.cWC2MB(ws, (size_t)-1, NULL); - - CPPUNIT_ASSERT( strcmp(buf, s) == 0 ); - } -#else // wxUSE_UNICODE - if ( s ) - { - wxWCharBuffer wbuf = conv.cMB2WC(s, (size_t)-1, NULL); - - if ( ws ) - { - CPPUNIT_ASSERT( wbuf.data() ); - CPPUNIT_ASSERT( wx_wcscmp(wbuf, ws) == 0 ); - } - else // conversion is supposed to fail - { - CPPUNIT_ASSERT_EQUAL( (wchar_t *)NULL, wbuf.data() ); - } - } -#endif // wxUSE_UNICODE/!wxUSE_UNICODE -} - -struct StringConversionData -{ - const char *str; - const wchar_t *wcs; -}; - void UnicodeTestCase::ConversionUTF7() { static const StringConversionData utf7data[] = { + // normal fragments + { "+AKM-", L"\xa3" }, + { "+AOk-t+AOk-", L"\xe9t\xe9" }, + + // this one is an alternative valid encoding of the same string + { "+AOk-t+AOk", L"\xe9t\xe9", StringConversionData::ONLY_MB2WC }, + + // some special cases { "+-", L"+" }, { "+--", L"+-" }, -#ifdef wxHAVE_U_ESCAPE - { "+AKM-", L"\u00a3" }, -#endif // wxHAVE_U_ESCAPE - // the following are invalid UTF-7 sequences + { "\xa3", NULL }, { "+", NULL }, { "+~", NULL }, { "a+", NULL }, }; - wxCSConv conv(_T("utf-7")); for ( size_t n = 0; n < WXSIZEOF(utf7data); n++ ) { const StringConversionData& d = utf7data[n]; @@ -271,9 +311,9 @@ void UnicodeTestCase::ConversionUTF7() // // I have no idea how to fix this so just disable the test for now #if 0 - DoTestConversion(d.str, d.wcs, conv); + d.Test(n, wxCSConv("utf-7")); #endif - DoTestConversion(d.str, d.wcs, wxConvUTF7); + d.Test(n, wxConvUTF7); } } @@ -291,8 +331,8 @@ void UnicodeTestCase::ConversionUTF8() for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ ) { const StringConversionData& d = utf8data[n]; - DoTestConversion(d.str, d.wcs, conv); - DoTestConversion(d.str, d.wcs, wxConvUTF8); + d.Test(n, conv); + d.Test(n, wxConvUTF8); } } @@ -312,7 +352,7 @@ void UnicodeTestCase::ConversionUTF16() for ( size_t n = 0; n < WXSIZEOF(utf16data); n++ ) { const StringConversionData& d = utf16data[n]; - DoTestConversion(d.str, d.wcs, conv); + d.Test(n, conv); } // special case: this string has consecutive NULs inside it which don't @@ -339,7 +379,7 @@ void UnicodeTestCase::ConversionUTF32() for ( size_t n = 0; n < WXSIZEOF(utf32data); n++ ) { const StringConversionData& d = utf32data[n]; - DoTestConversion(d.str, d.wcs, conv); + d.Test(n, conv); } size_t len; @@ -351,16 +391,15 @@ void UnicodeTestCase::ConversionUTF32() void UnicodeTestCase::IsConvOk() { CPPUNIT_ASSERT( wxCSConv(wxFONTENCODING_SYSTEM).IsOk() ); - CPPUNIT_ASSERT( wxCSConv(_T("UTF-8")).IsOk() ); - CPPUNIT_ASSERT( !wxCSConv(_T("NoSuchConversion")).IsOk() ); + CPPUNIT_ASSERT( wxCSConv("US-ASCII").IsOk() ); + CPPUNIT_ASSERT( wxCSConv("UTF-8").IsOk() ); + CPPUNIT_ASSERT( !wxCSConv("NoSuchConversion").IsOk() ); #ifdef __WINDOWS__ - CPPUNIT_ASSERT( wxCSConv(_T("WINDOWS-437")).IsOk() ); + CPPUNIT_ASSERT( wxCSConv("WINDOWS-437").IsOk() ); #endif } -#endif // wxUSE_WCHAR_T - #if wxUSE_UNICODE void UnicodeTestCase::Iteration() {