]>
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
7 // Copyright: (c) 2007 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ----------------------------------------------------------------------------
13 // ----------------------------------------------------------------------------
25 #include "wx/string.h"
27 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
31 class VarArgTestCase
: public CppUnit::TestCase
37 CPPUNIT_TEST_SUITE( VarArgTestCase
);
38 CPPUNIT_TEST( StringPrintf
);
39 CPPUNIT_TEST( CharPrintf
);
41 CPPUNIT_TEST( StdString
);
44 CPPUNIT_TEST( LongLongPrintf
);
46 CPPUNIT_TEST( Sscanf
);
47 CPPUNIT_TEST( RepeatedPrintf
);
48 CPPUNIT_TEST( ArgsValidation
);
49 CPPUNIT_TEST_SUITE_END();
57 void LongLongPrintf();
60 void RepeatedPrintf();
61 void ArgsValidation();
63 DECLARE_NO_COPY_CLASS(VarArgTestCase
)
66 // register in the unnamed registry so that these tests are run by default
67 CPPUNIT_TEST_SUITE_REGISTRATION( VarArgTestCase
);
69 // also include in its own registry so that these tests can be run alone
70 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VarArgTestCase
, "VarArgTestCase" );
72 void VarArgTestCase::StringPrintf()
76 // test passing literals:
77 s
.Printf("%s %i", "foo", 42);
78 CPPUNIT_ASSERT( s
== "foo 42" );
79 s
.Printf("%s %s %i", wxT("bar"), "=", 11);
81 // test passing c_str():
82 CPPUNIT_ASSERT( s
== "bar = 11" );
83 s2
.Printf("(%s)", s
.c_str());
84 CPPUNIT_ASSERT( s2
== "(bar = 11)" );
85 s2
.Printf(wxT("[%s](%s)"), s
.c_str(), "str");
86 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
88 s2
.Printf("%s mailbox", wxString("Opening").c_str());
89 CPPUNIT_ASSERT( s2
== "Opening mailbox" );
91 // test passing wxString directly:
92 s2
.Printf(wxT("[%s](%s)"), s
, "str");
93 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
95 // test passing wxCharBufferType<T>:
97 s2
.Printf(wxT("(%s)"), s
.mb_str());
98 CPPUNIT_ASSERT( s2
== "(FooBar)" );
99 s2
.Printf(wxT("value=%s;"), s
.wc_str());
100 CPPUNIT_ASSERT( s2
== "value=FooBar;" );
102 // this tests correct passing of wxCStrData constructed from string
105 s2
.Printf(wxT("foo %s"), !cond
? s
.c_str() : wxT("bar"));
108 void VarArgTestCase::CharPrintf()
113 // test using wchar_t:
114 s
.Printf("char=%c", L
'c');
115 CPPUNIT_ASSERT_EQUAL( "char=c", s
);
117 // test wxUniCharRef:
118 s
.Printf("string[1] is %c", foo
[1]);
119 CPPUNIT_ASSERT_EQUAL( "string[1] is o", s
);
123 s
.Printf("%c to %c", 'a', c
);
124 CPPUNIT_ASSERT_EQUAL( "a to z", s
);
126 // test char used as integer:
128 #pragma warning(disable:4305) // truncation of constant value in VC6
129 #pragma warning(disable:4309) // truncation of constant value
133 #pragma warning(default:4305) // truncation of constant value in VC6
134 #pragma warning(default:4309)
136 s
.Printf("value is %i (int)", c
);
137 CPPUNIT_ASSERT_EQUAL( wxString("value is -16 (int)"), s
);
139 unsigned char u
= 240;
140 s
.Printf("value is %i (int)", u
);
141 CPPUNIT_ASSERT_EQUAL( "value is 240 (int)", s
);
145 void VarArgTestCase::StdString()
147 // test passing std::[w]string
150 std::string
mb("multi-byte");
151 std::string
wc("widechar");
153 s
.Printf("string %s(%i).", mb
, 1);
154 CPPUNIT_ASSERT_EQUAL( "string multi-byte(1).", s
);
156 s
.Printf("string %s(%i).", wc
, 2);
157 CPPUNIT_ASSERT_EQUAL( "string widechar(2).", s
);
159 #endif // wxUSE_STD_STRING
162 void VarArgTestCase::LongLongPrintf()
164 const char * const llfmt
= "%" wxLongLongFmtSpec
"d";
166 CPPUNIT_ASSERT_EQUAL( "17", wxString::Format(llfmt
, wxLL(17)) );
168 wxLongLong ll
= 1234567890;
169 CPPUNIT_ASSERT_EQUAL( "1234567890", wxString::Format(llfmt
, ll
) );
171 #endif // wxUSE_LONGLONG
173 void VarArgTestCase::Sscanf()
179 wxString
input("42 test");
181 wxSscanf(input
, "%d %s", &i
, &str
);
182 CPPUNIT_ASSERT( i
== 42 );
183 CPPUNIT_ASSERT( wxStrcmp(str
, "test") == 0 );
186 wxSscanf(input
, L
"%d %s", &i
, &wstr
);
187 CPPUNIT_ASSERT( i
== 42 );
188 CPPUNIT_ASSERT( wxStrcmp(wstr
, "test") == 0 );
191 void VarArgTestCase::RepeatedPrintf()
193 wxCharBuffer
buffer(2);
194 char *p
= buffer
.data();
200 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
201 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
203 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
204 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
207 void VarArgTestCase::ArgsValidation()
214 wxString::Format("a string(%s,%s), ptr %p, int %i",
215 wxString(), "foo", "char* as pointer", 1);
217 // Microsoft has helpfully disabled support for "%n" in their CRT by
218 // default starting from VC8 and somehow even calling
219 // _set_printf_count_output() doesn't help here, so don't use "%n" at all
221 #if wxCHECK_VISUALC_VERSION(8)
222 #define wxNO_PRINTF_PERCENT_N
225 // Similarly, many modern Linux distributions ship with g++ that uses
226 // -D_FORTIFY_SOURCE=2 flag by default and this option prevents "%n" from
227 // being used in a string outside of read-only memory, meaning that it
228 // can't be used in wxString to which we (may, depending on build options)
229 // assign it, so also disable testing of "%n" in this case lest we die with
230 // an abort inside vswprintf().
231 #if defined(_FORTIFY_SOURCE)
232 #if _FORTIFY_SOURCE >= 2
233 #define wxNO_PRINTF_PERCENT_N
237 #ifndef wxNO_PRINTF_PERCENT_N
238 wxString::Format("foo%i%n", 42, &written
);
239 CPPUNIT_ASSERT_EQUAL( 5, written
);
242 // but these are not:
243 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i: too many arguments", 42, 1, 2, 3) );
244 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i", "foo") );
245 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", (void*)this) );
247 // for some reason assert is not generated with VC6, don't know what's
248 // going there so disable it for now to make the test suite pass when using
249 // this compiler until someone has time to debug this (FIXME-VC6)
251 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr
) );
254 // we don't check wxNO_PRINTF_PERCENT_N here as these expressions should
255 // result in an assert in our code before the CRT functions are even called
256 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written
) );
257 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr
) );
258 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten
) );
260 // the following test (correctly) fails at compile-time with <type_traits>
261 #if !defined(HAVE_TYPE_TRAITS) && !defined(HAVE_TR1_TYPE_TRAITS)
263 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", obj
) );
266 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", ref
) );
269 // %c should accept integers too
270 wxString::Format("%c", 80);
271 wxString::Format("%c", wxChar(80) + wxChar(1));
273 // check size_t handling
274 size_t len
= sizeof(*this);
276 wxString::Format("%Iu", len
);
278 wxString::Format("%zu", len
);