]>
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
);
43 CPPUNIT_TEST( Sscanf
);
44 CPPUNIT_TEST( RepeatedPrintf
);
45 CPPUNIT_TEST( ArgsValidation
);
46 CPPUNIT_TEST_SUITE_END();
54 void RepeatedPrintf();
55 void ArgsValidation();
57 DECLARE_NO_COPY_CLASS(VarArgTestCase
)
60 // register in the unnamed registry so that these tests are run by default
61 CPPUNIT_TEST_SUITE_REGISTRATION( VarArgTestCase
);
63 // also include in it's own registry so that these tests can be run alone
64 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VarArgTestCase
, "VarArgTestCase" );
66 void VarArgTestCase::StringPrintf()
70 // test passing literals:
71 s
.Printf("%s %i", "foo", 42);
72 CPPUNIT_ASSERT( s
== "foo 42" );
73 s
.Printf("%s %s %i", wxT("bar"), "=", 11);
75 // test passing c_str():
76 CPPUNIT_ASSERT( s
== "bar = 11" );
77 s2
.Printf("(%s)", s
.c_str());
78 CPPUNIT_ASSERT( s2
== "(bar = 11)" );
79 s2
.Printf(wxT("[%s](%s)"), s
.c_str(), "str");
80 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
82 s2
.Printf("%s mailbox", wxString("Opening").c_str());
83 CPPUNIT_ASSERT( s2
== "Opening mailbox" );
85 // test passing wxString directly:
86 s2
.Printf(wxT("[%s](%s)"), s
, "str");
87 CPPUNIT_ASSERT( s2
== "[bar = 11](str)" );
89 // test passing wxCharBufferType<T>:
91 s2
.Printf(wxT("(%s)"), s
.mb_str());
92 CPPUNIT_ASSERT( s2
== "(FooBar)" );
93 s2
.Printf(wxT("value=%s;"), s
.wc_str());
94 CPPUNIT_ASSERT( s2
== "value=FooBar;" );
96 // this tests correct passing of wxCStrData constructed from string
99 s2
.Printf(wxT("foo %s"), !cond
? s
.c_str() : wxT("bar"));
102 void VarArgTestCase::CharPrintf()
107 // test using wchar_t:
108 s
.Printf("char=%c", L
'c');
109 CPPUNIT_ASSERT_EQUAL( "char=c", s
);
111 // test wxUniCharRef:
112 s
.Printf("string[1] is %c", foo
[1]);
113 CPPUNIT_ASSERT_EQUAL( "string[1] is o", s
);
117 s
.Printf("%c to %c", 'a', c
);
118 CPPUNIT_ASSERT_EQUAL( "a to z", s
);
120 // test char used as integer:
122 #pragma warning(disable:4305) // truncation of constant value in VC6
123 #pragma warning(disable:4309) // truncation of constant value
127 #pragma warning(default:4305) // truncation of constant value in VC6
128 #pragma warning(default:4309)
130 s
.Printf("value is %i (int)", c
);
131 CPPUNIT_ASSERT_EQUAL( wxString("value is -16 (int)"), s
);
133 unsigned char u
= 240;
134 s
.Printf("value is %i (int)", u
);
135 CPPUNIT_ASSERT_EQUAL( "value is 240 (int)", s
);
139 void VarArgTestCase::StdString()
141 // test passing std::[w]string
144 std::string
mb("multi-byte");
145 std::string
wc("widechar");
147 s
.Printf("string %s(%i).", mb
, 1);
148 CPPUNIT_ASSERT_EQUAL( "string multi-byte(1).", s
);
150 s
.Printf("string %s(%i).", wc
, 2);
151 CPPUNIT_ASSERT_EQUAL( "string widechar(2).", s
);
153 #endif // wxUSE_STD_STRING
155 void VarArgTestCase::Sscanf()
161 wxString
input("42 test");
163 wxSscanf(input
, "%d %s", &i
, &str
);
164 CPPUNIT_ASSERT( i
== 42 );
165 CPPUNIT_ASSERT( wxStrcmp(str
, "test") == 0 );
168 wxSscanf(input
, L
"%d %s", &i
, &wstr
);
169 CPPUNIT_ASSERT( i
== 42 );
170 CPPUNIT_ASSERT( wxStrcmp(wstr
, "test") == 0 );
173 void VarArgTestCase::RepeatedPrintf()
175 wxCharBuffer
buffer(2);
176 char *p
= buffer
.data();
182 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
183 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
185 s
= wxString::Format("buffer %s, len %d", buffer
, (int)wxStrlen(buffer
));
186 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s
);
189 void VarArgTestCase::ArgsValidation()
196 wxString::Format("a string(%s,%s), ptr %p, int %i",
197 wxString(), "foo", "char* as pointer", 1);
199 // Microsoft has helpfully disabled support for "%n" in their CRT by
200 // default starting from VC8 and somehow even calling
201 // _set_printf_count_output() doesn't help here, so don't use "%n" at all
203 #if wxCHECK_VISUALC_VERSION(8)
204 #define wxNO_PRINTF_PERCENT_N
207 // Similarly, many modern Linux distributions ship with g++ that uses
208 // -D_FORTIFY_SOURCE=2 flag by default and this option prevents "%n" from
209 // being used in a string outside of read-only memory, meaning that it
210 // can't be used in wxString to which we (may, depending on build options)
211 // assign it, so also disable testing of "%n" in this case lest we die with
212 // an abort inside vswprintf().
213 #if defined(_FORTIFY_SOURCE)
214 #if _FORTIFY_SOURCE >= 2
215 #define wxNO_PRINTF_PERCENT_N
219 #ifndef wxNO_PRINTF_PERCENT_N
220 wxString::Format("foo%i%n", 42, &written
);
221 CPPUNIT_ASSERT_EQUAL( 5, written
);
224 // but these are not:
225 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i: too many arguments", 42, 1, 2, 3) );
226 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i", "foo") );
227 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", (void*)this) );
229 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr
) );
231 // we don't check wxNO_PRINTF_PERCENT_N here as these expressions should
232 // result in an assert in our code before the CRT functions are even called
233 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written
) );
234 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr
) );
235 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten
) );
237 // the following test (correctly) fails at compile-time with <type_traits>
238 // and it also (wrongly) fails when using VC6 because it somehow tries to
239 // use (inaccessible) VarArgTestCase copy ctor (FIXME-VC6)
240 #if !defined(HAVE_TYPE_TRAITS) && !defined(HAVE_TR1_TYPE_TRAITS) && \
241 !defined(__VISUALC6__)
242 VarArgTestCase
& somePOD
= *this;
243 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", somePOD
) );
246 // %c should accept integers too
247 wxString::Format("%c", 80);
248 wxString::Format("%c", wxChar(80) + wxChar(1));
250 // check size_t handling
251 size_t len
= sizeof(*this);
253 wxString::Format("%Iu", len
);
255 wxString::Format("%zu", len
);