+ CPPUNIT_ASSERT_EQUAL(4, s.length());
+ CPPUNIT_ASSERT(wxT('b') == s[0u]);
+ CPPUNIT_ASSERT(wxT('a') == s[1]);
+ CPPUNIT_ASSERT(wxT('r') == s[2]);
+ CPPUNIT_ASSERT(wxT('r') == s[3]);
+
+ // check that creating buffer of length smaller than string works, i.e. at
+ // least doesn't crash (it would if we naively copied the entire original
+ // string contents in the buffer)
+ *wxStringBuffer(s, 1) = '!';
+}
+
+void StringTestCase::UTF8Buf()
+{
+#if wxUSE_UNICODE
+ // "czech" in Czech ("cestina"):
+ static const char *textUTF8 = "\304\215e\305\241tina";
+ static const wchar_t textUTF16[] = {0x10D, 0x65, 0x161, 0x74, 0x69, 0x6E, 0x61, 0};
+
+ wxString s;
+ wxStrcpy(wxUTF8StringBuffer(s, 9), textUTF8);
+ CPPUNIT_ASSERT(s == textUTF16);
+
+ {
+ wxUTF8StringBufferLength buf(s, 20);
+ wxStrcpy(buf, textUTF8);
+ buf.SetLength(5);
+ }
+ CPPUNIT_ASSERT(s == wxString(textUTF16, 0, 3));
+#endif // wxUSE_UNICODE
+}
+
+
+
+void StringTestCase::CStrDataTernaryOperator()
+{
+ DoCStrDataTernaryOperator(true);
+ DoCStrDataTernaryOperator(false);
+}
+
+template<typename T> 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");
+
+ const wchar_t *wcStr = L"foo";
+ CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : wcStr)) );
+ CPPUNIT_ASSERT( CheckStr(s, (cond ? s.c_str() : L"foo")) );
+ CPPUNIT_ASSERT( CheckStr(s, (cond ? wcStr : s.c_str())) );
+ CPPUNIT_ASSERT( CheckStr(s, (cond ? L"foo" : s.c_str())) );
+
+ 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())) );
+
+ wxString empty("");
+ CPPUNIT_ASSERT( CheckStr(empty, (cond ? empty.c_str() : wxEmptyString)) );
+ CPPUNIT_ASSERT( CheckStr(empty, (cond ? wxEmptyString : empty.c_str())) );
+}
+
+void StringTestCase::CStrDataOperators()
+{
+ wxString s("hello");
+
+ CPPUNIT_ASSERT( s.c_str()[0] == 'h' );
+ CPPUNIT_ASSERT( s.c_str()[1] == 'e' );
+
+ // IMPORTANT: at least with the CRT coming with MSVC++ 2008 trying to access
+ // the final character results in an assert failure (with debug CRT)
+ //CPPUNIT_ASSERT( s.c_str()[5] == '\0' );
+
+ CPPUNIT_ASSERT( *s.c_str() == 'h' );
+ CPPUNIT_ASSERT( *(s.c_str() + 2) == 'l' );
+ //CPPUNIT_ASSERT( *(s.c_str() + 5) == '\0' );
+}
+
+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");
+
+ CPPUNIT_ASSERT( CheckStrConstWChar(s, s.c_str()) );
+ CPPUNIT_ASSERT( CheckStrConstChar(s, s.c_str()) );
+
+ // implicit conversion of wxString is not available in STL build
+#if !wxUSE_STL
+ CPPUNIT_ASSERT( CheckStrConstWChar(s, s) );
+ 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()) );
+}
+
+void StringTestCase::IndexedAccess()
+{
+ wxString s("bar");
+ CPPUNIT_ASSERT_EQUAL( 'r', (char)s[2] );
+
+ // this tests for a possible bug in UTF-8 based wxString implementation:
+ // the 3rd character of the underlying byte string is going to change, but
+ // the 3rd character of wxString should remain the same
+ s[0] = L'\xe9';
+ CPPUNIT_ASSERT_EQUAL( 'r', (char)s[2] );
+}
+
+void StringTestCase::BeforeAndAfter()
+{
+ // 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 );
+