]>
git.saurik.com Git - wxWidgets.git/blob - tests/strings/vararg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/strings/vararg.cpp
3 // Purpose: Test for wx vararg look-alike macros
4 // Author: Vaclav Slavik
6 // Copyright: (c) 2007 REA Elektronik GmbH
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
24 #include "wx/string.h"
26 // ----------------------------------------------------------------------------
28 // ----------------------------------------------------------------------------
30 class VarArgTestCase
: public CppUnit::TestCase
36 CPPUNIT_TEST_SUITE( VarArgTestCase
);
37 CPPUNIT_TEST( StringPrintf
);
38 CPPUNIT_TEST( CharPrintf
);
40 CPPUNIT_TEST( StdString
);
43 CPPUNIT_TEST( LongLongPrintf
);
45 CPPUNIT_TEST( Sscanf
);
46 CPPUNIT_TEST( RepeatedPrintf
);
47 CPPUNIT_TEST( ArgsValidation
);
48 CPPUNIT_TEST_SUITE_END();
56 void LongLongPrintf();
59 void RepeatedPrintf();
60 void ArgsValidation();
62 DECLARE_NO_COPY_CLASS(VarArgTestCase
)
65 // register in the unnamed registry so that these tests are run by default
66 CPPUNIT_TEST_SUITE_REGISTRATION( VarArgTestCase
);
68 // also include in its own registry so that these tests can be run alone
69 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VarArgTestCase
, "VarArgTestCase" );
71 void VarArgTestCase::StringPrintf()
75 // test passing literals:
76 s
.Printf("%s %i", "foo", 42);
77 CPPUNIT_ASSERT( s
== "foo 42" );
78 s
.Printf("%s %s %i", wxT("bar"), "=", 11);
80 // test passing c_str():
81 CPPUNIT_ASSERT( s
== "bar = 11" );
82 s2
.Printf("(%s)", s
.c_str());
83 CPPUNIT_ASSERT( s2
== "(bar = 11)" );
84 s2
.Printf(wxT("[%s](%s)"), s
.c_str(), "str");
85 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
87 s2
.Printf("%s mailbox", wxString("Opening").c_str());
88 CPPUNIT_ASSERT( s2
== "Opening mailbox" );
90 // test passing wxString directly:
91 s2
.Printf(wxT("[%s](%s)"), s
, "str");
92 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
94 // test passing wxCharBufferType<T>:
96 s2
.Printf(wxT("(%s)"), s
.mb_str());
97 CPPUNIT_ASSERT( s2
== "(FooBar)" );
98 s2
.Printf(wxT("value=%s;"), s
.wc_str());
99 CPPUNIT_ASSERT( s2
== "value=FooBar;" );
101 // this tests correct passing of wxCStrData constructed from string
104 s2
.Printf(wxT("foo %s"), !cond
? s
.c_str() : wxT("bar"));
107 void VarArgTestCase::CharPrintf()
112 // test using wchar_t:
113 s
.Printf("char=%c", L
'c');
114 CPPUNIT_ASSERT_EQUAL( "char=c", s
);
116 // test wxUniCharRef:
117 s
.Printf("string[1] is %c", foo
[1]);
118 CPPUNIT_ASSERT_EQUAL( "string[1] is o", s
);
122 s
.Printf("%c to %c", 'a', c
);
123 CPPUNIT_ASSERT_EQUAL( "a to z", s
);
125 // test char used as integer:
127 #pragma warning(disable:4305) // truncation of constant value in VC6
128 #pragma warning(disable:4309) // truncation of constant value
132 #pragma warning(default:4305) // truncation of constant value in VC6
133 #pragma warning(default:4309)
135 s
.Printf("value is %i (int)", c
);
136 CPPUNIT_ASSERT_EQUAL( wxString("value is -16 (int)"), s
);
138 unsigned char u
= 240;
139 s
.Printf("value is %i (int)", u
);
140 CPPUNIT_ASSERT_EQUAL( "value is 240 (int)", s
);
144 void VarArgTestCase::StdString()
146 // test passing std::[w]string
149 std::string
mb("multi-byte");
150 std::string
wc("widechar");
152 s
.Printf("string %s(%i).", mb
, 1);
153 CPPUNIT_ASSERT_EQUAL( "string multi-byte(1).", s
);
155 s
.Printf("string %s(%i).", wc
, 2);
156 CPPUNIT_ASSERT_EQUAL( "string widechar(2).", s
);
158 #endif // wxUSE_STD_STRING
161 void VarArgTestCase::LongLongPrintf()
163 const char * const llfmt
= "%" wxLongLongFmtSpec
"d";
165 CPPUNIT_ASSERT_EQUAL( "17", wxString::Format(llfmt
, wxLL(17)) );
167 wxLongLong ll
= 1234567890;
168 CPPUNIT_ASSERT_EQUAL( "1234567890", wxString::Format(llfmt
, ll
) );
170 #endif // wxUSE_LONGLONG
172 void VarArgTestCase::Sscanf()
178 wxString
input("42 test");
180 wxSscanf(input
, "%d %s", &i
, &str
);
181 CPPUNIT_ASSERT( i
== 42 );
182 CPPUNIT_ASSERT( wxStrcmp(str
, "test") == 0 );
185 wxSscanf(input
, L
"%d %s", &i
, &wstr
);
186 CPPUNIT_ASSERT( i
== 42 );
187 CPPUNIT_ASSERT( wxStrcmp(wstr
, "test") == 0 );
190 void VarArgTestCase::RepeatedPrintf()
192 wxCharBuffer
buffer(2);
193 char *p
= buffer
.data();
199 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
200 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
202 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
203 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
206 void VarArgTestCase::ArgsValidation()
213 wxString::Format("a string(%s,%s), ptr %p, int %i",
214 wxString(), "foo", "char* as pointer", 1);
216 // Microsoft has helpfully disabled support for "%n" in their CRT by
217 // default starting from VC8 and somehow even calling
218 // _set_printf_count_output() doesn't help here, so don't use "%n" at all
220 #if wxCHECK_VISUALC_VERSION(8)
221 #define wxNO_PRINTF_PERCENT_N
224 // Similarly, many modern Linux distributions ship with g++ that uses
225 // -D_FORTIFY_SOURCE=2 flag by default and this option prevents "%n" from
226 // being used in a string outside of read-only memory, meaning that it
227 // can't be used in wxString to which we (may, depending on build options)
228 // assign it, so also disable testing of "%n" in this case lest we die with
229 // an abort inside vswprintf().
230 #if defined(_FORTIFY_SOURCE)
231 #if _FORTIFY_SOURCE >= 2
232 #define wxNO_PRINTF_PERCENT_N
236 #ifndef wxNO_PRINTF_PERCENT_N
237 wxString::Format("foo%i%n", 42, &written
);
238 CPPUNIT_ASSERT_EQUAL( 5, written
);
241 // but these are not:
242 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i: too many arguments", 42, 1, 2, 3) );
243 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i", "foo") );
244 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", (void*)this) );
246 // for some reason assert is not generated with VC6, don't know what's
247 // going there so disable it for now to make the test suite pass when using
248 // this compiler until someone has time to debug this (FIXME-VC6)
250 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr
) );
253 // we don't check wxNO_PRINTF_PERCENT_N here as these expressions should
254 // result in an assert in our code before the CRT functions are even called
255 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written
) );
256 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr
) );
257 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten
) );
259 // the following test (correctly) fails at compile-time with <type_traits>
260 #if !defined(HAVE_TYPE_TRAITS) && !defined(HAVE_TR1_TYPE_TRAITS)
262 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", obj
) );
265 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", ref
) );
268 // %c should accept integers too
269 wxString::Format("%c", 80);
270 wxString::Format("%c", wxChar(80) + wxChar(1));
272 // check size_t handling
273 size_t len
= sizeof(*this);
275 wxString::Format("%Iu", len
);
277 wxString::Format("%zu", len
);