X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/00b34ed7ed66249448856c0819e107822e56d33b..bc50a2ae95f2ab36b16ceedc7902a9cbfb2f70ea:/tests/strings/strings.cpp diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index ff320ac926..3e25c70f48 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -21,8 +21,6 @@ #include "wx/wx.h" #endif // WX_PRECOMP -#include "wx/tokenzr.h" - // ---------------------------------------------------------------------------- // test class // ---------------------------------------------------------------------------- @@ -46,13 +44,14 @@ private: #endif // wxUSE_WCHAR_T CPPUNIT_TEST( Extraction ); CPPUNIT_TEST( Find ); - CPPUNIT_TEST( Tokenizer ); - CPPUNIT_TEST( TokenizerGetPosition ); CPPUNIT_TEST( Replace ); CPPUNIT_TEST( Match ); CPPUNIT_TEST( CaseChanges ); CPPUNIT_TEST( Compare ); CPPUNIT_TEST( CompareNoCase ); + CPPUNIT_TEST( ToLong ); + CPPUNIT_TEST( ToULong ); + CPPUNIT_TEST( ToDouble ); CPPUNIT_TEST_SUITE_END(); void String(); @@ -67,14 +66,14 @@ private: #endif // wxUSE_WCHAR_T void Extraction(); void Find(); - void SingleTokenizerTest( wxChar *str, wxChar *delims, size_t count , wxStringTokenizerMode mode ); - void Tokenizer(); - void TokenizerGetPosition(); void Replace(); void Match(); void CaseChanges(); void Compare(); void CompareNoCase(); + void ToLong(); + void ToULong(); + void ToDouble(); #if wxUSE_WCHAR_T // test if converting s using the given encoding gives ws and vice versa @@ -142,6 +141,15 @@ void StringTestCase::Format() CPPUNIT_ASSERT( s1 == wxString::Format(_T("%03d"), 18) ); s2.Printf(_T("Number 18: %s\n"), s1.c_str()); CPPUNIT_ASSERT( s2 == wxString::Format(_T("Number 18: %s\n"), s1.c_str()) ); + + static const size_t lengths[] = { 1, 512, 1024, 1025, 2048, 4096, 4097 }; + for ( size_t n = 0; n < WXSIZEOF(lengths); n++ ) + { + const size_t len = lengths[n]; + + wxString s(_T('Z'), len); + CPPUNIT_ASSERT_EQUAL( len, wxString::Format(_T("%s"), s.c_str()).length()); + } } void StringTestCase::Constructors() @@ -222,6 +230,20 @@ void StringTestCase::Conversion() #endif } +#if !wxUSE_UNICODE +// in case wcscmp is missing +// +static int wx_wcscmp(const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 == *s2 && *s1 != 0) + { + s1++; + s2++; + } + return *s1 - *s2; +} +#endif + void StringTestCase::DoTestConversion(const char *s, const wchar_t *ws, @@ -240,7 +262,7 @@ StringTestCase::DoTestConversion(const char *s, wxWCharBuffer wbuf(wxString(s).wc_str(conv)); if ( ws ) - CPPUNIT_ASSERT( wcscmp(wbuf, ws) == 0 ); + CPPUNIT_ASSERT( wx_wcscmp(wbuf, ws) == 0 ); else CPPUNIT_ASSERT( !*wbuf ); } @@ -259,8 +281,12 @@ void StringTestCase::ConversionUTF7() { { "+-", L"+" }, { "+--", L"+-" }, + //\u isn't recognized on MSVC 6 +#if !defined(_MSC_VER) +#if !defined(__GNUC__) || (__GNUC__ >= 3) { "+AKM-", L"\u00a3" }, - +#endif +#endif // Windows accepts invalid UTF-7 strings and so does our UTF-7 // conversion code -- this is wrong IMO but the way it is for now // @@ -284,7 +310,12 @@ void StringTestCase::ConversionUTF8() { static const StringConversionData utf8data[] = { + //\u isn't recognized on MSVC 6 +#if !defined(_MSC_VER) +#if !defined(__GNUC__) || (__GNUC__ >= 3) { "\xc2\xa3", L"\u00a3" }, +#endif +#endif { "\xc2", NULL }, }; @@ -342,98 +373,6 @@ void StringTestCase::Find() #undef TEST_FIND } -void StringTestCase::SingleTokenizerTest( wxChar *str, wxChar *delims, size_t count , wxStringTokenizerMode mode ) -{ - wxStringTokenizer tkz( str, delims, mode); - CPPUNIT_ASSERT( tkz.CountTokens() == count ); - - wxChar *buf, *s = NULL, *last; - - if ( tkz.GetMode() == wxTOKEN_STRTOK ) - { - buf = new wxChar[wxStrlen(str) + 1]; - wxStrcpy(buf, str); - s = wxStrtok(buf, delims, &last); - } - else - { - buf = NULL; - } - - size_t count2 = 0; - while ( tkz.HasMoreTokens() ) - { - wxString token = tkz.GetNextToken(); - if ( buf ) - { - CPPUNIT_ASSERT( token == s ); - s = wxStrtok(NULL, delims, &last); - } - count2++; - } - - CPPUNIT_ASSERT( count2 == count ); - if ( buf ) - { - delete [] buf; - } -} - -void StringTestCase::Tokenizer() -{ - SingleTokenizerTest( _T(""), _T(" "), 0, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello, world"), _T(" "), 2, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello, world "), _T(" "), 2, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello, world"), _T(","), 2, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello, world!"), _T(",!"), 2, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello,, world!"), _T(",!"), 3, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL ); - SingleTokenizerTest( _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY ); - SingleTokenizerTest( _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL ); - SingleTokenizerTest( _T("01/02/99"), _T("/-"), 3, wxTOKEN_DEFAULT ); - SingleTokenizerTest( _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS ); -} - -// call this with the string to tokenize, delimeters to use and the expected -// positions (i.e. results of GetPosition()) after each GetNextToken() call, -// terminate positions with 0 -static void -DoTokenizerGetPosition(const wxChar *s, const wxChar *delims, int pos, ...) -{ - wxStringTokenizer tkz(s, delims); - - CPPUNIT_ASSERT( tkz.GetPosition() == 0 ); - - va_list ap; - va_start(ap, pos); - - for ( ;; ) - { - if ( !pos ) - { - CPPUNIT_ASSERT( !tkz.HasMoreTokens() ); - break; - } - - tkz.GetNextToken(); - - CPPUNIT_ASSERT( tkz.GetPosition() == (size_t)pos ); - - pos = va_arg(ap, int); - } - - va_end(ap); -} - -void StringTestCase::TokenizerGetPosition() -{ - DoTokenizerGetPosition(_T("foo"), _T("_"), 3, 0); - DoTokenizerGetPosition(_T("foo_bar"), _T("_"), 4, 7, 0); - DoTokenizerGetPosition(_T("foo_bar_"), _T("_"), 4, 8, 0); -} - void StringTestCase::Replace() { #define TEST_REPLACE( original , pos , len , replacement , result ) \ @@ -449,6 +388,32 @@ void StringTestCase::Replace() TEST_REPLACE( _T("foobar"), 3, 0, _T("-"), _T("foo-bar") ); TEST_REPLACE( _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") ); + + #define TEST_NULLCHARREPLACE( o , olen, pos , len , replacement , r, rlen ) \ + { \ + wxString s(o,olen); \ + s.replace( pos , len , replacement ); \ + CPPUNIT_ASSERT( s == wxString(r,rlen) ); \ + } + + TEST_NULLCHARREPLACE( _T("null\0char"), 9, 5, 1, _T("d"), + _T("null\0dhar"), 9 ); + + #define TEST_WXREPLACE( o , olen, olds, news, all, r, rlen ) \ + { \ + wxString s(o,olen); \ + s.Replace( olds, news, all ); \ + CPPUNIT_ASSERT( s == wxString(r,rlen) ); \ + } + + TEST_WXREPLACE( _T("null\0char"), 9, _T("c"), _T("de"), true, + _T("null\0dehar"), 10 ); + + TEST_WXREPLACE( _T("null\0dehar"), 10, _T("de"), _T("c"), true, + _T("null\0char"), 9 ); + + #undef TEST_WXREPLACE + #undef TEST_NULLCHARREPLACE #undef TEST_REPLACE } @@ -494,8 +459,11 @@ void StringTestCase::CaseChanges() if ( locRu.IsOk() ) { // try upper casing 8bit strings - wxString sUpper("\xdf"), - sLower("\xff"); + const wchar_t capital_ya[] = { 0x42f, 0 }, + small_ya[] = { 0x44f, 0 }; + + wxString sUpper(wxConvLibc.cWC2MB(capital_ya)), + sLower(wxConvLibc.cWC2MB(small_ya)); CPPUNIT_ASSERT( sUpper.Lower() == sLower ); CPPUNIT_ASSERT( sLower.Upper() == sUpper ); @@ -585,3 +553,94 @@ void StringTestCase::CompareNoCase() CPPUNIT_CNCNEQ_ASSERT( s1, neq3 ); } +void StringTestCase::ToLong() +{ + long l; + static const struct ToLongData + { + const wxChar *str; + long value; + bool ok; + } longData[] = + { + { _T("1"), 1, true }, + { _T("0"), 0, true }, + { _T("a"), 0, false }, + { _T("12345"), 12345, true }, + { _T("-1"), -1, true }, + { _T("--1"), 0, false }, + }; + + size_t n; + for ( n = 0; n < WXSIZEOF(longData); n++ ) + { + const ToLongData& ld = longData[n]; + CPPUNIT_ASSERT_EQUAL( ld.ok, wxString(ld.str).ToLong(&l) ); + if ( ld.ok ) + CPPUNIT_ASSERT_EQUAL( ld.value, l ); + } +} + +void StringTestCase::ToULong() +{ + unsigned long ul; + static const struct ToULongData + { + const wxChar *str; + unsigned long value; + bool ok; + } ulongData[] = + { + { _T("1"), 1, true }, + { _T("0"), 0, true }, + { _T("a"), 0, false }, + { _T("12345"), 12345, true }, + // this is surprizing but consistent with strtoul() behaviour + { _T("-1"), ULONG_MAX, true }, + }; + + size_t n; + for ( n = 0; n < WXSIZEOF(ulongData); n++ ) + { + const ToULongData& uld = ulongData[n]; + CPPUNIT_ASSERT_EQUAL( uld.ok, wxString(uld.str).ToULong(&ul) ); + if ( uld.ok ) + CPPUNIT_ASSERT_EQUAL( uld.value, ul ); + } +} + +void StringTestCase::ToDouble() +{ + double d; + static const struct ToDoubleData + { + const wxChar *str; + double value; + bool ok; + } doubleData[] = + { + { _T("1"), 1, true }, + { _T("1.23"), 1.23, true }, + { _T(".1"), .1, true }, + { _T("1."), 1, true }, + { _T("1.."), 0, false }, + { _T("0"), 0, true }, + { _T("a"), 0, false }, + { _T("12345"), 12345, true }, + { _T("-1"), -1, true }, + { _T("--1"), 0, false }, + }; + + // we need to use decimal point, not comma or whatever is its value for the + // current locale + wxSetlocale(LC_ALL, _T("C")); + + size_t n; + for ( n = 0; n < WXSIZEOF(doubleData); n++ ) + { + const ToDoubleData& ld = doubleData[n]; + CPPUNIT_ASSERT_EQUAL( ld.ok, wxString(ld.str).ToDouble(&d) ); + if ( ld.ok ) + CPPUNIT_ASSERT_EQUAL( ld.value, d ); + } +}