initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
280
libs/wxWidgets-3.3.1/tests/strings/crt.cpp
Normal file
280
libs/wxWidgets-3.3.1/tests/strings/crt.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/crt.cpp
|
||||
// Purpose: Test for wx C runtime functions wrappers
|
||||
// Author: Vaclav Slavik
|
||||
// Created: 2004-06-03
|
||||
// Copyright: (c) 2004 Vaclav Slavik
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/textfile.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const char *strMB = "hello, world";
|
||||
static const wchar_t *strWC = L"hello, world";
|
||||
static const wxString strWX("hello, world");
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("CRT::SetGetEnv", "[crt][getenv][setenv]")
|
||||
{
|
||||
#define TESTVAR_NAME "WXTESTVAR"
|
||||
|
||||
wxString val;
|
||||
wxSetEnv(TESTVAR_NAME, wxT("value"));
|
||||
CHECK( wxGetEnv(TESTVAR_NAME, &val) );
|
||||
CHECK( val == "value" );
|
||||
CHECK( wxString(wxGetenv(TESTVAR_NAME)) == "value" );
|
||||
|
||||
const wxString nonASCII = wxString::FromUTF8("☺");
|
||||
wxSetEnv(TESTVAR_NAME, nonASCII);
|
||||
CHECK( wxGetEnv(TESTVAR_NAME, &val) );
|
||||
CHECK( val == nonASCII );
|
||||
|
||||
// Under MSW the current locale encoding is used for storing the value in
|
||||
// the ASCII environment block, so we can't expect to get it back unless
|
||||
// this encoding is UTF-8, which is not the case by default.
|
||||
#ifndef __WINDOWS__
|
||||
CHECK( wxString::FromUTF8(wxGetenv(TESTVAR_NAME)) == nonASCII );
|
||||
#endif
|
||||
|
||||
// Wide char wxGetenv() overload does work, under both MSW and Unix.
|
||||
CHECK( wxGetenv(L"WXTESTVAR") == nonASCII );
|
||||
|
||||
CHECK( wxUnsetEnv(TESTVAR_NAME) );
|
||||
CHECK( !wxGetEnv(TESTVAR_NAME, nullptr) );
|
||||
CHECK( !wxGetenv(TESTVAR_NAME) );
|
||||
|
||||
#undef TESTVAR_NAME
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strchr", "[crt][strchr]")
|
||||
{
|
||||
// test that searching for a wide character in a narrow string simply
|
||||
// doesn't find it but doesn't fail with an assert (#11487)
|
||||
const wxUniChar smiley = *wxString::FromUTF8("☺").begin();
|
||||
|
||||
CHECK( !wxStrchr("hello", smiley) );
|
||||
|
||||
// but searching for an explicitly wide character does find it
|
||||
CHECK( wxStrchr(wxString::FromUTF8(":-) == ☺"),
|
||||
static_cast<wchar_t>(smiley)) );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strcmp", "[crt][strcmp]")
|
||||
{
|
||||
// this code tests if all possible ways of calling wxStrcmp() compile:
|
||||
const char * const char1 = "first";
|
||||
const wchar_t * const wchar1 = L"first";
|
||||
wxString str1("first");
|
||||
wxCStrData cstr1(str1.c_str());
|
||||
wxCharBuffer charbuf1(char1);
|
||||
wxWCharBuffer wcharbuf1(wchar1);
|
||||
|
||||
const char * const char2 = "last";
|
||||
const wchar_t * const wchar2 = L"last";
|
||||
wxString str2("last");
|
||||
wxCStrData cstr2(str2.c_str());
|
||||
wxCharBuffer charbuf2(char2);
|
||||
wxWCharBuffer wcharbuf2(wchar2);
|
||||
|
||||
CHECK( wxStrcmp(char1, char2) < 0 );
|
||||
CHECK( wxStrcmp(char1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(char1, str2) < 0 );
|
||||
CHECK( wxStrcmp(char1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(char1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(char1, wcharbuf2) < 0 );
|
||||
|
||||
CHECK( wxStrcmp(wchar1, char2) < 0 );
|
||||
CHECK( wxStrcmp(wchar1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(wchar1, str2) < 0 );
|
||||
CHECK( wxStrcmp(wchar1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(wchar1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(wchar1, wcharbuf2) < 0 );
|
||||
|
||||
CHECK( wxStrcmp(str1, char2) < 0 );
|
||||
CHECK( wxStrcmp(str1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(str1, str2) < 0 );
|
||||
CHECK( wxStrcmp(str1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(str1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(str1, wcharbuf2) < 0 );
|
||||
|
||||
CHECK( wxStrcmp(cstr1, char2) < 0 );
|
||||
CHECK( wxStrcmp(cstr1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(cstr1, str2) < 0 );
|
||||
CHECK( wxStrcmp(cstr1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(cstr1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(cstr1, wcharbuf2) < 0 );
|
||||
|
||||
CHECK( wxStrcmp(charbuf1, char2) < 0 );
|
||||
CHECK( wxStrcmp(charbuf1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(charbuf1, str2) < 0 );
|
||||
CHECK( wxStrcmp(charbuf1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(charbuf1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(charbuf1, wcharbuf2) < 0 );
|
||||
|
||||
CHECK( wxStrcmp(wcharbuf1, char2) < 0 );
|
||||
CHECK( wxStrcmp(wcharbuf1, wchar2) < 0 );
|
||||
CHECK( wxStrcmp(wcharbuf1, str2) < 0 );
|
||||
CHECK( wxStrcmp(wcharbuf1, cstr2) < 0 );
|
||||
CHECK( wxStrcmp(wcharbuf1, charbuf2) < 0 );
|
||||
CHECK( wxStrcmp(wcharbuf1, wcharbuf2) < 0 );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strspn", "[crt][strspn]")
|
||||
{
|
||||
CHECK( wxStrspn(strMB, "xyz") == 0 );
|
||||
CHECK( wxStrspn(strWC, "xyz") == 0 );
|
||||
CHECK( wxStrspn(strWX, "xyz") == 0 );
|
||||
CHECK( wxStrspn(strMB, L"xyz") == 0 );
|
||||
CHECK( wxStrspn(strWC, L"xyz") == 0 );
|
||||
CHECK( wxStrspn(strWX, L"xyz") == 0 );
|
||||
|
||||
CHECK( wxStrspn(strMB, "hleo") == 5 );
|
||||
CHECK( wxStrspn(strWC, "hleo") == 5 );
|
||||
CHECK( wxStrspn(strWX, "hleo") == 5 );
|
||||
|
||||
CHECK( wxStrspn(strMB, "ld") == 0 );
|
||||
CHECK( wxStrspn(strWC, "ld") == 0 );
|
||||
CHECK( wxStrspn(strWX, "ld") == 0 );
|
||||
|
||||
CHECK( wxStrspn(strMB, strWC) == strWX.length() );
|
||||
CHECK( wxStrspn(strWC, strWX) == strWX.length() );
|
||||
CHECK( wxStrspn(strWX, strMB) == strWX.length() );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strcspn", "[crt][strcspn]")
|
||||
{
|
||||
CHECK( wxStrcspn(strMB, strWX) == 0 );
|
||||
CHECK( wxStrcspn(strWC, strMB) == 0 );
|
||||
CHECK( wxStrcspn(strWX, strWC) == 0 );
|
||||
|
||||
CHECK( wxStrcspn(strMB, ", ") == 5 );
|
||||
CHECK( wxStrcspn(strWC, ", ") == 5 );
|
||||
CHECK( wxStrcspn(strWX, ", ") == 5 );
|
||||
|
||||
CHECK( wxStrcspn(strMB, "hel") == 0 );
|
||||
CHECK( wxStrcspn(strWC, "hel") == 0 );
|
||||
CHECK( wxStrcspn(strWX, "hel") == 0 );
|
||||
|
||||
CHECK( wxStrcspn(strMB, "xy") == strWX.length() );
|
||||
CHECK( wxStrcspn(strWC, "xy") == strWX.length() );
|
||||
CHECK( wxStrcspn(strWX, "xy") == strWX.length() );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strpbrk", "[crt][strpbrk]")
|
||||
{
|
||||
const wxString s(", ");
|
||||
|
||||
CHECK( *wxStrpbrk(strMB, ", ") == ',' );
|
||||
CHECK( *wxStrpbrk(strWC, L", ") == L',' );
|
||||
CHECK( *wxStrpbrk(strWX, ", ") == ',' );
|
||||
CHECK( *wxStrpbrk(strWX, L", ") == L',' );
|
||||
|
||||
CHECK( *wxStrpbrk(strMB, s) == ',' );
|
||||
CHECK( *wxStrpbrk(strWC, s) == L',' );
|
||||
CHECK( *wxStrpbrk(strWX, s) == ',' );
|
||||
CHECK( *wxStrpbrk(strWX.c_str(), s) == ',' );
|
||||
|
||||
CHECK( *wxStrpbrk(strMB, s.c_str()) == ',' );
|
||||
CHECK( *wxStrpbrk(strWC, s.c_str()) == L',' );
|
||||
CHECK( *wxStrpbrk(strWX, s.c_str()) == ',' );
|
||||
CHECK( *wxStrpbrk(strWX.c_str(), s.c_str()) == ',' );
|
||||
|
||||
CHECK( *wxStrpbrk(strMB, s.mb_str()) == ',' );
|
||||
CHECK( *wxStrpbrk(strWC, s.wc_str()) == L',' );
|
||||
CHECK( *wxStrpbrk(strWX, s.mb_str()) == ',' );
|
||||
CHECK( *wxStrpbrk(strWX, s.wc_str()) == L',' );
|
||||
CHECK( *wxStrpbrk(strWX.c_str(), s.mb_str()) == ',' );
|
||||
CHECK( *wxStrpbrk(strWX.c_str(), s.wc_str()) == L',' );
|
||||
|
||||
CHECK( !wxStrpbrk(strWX, "xyz") );
|
||||
CHECK( !wxStrpbrk(strWX.c_str(), L"xyz") );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strnlen", "[crt][strnlen]")
|
||||
{
|
||||
// other misc tests for wxStrnlen(const char*, size_t)
|
||||
|
||||
CHECK( wxStrnlen("", 0) == 0 );
|
||||
CHECK( wxStrnlen("", 8) == 0 );
|
||||
CHECK( wxStrnlen("1234", 0) == 0 );
|
||||
CHECK( wxStrnlen("1234", 2) == 2 );
|
||||
CHECK( wxStrnlen("1234", 8) == 4 );
|
||||
CHECK( wxStrnlen("1234567", 8) == 7 );
|
||||
CHECK( wxStrnlen("12345678", 8) == 8 );
|
||||
CHECK( wxStrnlen("123456789", 8) == 8 );
|
||||
CHECK( wxStrnlen("123456789", 12) == 9 );
|
||||
|
||||
// other misc tests for wxStrnlen(const wchar_t*, size_t)
|
||||
|
||||
CHECK( wxStrnlen(L"", 0) == 0 );
|
||||
CHECK( wxStrnlen(L"", 8) == 0 );
|
||||
CHECK( wxStrnlen(L"1234", 0) == 0 );
|
||||
CHECK( wxStrnlen(L"1234", 2) == 2 );
|
||||
CHECK( wxStrnlen(L"1234", 8) == 4 );
|
||||
CHECK( wxStrnlen(L"1234567", 8) == 7 );
|
||||
CHECK( wxStrnlen(L"12345678", 8) == 8 );
|
||||
CHECK( wxStrnlen(L"123456789", 8) == 8 );
|
||||
CHECK( wxStrnlen(L"123456789", 12) == 9 );
|
||||
|
||||
// wxStrlen() is only for null-terminated strings:
|
||||
CHECK( wxStrnlen("1234" "\0" "78", 12) == 4 );
|
||||
CHECK( wxStrnlen(L"1234" L"\0" L"5678", 12) == 4 );
|
||||
}
|
||||
|
||||
TEST_CASE("CRT::Strtox", "[crt][strtod][strtol]")
|
||||
{
|
||||
const wxString s = "123@";
|
||||
const double d = 123.0;
|
||||
const long l = 123;
|
||||
|
||||
SECTION("char")
|
||||
{
|
||||
char* end = nullptr;
|
||||
CHECK( wxStrtod(s, &end) == d );
|
||||
REQUIRE( end );
|
||||
CHECK( *end == '@' );
|
||||
|
||||
CHECK( wxStrtol(s, &end, 10) == l );
|
||||
REQUIRE( end );
|
||||
CHECK( *end == '@' );
|
||||
}
|
||||
|
||||
SECTION("wchar_t")
|
||||
{
|
||||
wchar_t* end = nullptr;
|
||||
CHECK( wxStrtod(s, &end) == d );
|
||||
REQUIRE( end );
|
||||
CHECK( *end == L'@' );
|
||||
|
||||
CHECK( wxStrtol(s, &end, 10) == l );
|
||||
REQUIRE( end );
|
||||
CHECK( *end == L'@' );
|
||||
}
|
||||
|
||||
SECTION("other")
|
||||
{
|
||||
CHECK( wxStrtod(s, 0) == d );
|
||||
#ifdef wxHAS_NULLPTR_T
|
||||
CHECK( wxStrtod(s, nullptr) == d );
|
||||
CHECK( wxStrtol(s, nullptr, 10) == l );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
127
libs/wxWidgets-3.3.1/tests/strings/hexconv.cpp
Normal file
127
libs/wxWidgets-3.3.1/tests/strings/hexconv.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/hexconv.cpp
|
||||
// Purpose: wxDecToHex, wxHexToDec unit test
|
||||
// Author: Artur Wieczorek
|
||||
// Created: 2017-02-23
|
||||
// Copyright: (c) 2017 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/utils.h"
|
||||
|
||||
static void DecToHex1();
|
||||
static void DecToHex2();
|
||||
static void DecToHex3();
|
||||
static void HexToDec1();
|
||||
static void HexToDec2();
|
||||
|
||||
TEST_CASE("HexConvTestCase", "[string][hexconv]")
|
||||
{
|
||||
SECTION("DecToHex1") // Conversion to wxString
|
||||
{
|
||||
DecToHex1();
|
||||
}
|
||||
|
||||
SECTION("DecToHex2") // Conversion to wxChar string
|
||||
{
|
||||
DecToHex2();
|
||||
}
|
||||
|
||||
SECTION("DecToHex3") // Conversion to 2 characters
|
||||
{
|
||||
DecToHex3();
|
||||
}
|
||||
|
||||
SECTION("HexToDec1") // Conversion from char string
|
||||
{
|
||||
HexToDec1();
|
||||
}
|
||||
|
||||
SECTION("HexToDec2") // Conversion from wxString
|
||||
{
|
||||
HexToDec2();
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Implementation =====
|
||||
|
||||
static void DecToHex1()
|
||||
{
|
||||
// Conversion to wxString
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
char szHexStrRef[16];
|
||||
sprintf(szHexStrRef, "%02X", i);
|
||||
wxString hexStrRef = wxString(szHexStrRef);
|
||||
|
||||
wxString hexStr = wxDecToHex(i);
|
||||
|
||||
CHECK(hexStr == hexStrRef);
|
||||
}
|
||||
}
|
||||
|
||||
static void DecToHex2()
|
||||
{
|
||||
// Conversion to wxChar string
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
char szHexStrRef[16];
|
||||
sprintf(szHexStrRef, "%02X", i);
|
||||
|
||||
wxChar hexStr[4];
|
||||
memset(hexStr, 0xFF, sizeof(hexStr));
|
||||
wxChar c3 = hexStr[3]; // This character should remain untouched
|
||||
wxDecToHex(i, hexStr);
|
||||
|
||||
CHECK(hexStr[0] == (wxChar)szHexStrRef[0]);
|
||||
CHECK(hexStr[1] == (wxChar)szHexStrRef[1]);
|
||||
CHECK(hexStr[2] == (wxChar)'\0');
|
||||
CHECK(hexStr[3] == c3);
|
||||
}
|
||||
}
|
||||
|
||||
static void DecToHex3()
|
||||
{
|
||||
// Conversion to 2 characters
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
char szHexStrRef[16];
|
||||
sprintf(szHexStrRef, "%02X", i);
|
||||
|
||||
char c1 = '\xFF';
|
||||
char c2 = '\xFF';
|
||||
wxDecToHex(i, &c1, &c2);
|
||||
|
||||
CHECK(c1 == szHexStrRef[0]);
|
||||
CHECK(c2 == szHexStrRef[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void HexToDec1()
|
||||
{
|
||||
// Conversion from char string
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
char szHexStr[16];
|
||||
sprintf(szHexStr, "%02X", i);
|
||||
|
||||
int n = wxHexToDec(szHexStr);
|
||||
CHECK(n == i);
|
||||
}
|
||||
}
|
||||
|
||||
static void HexToDec2()
|
||||
{
|
||||
// Conversion from wxString
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
char szHexStr[16];
|
||||
sprintf(szHexStr, "%02X", i);
|
||||
wxString hexStr = wxString(szHexStr);
|
||||
|
||||
int n = wxHexToDec(hexStr);
|
||||
CHECK(n == i);
|
||||
}
|
||||
}
|
||||
62
libs/wxWidgets-3.3.1/tests/strings/iostream.cpp
Normal file
62
libs/wxWidgets-3.3.1/tests/strings/iostream.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/iostream.cpp
|
||||
// Purpose: unit test of wxString interaction with std::[io]stream
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2007-10-09
|
||||
// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/string.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#if wxUSE_STD_IOSTREAM
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#define ASSERT_OSTREAM_EQUAL(p, s) CPPUNIT_ASSERT_EQUAL(std::string(p), s.str())
|
||||
#define ASSERT_WOSTREAM_EQUAL(p, s) CPPUNIT_ASSERT_EQUAL(std::wstring(p), s.str())
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class StringIostreamTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
StringIostreamTestCase() { }
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( StringIostreamTestCase );
|
||||
CPPUNIT_TEST( Out );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void Out();
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( StringIostreamTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( StringIostreamTestCase, "StringIostream" );
|
||||
|
||||
void StringIostreamTestCase::Out()
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << wxString("hello");
|
||||
ASSERT_OSTREAM_EQUAL("hello", s);
|
||||
|
||||
#if defined(HAVE_WOSTREAM)
|
||||
std::wostringstream ws;
|
||||
ws << wxString("bye");
|
||||
ASSERT_WOSTREAM_EQUAL(L"bye", ws);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // wxUSE_STD_IOSTREAM
|
||||
343
libs/wxWidgets-3.3.1/tests/strings/numformatter.cpp
Normal file
343
libs/wxWidgets-3.3.1/tests/strings/numformatter.cpp
Normal file
@@ -0,0 +1,343 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/numformat.cpp
|
||||
// Purpose: wxNumberFormatter unit test
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2011-01-15
|
||||
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/numformatter.h"
|
||||
#include "wx/intl.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class NumFormatterTestCase
|
||||
{
|
||||
public:
|
||||
NumFormatterTestCase() :
|
||||
// We need to use a locale with known decimal point and which uses the
|
||||
// thousands separator for the tests to make sense.
|
||||
m_locale(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool CanRunTest() const { return m_locale.IsOk(); }
|
||||
|
||||
private:
|
||||
wxLocale m_locale;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(NumFormatterTestCase);
|
||||
};
|
||||
|
||||
// A couple of helpers to avoid writing over long expressions.
|
||||
wxString ToStringWithoutTrailingZeroes(double val, int precision)
|
||||
{
|
||||
return wxNumberFormatter::ToString
|
||||
(
|
||||
val,
|
||||
precision,
|
||||
wxNumberFormatter::Style_NoTrailingZeroes
|
||||
);
|
||||
}
|
||||
|
||||
wxString ToStringWithTrailingZeroes(double val, int precision)
|
||||
{
|
||||
return wxNumberFormatter::ToString
|
||||
(
|
||||
val,
|
||||
precision,
|
||||
wxNumberFormatter::Style_None
|
||||
);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongToString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
CHECK( wxNumberFormatter::ToString( 1L) == "1" );
|
||||
CHECK( wxNumberFormatter::ToString( -1L) == "-1" );
|
||||
CHECK( wxNumberFormatter::ToString( 12L) == "12" );
|
||||
CHECK( wxNumberFormatter::ToString( -12L) == "-12" );
|
||||
CHECK( wxNumberFormatter::ToString( 123L) == "123" );
|
||||
CHECK( wxNumberFormatter::ToString( -123L) == "-123" );
|
||||
CHECK( wxNumberFormatter::ToString( 1234L) == "1,234" );
|
||||
CHECK( wxNumberFormatter::ToString( -1234L) == "-1,234" );
|
||||
CHECK( wxNumberFormatter::ToString( 12345L) == "12,345" );
|
||||
CHECK( wxNumberFormatter::ToString( -12345L) == "-12,345" );
|
||||
CHECK( wxNumberFormatter::ToString( 123456L) == "123,456" );
|
||||
CHECK( wxNumberFormatter::ToString( -123456L) == "-123,456" );
|
||||
CHECK( wxNumberFormatter::ToString( 1234567L) == "1,234,567" );
|
||||
CHECK( wxNumberFormatter::ToString( -1234567L) == "-1,234,567" );
|
||||
CHECK( wxNumberFormatter::ToString( 12345678L) == "12,345,678" );
|
||||
CHECK( wxNumberFormatter::ToString( -12345678L) == "-12,345,678" );
|
||||
CHECK( wxNumberFormatter::ToString( 123456789L) == "123,456,789" );
|
||||
}
|
||||
|
||||
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongToString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 1)) == "1" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 12)) == "12" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 123)) == "123" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 1234)) == "1,234" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 12345)) == "12,345" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 123456)) == "123,456" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 1234567)) == "1,234,567" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 12345678)) == "12,345,678" );
|
||||
CHECK( wxNumberFormatter::ToString(wxLL( 123456789)) == "123,456,789" );
|
||||
}
|
||||
|
||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleToString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
CHECK( wxNumberFormatter::ToString( 1., 1) == "1.0" );
|
||||
CHECK( wxNumberFormatter::ToString( 0.123456, 6) == "0.123456" );
|
||||
CHECK( wxNumberFormatter::ToString( 1.234567, 6) == "1.234567" );
|
||||
CHECK( wxNumberFormatter::ToString( 12.34567, 5) == "12.34567" );
|
||||
CHECK( wxNumberFormatter::ToString( 123.4567, 4) == "123.4567" );
|
||||
CHECK( wxNumberFormatter::ToString( 1234.56, 2) == "1,234.56" );
|
||||
CHECK( wxNumberFormatter::ToString( 12345.6, 1) == "12,345.6" );
|
||||
CHECK( wxNumberFormatter::ToString(123456789.012, 3) == "123,456,789.012" );
|
||||
CHECK( wxNumberFormatter::ToString( 12345.012, -1) == "12,345" );
|
||||
|
||||
CHECK( ToStringWithTrailingZeroes(-123.123, 4) == "-123.1230" );
|
||||
CHECK( ToStringWithTrailingZeroes( 0.02, 1) == "0.0" );
|
||||
CHECK( ToStringWithTrailingZeroes( -0.02, 1) == "-0.0" );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::NoTrailingZeroes", "[numformatter]")
|
||||
{
|
||||
WX_ASSERT_FAILS_WITH_ASSERT
|
||||
(
|
||||
wxNumberFormatter::ToString(123L, wxNumberFormatter::Style_NoTrailingZeroes)
|
||||
);
|
||||
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
CHECK( ToStringWithTrailingZeroes ( 123., 3) == "123.000" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123., 3) == "123" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123., 9) == "123" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123.456, 3) == "123.456" );
|
||||
CHECK( ToStringWithTrailingZeroes ( 123.456, 9) == "123.456000000" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123.456, 9) == "123.456" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123.123, 2) == "123.12" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123.123, 0) == "123" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( -0.000123, 3) == "0" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 123., -1) == "123" );
|
||||
CHECK( ToStringWithoutTrailingZeroes( 1e-120, -1) == "1e-120" );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongFromString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
WX_ASSERT_FAILS_WITH_ASSERT
|
||||
(
|
||||
wxNumberFormatter::FromString("123", static_cast<long *>(nullptr))
|
||||
);
|
||||
|
||||
long l;
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("", &l) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("foo", &l) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("1.234", &l) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("-", &l) );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("0", &l) );
|
||||
CHECK( l == 0 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123", &l) );
|
||||
CHECK( l == 123 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1234", &l) );
|
||||
CHECK( l == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234", &l) );
|
||||
CHECK( l == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("12,345", &l) );
|
||||
CHECK( l == 12345 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123,456", &l) );
|
||||
CHECK( l == 123456 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234,567", &l) );
|
||||
CHECK( l == 1234567 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("-123", &l) );
|
||||
CHECK( l == -123 );
|
||||
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("9223372036854775808", &l) );
|
||||
}
|
||||
|
||||
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongFromString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
WX_ASSERT_FAILS_WITH_ASSERT
|
||||
(
|
||||
wxNumberFormatter::FromString("123", static_cast<wxLongLong_t *>(nullptr))
|
||||
);
|
||||
|
||||
wxLongLong_t l;
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("", &l) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("foo", &l) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("1.234", &l) );
|
||||
|
||||
// This somehow succeeds with gcc 4.8.4 under Ubuntu and MinGW 5.3, so
|
||||
// don't use CHECK() for it.
|
||||
if ( wxNumberFormatter::FromString("-", &l) )
|
||||
{
|
||||
WARN("Converting \"-\" to long long unexpectedly succeeded, result: " << l);
|
||||
}
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("0", &l) );
|
||||
CHECK( l == 0 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123", &l) );
|
||||
CHECK( l == 123 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1234", &l) );
|
||||
CHECK( l == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234", &l) );
|
||||
CHECK( l == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("12,345", &l) );
|
||||
CHECK( l == 12345 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123,456", &l) );
|
||||
CHECK( l == 123456 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234,567", &l) );
|
||||
CHECK( l == 1234567 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("-123", &l) );
|
||||
CHECK( l == -123 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("9223372036854775807", &l) );
|
||||
CHECK( l == wxINT64_MAX );
|
||||
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("9223372036854775808", &l) );
|
||||
}
|
||||
|
||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::ULongLongFromString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
wxULongLong_t u;
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("", &u) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("bar", &u) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("1.234", &u) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("-2", &u) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("-", &u) );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("0", &u) );
|
||||
CHECK( u == 0 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123", &u) );
|
||||
CHECK( u == 123 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1234", &u) );
|
||||
CHECK( u == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234", &u) );
|
||||
CHECK( u == 1234 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("12,345", &u) );
|
||||
CHECK( u == 12345 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123,456", &u) );
|
||||
CHECK( u == 123456 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234,567", &u) );
|
||||
CHECK( u == 1234567 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("9223372036854775807", &u) );
|
||||
CHECK( u == static_cast<wxULongLong_t>(wxINT64_MAX) );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("9223372036854775808", &u) );
|
||||
CHECK( u == static_cast<wxULongLong_t>(wxINT64_MAX) + 1 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("18446744073709551615", &u) );
|
||||
CHECK( u == wxUINT64_MAX );
|
||||
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("18446744073709551616", &u) );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleFromString", "[numformatter]")
|
||||
{
|
||||
if ( !CanRunTest() )
|
||||
return;
|
||||
|
||||
WX_ASSERT_FAILS_WITH_ASSERT
|
||||
(
|
||||
wxNumberFormatter::FromString("123", static_cast<double *>(nullptr))
|
||||
);
|
||||
|
||||
double d;
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("", &d) );
|
||||
CHECK_FALSE( wxNumberFormatter::FromString("bar", &d) );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123", &d) );
|
||||
CHECK( d == 123. );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123.456789012", &d) );
|
||||
CHECK( d == 123.456789012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234.56789012", &d) );
|
||||
CHECK( d == 1234.56789012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("12,345.6789012", &d) );
|
||||
CHECK( d == 12345.6789012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123,456.789012", &d) );
|
||||
CHECK( d == 123456.789012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("1,234,567.89012", &d) );
|
||||
CHECK( d == 1234567.89012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("12,345,678.9012", &d) );
|
||||
CHECK( d == 12345678.9012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123,456,789.012", &d) );
|
||||
CHECK( d == 123456789.012 );
|
||||
|
||||
CHECK( wxNumberFormatter::FromString("123456789.012", &d) );
|
||||
CHECK( d == 123456789.012 );
|
||||
}
|
||||
704
libs/wxWidgets-3.3.1/tests/strings/stdstrings.cpp
Normal file
704
libs/wxWidgets-3.3.1/tests/strings/stdstrings.cpp
Normal file
@@ -0,0 +1,704 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/stdstrings.cpp
|
||||
// Purpose: wxString unit test
|
||||
// Author: Vadim Zeitlin, Wlodzimierz ABX Skiba
|
||||
// Created: 2004-05-07
|
||||
// Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TEST_CASE("StdString::Constructors", "[stdstring]")
|
||||
{
|
||||
wxString s1(wxT("abcdefgh")),
|
||||
s2(wxT("abcdefghijklm"), 8),
|
||||
s3(wxT("abcdefghijklm")),
|
||||
s4(8, wxT('a'));
|
||||
wxString s5(s1),
|
||||
s6(s3, 0, 8),
|
||||
s7(s3.begin(), s3.begin() + 8);
|
||||
wxString s8(s1, 4, 8);
|
||||
|
||||
CHECK( s1 == wxT("abcdefgh") );
|
||||
CHECK( s2 == s1 );
|
||||
CHECK( s4 == wxT("aaaaaaaa") );
|
||||
CHECK( s5 == wxT("abcdefgh") );
|
||||
CHECK( s6 == s1 );
|
||||
CHECK( s7 == s1 );
|
||||
CHECK( s8 == wxT("efgh") );
|
||||
|
||||
const char *pc = s1.c_str();
|
||||
CHECK( wxString(pc + 1, pc + 4) == "bcd" );
|
||||
|
||||
const wchar_t *pw = s2.c_str();
|
||||
CHECK( wxString(pw, pw + 1) == "a" );
|
||||
|
||||
wxString s9(std::move(s1));
|
||||
CHECK( s9 == wxT("abcdefgh"));
|
||||
wxString s10(std::move(s3), 8);
|
||||
CHECK( s10 == wxT("abcdefgh"));
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Iterators", "[stdstring]")
|
||||
{
|
||||
// test compilation of default iterators ctors:
|
||||
wxString::iterator i1;
|
||||
wxUnusedVar(i1);
|
||||
wxString::const_iterator i2;
|
||||
wxUnusedVar(i2);
|
||||
wxString::reverse_iterator i3;
|
||||
wxUnusedVar(i3);
|
||||
wxString::const_reverse_iterator i4;
|
||||
wxUnusedVar(i4);
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::IteratorsCmp", "[stdstring]")
|
||||
{
|
||||
wxString s("foobar");
|
||||
wxString::iterator i = s.begin();
|
||||
wxString::const_iterator ci = s.begin();
|
||||
|
||||
CHECK( i == ci );
|
||||
CHECK( i >= ci );
|
||||
CHECK( i <= ci );
|
||||
CHECK( ci == i );
|
||||
CHECK( ci >= i );
|
||||
CHECK( ci <= i );
|
||||
|
||||
ci++;
|
||||
|
||||
CHECK( i != ci );
|
||||
CHECK( i < ci );
|
||||
CHECK( !(i > ci) );
|
||||
|
||||
CHECK( ci != i );
|
||||
CHECK( ci > i );
|
||||
CHECK( !(ci < i) );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Append", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6, s7, s8;
|
||||
|
||||
s1 = s2 = s3 = s4 = s5 = s6 = wxT("abc");
|
||||
s1.append(wxT("def"));
|
||||
s2.append(wxT("defgh"), 3);
|
||||
s3.append(wxString(wxT("abcdef")), 3, 6);
|
||||
s4.append(s1);
|
||||
s5.append(3, wxT('a'));
|
||||
s5.append(2, 'x');
|
||||
s5.append(1, (unsigned char)'y');
|
||||
s6.append(s1.begin() + 3, s1.end());
|
||||
|
||||
CHECK( s1 == wxT("abcdef") );
|
||||
CHECK( s2 == wxT("abcdef") );
|
||||
CHECK( s3 == wxT("abcdef") );
|
||||
CHECK( s4 == wxT("abcabcdef") );
|
||||
CHECK( s5 == wxT("abcaaaxxy") );
|
||||
CHECK( s6 == wxT("abcdef") );
|
||||
|
||||
const char *pc = s1.c_str() + 2;
|
||||
s7.append(pc, pc + 4);
|
||||
CHECK( s7 == "cdef" );
|
||||
|
||||
const wchar_t *pw = s2.c_str() + 2;
|
||||
s8.append(pw, pw + 4);
|
||||
CHECK( s8 == "cdef" );
|
||||
|
||||
s7 = s8 = wxString(wxT("null\0time"), 9);
|
||||
|
||||
s7.append(wxT("def"));
|
||||
s8.append(wxT("defgh"), 3);
|
||||
|
||||
CHECK( s7 == wxString(wxT("null\0timedef"), 12) );
|
||||
CHECK( s8 == wxString(wxT("null\0timedef"), 12) );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Assign", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
||||
|
||||
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = wxT("abc");
|
||||
s1.assign(wxT("def"));
|
||||
s2.assign(wxT("defgh"), 3);
|
||||
s3.assign(wxString(wxT("abcdef")), 3, 6);
|
||||
s4.assign(s1);
|
||||
s5.assign(3, wxT('a'));
|
||||
s6.assign(s1.begin() + 1, s1.end());
|
||||
|
||||
CHECK( s1 == wxT("def") );
|
||||
CHECK( s2 == wxT("def") );
|
||||
CHECK( s3 == wxT("def") );
|
||||
CHECK( s4 == wxT("def") );
|
||||
CHECK( s5 == wxT("aaa") );
|
||||
CHECK( s6 == wxT("ef") );
|
||||
|
||||
const char *pc = s1.c_str();
|
||||
s7.assign(pc, pc + 2);
|
||||
CHECK( s7 == "de" );
|
||||
|
||||
const wchar_t *pw = s1.c_str();
|
||||
s8.assign(pw + 2, pw + 3);
|
||||
CHECK( s8 == "f" );
|
||||
|
||||
s1.assign(s1, 1, 1);
|
||||
CHECK( s1 == "e" );
|
||||
|
||||
s9.assign(std::move(s2));
|
||||
CHECK(s9 == wxT("def"));
|
||||
s2 = wxT("qwerty");
|
||||
CHECK(s2 == wxT("qwerty"));
|
||||
|
||||
// Self-assignment
|
||||
wxString& s9ref = s9;
|
||||
s9ref.assign(s9);
|
||||
CHECK(s9 == wxT("def"));
|
||||
// Self-move may change the value, but shouldn't crash
|
||||
// and reassignment should work
|
||||
s9ref.assign(std::move(s9));
|
||||
s9 = "qwerty";
|
||||
CHECK(s9 == wxT("qwerty"));
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::AssignOp", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6, s7, s8;
|
||||
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = wxT("abc");
|
||||
|
||||
// operator=
|
||||
s1 = wxT("def");
|
||||
CHECK(s1 == wxT("def"));
|
||||
|
||||
s2 = s1;
|
||||
CHECK(s2 == wxT("def"));
|
||||
|
||||
const char* pc = s1.c_str();
|
||||
s3 = pc;
|
||||
CHECK(s3 == wxT("def"));
|
||||
|
||||
const wchar_t* pw = s1.c_str();
|
||||
s4 = pw;
|
||||
CHECK(s4 == wxT("def"));
|
||||
|
||||
s5 = std::move(s1);
|
||||
CHECK(s5 == wxT("def"));
|
||||
s1 = wxT("qwerty");
|
||||
CHECK(s1 == wxT("qwerty"));
|
||||
|
||||
// swap
|
||||
s6 = wxT("def");
|
||||
std::swap(s6, s7);
|
||||
CHECK(s6 == wxT("abc"));
|
||||
CHECK(s7 == wxT("def"));
|
||||
swap(s6, s7);
|
||||
CHECK(s6 == wxT("def"));
|
||||
CHECK(s7 == wxT("abc"));
|
||||
s6.swap(s7);
|
||||
CHECK(s6 == wxT("abc"));
|
||||
CHECK(s7 == wxT("def"));
|
||||
|
||||
// Self-assignment
|
||||
wxString& s8ref = s8;
|
||||
s8ref = s8;
|
||||
CHECK(s8 == wxT("abc"));
|
||||
// Self-move may change the value, but shouldn't crash
|
||||
// and reassignment should work
|
||||
s8ref = std::move(s8);
|
||||
s8 = "qwerty";
|
||||
CHECK(s8 == wxT("qwerty"));
|
||||
// Self-swap
|
||||
std::swap(s8, s8ref);
|
||||
CHECK(s8 == wxT("qwerty"));
|
||||
swap(s8, s8ref);
|
||||
CHECK(s8 == wxT("qwerty"));
|
||||
s8.swap(s8ref);
|
||||
CHECK(s8 == wxT("qwerty"));
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Compare", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6;
|
||||
|
||||
s1 = wxT("abcdefgh");
|
||||
s2 = wxT("abcdefgh");
|
||||
s3 = wxT("abc");
|
||||
s4 = wxT("abcdefghi");
|
||||
s5 = wxT("aaa");
|
||||
s6 = wxT("zzz");
|
||||
|
||||
CHECK( s1.compare(s2) == 0 );
|
||||
CHECK( s1.compare(s3) > 0 );
|
||||
CHECK( s1.compare(s4) < 0 );
|
||||
CHECK( s1.compare(s5) > 0 );
|
||||
CHECK( s1.compare(s6) < 0 );
|
||||
CHECK( s1.compare(1, 12, s1) > 0);
|
||||
CHECK( s1.compare(wxT("abcdefgh")) == 0);
|
||||
CHECK( s1.compare(1, 7, wxT("bcdefgh")) == 0);
|
||||
CHECK( s1.compare(1, 7, wxT("bcdefgh"), 7) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Erase", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s7;
|
||||
|
||||
s1 = wxT("abcdefgh");
|
||||
s2 = wxT("abcdefgh");
|
||||
s3 = wxT("abc");
|
||||
s4 = wxT("abcdefghi");
|
||||
s7 = wxT("zabcdefg");
|
||||
|
||||
s1.erase(1, 1);
|
||||
s2.erase(4, 12);
|
||||
wxString::iterator it = s3.erase(s3.begin() + 1);
|
||||
wxString::iterator it2 = s4.erase(s4.begin() + 4, s4.begin() + 6);
|
||||
wxString::iterator it3 = s7.erase(s7.begin() + 4, s7.begin() + 8);
|
||||
|
||||
CHECK( s1 == wxT("acdefgh") );
|
||||
CHECK( s2 == wxT("abcd") );
|
||||
CHECK( s3 == wxT("ac") );
|
||||
CHECK( s4 == wxT("abcdghi") );
|
||||
CHECK( s7 == wxT("zabc") );
|
||||
CHECK( *it == wxT('c') );
|
||||
CHECK( *it2 == wxT('g') );
|
||||
CHECK( it3 == s7.end() );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Find", "[stdstring]")
|
||||
{
|
||||
// 0 1 2
|
||||
// 01234567890123456789012345
|
||||
wxString s1 = wxT("abcdefgABCDEFGabcABCabcABC");
|
||||
wxString s2 = wxT("gAB");
|
||||
|
||||
CHECK( s1.find(wxT('A')) == 7u );
|
||||
CHECK( s1.find(wxT('A'), 7) == 7u );
|
||||
CHECK( s1.find(wxT('Z')) == wxString::npos );
|
||||
CHECK( s1.find(wxT('C'), 22) == 25u );
|
||||
|
||||
CHECK( s1.find(wxT("gAB")) == 6u );
|
||||
CHECK( s1.find(wxT("gAB"), 7) == wxString::npos );
|
||||
CHECK( s1.find(wxT("gAB"), 6) == 6u );
|
||||
|
||||
CHECK( s1.find(wxT("gABZZZ"), 2, 3) == 6u );
|
||||
CHECK( s1.find(wxT("gABZZZ"), 7, 3) == wxString::npos );
|
||||
|
||||
CHECK( s1.find(s2) == 6u );
|
||||
CHECK( s1.find(s2, 7) == wxString::npos );
|
||||
CHECK( s1.find(s2, 6) == 6u );
|
||||
|
||||
// 0 1 2
|
||||
// 0123456 78901234567 8901234567
|
||||
//wxString _s1 = wxT("abcdefg\0ABCDEFGabc\0ABCabcABC");
|
||||
//wxString _s2 = wxT("g\0AB");
|
||||
wxString _s1 = wxT("abcdefgABCDEFGabcABCabcABC");
|
||||
wxString _s2 = wxT("gAB");
|
||||
|
||||
_s1.insert(7, 1, '\0');
|
||||
_s1.insert(18, 1, '\0');
|
||||
_s2.insert(1, 1, '\0');
|
||||
|
||||
CHECK( _s1.find(wxT('A')) == 8u );
|
||||
CHECK( _s1.find(wxT('A'), 8) == 8u );
|
||||
CHECK( _s1.find(wxT('Z')) == wxString::npos );
|
||||
CHECK( _s1.find(wxT('C'), 22) == 27u );
|
||||
|
||||
CHECK( _s1.find(wxT("AB")) == 8u );
|
||||
CHECK( _s1.find(wxT("AB"), 26) == wxString::npos );
|
||||
CHECK( _s1.find(wxT("AB"), 23) == 25u );
|
||||
|
||||
CHECK( _s1.find(wxT("ABZZZ"), 2, 2) == 8u );
|
||||
CHECK( _s1.find(wxT("ABZZZ"), 26, 2) == wxString::npos );
|
||||
|
||||
CHECK( _s1.find(_s2) == 6u );
|
||||
CHECK( _s1.find(_s2, 7) == wxString::npos );
|
||||
CHECK( _s1.find(_s2, 6) == 6u );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::FindFirst", "[stdstring]")
|
||||
{
|
||||
// 0 1 2 3
|
||||
// 01234567890123456789012345678901234
|
||||
wxString s1 = wxT("aaaaaabcdefghlkjiaaaaaabcdbcdbcdbcd");
|
||||
wxString s2 = wxT("aaaaaa");
|
||||
|
||||
CHECK( s1.find_first_not_of(wxT('a')) == 6u );
|
||||
CHECK( s1.find_first_not_of(wxT('a'), 7) == 7u );
|
||||
CHECK( s2.find_first_not_of(wxT('a')) == wxString::npos );
|
||||
|
||||
CHECK( s1.find_first_not_of(wxT("abde"), 4) == 7u );
|
||||
CHECK( s1.find_first_not_of(wxT("abde"), 7) == 7u );
|
||||
CHECK( s1.find_first_not_of(wxT("abcdefghijkl")) == wxString::npos );
|
||||
|
||||
CHECK( s1.find_first_not_of(wxT("abcdefghi"), 0, 4) == 9u );
|
||||
|
||||
CHECK( s1.find_first_of(wxT('c')) == 7u );
|
||||
CHECK( s1.find_first_of(wxT('v')) == wxString::npos );
|
||||
CHECK( s1.find_first_of(wxT('c'), 10) == 24u );
|
||||
|
||||
CHECK( s1.find_first_of(wxT("ijkl")) == 13u );
|
||||
CHECK( s1.find_first_of(wxT("ddcfg"), 17) == 24u );
|
||||
CHECK( s1.find_first_of(wxT("ddcfga"), 17, 5) == 24u );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::FindLast", "[stdstring]")
|
||||
{
|
||||
// 0 1 2 3
|
||||
// 01234567890123456789012345678901234
|
||||
wxString s1 = wxT("aaaaaabcdefghlkjiaaaaaabcdbcdbcdbcd");
|
||||
wxString s2 = wxT("aaaaaa");
|
||||
|
||||
CHECK( s2.find_last_not_of(wxT('a')) == wxString::npos );
|
||||
CHECK( s1.find_last_not_of(wxT('d')) == 33u );
|
||||
CHECK( s1.find_last_not_of(wxT('d'), 25) == 24u );
|
||||
|
||||
CHECK( s1.find_last_not_of(wxT("bcd")) == 22u );
|
||||
CHECK( s1.find_last_not_of(wxT("abc"), 24) == 16u );
|
||||
|
||||
CHECK( s1.find_last_not_of(wxT("abcdefghijklmnopqrstuv"), 24, 3) == 16u );
|
||||
|
||||
CHECK( s2.find_last_of(wxT('c')) == wxString::npos );
|
||||
CHECK( s1.find_last_of(wxT('a')) == 22u );
|
||||
CHECK( s1.find_last_of(wxT('b'), 24) == 23u );
|
||||
|
||||
CHECK( s1.find_last_of(wxT("ijklm")) == 16u );
|
||||
CHECK( s1.find_last_of(wxT("ijklma"), 33, 4) == 16u );
|
||||
CHECK( s1.find_last_of(wxT("a"), 17) == 17u );
|
||||
|
||||
|
||||
|
||||
// 0 1 2 3
|
||||
// 012345 67890123456789 01234567890123456
|
||||
// wxString s1 = wxT("aaaaaa\0bcdefghlkjiaa\0aaaabcdbcdbcdbcd");
|
||||
// wxString s2 = wxT("aaaaaa\0");
|
||||
s1.insert(6,1,'\0');
|
||||
s1.insert(20,1,'\0');
|
||||
s2.insert(6,1,'\0');
|
||||
|
||||
CHECK( s2.find_last_not_of(wxT('a')) == 6u );
|
||||
CHECK( s1.find_last_not_of(wxT('d')) == 35u );
|
||||
CHECK( s1.find_last_not_of(wxT('d'), 27) == 26u );
|
||||
|
||||
CHECK( s1.find_last_not_of(wxT("bcd")) == 24u );
|
||||
CHECK( s1.find_last_not_of(wxT("abc"), 26) == 20u );
|
||||
|
||||
CHECK( s1.find_last_not_of(wxT("abcdefghijklmnopqrstuv"), 26, 3) == 20u );
|
||||
|
||||
CHECK( s2.find_last_of(wxT('c')) == wxString::npos );
|
||||
CHECK( s1.find_last_of(wxT('a')) == 24u );
|
||||
CHECK( s1.find_last_of(wxT('b'), 26) == 25u );
|
||||
|
||||
CHECK( s1.find_last_of(wxT("ijklm")) == 17u );
|
||||
CHECK( s1.find_last_of(wxT("ijklma"), 35, 4) == 17u );
|
||||
CHECK( s1.find_last_of(wxT("a"), 18) == 18u );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::StartsEndsWith", "[stdstring]")
|
||||
{
|
||||
const wxString s(wxT("Hello, world!"));
|
||||
CHECK( s.starts_with(wxT("Hello")) == true );
|
||||
CHECK( s.starts_with(wxT("Hello, ")) == true );
|
||||
CHECK( s.starts_with(wxT("Hello, world!")) == true );
|
||||
CHECK( s.starts_with(wxT("Hello, world!!!")) == false );
|
||||
CHECK( s.starts_with(wxT("")) == true );
|
||||
CHECK( s.starts_with(wxT("Goodbye")) == false );
|
||||
CHECK( s.starts_with(wxT("Hi")) == false );
|
||||
|
||||
CHECK( s.ends_with(wxT("Hello, world!")) == true );
|
||||
CHECK( s.ends_with(wxT("world!")) == true );
|
||||
CHECK( s.ends_with(wxT("Hello")) == false );
|
||||
CHECK( s.ends_with(wxT("!")) == true );
|
||||
CHECK( s.ends_with(wxT("")) == true );
|
||||
CHECK( s.ends_with(wxT("very long string")) == false );
|
||||
CHECK( s.ends_with(wxT("?")) == false );
|
||||
CHECK( s.ends_with(wxT("Hello, world")) == false );
|
||||
CHECK( s.ends_with(wxT("Gello, world!")) == false );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Insert", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;
|
||||
|
||||
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = wxT("aaaa");
|
||||
s9 = s10 = wxT("cdefg");
|
||||
|
||||
s1.insert(1, wxT("cc") );
|
||||
s2.insert(2, wxT("cdef"), 3);
|
||||
s3.insert(2, s10);
|
||||
s4.insert(2, s10, 3, 7);
|
||||
s5.insert(1, 2, wxT('c'));
|
||||
s6.insert(s6.begin() + 3, wxT('X'));
|
||||
s7.insert(s7.begin(), s9.begin(), s9.end() - 1);
|
||||
s8.insert(s8.begin(), 2, wxT('c'));
|
||||
|
||||
CHECK( s1 == wxT("accaaa") );
|
||||
CHECK( s2 == wxT("aacdeaa") );
|
||||
CHECK( s3 == wxT("aacdefgaa") );
|
||||
CHECK( s4 == wxT("aafgaa") );
|
||||
CHECK( s5 == wxT("accaaa") );
|
||||
CHECK( s6 == wxT("aaaXa") );
|
||||
CHECK( s7 == wxT("cdefaaaa") );
|
||||
CHECK( s8 == wxT("ccaaaa") );
|
||||
|
||||
s1 = s2 = s3 = wxT("aaaa");
|
||||
s1.insert(0, wxT("ccc"), 2);
|
||||
s2.insert(4, wxT("ccc"), 2);
|
||||
|
||||
CHECK( s1 == wxT("ccaaaa") );
|
||||
CHECK( s2 == wxT("aaaacc") );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Replace", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
||||
|
||||
s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = wxT("QWERTYUIOP");
|
||||
s9 = wxT("werty");
|
||||
|
||||
s1.replace(3, 4, wxT("rtyu"));
|
||||
s1.replace(8, 7, wxT("opopop"));
|
||||
s2.replace(10, 12, wxT("WWWW"));
|
||||
s3.replace(1, 5, s9);
|
||||
s4.replace(1, 4, s9, 0, 4);
|
||||
s5.replace(1, 2, s9, 1, 12);
|
||||
s6.replace(0, 123, s9, 0, 123);
|
||||
s7.replace(2, 7, s9);
|
||||
|
||||
CHECK( s1 == wxT("QWErtyuIopopop") );
|
||||
CHECK( s2 == wxT("QWERTYUIOPWWWW") );
|
||||
CHECK( s3 == wxT("QwertyUIOP") );
|
||||
CHECK( s4 == wxT("QwertYUIOP") );
|
||||
CHECK( s5 == wxT("QertyRTYUIOP") );
|
||||
CHECK( s6 == s9 );
|
||||
CHECK( s7 == wxT("QWwertyP") );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::RFind", "[stdstring]")
|
||||
{
|
||||
// 0 1 2
|
||||
// 01234567890123456789012345
|
||||
wxString s1 = wxT("abcdefgABCDEFGabcABCabcABC");
|
||||
wxString s2 = wxT("gAB");
|
||||
wxString s3 = wxT("ab");
|
||||
|
||||
CHECK( s1.rfind(wxT('A')) == 23u );
|
||||
CHECK( s1.rfind(wxT('A'), 7) == 7u );
|
||||
CHECK( s1.rfind(wxT('Z')) == wxString::npos );
|
||||
CHECK( s1.rfind(wxT('C'), 22) == 19u );
|
||||
|
||||
CHECK( s1.rfind(wxT("cAB")) == 22u );
|
||||
CHECK( s1.rfind(wxT("cAB"), 15) == wxString::npos );
|
||||
CHECK( s1.rfind(wxT("cAB"), 21) == 16u );
|
||||
|
||||
CHECK( s1.rfind(wxT("gABZZZ"), 7, 3) == 6u );
|
||||
CHECK( s1.rfind(wxT("gABZZZ"), 5, 3) == wxString::npos );
|
||||
|
||||
CHECK( s1.rfind(s2) == 6u );
|
||||
CHECK( s1.rfind(s2, 5) == wxString::npos );
|
||||
CHECK( s1.rfind(s2, 6) == 6u );
|
||||
CHECK( s1.rfind(s3, 1) == 0u );
|
||||
|
||||
|
||||
// 0 1 2
|
||||
// 01234 56789012 345678901234567
|
||||
// wxString s1 = wxT("abcde\0fgABCDE\0FGabcABCabcABC");
|
||||
// wxString s2 = wxT("gAB");
|
||||
// wxString s3 = wxT("ab");
|
||||
|
||||
s1.insert(5,1,'\0');
|
||||
s1.insert(13,1,'\0');
|
||||
|
||||
CHECK( s1.rfind(wxT('A')) == 25u );
|
||||
CHECK( s1.rfind(wxT('A'), 8) == 8u );
|
||||
CHECK( s1.rfind(wxT('Z')) == wxString::npos );
|
||||
CHECK( s1.rfind(wxT('C'), 22) == 21u );
|
||||
|
||||
CHECK( s1.rfind(wxT("cAB")) == 24u );
|
||||
CHECK( s1.rfind(wxT("cAB"), 15) == wxString::npos );
|
||||
CHECK( s1.rfind(wxT("cAB"), 21) == 18u );
|
||||
|
||||
CHECK( s1.rfind(wxT("gABZZZ"), 8, 3) == 7u );
|
||||
CHECK( s1.rfind(wxT("gABZZZ"), 5, 3) == wxString::npos );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Resize", "[stdstring]")
|
||||
{
|
||||
wxString s1, s2, s3, s4;
|
||||
|
||||
s1 = s2 = s3 = s4 = wxT("abcABCdefDEF");
|
||||
|
||||
s1.resize( 12 );
|
||||
s2.resize( 10 );
|
||||
s3.resize( 14, wxT(' ') );
|
||||
s4.resize( 14, wxT('W') );
|
||||
|
||||
CHECK( s1 == wxT("abcABCdefDEF") );
|
||||
CHECK( s2 == wxT("abcABCdefD") );
|
||||
CHECK( s3 == wxT("abcABCdefDEF ") );
|
||||
CHECK( s4 == wxT("abcABCdefDEFWW") );
|
||||
|
||||
wxString s = wxString::FromUTF8("Привет");
|
||||
s.resize(3);
|
||||
CHECK( s == wxString::FromUTF8("При") );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Riter", "[stdstring]")
|
||||
{
|
||||
const wxString s(wxT("fozbar"));
|
||||
|
||||
wxString::const_reverse_iterator ri(s.rbegin());
|
||||
CHECK( wxT('r') == *ri );
|
||||
CHECK( wxT('a') == *++ri );
|
||||
CHECK( wxT('r') == *--ri );
|
||||
|
||||
ri = s.rend();
|
||||
ri--;
|
||||
CHECK( wxT('f') == *ri );
|
||||
|
||||
--ri;
|
||||
CHECK( wxT('o') == *ri );
|
||||
|
||||
wxString::const_iterator i = ri.base();
|
||||
CHECK( wxT('z') == *i );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Substr", "[stdstring]")
|
||||
{
|
||||
wxString s1 = wxT("abcdefgABCDEFG");
|
||||
|
||||
CHECK( s1.substr( 0, 14 ) == s1 );
|
||||
CHECK( s1.substr( 1, 13 ) == wxT("bcdefgABCDEFG") );
|
||||
CHECK( s1.substr( 1, 20 ) == wxT("bcdefgABCDEFG") );
|
||||
CHECK( s1.substr( 14, 30 ) == wxT("") );
|
||||
|
||||
s1.insert(3,1,'\0');
|
||||
s1.insert(8,1,'\0');
|
||||
s1.insert(13,1,'\0');
|
||||
|
||||
wxString s2 = wxT("bcdefgABCDEFG");
|
||||
s2.insert(2,1,'\0');
|
||||
s2.insert(7,1,'\0');
|
||||
s2.insert(12,1,'\0');
|
||||
|
||||
CHECK( s1.substr( 0, 17 ) == s1 );
|
||||
CHECK( s1.substr( 1, 17 ) == s2 );
|
||||
CHECK( s1.substr( 1, 20 ) == s2 );
|
||||
CHECK( s1.substr( 17, 30 ) == wxT("") );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Conversion", "[stdstring]")
|
||||
{
|
||||
std::string strStd("std::string value");
|
||||
std::wstring strStdWide(L"std::wstring value");
|
||||
|
||||
wxString s1(strStd);
|
||||
CHECK( s1 == "std::string value" );
|
||||
|
||||
wxString s2(strStdWide);
|
||||
CHECK( s2 == "std::wstring value" );
|
||||
|
||||
wxString s3;
|
||||
s3 = strStd;
|
||||
CHECK( s3 == "std::string value" );
|
||||
s3 = strStdWide;
|
||||
CHECK( s3 == "std::wstring value" );
|
||||
|
||||
wxString s4("hello");
|
||||
|
||||
#if wxUSE_STD_STRING_CONV_IN_WXSTRING && !defined(wxNO_UNSAFE_WXSTRING_CONV)
|
||||
std::string s5 = s4;
|
||||
#else
|
||||
std::string s5 = s4.ToStdString();
|
||||
#endif
|
||||
CHECK( s5 == "hello" );
|
||||
|
||||
#if wxUSE_STD_STRING_CONV_IN_WXSTRING
|
||||
std::wstring s6 = s4;
|
||||
#else
|
||||
std::wstring s6 = s4.ToStdWstring();
|
||||
#endif
|
||||
CHECK( s6 == L"hello" );
|
||||
|
||||
CHECK( s4.wc_string() == L"hello" );
|
||||
|
||||
#if wxUSE_STD_STRING_CONV_IN_WXSTRING
|
||||
#if !defined(wxNO_UNSAFE_WXSTRING_CONV)
|
||||
std::string s7(s4);
|
||||
CHECK( s7 == "hello" );
|
||||
#endif
|
||||
|
||||
std::wstring s8(s4);
|
||||
CHECK( s8 == L"hello" );
|
||||
#endif // wxUSE_STD_STRING_CONV_IN_WXSTRING
|
||||
|
||||
std::string s9("\xF0\x9F\x90\xB1\0\xE7\x8C\xAB", 9); /* U+1F431 U+0000 U+732B */
|
||||
wxString s10 = wxString::FromUTF8(s9);
|
||||
CHECK( s10.ToStdString(wxConvUTF8) == s9 );
|
||||
CHECK( s10.utf8_string() == s9 );
|
||||
|
||||
std::string s11("xyz\0\xFF", 5); /* an invalid UTF-8 sequence */
|
||||
CHECK( "" == wxString::FromUTF8(s11) );
|
||||
|
||||
CHECK( wxString("bye").utf8_string() == std::string("bye") );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString::Algo", "[stdstring]")
|
||||
{
|
||||
wxString s("AB");
|
||||
std::reverse(s.begin(), s.end());
|
||||
CHECK( s == "BA" );
|
||||
}
|
||||
|
||||
#ifdef wxHAS_STD_STRING_VIEW
|
||||
TEST_CASE("StdString::View", "[stdstring]")
|
||||
{
|
||||
std::string strStd("std::string value");
|
||||
std::wstring strStdWide(L"std::wstring value");
|
||||
|
||||
std::string_view strStdView(strStd);
|
||||
std::wstring_view strStdWideView(strStdWide);
|
||||
|
||||
wxString s1(strStdView);
|
||||
CHECK( s1 == "std::string value" );
|
||||
|
||||
wxString s2(strStdWideView);
|
||||
CHECK( s2 == "std::wstring value" );
|
||||
|
||||
wxString s3;
|
||||
s3 = strStdView;
|
||||
CHECK( s3 == "std::string value" );
|
||||
s3 = strStdWideView;
|
||||
CHECK( s3 == "std::wstring value" );
|
||||
|
||||
std::string strUTF("\xF0\x9F\x90\xB1\0\xE7\x8C\xAB", 9); /* U+1F431 U+0000 U+732B */
|
||||
std::string_view strViewUTF(strUTF);
|
||||
|
||||
wxString wxstrUTF = wxString::FromUTF8(strViewUTF);
|
||||
CHECK( wxstrUTF.ToStdString(wxConvUTF8) == strUTF );
|
||||
CHECK( wxstrUTF.utf8_string() == strUTF );
|
||||
|
||||
std::string strInvalidUTF("xyz\0\xFF", 5); /* an invalid UTF-8 sequence */
|
||||
std::string_view strViewInvalidUTF(strInvalidUTF);
|
||||
|
||||
CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) );
|
||||
|
||||
/* Ensure we don't clobber comparisons on base types */
|
||||
std::string_view view = "abc";
|
||||
const char *str = "abc";
|
||||
CHECK( view == str );
|
||||
|
||||
std::wstring_view wview = L"abc";
|
||||
const wchar_t *wstr = L"abc";
|
||||
CHECK( wview == wstr );
|
||||
}
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
1371
libs/wxWidgets-3.3.1/tests/strings/strings.cpp
Normal file
1371
libs/wxWidgets-3.3.1/tests/strings/strings.cpp
Normal file
File diff suppressed because it is too large
Load Diff
309
libs/wxWidgets-3.3.1/tests/strings/tokenizer.cpp
Normal file
309
libs/wxWidgets-3.3.1/tests/strings/tokenizer.cpp
Normal file
@@ -0,0 +1,309 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/strings.cpp
|
||||
// Purpose: wxStringTokenizer unit test
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2005-12-20 (extacted from strings.cpp)
|
||||
// Copyright: (c) 2004-2005 Vadim Zeitlin
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/tokenzr.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class TokenizerTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
TokenizerTestCase() { }
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TokenizerTestCase );
|
||||
CPPUNIT_TEST( GetCount );
|
||||
CPPUNIT_TEST( GetPosition );
|
||||
CPPUNIT_TEST( GetString );
|
||||
CPPUNIT_TEST( LastDelimiter );
|
||||
CPPUNIT_TEST( StrtokCompat );
|
||||
CPPUNIT_TEST( CopyObj );
|
||||
CPPUNIT_TEST( AssignObj );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void GetCount();
|
||||
void GetPosition();
|
||||
void GetString();
|
||||
void LastDelimiter();
|
||||
void StrtokCompat();
|
||||
void CopyObj();
|
||||
void AssignObj();
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TokenizerTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( TokenizerTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TokenizerTestCase, "TokenizerTestCase" );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const struct TokenizerTestData
|
||||
{
|
||||
// the string to tokenize
|
||||
const wxChar *str;
|
||||
|
||||
// the delimiters to use
|
||||
const wxChar *delims;
|
||||
|
||||
// the tokenizer mode
|
||||
wxStringTokenizerMode mode;
|
||||
|
||||
// expected number of tokens
|
||||
size_t count;
|
||||
}
|
||||
gs_testData[] =
|
||||
{
|
||||
{ wxT(""), wxT(" "), wxTOKEN_DEFAULT, 0 },
|
||||
{ wxT(""), wxT(" "), wxTOKEN_RET_EMPTY, 0 },
|
||||
{ wxT(""), wxT(" "), wxTOKEN_RET_EMPTY_ALL, 0 },
|
||||
{ wxT(""), wxT(" "), wxTOKEN_RET_DELIMS, 0 },
|
||||
{ wxT(":"), wxT(":"), wxTOKEN_RET_EMPTY, 1 },
|
||||
{ wxT(":"), wxT(":"), wxTOKEN_RET_DELIMS, 1 },
|
||||
{ wxT(":"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 2 },
|
||||
{ wxT("::"), wxT(":"), wxTOKEN_RET_EMPTY, 1 },
|
||||
{ wxT("::"), wxT(":"), wxTOKEN_RET_DELIMS, 1 },
|
||||
{ wxT("::"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 3 },
|
||||
|
||||
{ wxT("Hello, world"), wxT(" "), wxTOKEN_DEFAULT, 2 },
|
||||
{ wxT("Hello, world "), wxT(" "), wxTOKEN_DEFAULT, 2 },
|
||||
{ wxT("Hello, world"), wxT(","), wxTOKEN_DEFAULT, 2 },
|
||||
{ wxT("Hello, world!"), wxT(",!"), wxTOKEN_DEFAULT, 2 },
|
||||
{ wxT("Hello,, world!"), wxT(",!"), wxTOKEN_DEFAULT, 3 },
|
||||
{ wxT("Hello,, world!"), wxT(",!"), wxTOKEN_STRTOK, 2 },
|
||||
{ wxT("Hello, world!"), wxT(",!"), wxTOKEN_RET_EMPTY_ALL, 3 },
|
||||
|
||||
{ wxT("username:password:uid:gid:gecos:home:shell"),
|
||||
wxT(":"), wxTOKEN_DEFAULT, 7 },
|
||||
|
||||
{ wxT("1:2::3:"), wxT(":"), wxTOKEN_DEFAULT, 4 },
|
||||
{ wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_EMPTY, 4 },
|
||||
{ wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 5 },
|
||||
{ wxT("1:2::3:"), wxT(":"), wxTOKEN_RET_DELIMS, 4 },
|
||||
{ wxT("1:2::3:"), wxT(":"), wxTOKEN_STRTOK, 3 },
|
||||
|
||||
{ wxT("1:2::3::"), wxT(":"), wxTOKEN_DEFAULT, 4 },
|
||||
{ wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_EMPTY, 4 },
|
||||
{ wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_EMPTY_ALL, 6 },
|
||||
{ wxT("1:2::3::"), wxT(":"), wxTOKEN_RET_DELIMS, 4 },
|
||||
{ wxT("1:2::3::"), wxT(":"), wxTOKEN_STRTOK, 3 },
|
||||
|
||||
{ wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_DEFAULT, 4 },
|
||||
{ wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_STRTOK, 4 },
|
||||
{ wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_RET_EMPTY, 6 },
|
||||
{ wxT("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, wxTOKEN_RET_EMPTY_ALL, 9 },
|
||||
|
||||
{ wxT("01/02/99"), wxT("/-"), wxTOKEN_DEFAULT, 3 },
|
||||
{ wxT("01-02/99"), wxT("/-"), wxTOKEN_RET_DELIMS, 3 },
|
||||
};
|
||||
|
||||
// helper function returning the string showing the index for which the test
|
||||
// fails in the diagnostic message
|
||||
static std::string Nth(size_t n)
|
||||
{
|
||||
return std::string(wxString::Format(wxT("for loop index %lu"),
|
||||
(unsigned long)n).mb_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// the tests
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void TokenizerTestCase::GetCount()
|
||||
{
|
||||
for ( size_t n = 0; n < WXSIZEOF(gs_testData); n++ )
|
||||
{
|
||||
const TokenizerTestData& ttd = gs_testData[n];
|
||||
|
||||
wxStringTokenizer tkz(ttd.str, ttd.delims, ttd.mode);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE( Nth(n), ttd.count, tkz.CountTokens() );
|
||||
|
||||
size_t count = 0;
|
||||
while ( tkz.HasMoreTokens() )
|
||||
{
|
||||
tkz.GetNextToken();
|
||||
count++;
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE( Nth(n), ttd.count, count );
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
DoTestGetPosition(const wxChar *s, const wxChar *delims, int pos, ...)
|
||||
{
|
||||
wxStringTokenizer tkz(s, delims);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( (size_t)0, tkz.GetPosition() );
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, pos);
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !pos )
|
||||
{
|
||||
CPPUNIT_ASSERT( !tkz.HasMoreTokens() );
|
||||
break;
|
||||
}
|
||||
|
||||
tkz.GetNextToken();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( (size_t)pos, tkz.GetPosition() );
|
||||
|
||||
pos = va_arg(ap, int);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void TokenizerTestCase::GetPosition()
|
||||
{
|
||||
DoTestGetPosition(wxT("foo"), wxT("_"), 3, 0);
|
||||
DoTestGetPosition(wxT("foo_bar"), wxT("_"), 4, 7, 0);
|
||||
DoTestGetPosition(wxT("foo_bar_"), wxT("_"), 4, 8, 0);
|
||||
}
|
||||
|
||||
// helper for GetString(): the parameters are the same as for DoTestGetPosition
|
||||
// but it checks GetString() return value instead of GetPosition()
|
||||
static void
|
||||
DoTestGetString(const wxChar *s, const wxChar *delims, int pos, ...)
|
||||
{
|
||||
wxStringTokenizer tkz(s, delims);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( wxString(s), tkz.GetString() );
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, pos);
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !pos )
|
||||
{
|
||||
CPPUNIT_ASSERT( tkz.GetString().empty() ) ;
|
||||
break;
|
||||
}
|
||||
|
||||
tkz.GetNextToken();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( wxString(s + pos), tkz.GetString() );
|
||||
|
||||
pos = va_arg(ap, int);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void TokenizerTestCase::GetString()
|
||||
{
|
||||
DoTestGetString(wxT("foo"), wxT("_"), 3, 0);
|
||||
DoTestGetString(wxT("foo_bar"), wxT("_"), 4, 7, 0);
|
||||
DoTestGetString(wxT("foo_bar_"), wxT("_"), 4, 8, 0);
|
||||
}
|
||||
|
||||
void TokenizerTestCase::LastDelimiter()
|
||||
{
|
||||
wxStringTokenizer tkz(wxT("a+-b=c"), wxT("+-="));
|
||||
|
||||
tkz.GetNextToken();
|
||||
CPPUNIT_ASSERT_EQUAL( wxT('+'), tkz.GetLastDelimiter() );
|
||||
|
||||
tkz.GetNextToken();
|
||||
CPPUNIT_ASSERT_EQUAL( wxT('-'), tkz.GetLastDelimiter() );
|
||||
|
||||
tkz.GetNextToken();
|
||||
CPPUNIT_ASSERT_EQUAL( wxT('='), tkz.GetLastDelimiter() );
|
||||
|
||||
tkz.GetNextToken();
|
||||
CPPUNIT_ASSERT_EQUAL( wxT('\0'), tkz.GetLastDelimiter() );
|
||||
}
|
||||
|
||||
void TokenizerTestCase::StrtokCompat()
|
||||
{
|
||||
for ( size_t n = 0; n < WXSIZEOF(gs_testData); n++ )
|
||||
{
|
||||
const TokenizerTestData& ttd = gs_testData[n];
|
||||
if ( ttd.mode != wxTOKEN_STRTOK )
|
||||
continue;
|
||||
|
||||
wxWCharBuffer
|
||||
buf(ttd.str);
|
||||
wxChar *last;
|
||||
wxChar *s = wxStrtok(buf.data(), ttd.delims, &last);
|
||||
|
||||
wxStringTokenizer tkz(ttd.str, ttd.delims, ttd.mode);
|
||||
while ( tkz.HasMoreTokens() )
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL( wxString(s), tkz.GetNextToken() );
|
||||
s = wxStrtok(nullptr, ttd.delims, &last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TokenizerTestCase::CopyObj()
|
||||
{
|
||||
// Test copy ctor
|
||||
wxStringTokenizer tkzSrc(wxT("first:second:third:fourth"), wxT(":"));
|
||||
while ( tkzSrc.HasMoreTokens() )
|
||||
{
|
||||
tkzSrc.GetNextToken();
|
||||
wxStringTokenizer tkz = tkzSrc;
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
|
||||
|
||||
// Change the state of both objects and compare again...
|
||||
tkzSrc.GetNextToken();
|
||||
tkz.GetNextToken();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
|
||||
}
|
||||
}
|
||||
|
||||
void TokenizerTestCase::AssignObj()
|
||||
{
|
||||
// Test assignment
|
||||
wxStringTokenizer tkzSrc(wxT("first:second:third:fourth"), wxT(":"));
|
||||
wxStringTokenizer tkz;
|
||||
while ( tkzSrc.HasMoreTokens() )
|
||||
{
|
||||
tkzSrc.GetNextToken();
|
||||
tkz = tkzSrc;
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
|
||||
|
||||
// Change the state of both objects and compare again...
|
||||
tkzSrc.GetNextToken();
|
||||
tkz.GetNextToken();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetPosition(), tkz.GetPosition() );
|
||||
CPPUNIT_ASSERT_EQUAL( tkzSrc.GetString(), tkz.GetString() );
|
||||
}
|
||||
}
|
||||
1152
libs/wxWidgets-3.3.1/tests/strings/unichar.cpp
Normal file
1152
libs/wxWidgets-3.3.1/tests/strings/unichar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
484
libs/wxWidgets-3.3.1/tests/strings/unicode.cpp
Normal file
484
libs/wxWidgets-3.3.1/tests/strings/unicode.cpp
Normal file
@@ -0,0 +1,484 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/unicode.cpp
|
||||
// Purpose: Unicode unit test
|
||||
// Author: Vadim Zeitlin, Wlodzimierz ABX Skiba
|
||||
// Created: 2004-04-28
|
||||
// Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/encconv.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helper class holding the matching MB and WC strings
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct StringConversionData
|
||||
{
|
||||
// either str or wcs (but not both) may be null, this means that the conversion
|
||||
// to it should fail
|
||||
StringConversionData(const char *str_, const wchar_t *wcs_, int flags_ = 0)
|
||||
: str(str_), wcs(wcs_), flags(flags_)
|
||||
{
|
||||
}
|
||||
|
||||
const char * const str;
|
||||
const wchar_t * const wcs;
|
||||
|
||||
enum
|
||||
{
|
||||
TEST_BOTH = 0, // test both str -> wcs and wcs -> str
|
||||
ONLY_MB2WC = 1 // only test str -> wcs conversion
|
||||
};
|
||||
|
||||
const int flags;
|
||||
|
||||
// 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
|
||||
{
|
||||
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 wxString::Format("#%lu: %s", (unsigned long)n, msg).ToStdString();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::string
|
||||
Message(size_t n,
|
||||
const char *func,
|
||||
const wxCharTypeBuffer<T>& actual,
|
||||
const T *expected)
|
||||
{
|
||||
return Message(n,
|
||||
wxString::Format("%s returned \"%s\", expected \"%s\"",
|
||||
func, actual.data(), expected));
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class UnicodeTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
UnicodeTestCase();
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( UnicodeTestCase );
|
||||
CPPUNIT_TEST( ToFromAscii );
|
||||
CPPUNIT_TEST( ConstructorsWithConversion );
|
||||
CPPUNIT_TEST( ConversionFixed );
|
||||
CPPUNIT_TEST( ConversionWithNULs );
|
||||
CPPUNIT_TEST( ConversionUTF7 );
|
||||
CPPUNIT_TEST( ConversionUTF8 );
|
||||
CPPUNIT_TEST( ConversionUTF16 );
|
||||
CPPUNIT_TEST( ConversionUTF32 );
|
||||
CPPUNIT_TEST( IsConvOk );
|
||||
CPPUNIT_TEST( Iteration );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void ToFromAscii();
|
||||
void ConstructorsWithConversion();
|
||||
void ConversionFixed();
|
||||
void ConversionWithNULs();
|
||||
void ConversionUTF7();
|
||||
void ConversionUTF8();
|
||||
void ConversionUTF16();
|
||||
void ConversionUTF32();
|
||||
void IsConvOk();
|
||||
void Iteration();
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(UnicodeTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( UnicodeTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( UnicodeTestCase, "UnicodeTestCase" );
|
||||
|
||||
UnicodeTestCase::UnicodeTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ToFromAscii()
|
||||
{
|
||||
|
||||
#define TEST_TO_FROM_ASCII(txt) \
|
||||
{ \
|
||||
static const char *msg = txt; \
|
||||
wxString s = wxString::FromAscii(msg); \
|
||||
CPPUNIT_ASSERT( strcmp( s.ToAscii() , msg ) == 0 ); \
|
||||
}
|
||||
|
||||
TEST_TO_FROM_ASCII( "Hello, world!" );
|
||||
TEST_TO_FROM_ASCII( "additional \" special \t test \\ component \n :-)" );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConstructorsWithConversion()
|
||||
{
|
||||
const unsigned char utf8Buf[] = "Déjà";
|
||||
const unsigned char utf8subBuf[] = "Déj";
|
||||
const char* utf8 = reinterpret_cast<const char*>(utf8Buf);
|
||||
const char* utf8sub = reinterpret_cast<const char*>(utf8subBuf);
|
||||
|
||||
wxString s1(utf8, wxConvUTF8);
|
||||
|
||||
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( wxString::FromUTF8(utf8), s2 );
|
||||
|
||||
wxString sub(utf8sub, wxConvUTF8); // "Dej" substring
|
||||
wxString s3(utf8, wxConvUTF8, 4);
|
||||
CPPUNIT_ASSERT_EQUAL( sub, s3 );
|
||||
|
||||
wxString s4(wchar, 3);
|
||||
CPPUNIT_ASSERT_EQUAL( sub, s4 );
|
||||
|
||||
// conversion should stop with failure at pos 35
|
||||
wxString s("\t[pl]open.format.Sformatuj dyskietk\xea=gfloppy %f", wxConvUTF8);
|
||||
CPPUNIT_ASSERT( s.empty() );
|
||||
|
||||
|
||||
// test using Unicode strings together with char* strings (this must work
|
||||
// in ANSI mode as well, of course):
|
||||
wxString s5("ascii");
|
||||
CPPUNIT_ASSERT_EQUAL( "ascii", s5 );
|
||||
|
||||
s5 += " value";
|
||||
|
||||
CPPUNIT_ASSERT( strcmp(s5.mb_str(), "ascii value") == 0 );
|
||||
CPPUNIT_ASSERT_EQUAL( "ascii value", s5 );
|
||||
CPPUNIT_ASSERT( s5 != "SomethingElse" );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionFixed()
|
||||
{
|
||||
size_t len;
|
||||
|
||||
wxConvLibc.cWC2MB(L"", 0, &len);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL( 0, len );
|
||||
|
||||
// check that when we convert a fixed number of characters we obtain the
|
||||
// expected return value
|
||||
CPPUNIT_ASSERT_EQUAL( 0, wxConvLibc.ToWChar(nullptr, 0, "", 0) );
|
||||
CPPUNIT_ASSERT_EQUAL( 1, wxConvLibc.ToWChar(nullptr, 0, "x", 1) );
|
||||
CPPUNIT_ASSERT_EQUAL( 2, wxConvLibc.ToWChar(nullptr, 0, "x", 2) );
|
||||
CPPUNIT_ASSERT_EQUAL( 2, wxConvLibc.ToWChar(nullptr, 0, "xy", 2) );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionWithNULs()
|
||||
{
|
||||
static const size_t lenNulString = 10;
|
||||
|
||||
wxString szTheString(L"The\0String", lenNulString);
|
||||
wxCharBuffer theBuffer = szTheString.mb_str(wxConvLibc);
|
||||
|
||||
CPPUNIT_ASSERT( memcmp(theBuffer.data(), "The\0String",
|
||||
lenNulString + 1) == 0 );
|
||||
|
||||
wxString szTheString2("The\0String", wxConvLocal, lenNulString);
|
||||
CPPUNIT_ASSERT_EQUAL( lenNulString, szTheString2.length() );
|
||||
CPPUNIT_ASSERT( wxTmemcmp(szTheString2.c_str(), L"The\0String",
|
||||
lenNulString) == 0 );
|
||||
|
||||
const char *null4buff = "\0\0\0\0";
|
||||
wxString null4str(null4buff, 4);
|
||||
CPPUNIT_ASSERT_EQUAL( 4, null4str.length() );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionUTF7()
|
||||
{
|
||||
static const StringConversionData utf7data[] =
|
||||
{
|
||||
// normal fragments
|
||||
StringConversionData("+AKM-", L"\xa3"),
|
||||
StringConversionData("+AOk-t+AOk-", L"\xe9t\xe9"),
|
||||
|
||||
// this one is an alternative valid encoding of the same string
|
||||
StringConversionData("+AOk-t+AOk", L"\xe9t\xe9",
|
||||
StringConversionData::ONLY_MB2WC),
|
||||
|
||||
// some special cases
|
||||
StringConversionData("+-", L"+"),
|
||||
StringConversionData("+--", L"+-"),
|
||||
|
||||
// the following are invalid UTF-7 sequences
|
||||
StringConversionData("\xa3", nullptr),
|
||||
StringConversionData("+", nullptr),
|
||||
StringConversionData("+~", nullptr),
|
||||
StringConversionData("a+", nullptr),
|
||||
};
|
||||
|
||||
for ( size_t n = 0; n < WXSIZEOF(utf7data); n++ )
|
||||
{
|
||||
const StringConversionData& d = utf7data[n];
|
||||
|
||||
// converting to/from UTF-7 using iconv() currently doesn't work
|
||||
// because of several problems:
|
||||
// - GetMBNulLen() doesn't return correct result (iconv converts L'\0'
|
||||
// to an incomplete and anyhow nonsensical "+AA" string)
|
||||
// - iconv refuses to convert "+-" (although it converts "+-\n" just
|
||||
// fine, go figure)
|
||||
//
|
||||
// I have no idea how to fix this so just disable the test for now
|
||||
#ifdef __WINDOWS__
|
||||
wxCSConv conv("utf-7");
|
||||
d.Test(n, conv);
|
||||
#endif
|
||||
d.Test(n, wxConvUTF7);
|
||||
}
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionUTF8()
|
||||
{
|
||||
static const StringConversionData utf8data[] =
|
||||
{
|
||||
#ifdef wxMUST_USE_U_ESCAPE
|
||||
StringConversionData("\xc2\xa3", L"\u00a3"),
|
||||
#else
|
||||
StringConversionData("£", L"£"),
|
||||
#endif
|
||||
};
|
||||
|
||||
wxCSConv conv(wxT("utf-8"));
|
||||
for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
|
||||
{
|
||||
const StringConversionData& d = utf8data[n];
|
||||
d.Test(n, conv);
|
||||
d.Test(n, wxConvUTF8);
|
||||
}
|
||||
|
||||
static const char* const u25a6 = "\xe2\x96\xa6";
|
||||
wxMBConvUTF8 c(wxMBConvUTF8::MAP_INVALID_UTF8_TO_OCTAL);
|
||||
CPPUNIT_ASSERT_EQUAL( 2, c.ToWChar(nullptr, 0, u25a6, wxNO_LEN) );
|
||||
CPPUNIT_ASSERT_EQUAL( 0, c.ToWChar(nullptr, 0, u25a6, 0) );
|
||||
CPPUNIT_ASSERT_EQUAL( 1, c.ToWChar(nullptr, 0, u25a6, 3) );
|
||||
CPPUNIT_ASSERT_EQUAL( 2, c.ToWChar(nullptr, 0, u25a6, 4) );
|
||||
|
||||
// Verify that converting a string with embedded NULs works.
|
||||
CPPUNIT_ASSERT_EQUAL( 5, wxString::FromUTF8("abc\0\x32", 5).length() );
|
||||
|
||||
// Verify that converting a string containing invalid UTF-8 does not work,
|
||||
// even if it happens after an embedded NUL.
|
||||
CPPUNIT_ASSERT( wxString::FromUTF8("abc\xff").empty() );
|
||||
CPPUNIT_ASSERT( wxString::FromUTF8("abc\0\xff", 5).empty() );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionUTF16()
|
||||
{
|
||||
static const StringConversionData utf16data[] =
|
||||
{
|
||||
#ifdef wxMUST_USE_U_ESCAPE
|
||||
StringConversionData(
|
||||
"\x04\x1f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42\0\0",
|
||||
L"\u041f\u0440\u0438\u0432\u0435\u0442"),
|
||||
#else
|
||||
StringConversionData(
|
||||
"\x04\x1f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42\0\0",
|
||||
L"Привет"),
|
||||
#endif
|
||||
};
|
||||
|
||||
wxCSConv conv(wxFONTENCODING_UTF16BE);
|
||||
for ( size_t n = 0; n < WXSIZEOF(utf16data); n++ )
|
||||
{
|
||||
const StringConversionData& d = utf16data[n];
|
||||
d.Test(n, conv);
|
||||
}
|
||||
|
||||
// special case: this string has consecutive NULs inside it which don't
|
||||
// terminate the string, this exposed a bug in our conversion code which
|
||||
// got confused in this case
|
||||
size_t len;
|
||||
conv.cMB2WC("\x01\0\0B\0C" /* A macron BC */, 6, &len);
|
||||
CPPUNIT_ASSERT_EQUAL( 3, len );
|
||||
|
||||
// When using UTF-16 internally (i.e. MSW), we don't have any surrogate
|
||||
// support, so the length of the string below is 2, not 1.
|
||||
#if SIZEOF_WCHAR_T == 4
|
||||
// Another one: verify that the length of the resulting string is computed
|
||||
// correctly when there is a surrogate in the input.
|
||||
wxMBConvUTF16BE().cMB2WC("\xd8\x03\xdc\x01\0" /* OLD TURKIC LETTER YENISEI A */, wxNO_LEN, &len);
|
||||
CPPUNIT_ASSERT_EQUAL( 1, len );
|
||||
#endif // UTF-32 internal representation
|
||||
|
||||
#if SIZEOF_WCHAR_T == 2
|
||||
// Verify that the length of UTF-32 string is correct even when converting
|
||||
// to it from a longer UTF-16 string with surrogates.
|
||||
|
||||
// Construct CAT FACE U+1F431 without using \U which is not supported by
|
||||
// ancient compilers and without using \u with surrogates which is
|
||||
// (correctly) flagged as an error by the newer ones.
|
||||
wchar_t ws[2];
|
||||
ws[0] = 0xd83d;
|
||||
ws[1] = 0xdc31;
|
||||
CPPUNIT_ASSERT_EQUAL( 4, wxMBConvUTF32BE().FromWChar(nullptr, 0, ws, 2) );
|
||||
#endif // UTF-16 internal representation
|
||||
}
|
||||
|
||||
void UnicodeTestCase::ConversionUTF32()
|
||||
{
|
||||
static const StringConversionData utf32data[] =
|
||||
{
|
||||
#ifdef wxMUST_USE_U_ESCAPE
|
||||
StringConversionData(
|
||||
"\0\0\x04\x1f\0\0\x04\x40\0\0\x04\x38\0\0\x04\x32\0\0\x04\x35\0\0\x04\x42\0\0\0\0",
|
||||
L"\u041f\u0440\u0438\u0432\u0435\u0442"),
|
||||
#else
|
||||
StringConversionData(
|
||||
"\0\0\x04\x1f\0\0\x04\x40\0\0\x04\x38\0\0\x04\x32\0\0\x04\x35\0\0\x04\x42\0\0\0\0",
|
||||
L"Привет"),
|
||||
#endif
|
||||
};
|
||||
|
||||
wxCSConv conv(wxFONTENCODING_UTF32BE);
|
||||
for ( size_t n = 0; n < WXSIZEOF(utf32data); n++ )
|
||||
{
|
||||
const StringConversionData& d = utf32data[n];
|
||||
d.Test(n, conv);
|
||||
}
|
||||
|
||||
size_t len;
|
||||
conv.cMB2WC("\0\0\x01\0\0\0\0B\0\0\0C" /* A macron BC */, 12, &len);
|
||||
CPPUNIT_ASSERT_EQUAL( 3, len );
|
||||
}
|
||||
|
||||
void UnicodeTestCase::IsConvOk()
|
||||
{
|
||||
CPPUNIT_ASSERT( wxCSConv(wxFONTENCODING_SYSTEM).IsOk() );
|
||||
CPPUNIT_ASSERT( wxCSConv("US-ASCII").IsOk() );
|
||||
CPPUNIT_ASSERT( wxCSConv("UTF-8").IsOk() );
|
||||
CPPUNIT_ASSERT( !wxCSConv("NoSuchConversion").IsOk() );
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
CPPUNIT_ASSERT( wxCSConv("WINDOWS-437").IsOk() );
|
||||
#endif
|
||||
}
|
||||
|
||||
void UnicodeTestCase::Iteration()
|
||||
{
|
||||
static const char *textUTF8 = "čeština";// "czech" in Czech
|
||||
static const wchar_t textUTF16[] = {0x10D, 0x65, 0x161, 0x74, 0x69, 0x6E, 0x61, 0};
|
||||
|
||||
wxString text(wxString::FromUTF8(textUTF8));
|
||||
CPPUNIT_ASSERT( wxStrcmp(text.wc_str(), textUTF16) == 0 );
|
||||
|
||||
// verify the string was decoded correctly:
|
||||
{
|
||||
size_t idx = 0;
|
||||
for ( auto c : text )
|
||||
{
|
||||
CPPUNIT_ASSERT( c == textUTF16[idx++] );
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite the string with something that is shorter in UTF-8:
|
||||
{
|
||||
for ( auto c : text )
|
||||
c = 'x';
|
||||
}
|
||||
|
||||
// restore the original text now:
|
||||
{
|
||||
wxString::iterator end1 = text.end();
|
||||
wxString::const_iterator end2 = text.end();
|
||||
|
||||
size_t idx = 0;
|
||||
for ( auto c : text )
|
||||
{
|
||||
c = textUTF16[idx++];
|
||||
|
||||
CPPUNIT_ASSERT( end1 == text.end() );
|
||||
CPPUNIT_ASSERT( end2 == text.end() );
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT( end1 == text.end() );
|
||||
CPPUNIT_ASSERT( end2 == text.end() );
|
||||
}
|
||||
|
||||
// and verify it again:
|
||||
{
|
||||
size_t idx = 0;
|
||||
for ( auto c : text )
|
||||
{
|
||||
CPPUNIT_ASSERT( c == textUTF16[idx++] );
|
||||
}
|
||||
}
|
||||
}
|
||||
294
libs/wxWidgets-3.3.1/tests/strings/vararg.cpp
Normal file
294
libs/wxWidgets-3.3.1/tests/strings/vararg.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/vararg.cpp
|
||||
// Purpose: Test for wx vararg look-alike macros
|
||||
// Author: Vaclav Slavik
|
||||
// Created: 2007-02-20
|
||||
// Copyright: (c) 2007 REA Elektronik GmbH
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/string.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("StringPrintf", "[wxString][Printf][vararg]")
|
||||
{
|
||||
wxString s, s2;
|
||||
|
||||
// test passing literals:
|
||||
s.Printf("%s %i", "foo", 42);
|
||||
CHECK( s == "foo 42" );
|
||||
s.Printf("%s %s %i", wxT("bar"), "=", 11);
|
||||
|
||||
// test passing c_str():
|
||||
CHECK( s == "bar = 11" );
|
||||
s2.Printf("(%s)", s.c_str());
|
||||
CHECK( s2 == "(bar = 11)" );
|
||||
s2.Printf(wxT("[%s](%s)"), s.c_str(), "str");
|
||||
CHECK( s2 == "[bar = 11](str)" );
|
||||
|
||||
s2.Printf("%s mailbox", wxString("Opening").c_str());
|
||||
CHECK( s2 == "Opening mailbox" );
|
||||
|
||||
// test passing wxString directly:
|
||||
s2.Printf(wxT("[%s](%s)"), s, "str");
|
||||
CHECK( s2 == "[bar = 11](str)" );
|
||||
|
||||
// test passing wxCharBufferType<T>:
|
||||
s = "FooBar";
|
||||
s2.Printf(wxT("(%s)"), s.mb_str());
|
||||
CHECK( s2 == "(FooBar)" );
|
||||
s2.Printf(wxT("value=%s;"), s.wc_str());
|
||||
CHECK( s2 == "value=FooBar;" );
|
||||
|
||||
// this tests correct passing of wxCStrData constructed from string
|
||||
// literal (and we disable the warnings related to the use of a literal
|
||||
// here because we want to test that this compiles, even with warnings):
|
||||
wxGCC_WARNING_SUPPRESS(write-strings)
|
||||
wxCLANG_WARNING_SUPPRESS(c++11-compat-deprecated-writable-strings)
|
||||
|
||||
bool cond = true;
|
||||
s2.Printf(wxT("foo %s"), !cond ? s.c_str() : wxT("bar"));
|
||||
|
||||
wxGCC_WARNING_RESTORE(write-strings)
|
||||
wxCLANG_WARNING_RESTORE(c++11-compat-deprecated-writable-strings)
|
||||
|
||||
#ifdef __cpp_lib_string_view
|
||||
CHECK( wxString::Format("%s", std::string_view{"foobar", 3}) == "foo" );
|
||||
CHECK( wxString::Format("%s", std::string_view{"bar"}) == "bar" );
|
||||
#endif // __cpp_lib_string_view
|
||||
}
|
||||
|
||||
TEST_CASE("CharPrintf", "[wxString][Printf][vararg]")
|
||||
{
|
||||
wxString foo("foo");
|
||||
wxString s;
|
||||
|
||||
// test using wchar_t:
|
||||
s.Printf("char=%c", L'c');
|
||||
CHECK( s == "char=c" );
|
||||
|
||||
// test wxUniCharRef:
|
||||
s.Printf("string[1] is %c", foo[1]);
|
||||
CHECK( s == "string[1] is o" );
|
||||
|
||||
// test char
|
||||
char c = 'z';
|
||||
s.Printf("%c to %c", 'a', c);
|
||||
CHECK( s == "a to z" );
|
||||
|
||||
// test char used as integer:
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4309) // truncation of constant value
|
||||
#endif
|
||||
wxCLANG_WARNING_SUPPRESS(constant-conversion)
|
||||
c = 240;
|
||||
wxCLANG_WARNING_RESTORE(constant-conversion)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default:4309)
|
||||
#endif
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
s.Printf("value is %i (int)", c);
|
||||
CHECK( s == wxString("value is -16 (int)") );
|
||||
#endif
|
||||
|
||||
unsigned char u = 240;
|
||||
s.Printf("value is %i (int)", u);
|
||||
CHECK( s == "value is 240 (int)" );
|
||||
}
|
||||
|
||||
TEST_CASE("SizetPrintf", "[wxString][Printf][vararg]")
|
||||
{
|
||||
size_t i = 1;
|
||||
ssize_t j = -2;
|
||||
|
||||
CHECK( wxString::Format("size_t=%zu ssize_t=%zd", i, j)
|
||||
== "size_t=1 ssize_t=-2" );
|
||||
|
||||
CHECK( wxString::Format("size_t=0x%zX", static_cast<size_t>(160))
|
||||
== "size_t=0xA0" );
|
||||
}
|
||||
|
||||
TEST_CASE("StdString", "[wxString][Printf][vararg]")
|
||||
{
|
||||
// test passing std::[w]string
|
||||
wxString s;
|
||||
|
||||
std::string mb("multi-byte");
|
||||
std::string wc("widechar");
|
||||
|
||||
s.Printf("string %s(%i).", mb, 1);
|
||||
CHECK( s == "string multi-byte(1)." );
|
||||
|
||||
s.Printf("string %s(%i).", wc, 2);
|
||||
CHECK( s == "string widechar(2)." );
|
||||
}
|
||||
|
||||
TEST_CASE("LongLongPrintf", "[wxString][Printf][vararg]")
|
||||
{
|
||||
const char * const llfmt = "%" wxLongLongFmtSpec "d";
|
||||
|
||||
CHECK( wxString::Format(llfmt, wxLL(17)) == "17" );
|
||||
|
||||
wxLongLong ll = 1234567890;
|
||||
CHECK( wxString::Format(llfmt, ll) == "1234567890" );
|
||||
}
|
||||
|
||||
TEST_CASE("Sscanf", "[wxSscanf][vararg]")
|
||||
{
|
||||
int i = 0;
|
||||
char str[20];
|
||||
|
||||
wxString input("42 test");
|
||||
|
||||
wxSscanf(input, "%d %s", &i, &str);
|
||||
CHECK( i == 42 );
|
||||
CHECK( wxString(str) == "test" );
|
||||
|
||||
#if !(defined(__MINGW32__) && \
|
||||
defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO == 1)
|
||||
// disable this test on mingw with __USE_MINGW_ANSI_STDIO=1
|
||||
// to prevent a segmentation fault. See:
|
||||
// https://sourceforge.net/p/mingw-w64/mailman/message/36118530/
|
||||
wchar_t wstr[20];
|
||||
|
||||
i = 0;
|
||||
wxSscanf(input, L"%d %s", &i, &wstr);
|
||||
CHECK( i == 42 );
|
||||
CHECK( wxString(wstr) == "test" );
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("RepeatedPrintf", "[wxString][Printf][vararg]")
|
||||
{
|
||||
wxCharBuffer buffer(2);
|
||||
char *p = buffer.data();
|
||||
*p = 'h';
|
||||
p++;
|
||||
*p = 'i';
|
||||
|
||||
wxString s;
|
||||
s = wxString::Format("buffer %s, len %d", buffer, (int)wxStrlen(buffer));
|
||||
CHECK( s == "buffer hi, len 2" );
|
||||
|
||||
s = wxString::Format("buffer %s, len %d", buffer, (int)wxStrlen(buffer));
|
||||
CHECK( s == "buffer hi, len 2" );
|
||||
}
|
||||
|
||||
TEST_CASE("ArgsValidation", "[wxString][vararg][error]")
|
||||
{
|
||||
int written;
|
||||
void *ptr = &written;
|
||||
short int swritten = 0;
|
||||
wxUnusedVar(swritten); // We're not really going to use it.
|
||||
|
||||
// these are valid:
|
||||
wxString::Format("a string(%s,%s), ptr %p, int %i",
|
||||
wxString(), "foo", "char* as pointer", 1);
|
||||
|
||||
// Unfortunately we can't check the result as different standard libraries
|
||||
// implementations format it in different ways, so just check that it
|
||||
// compiles.
|
||||
wxString::Format("null pointer is %p", nullptr);
|
||||
|
||||
// Microsoft has helpfully disabled support for "%n" in their CRT by
|
||||
// default starting from VC8 and somehow even calling
|
||||
// _set_printf_count_output() doesn't help here, so don't use "%n" at all
|
||||
// with it.
|
||||
#if defined(__VISUALC__)
|
||||
#define wxNO_PRINTF_PERCENT_N
|
||||
#endif // VC8+
|
||||
|
||||
// Similarly, many modern Linux distributions ship with g++ that uses
|
||||
// -D_FORTIFY_SOURCE=2 flag by default and this option prevents "%n" from
|
||||
// being used in a string outside of read-only memory, meaning that it
|
||||
// can't be used in wxString to which we (may, depending on build options)
|
||||
// assign it, so also disable testing of "%n" in this case lest we die with
|
||||
// an abort inside vswprintf().
|
||||
#if defined(_FORTIFY_SOURCE)
|
||||
#if _FORTIFY_SOURCE >= 2
|
||||
#define wxNO_PRINTF_PERCENT_N
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef wxNO_PRINTF_PERCENT_N
|
||||
wxString::Format("foo%i%n", 42, &written);
|
||||
CHECK( written == 5 );
|
||||
#endif
|
||||
|
||||
// but these are not:
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d + %d = %d", 2, 2) );
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i", "foo") );
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", (void*)&written) );
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr) );
|
||||
|
||||
// we don't check wxNO_PRINTF_PERCENT_N here as these expressions should
|
||||
// result in an assert in our code before the CRT functions are even called
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written) );
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr) );
|
||||
WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten) );
|
||||
|
||||
// %c should accept integers too
|
||||
wxString::Format("%c", 80);
|
||||
wxString::Format("%c", wxChar(80) + wxChar(1));
|
||||
|
||||
// check size_t handling
|
||||
size_t len = sizeof(ptr);
|
||||
#ifdef __WINDOWS__
|
||||
wxString::Format("%Iu", len);
|
||||
#else
|
||||
wxString::Format("%zu", len);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("VeryLongArg", "[wxString][Format][vararg]")
|
||||
{
|
||||
const size_t LENGTH = 70000;
|
||||
wxString veryLongString('.', LENGTH);
|
||||
REQUIRE( veryLongString.length() == LENGTH );
|
||||
|
||||
const wxString s = wxString::Format("%s", veryLongString);
|
||||
|
||||
// Check the length first to avoid very long output if this fails.
|
||||
REQUIRE( s.length() == LENGTH );
|
||||
CHECK( s == veryLongString );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Helpers for the "PrintfError" test: we must pass by these functions
|
||||
// because specifying "%c" directly inline would convert it to "%lc" and avoid
|
||||
// the error.
|
||||
wxString CallPrintfV(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
wxString s;
|
||||
s.PrintfV(wxString::FromAscii(format), ap);
|
||||
va_end(ap);
|
||||
return s;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_CASE("PrintfError", "[wxString][Format][vararg][error]")
|
||||
{
|
||||
// Check that using invalid argument doesn't keep doubling the buffer until
|
||||
// we run out of memory and die.
|
||||
const int invalidChar = 0x1780;
|
||||
REQUIRE_NOTHROW( CallPrintfV("%c", invalidChar) );
|
||||
}
|
||||
540
libs/wxWidgets-3.3.1/tests/strings/vsnprintf.cpp
Normal file
540
libs/wxWidgets-3.3.1/tests/strings/vsnprintf.cpp
Normal file
@@ -0,0 +1,540 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/strings/vsnprintf.cpp
|
||||
// Purpose: wxVsnprintf unit test
|
||||
// Author: Francesco Montorsi
|
||||
// (part of this file was taken from CMP.c of TRIO package
|
||||
// written by Bjorn Reese and Daniel Stenberg)
|
||||
// Created: 2006-04-01
|
||||
// Copyright: (c) 2006 Francesco Montorsi, Bjorn Reese and Daniel Stenberg
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/crt.h"
|
||||
|
||||
#if wxUSE_WXVSNPRINTF
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#include "wx/wxchar.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/private/localeset.h"
|
||||
|
||||
// NOTE: for more info about the specification of wxVsnprintf() behaviour you can
|
||||
// refer to the following page of the GNU libc manual:
|
||||
// http://www.gnu.org/software/libc/manual/html_node/Formatted-Output.html
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// global utilities for testing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_TEST_LEN 1024
|
||||
|
||||
// temporary buffers
|
||||
static wxChar buf[MAX_TEST_LEN];
|
||||
int r;
|
||||
|
||||
// Helper macro verifying both the return value of wxSnprintf() and its output.
|
||||
//
|
||||
// NOTE: the expected string length with this macro must not exceed MAX_TEST_LEN
|
||||
|
||||
#define CMP(expected, fmt, ...) \
|
||||
r=wxSnprintf(buf, MAX_TEST_LEN, fmt, ##__VA_ARGS__); \
|
||||
CHECK( r == (int)wxStrlen(buf) ); \
|
||||
CHECK( buf == wxString(expected) )
|
||||
|
||||
// Another helper which takes the size explicitly instead of using MAX_TEST_LEN
|
||||
//
|
||||
// NOTE: this macro is used also with too-small buffers (see Miscellaneous())
|
||||
// test function, thus the return value can be either -1 or > size and we
|
||||
// cannot check if r == (int)wxStrlen(buf)
|
||||
#define CMPTOSIZE(buffer, size, failuremsg, expected, fmt, ...) \
|
||||
r=wxSnprintf(buffer, size, fmt, ##__VA_ARGS__); \
|
||||
INFO(failuremsg); \
|
||||
CHECK( buffer == wxString(expected).Left(size - 1) )
|
||||
|
||||
// this is the same as wxSnprintf() but it passes the format string to
|
||||
// wxVsnprintf() without using WX_ATTRIBUTE_PRINTF and thus suppresses the gcc
|
||||
// checks (and resulting warnings) for the format string
|
||||
//
|
||||
// use with extreme care and only when you're really sure the warnings must be
|
||||
// suppressed!
|
||||
template<typename T>
|
||||
static int
|
||||
wxUnsafeSnprintf(T *buf, size_t len, const wxChar *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
int rc = wxVsnprintf(buf, len, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test fixture
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Explicitly set C locale to avoid check failures when running on machines
|
||||
// with a locale where the decimal point is not '.'
|
||||
class VsnprintfTestCase : wxCLocaleSetter
|
||||
{
|
||||
public:
|
||||
VsnprintfTestCase() : wxCLocaleSetter() { }
|
||||
|
||||
protected:
|
||||
template<typename T>
|
||||
void DoBigToSmallBuffer(T *buffer, int size);
|
||||
|
||||
// compares the expectedString and the result of wxVsnprintf() char by char
|
||||
// for all its length (not only for first expectedLen chars) and also
|
||||
// checks the return value
|
||||
void DoMisc(int expectedLen, const wxString& expectedString,
|
||||
size_t max, const wxChar *format, ...);
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(VsnprintfTestCase);
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::C", "[vsnprintf]")
|
||||
{
|
||||
CMP("hi!", "%c%c%c", wxT('h'), wxT('i'), wxT('!'));
|
||||
|
||||
// NOTE:
|
||||
// the NUL characters _can_ be passed to %c to e.g. create strings
|
||||
// with embedded NULs (because strings are not always supposed to be
|
||||
// NUL-terminated).
|
||||
|
||||
DoMisc(14, wxT("Hello \0 World!"), 16, wxT("Hello %c World!"), wxT('\0'));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::D", "[vsnprintf]")
|
||||
{
|
||||
CMP("+123456", "%+d", 123456);
|
||||
CMP("-123456", "%d", -123456);
|
||||
CMP(" 123456", "% d", 123456);
|
||||
CMP(" 123456", "%10d", 123456);
|
||||
CMP("0000123456", "%010d", 123456);
|
||||
CMP("-123456 ", "%-10d", -123456);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::X", "[vsnprintf]")
|
||||
{
|
||||
CMP("ABCD", "%X", 0xABCD);
|
||||
CMP("0XABCD", "%#X", 0xABCD);
|
||||
CMP("0xabcd", "%#x", 0xABCD);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::O", "[vsnprintf]")
|
||||
{
|
||||
CMP("1234567", "%o", 01234567);
|
||||
CMP("01234567", "%#o", 01234567);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::P", "[vsnprintf]")
|
||||
{
|
||||
// The exact format used for "%p" is not specified by the standard and so
|
||||
// varies among different platforms, so we need to expect different results
|
||||
// here (remember that while we test our own wxPrintf() code here, it uses
|
||||
// the system sprintf() for actual formatting so the results are still
|
||||
// different under different systems).
|
||||
|
||||
#if defined(__VISUALC__) || (defined(__MINGW32__) && \
|
||||
(!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO))
|
||||
#if SIZEOF_VOID_P == 4
|
||||
CMP("00ABCDEF", "%p", (void*)0xABCDEF);
|
||||
CMP("00000000", "%p", (void*)nullptr);
|
||||
#elif SIZEOF_VOID_P == 8
|
||||
CMP("0000ABCDEFABCDEF", "%p", (void*)0xABCDEFABCDEF);
|
||||
CMP("0000000000000000", "%p", (void*)nullptr);
|
||||
#endif
|
||||
#elif defined(__MINGW32__)
|
||||
#if SIZEOF_VOID_P == 4
|
||||
CMP("00abcdef", "%p", (void*)0xABCDEF);
|
||||
CMP("00000000", "%p", (void*)nullptr);
|
||||
#elif SIZEOF_VOID_P == 8
|
||||
CMP("0000abcdefabcdef", "%p", (void*)0xABCDEFABCDEF);
|
||||
CMP("0000000000000000", "%p", (void*)nullptr);
|
||||
#endif
|
||||
#elif defined(__GNUG__)
|
||||
// glibc prints pointers as %#x except for null pointers which are printed
|
||||
// as '(nil)'.
|
||||
CMP("0xabcdef", "%p", (void*)0xABCDEF);
|
||||
CMP("(nil)", "%p", (void*)nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::N", "[vsnprintf]")
|
||||
{
|
||||
int nchar;
|
||||
|
||||
wxSnprintf(buf, MAX_TEST_LEN, wxT("%d %s%n\n"), 3, wxT("bears"), &nchar);
|
||||
CHECK( nchar == 7 );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::E", "[vsnprintf]")
|
||||
{
|
||||
// NB: Use at least three digits for the exponent to workaround
|
||||
// differences between MSVC, MinGW and GNU libc.
|
||||
// See wxUSING_MANTISSA_SIZE_3 in testprec.h as well.
|
||||
//
|
||||
// Some examples:
|
||||
// printf("%e",2.342E+02);
|
||||
// -> under MSVC7.1 prints: 2.342000e+002
|
||||
// -> under GNU libc 2.4 prints: 2.342000e+02
|
||||
CMP("2.342000e+112", "%e",2.342E+112);
|
||||
CMP("-2.3420e-112", "%10.4e",-2.342E-112);
|
||||
CMP("-2.3420e-112", "%11.4e",-2.342E-112);
|
||||
CMP(" -2.3420e-112", "%15.4e",-2.342E-112);
|
||||
|
||||
CMP("-0.02342", "%G",-2.342E-02);
|
||||
CMP("3.1415E-116", "%G",3.1415e-116);
|
||||
CMP("0003.141500e+103", "%016e", 3141.5e100);
|
||||
CMP(" 3.141500e+103", "%16e", 3141.5e100);
|
||||
CMP("3.141500e+103 ", "%-16e", 3141.5e100);
|
||||
CMP("3.142e+103", "%010.3e", 3141.5e100);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::F", "[vsnprintf]")
|
||||
{
|
||||
CMP("3.300000", "%5f", 3.3);
|
||||
CMP("3.000000", "%5f", 3.0);
|
||||
CMP("0.000100", "%5f", .999999E-4);
|
||||
CMP("0.000990", "%5f", .99E-3);
|
||||
CMP("3333.000000", "%5f", 3333.0);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::G", "[vsnprintf]")
|
||||
{
|
||||
// NOTE: the same about E() testcase applies here...
|
||||
|
||||
CMP(" 3.3", "%5g", 3.3);
|
||||
CMP(" 3", "%5g", 3.0);
|
||||
CMP("9.99999e-115", "%5g", .999999E-114);
|
||||
CMP("0.00099", "%5g", .99E-3);
|
||||
CMP(" 3333", "%5g", 3333.0);
|
||||
CMP(" 0.01", "%5g", 0.01);
|
||||
|
||||
CMP(" 3", "%5.g", 3.3);
|
||||
CMP(" 3", "%5.g", 3.0);
|
||||
CMP("1e-114", "%5.g", .999999E-114);
|
||||
CMP("0.0001", "%5.g", 1.0E-4);
|
||||
CMP("0.001", "%5.g", .99E-3);
|
||||
CMP("3e+103", "%5.g", 3333.0E100);
|
||||
CMP(" 0.01", "%5.g", 0.01);
|
||||
|
||||
CMP(" 3.3", "%5.2g", 3.3);
|
||||
CMP(" 3", "%5.2g", 3.0);
|
||||
CMP("1e-114", "%5.2g", .999999E-114);
|
||||
CMP("0.00099", "%5.2g", .99E-3);
|
||||
CMP("3.3e+103", "%5.2g", 3333.0E100);
|
||||
CMP(" 0.01", "%5.2g", 0.01);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::S", "[vsnprintf]")
|
||||
{
|
||||
CMP(" abc", "%5s", wxT("abc"));
|
||||
CMP(" a", "%5s", wxT("a"));
|
||||
CMP("abcdefghi", "%5s", wxT("abcdefghi"));
|
||||
CMP("abc ", "%-5s", wxT("abc"));
|
||||
CMP("abcdefghi", "%-5s", wxT("abcdefghi"));
|
||||
|
||||
CMP("abcde", "%.5s", wxT("abcdefghi"));
|
||||
|
||||
// do the same tests but with Unicode characters:
|
||||
|
||||
// Unicode code points from U+03B1 to U+03B9 are the greek letters alpha-iota;
|
||||
// UTF8 encoding of such code points is 0xCEB1 to 0xCEB9
|
||||
|
||||
#define ALPHA "α"
|
||||
// alpha
|
||||
#define ABC "αβγ"
|
||||
// alpha+beta+gamma
|
||||
#define ABCDE "αβγδε"
|
||||
// alpha+beta+gamma+delta+epsilon
|
||||
#define ABCDEFGHI "αβγδεζηθι"
|
||||
// alpha+beta+gamma+delta+epsilon+zeta+eta+theta+iota
|
||||
|
||||
// the 'expected' and 'arg' parameters of this macro are supposed to be
|
||||
// UTF-8 strings
|
||||
#define CMP_UTF8(expected, fmt, arg) \
|
||||
CHECK \
|
||||
( \
|
||||
(int)wxString::FromUTF8(expected).length() == \
|
||||
wxSnprintf(buf, MAX_TEST_LEN, fmt, wxString::FromUTF8(arg)) \
|
||||
); \
|
||||
CHECK( wxString::FromUTF8(expected) == buf )
|
||||
|
||||
CMP_UTF8(" " ABC, "%5s", ABC);
|
||||
CMP_UTF8(" " ALPHA, "%5s", ALPHA);
|
||||
CMP_UTF8(ABCDEFGHI, "%5s", ABCDEFGHI);
|
||||
CMP_UTF8(ABC " ", "%-5s", ABC);
|
||||
CMP_UTF8(ABCDEFGHI, "%-5s", ABCDEFGHI);
|
||||
CMP_UTF8(ABCDE, "%.5s", ABCDEFGHI);
|
||||
|
||||
// test a string which has a NUL character after "ab";
|
||||
// obviously it should be handled exactly like just as "ab"
|
||||
CMP(" ab", "%5s", wxT("ab\0cdefghi"));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::Asterisk", "[vsnprintf]")
|
||||
{
|
||||
CMP(" 0.1", "%*.*f", 10, 1, 0.123);
|
||||
CMP(" 0.1230", "%*.*f", 10, 4, 0.123);
|
||||
CMP("0.1", "%*.*f", 3, 1, 0.123);
|
||||
|
||||
CMP("%0.002", "%%%.*f", 3, 0.0023456789);
|
||||
|
||||
CMP(" a", "%*c", 8, 'a');
|
||||
CMP(" four", "%*s", 8, "four");
|
||||
CMP(" four four", "%*s %*s", 8, "four", 6, "four");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::Percent", "[vsnprintf]")
|
||||
{
|
||||
// some tests without any argument passed through ...
|
||||
CMP("%", "%%");
|
||||
CMP("%%%", "%%%%%%");
|
||||
|
||||
CMP("% abc", "%%%5s", wxT("abc"));
|
||||
CMP("% abc%", "%%%5s%%", wxT("abc"));
|
||||
|
||||
// do not test odd number of '%' symbols as different implementations
|
||||
// of snprintf() give different outputs as this situation is not considered
|
||||
// by any standard (in fact, GCC will also warn you about a spurious % if
|
||||
// you write %%% as argument of some *printf function !)
|
||||
// Compare(wxT("%"), wxT("%%%"));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::LongLong", "[vsnprintf]")
|
||||
{
|
||||
CMP("123456789", "%lld", (wxLongLong_t)123456789);
|
||||
CMP("-123456789", "%lld", (wxLongLong_t)-123456789);
|
||||
|
||||
CMP("123456789", "%llu", (wxULongLong_t)123456789);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
CMP("123456789", "%I64d", (wxLongLong_t)123456789);
|
||||
CMP("123456789abcdef", "%I64x", wxLL(0x123456789abcdef));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::WrongFormatStrings", "[vsnprintf]")
|
||||
{
|
||||
// test how wxVsnprintf() behaves with wrong format string:
|
||||
|
||||
// a missing positional arg should result in an assert
|
||||
WX_ASSERT_FAILS_WITH_ASSERT(
|
||||
wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %3$d"), 1, 2, 3) );
|
||||
|
||||
// positional and non-positionals in the same format string:
|
||||
errno = 0;
|
||||
r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %d %3$d"), 1, 2, 3);
|
||||
CHECK( r == -1 );
|
||||
CHECK( errno == EINVAL );
|
||||
}
|
||||
|
||||
// BigToSmallBuffer() test case helper:
|
||||
template<typename T>
|
||||
void VsnprintfTestCase::DoBigToSmallBuffer(T *buffer, int size)
|
||||
{
|
||||
// Remember that wx*printf could be mapped either to system
|
||||
// implementation or to wx implementation.
|
||||
// In the first case, when the output buffer is too small, the returned
|
||||
// value can be the number of characters required for the output buffer
|
||||
// (conforming to ISO C99; implemented in e.g. GNU libc >= 2.1), or
|
||||
// just a negative number, usually -1; (this is how e.g. MSVC's
|
||||
// *printf() behaves). Luckily, in all implementations, when the
|
||||
// output buffer is too small, it's nonetheless filled up to its max size.
|
||||
//
|
||||
// Note that in the second case (i.e. when we're using our own implementation),
|
||||
// wxVsnprintf() will return the number of characters written in the standard
|
||||
// output or
|
||||
// -1 if there was an error in the format string
|
||||
// maxSize+1 if the output buffer is too small
|
||||
|
||||
wxString errStr;
|
||||
errStr << "The size of the buffer was " << size;
|
||||
std::string errMsg(errStr.mb_str());
|
||||
|
||||
// test without positionals
|
||||
CMPTOSIZE(buffer, size, errMsg,
|
||||
"123456789012 - test - 123 -4.567",
|
||||
"%i%li - test - %d %.3f",
|
||||
123, (long int)456789012, 123, -4.567);
|
||||
|
||||
#if wxUSE_PRINTF_POS_PARAMS
|
||||
// test with positional
|
||||
CMPTOSIZE(buffer, size, errMsg,
|
||||
"-4.567 123 - test - 456789012 123",
|
||||
"%4$.3f %1$i - test - %2$li %3$d",
|
||||
123, (long int)456789012, 123, -4.567);
|
||||
#endif
|
||||
|
||||
// test unicode/ansi conversion specifiers
|
||||
//
|
||||
// NB: we use wxUnsafeSnprintf() as %hs and %hc are invalid in printf
|
||||
// format and gcc would warn about this otherwise
|
||||
|
||||
r = wxUnsafeSnprintf(buffer, size,
|
||||
wxT("unicode string/char: %ls/%lc -- ansi string/char: %hs/%hc"),
|
||||
L"unicode", L'U', "ansi", 'A');
|
||||
wxString expected =
|
||||
wxString(wxT("unicode string/char: unicode/U -- ansi string/char: ansi/A")).Left(size - 1);
|
||||
|
||||
CHECK( expected == buffer );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::BigToSmallBuffer", "[vsnprintf]")
|
||||
{
|
||||
wchar_t bufw[1024], bufw2[16], bufw3[4], bufw4;
|
||||
DoBigToSmallBuffer(bufw, 1024);
|
||||
DoBigToSmallBuffer(bufw2, 16);
|
||||
DoBigToSmallBuffer(bufw3, 4);
|
||||
DoBigToSmallBuffer(&bufw4, 1);
|
||||
|
||||
char bufa[1024], bufa2[16], bufa3[4], bufa4;
|
||||
DoBigToSmallBuffer(bufa, 1024);
|
||||
DoBigToSmallBuffer(bufa2, 16);
|
||||
DoBigToSmallBuffer(bufa3, 4);
|
||||
DoBigToSmallBuffer(&bufa4, 1);
|
||||
}
|
||||
|
||||
// Miscellaneous() test case helper:
|
||||
void VsnprintfTestCase::DoMisc(
|
||||
int expectedLen,
|
||||
const wxString& expectedString,
|
||||
size_t max,
|
||||
const wxChar *format, ...)
|
||||
{
|
||||
const size_t BUFSIZE = MAX_TEST_LEN - 1;
|
||||
size_t i;
|
||||
static int count = 0;
|
||||
|
||||
wxASSERT(max <= BUFSIZE);
|
||||
|
||||
for (i = 0; i < BUFSIZE; i++)
|
||||
buf[i] = '*';
|
||||
buf[BUFSIZE] = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
int n = wxVsnprintf(buf, max, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
// Prepare messages so that it is possible to see from the error which
|
||||
// test was running.
|
||||
wxString errStr, overflowStr;
|
||||
errStr << wxT("No.: ") << ++count << wxT(", expected: ") << expectedLen
|
||||
<< wxT(" '") << expectedString << wxT("', result: ");
|
||||
overflowStr << errStr << wxT("buffer overflow");
|
||||
errStr << n << wxT(" '") << buf << wxT("'");
|
||||
|
||||
// turn them into std::strings
|
||||
std::string errMsg(errStr.mb_str());
|
||||
std::string overflowMsg(overflowStr.mb_str());
|
||||
|
||||
INFO(errMsg);
|
||||
if ( size_t(n) < max )
|
||||
CHECK(expectedLen == n);
|
||||
else
|
||||
CHECK(expectedLen == -1);
|
||||
|
||||
CHECK(expectedString == buf);
|
||||
|
||||
for (i = max; i < BUFSIZE; i++)
|
||||
{
|
||||
INFO(overflowMsg);
|
||||
CHECK(buf[i] == '*');
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::Miscellaneous", "[vsnprintf]")
|
||||
{
|
||||
// expectedLen, expectedString, max, format, ...
|
||||
DoMisc(5, wxT("-1234"), 8, wxT("%d"), -1234);
|
||||
DoMisc(7, wxT("1234567"), 8, wxT("%d"), 1234567);
|
||||
DoMisc(-1, wxT("1234567"), 8, wxT("%d"), 12345678);
|
||||
DoMisc(-1, wxT("-123456"), 8, wxT("%d"), -1234567890);
|
||||
|
||||
DoMisc(6, wxT("123456"), 8, wxT("123456"));
|
||||
DoMisc(7, wxT("1234567"), 8, wxT("1234567"));
|
||||
DoMisc(-1, wxT("1234567"), 8, wxT("12345678"));
|
||||
|
||||
DoMisc(6, wxT("123450"), 8, wxT("12345%d"), 0);
|
||||
DoMisc(7, wxT("1234560"), 8, wxT("123456%d"), 0);
|
||||
DoMisc(-1, wxT("1234567"), 8, wxT("1234567%d"), 0);
|
||||
DoMisc(-1, wxT("1234567"), 8, wxT("12345678%d"), 0);
|
||||
|
||||
DoMisc(6, wxT("12%45%"), 8, wxT("12%%45%%"));
|
||||
DoMisc(7, wxT("12%45%7"), 8, wxT("12%%45%%7"));
|
||||
DoMisc(-1, wxT("12%45%7"), 8, wxT("12%%45%%78"));
|
||||
|
||||
DoMisc(5, wxT("%%%%%"), 6, wxT("%%%%%%%%%%"));
|
||||
DoMisc(6, wxT("%%%%12"), 7, wxT("%%%%%%%%%d"), 12);
|
||||
}
|
||||
|
||||
|
||||
/* (C) Copyright C E Chew
|
||||
*
|
||||
* Feel free to copy, use and distribute this software provided:
|
||||
*
|
||||
* 1. you do not pretend that you wrote it
|
||||
* 2. you leave this copyright notice intact.
|
||||
*/
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::GlibcMisc1", "[vsnprintf]")
|
||||
{
|
||||
CMP(" ", "%5.s", "xyz");
|
||||
CMP(" 33", "%5.f", 33.3);
|
||||
#if defined(wxDEFAULT_MANTISSA_SIZE_3)
|
||||
CMP(" 3e+008", "%8.e", 33.3e7);
|
||||
CMP(" 3E+008", "%8.E", 33.3e7);
|
||||
CMP("3e+001", "%.g", 33.3);
|
||||
CMP("3E+001", "%.G", 33.3);
|
||||
#else
|
||||
CMP(" 3e+08", "%8.e", 33.3e7);
|
||||
CMP(" 3E+08", "%8.E", 33.3e7);
|
||||
CMP("3e+01", "%.g", 33.3);
|
||||
CMP("3E+01", "%.G", 33.3);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::GlibcMisc2", "[vsnprintf]")
|
||||
{
|
||||
int prec;
|
||||
|
||||
prec = 0;
|
||||
CMP("3", "%.*g", prec, 3.3);
|
||||
|
||||
prec = 0;
|
||||
CMP("3", "%.*G", prec, 3.3);
|
||||
|
||||
prec = 0;
|
||||
CMP(" 3", "%7.*G", prec, 3.33);
|
||||
|
||||
prec = 3;
|
||||
CMP(" 041", "%04.*o", prec, 33);
|
||||
|
||||
prec = 7;
|
||||
CMP(" 0000033", "%09.*u", prec, 33);
|
||||
|
||||
prec = 3;
|
||||
CMP(" 021", "%04.*x", prec, 33);
|
||||
|
||||
prec = 3;
|
||||
CMP(" 021", "%04.*X", prec, 33);
|
||||
}
|
||||
|
||||
#endif // wxUSE_WXVSNPRINTF
|
||||
|
||||
Reference in New Issue
Block a user