X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ffcd6cc61e286e421d6bf0e03755755ae8c90577..3942aa77f5f737e668137a09ee197c7099c45a9e:/tests/strings/strings.cpp diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index b613cb65b0..a0485c9007 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -35,6 +35,7 @@ private: CPPUNIT_TEST( String ); CPPUNIT_TEST( PChar ); CPPUNIT_TEST( Format ); + CPPUNIT_TEST( FormatUnicode ); CPPUNIT_TEST( Constructors ); CPPUNIT_TEST( StaticConstructors ); CPPUNIT_TEST( Extraction ); @@ -68,6 +69,7 @@ private: void String(); void PChar(); void Format(); + void FormatUnicode(); void Constructors(); void StaticConstructors(); void Extraction(); @@ -104,7 +106,7 @@ private: // register in the unnamed registry so that these tests are run by default CPPUNIT_TEST_SUITE_REGISTRATION( StringTestCase ); -// also include in it's own registry so that these tests can be run alone +// also include in its own registry so that these tests can be run alone CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( StringTestCase, "StringTestCase" ); StringTestCase::StringTestCase() @@ -165,6 +167,27 @@ void StringTestCase::Format() wxString s(wxT('Z'), len); CPPUNIT_ASSERT_EQUAL( len, wxString::Format(wxT("%s"), s.c_str()).length()); } + + + CPPUNIT_ASSERT_EQUAL + ( + "two one", + wxString::Format(wxT("%2$s %1$s"), wxT("one"), wxT("two")) + ); +} + +void StringTestCase::FormatUnicode() +{ +#if wxUSE_UNICODE + const char *UNICODE_STR = "Iestat\xC4\xAB %i%i"; + //const char *UNICODE_STR = "Iestat\xCC\x84 %i%i"; + + wxString fmt = wxString::FromUTF8(UNICODE_STR); + wxString s = wxString::Format(fmt, 1, 1); + wxString expected(fmt); + expected.Replace("%i", "1"); + CPPUNIT_ASSERT_EQUAL( expected, s ); +#endif // wxUSE_UNICODE } void StringTestCase::Constructors() @@ -183,6 +206,20 @@ void StringTestCase::Constructors() CPPUNIT_ASSERT_EQUAL( L"Hello", wxString(L"Hello", 5) ); #endif // wxUSE_UNICODE + CPPUNIT_ASSERT_EQUAL( 0, wxString(wxString(), 17).length() ); + +#if wxUSE_UNICODE_UTF8 + // This string has 3 characters (, and ), not 4 when using UTF-8 + // locale! + if ( wxConvLibc.IsUTF8() ) + { + wxString s3("h\xc3\xa9llo", 4); + CPPUNIT_ASSERT_EQUAL( 3, s3.length() ); + CPPUNIT_ASSERT_EQUAL( 'l', (char)s3[2] ); + } +#endif // wxUSE_UNICODE_UTF8 + + static const char *s = "?really!"; const char *start = wxStrchr(s, 'r'); const char *end = wxStrchr(s, '!'); @@ -210,6 +247,9 @@ void StringTestCase::StaticConstructors() CPPUNIT_ASSERT_EQUAL( "Hello", wxString::FromUTF8("Hello", 5) ); CPPUNIT_ASSERT_EQUAL( "Hello", wxString::FromUTF8("Hello") ); + CPPUNIT_ASSERT_EQUAL( 2, wxString::FromUTF8("h\xc3\xa9llo", 3).length() ); + + //CPPUNIT_ASSERT_EQUAL( 1, wxString::FromUTF8("", 1).length() ); } @@ -455,6 +495,10 @@ void StringTestCase::Compare() CPPUNIT_ASSERT( s1 != neq2 ); CPPUNIT_ASSERT( s1 != neq3 ); CPPUNIT_ASSERT( s1 != neq4 ); + + CPPUNIT_ASSERT( wxString("\n").Cmp(" ") < 0 ); + CPPUNIT_ASSERT( wxString("'").Cmp("!") > 0 ); + CPPUNIT_ASSERT( wxString("!").Cmp("z") < 0 ); } void StringTestCase::CompareNoCase() @@ -502,6 +546,10 @@ void StringTestCase::CompareNoCase() CPPUNIT_CNCNEQ_ASSERT( s1, neq ); CPPUNIT_CNCNEQ_ASSERT( s1, neq2 ); CPPUNIT_CNCNEQ_ASSERT( s1, neq3 ); + + CPPUNIT_ASSERT( wxString("\n").CmpNoCase(" ") < 0 ); + CPPUNIT_ASSERT( wxString("'").CmpNoCase("!") > 0); + CPPUNIT_ASSERT( wxString("!").Cmp("Z") < 0 ); } void StringTestCase::Contains() @@ -551,6 +599,7 @@ static const struct ToLongData long value; #endif // wxLongLong_t int flags; + int base; long LValue() const { return value; } unsigned long ULValue() const { return value; } @@ -581,6 +630,22 @@ static const struct ToLongData { wxT("9223372036854775808"), wxULL(9223372036854775808), Number_LongLong | Number_Unsigned }, #endif // wxLongLong_t + + // Base tests. + { wxT("010"), 10, Number_Ok, 10 }, + { wxT("010"), 8, Number_Ok, 0 }, + { wxT("010"), 8, Number_Ok, 8 }, + { wxT("010"), 16, Number_Ok, 16 }, + + { wxT("0010"), 10, Number_Ok, 10 }, + { wxT("0010"), 8, Number_Ok, 0 }, + { wxT("0010"), 8, Number_Ok, 8 }, + { wxT("0010"), 16, Number_Ok, 16 }, + + { wxT("0x11"), 0, Number_Invalid, 10 }, + { wxT("0x11"), 17, Number_Ok, 0 }, + { wxT("0x11"), 0, Number_Invalid, 8 }, + { wxT("0x11"), 17, Number_Ok, 16 }, }; void StringTestCase::ToLong() @@ -596,11 +661,13 @@ void StringTestCase::ToLong() // NOTE: unless you're using some exotic locale, ToCLong and ToLong // should behave the same for our test data set: - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToCLong(&l) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToCLong(&l, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.LValue(), l ); - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToLong(&l) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToLong(&l, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.LValue(), l ); } @@ -630,11 +697,13 @@ void StringTestCase::ToULong() // NOTE: unless you're using some exotic locale, ToCLong and ToLong // should behave the same for our test data set: - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToCULong(&ul) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToCULong(&ul, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.ULValue(), ul ); - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToULong(&ul) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToULong(&ul, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.ULValue(), ul ); } @@ -652,7 +721,8 @@ void StringTestCase::ToLongLong() if ( ld.flags & (Number_Long | Number_Unsigned) ) continue; - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToLongLong(&l) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToLongLong(&l, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.LLValue(), l ); } @@ -668,7 +738,8 @@ void StringTestCase::ToULongLong() if ( ld.flags & (Number_Long | Number_Signed) ) continue; - CPPUNIT_ASSERT_EQUAL( ld.IsOk(), wxString(ld.str).ToULongLong(&ul) ); + CPPUNIT_ASSERT_EQUAL( ld.IsOk(), + wxString(ld.str).ToULongLong(&ul, ld.base) ); if ( ld.IsOk() ) CPPUNIT_ASSERT_EQUAL( ld.ULLValue(), ul ); } @@ -754,25 +825,30 @@ void StringTestCase::FromDouble() static const struct FromDoubleTestData { double value; + int prec; const char *str; } testData[] = { - { 1.23, "1.23" }, + { 1.23, -1, "1.23" }, // NB: there are no standards about the minimum exponent width // and newer MSVC versions use 3 digits as minimum exponent // width while GNU libc uses 2 digits as minimum width... -#ifdef __VISUALC__ - { -3e-10, "-3e-010" }, +#ifdef wxUSING_VC_CRT_IO + { -3e-10, -1, "-3e-010" }, #else - { -3e-10, "-3e-10" }, + { -3e-10, -1, "-3e-10" }, #endif - { -0.45678, "-0.45678" }, + { -0.45678, -1, "-0.45678" }, + { 1.2345678, 0, "1" }, + { 1.2345678, 1, "1.2" }, + { 1.2345678, 2, "1.23" }, + { 1.2345678, 3, "1.235" }, }; for ( unsigned n = 0; n < WXSIZEOF(testData); n++ ) { const FromDoubleTestData& td = testData[n]; - CPPUNIT_ASSERT_EQUAL( td.str, wxString::FromCDouble(td.value) ); + CPPUNIT_ASSERT_EQUAL( td.str, wxString::FromCDouble(td.value, td.prec) ); } if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) ) @@ -787,7 +863,7 @@ void StringTestCase::FromDouble() wxString str(td.str); str.Replace(".", ","); - CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value) ); + CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value, td.prec) ); } } @@ -960,23 +1036,48 @@ void StringTestCase::IndexedAccess() void StringTestCase::BeforeAndAfter() { - const wxString s(L"letter=\xe9;\xe7a=l\xe0"); + // Construct a string with 2 equal signs in it by concatenating its three + // parts: before the first "=", in between the two "="s and after the last + // one. This allows to avoid duplicating the string contents (which has to + // be different for Unicode and ANSI builds) in the tests below. +#if wxUSE_UNICODE + #define FIRST_PART L"letter" + #define MIDDLE_PART L"\xe9;\xe7a" + #define LAST_PART L"l\xe0" +#else // !wxUSE_UNICODE + #define FIRST_PART "letter" + #define MIDDLE_PART "e;ca" + #define LAST_PART "la" +#endif // wxUSE_UNICODE/!wxUSE_UNICODE + + const wxString s(FIRST_PART wxT("=") MIDDLE_PART wxT("=") LAST_PART); + + wxString r; + + CPPUNIT_ASSERT_EQUAL( FIRST_PART, s.BeforeFirst('=', &r) ); + CPPUNIT_ASSERT_EQUAL( MIDDLE_PART wxT("=") LAST_PART, r ); + + CPPUNIT_ASSERT_EQUAL( s, s.BeforeFirst('!', &r) ); + CPPUNIT_ASSERT_EQUAL( "", r ); + - CPPUNIT_ASSERT_EQUAL( "letter", s.BeforeFirst('=') ); - CPPUNIT_ASSERT_EQUAL( s, s.BeforeFirst('!') ); - CPPUNIT_ASSERT_EQUAL( L"letter=\xe9", s.BeforeFirst(';') ); + CPPUNIT_ASSERT_EQUAL( FIRST_PART wxT("=") MIDDLE_PART, s.BeforeLast('=', &r) ); + CPPUNIT_ASSERT_EQUAL( LAST_PART, r ); - CPPUNIT_ASSERT_EQUAL( L"letter=\xe9;\xe7a", s.BeforeLast('=') ); - CPPUNIT_ASSERT_EQUAL( "", s.BeforeLast('!') ); - CPPUNIT_ASSERT_EQUAL( L"letter=\xe9", s.BeforeLast(';') ); + CPPUNIT_ASSERT_EQUAL( "", s.BeforeLast('!', &r) ); + CPPUNIT_ASSERT_EQUAL( s, r ); - CPPUNIT_ASSERT_EQUAL( L"\xe9;\xe7a=l\xe0", s.AfterFirst('=') ); + + CPPUNIT_ASSERT_EQUAL( MIDDLE_PART wxT("=") LAST_PART, s.AfterFirst('=') ); CPPUNIT_ASSERT_EQUAL( "", s.AfterFirst('!') ); - CPPUNIT_ASSERT_EQUAL( L"\xe7a=l\xe0", s.AfterFirst(';') ); - CPPUNIT_ASSERT_EQUAL( L"l\xe0", s.AfterLast('=') ); + + CPPUNIT_ASSERT_EQUAL( LAST_PART, s.AfterLast('=') ); CPPUNIT_ASSERT_EQUAL( s, s.AfterLast('!') ); - CPPUNIT_ASSERT_EQUAL( L"\xe7a=l\xe0", s.AfterLast(';') ); + + #undef LAST_PART + #undef MIDDLE_PART + #undef FIRST_PART } void StringTestCase::ScopedBuffers() @@ -1001,4 +1102,18 @@ void StringTestCase::ScopedBuffers() wxCharBuffer buf2 = sbuf; CPPUNIT_ASSERT( buf2.data() != literal ); CPPUNIT_ASSERT_EQUAL( literal, buf.data() ); + + // Check that extending the buffer keeps it NUL-terminated. + size_t len = 10; + + wxCharBuffer buf3(len); + CPPUNIT_ASSERT_EQUAL('\0', buf3.data()[len]); + + wxCharBuffer buf4; + buf4.extend(len); + CPPUNIT_ASSERT_EQUAL('\0', buf4.data()[len]); + + wxCharBuffer buf5(5); + buf5.extend(len); + CPPUNIT_ASSERT_EQUAL('\0', buf5.data()[len]); }