X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c4f35063ce0d6fd6deb56fd558d386c0e6de8975..633566f6ef1729066b478918d963762f90dbae37:/tests/strings/strings.cpp diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 32e77b8214..ca6a5cd709 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -47,7 +47,15 @@ private: CPPUNIT_TEST( Contains ); CPPUNIT_TEST( ToLong ); CPPUNIT_TEST( ToULong ); +#ifdef wxLongLong_t + CPPUNIT_TEST( ToLongLong ); + CPPUNIT_TEST( ToULongLong ); +#endif // wxLongLong_t CPPUNIT_TEST( ToDouble ); + CPPUNIT_TEST( WriteBuf ); + CPPUNIT_TEST( CStrDataTernaryOperator ); + CPPUNIT_TEST( CStrDataImplicitConversion ); + CPPUNIT_TEST( ExplicitConversion ); CPPUNIT_TEST_SUITE_END(); void String(); @@ -65,7 +73,16 @@ private: void Contains(); void ToLong(); void ToULong(); +#ifdef wxLongLong_t + void ToLongLong(); + void ToULongLong(); +#endif // wxLongLong_t void ToDouble(); + void WriteBuf(); + void CStrDataTernaryOperator(); + void DoCStrDataTernaryOperator(bool cond); + void CStrDataImplicitConversion(); + void ExplicitConversion(); DECLARE_NO_COPY_CLASS(StringTestCase) }; @@ -345,6 +362,26 @@ void StringTestCase::Compare() CPPUNIT_ASSERT( s1 != neq3 ); CPPUNIT_ASSERT( s1 != neq4 ); + CPPUNIT_ASSERT( s1 == wxT("AHH") ); + CPPUNIT_ASSERT( s1 != wxT("no") ); + CPPUNIT_ASSERT( s1 < wxT("AZ") ); + CPPUNIT_ASSERT( s1 <= wxT("AZ") ); + CPPUNIT_ASSERT( s1 <= wxT("AHH") ); + CPPUNIT_ASSERT( s1 > wxT("AA") ); + CPPUNIT_ASSERT( s1 >= wxT("AA") ); + CPPUNIT_ASSERT( s1 >= wxT("AHH") ); + + // test comparison with C strings in Unicode build (must work in ANSI as + // well, of course): + CPPUNIT_ASSERT( s1 == "AHH" ); + CPPUNIT_ASSERT( s1 != "no" ); + CPPUNIT_ASSERT( s1 < "AZ" ); + CPPUNIT_ASSERT( s1 <= "AZ" ); + CPPUNIT_ASSERT( s1 <= "AHH" ); + CPPUNIT_ASSERT( s1 > "AA" ); + CPPUNIT_ASSERT( s1 >= "AA" ); + CPPUNIT_ASSERT( s1 >= "AHH" ); + // wxString _s1 = wxT("A\0HH"); // wxString _eq = wxT("A\0HH"); // wxString _neq1 = wxT("H\0AH"); @@ -439,61 +476,126 @@ void StringTestCase::Contains() } } -void StringTestCase::ToLong() +// flags used in ToLongData.flags +enum { - 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 }, - }; + Number_Ok = 0, + Number_Invalid = 1, + Number_Unsigned = 2, // if not specified, works for signed conversion + Number_Signed = 4, // if not specified, works for unsigned + Number_LongLong = 8, // only for long long tests + Number_Long = 16, // only for long tests +}; +static const struct ToLongData +{ + const wxChar *str; +#ifdef wxLongLong_t + wxLongLong_t value; +#else + long value; +#endif // wxLongLong_t + int flags; + + long LValue() const { return value; } + unsigned long ULValue() const { return value; } +#ifdef wxLongLong_t + wxLongLong_t LLValue() const { return value; } + wxULongLong_t ULLValue() const { return (wxULongLong_t)value; } +#endif // wxLongLong_t + + bool IsOk() const { return !(flags & Number_Invalid); } +} longData[] = +{ + { _T("1"), 1, Number_Ok }, + { _T("0"), 0, Number_Ok }, + { _T("a"), 0, Number_Invalid }, + { _T("12345"), 12345, Number_Ok }, + { _T("--1"), 0, Number_Invalid }, + + { _T("-1"), -1, Number_Signed | Number_Long }, + // this is surprizing but consistent with strtoul() behaviour + { _T("-1"), ULONG_MAX, Number_Unsigned | Number_Long }, + + // this must overflow, even with 64 bit long + { _T("922337203685477580711"), 0, Number_Invalid }, + +#ifdef wxLongLong_t + { _T("2147483648"), wxLL(2147483648), Number_LongLong }, + { _T("-2147483648"), wxLL(-2147483648), Number_LongLong | Number_Signed }, + { _T("9223372036854775808"), wxULL(9223372036854775808), Number_LongLong | + Number_Unsigned }, +#endif // wxLongLong_t +}; + +void StringTestCase::ToLong() +{ long l; for ( size_t 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 ); + + if ( ld.flags & (Number_LongLong | Number_Unsigned) ) + continue; + + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToLong(&l) ); + if ( ld.IsOk() ) + CPPUNIT_ASSERT_EQUAL( ld.LValue(), l ); } } void StringTestCase::ToULong() { unsigned long ul; - static const struct ToULongData + for ( size_t n = 0; n < WXSIZEOF(longData); n++ ) { - const wxChar *str; - unsigned long value; - bool ok; - } ulongData[] = + const ToLongData& ld = longData[n]; + + if ( ld.flags & (Number_LongLong | Number_Signed) ) + continue; + + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToULong(&ul) ); + if ( ld.IsOk() ) + CPPUNIT_ASSERT_EQUAL( ld.ULValue(), ul ); + } +} + +#ifdef wxLongLong_t + +void StringTestCase::ToLongLong() +{ + wxLongLong_t l; + for ( size_t n = 0; n < WXSIZEOF(longData); n++ ) { - { _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 }, - }; + const ToLongData& ld = longData[n]; - size_t n; - for ( n = 0; n < WXSIZEOF(ulongData); n++ ) + if ( ld.flags & (Number_Long | Number_Unsigned) ) + continue; + + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToLongLong(&l) ); + if ( ld.IsOk() ) + CPPUNIT_ASSERT_EQUAL( ld.LLValue(), l ); + } +} + +void StringTestCase::ToULongLong() +{ + wxULongLong_t ul; + for ( size_t n = 0; n < WXSIZEOF(longData); 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 ); + const ToLongData& ld = longData[n]; + + if ( ld.flags & (Number_Long | Number_Signed) ) + continue; + + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToULongLong(&ul) ); + if ( ld.IsOk() ) + CPPUNIT_ASSERT_EQUAL( ld.ULLValue(), ul ); } } +#endif // wxLongLong_t + void StringTestCase::ToDouble() { double d; @@ -529,3 +631,108 @@ void StringTestCase::ToDouble() CPPUNIT_ASSERT_EQUAL( ld.value, d ); } } + +void StringTestCase::WriteBuf() +{ + wxString s; + wxStrcpy(wxStringBuffer(s, 10), _T("foo")); + + CPPUNIT_ASSERT(s[0u] == _T('f') ); + CPPUNIT_ASSERT(_T('f') == s[0u]); + CPPUNIT_ASSERT(_T('o') == s[1]); + CPPUNIT_ASSERT(_T('o') == s[2]); + CPPUNIT_ASSERT_EQUAL((size_t)3, s.length()); + + + { + wxStringBufferLength buf(s, 10); + wxStrcpy(buf, _T("barrbaz")); + buf.SetLength(4); + } + + CPPUNIT_ASSERT(_T('b') == s[0u]); + CPPUNIT_ASSERT(_T('a') == s[1]); + CPPUNIT_ASSERT(_T('r') == s[2]); + CPPUNIT_ASSERT(_T('r') == s[3]); + CPPUNIT_ASSERT_EQUAL((size_t)4, s.length()); + + CPPUNIT_ASSERT_EQUAL( 0, wxStrcmp(_T("barr"), s) ); +} + + + +void StringTestCase::CStrDataTernaryOperator() +{ + DoCStrDataTernaryOperator(true); + DoCStrDataTernaryOperator(false); +} + +template bool CheckStr(const wxString& expected, T s) +{ + return expected == wxString(s); +} + +void StringTestCase::DoCStrDataTernaryOperator(bool cond) +{ + // test compilation of wxCStrData when used with operator?: (the asserts + // are not very important, we're testing if the code compiles at all): + + wxString s("foo"); + + // FIXME-UTF8: when wxCStrData can handle both conversions, this should + // be changed to always test all versions, both MB and WC +#if wxUSE_UNICODE + const wchar_t *wcStr = L"foo"; + CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : wcStr)) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : L"bar")) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? wcStr : s.c_str())) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? L"bar" : s.c_str())) ); +#else + const char *mbStr = "foo"; + CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : mbStr)) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : "foo")) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? mbStr : s.c_str())) ); + CPPUNIT_ASSERT( CheckStr(s, (cond ? "foo" : s.c_str())) ); +#endif + + wxString empty(""); + CPPUNIT_ASSERT( CheckStr(empty, (cond ? empty.c_str() : wxEmptyString)) ); + CPPUNIT_ASSERT( CheckStr(empty, (cond ? wxEmptyString : empty.c_str())) ); +} + +bool CheckStrChar(const wxString& expected, char *s) + { return CheckStr(expected, s); } +bool CheckStrWChar(const wxString& expected, wchar_t *s) + { return CheckStr(expected, s); } +bool CheckStrConstChar(const wxString& expected, const char *s) + { return CheckStr(expected, s); } +bool CheckStrConstWChar(const wxString& expected, const wchar_t *s) + { return CheckStr(expected, s); } + +void StringTestCase::CStrDataImplicitConversion() +{ + wxString s("foo"); + + // FIXME-UTF8: when wxCStrData can handle both conversions, this should + // be changed to always test all versions, both MB and WC +#if wxUSE_UNICODE + CPPUNIT_ASSERT( CheckStrConstWChar(s, s.c_str()) ); + CPPUNIT_ASSERT( CheckStrConstWChar(s, s) ); +#else + CPPUNIT_ASSERT( CheckStrConstChar(s, s.c_str()) ); + CPPUNIT_ASSERT( CheckStrConstChar(s, s) ); +#endif +} + +void StringTestCase::ExplicitConversion() +{ + wxString s("foo"); + + CPPUNIT_ASSERT( CheckStr(s, s.mb_str()) ); + CPPUNIT_ASSERT( CheckStrConstChar(s, s.mb_str()) ); + CPPUNIT_ASSERT( CheckStrChar(s, s.char_str()) ); + + CPPUNIT_ASSERT( CheckStr(s, s.wc_str()) ); + CPPUNIT_ASSERT( CheckStrConstWChar(s, s.wc_str()) ); + CPPUNIT_ASSERT( CheckStrWChar(s, s.wchar_str()) ); +}