]> git.saurik.com Git - wxWidgets.git/blame - tests/strings/vararg.cpp
Fix for wxChm
[wxWidgets.git] / tests / strings / vararg.cpp
CommitLineData
c9f78968
VS
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/strings/vararg.cpp
3// Purpose: Test for wx vararg look-alike macros
4// Author: Vaclav Slavik
5// Created: 2007-02-20
6// RCS-ID: $Id$
7// Copyright: (c) 2007 REA Elektronik GmbH
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ----------------------------------------------------------------------------
12// headers
13// ----------------------------------------------------------------------------
14
15#include "testprec.h"
16
17#ifdef __BORLANDC__
18 #pragma hdrstop
19#endif
20
21#ifndef WX_PRECOMP
22 #include "wx/wx.h"
23#endif // WX_PRECOMP
24
25#include "wx/string.h"
26
27// ----------------------------------------------------------------------------
28// test class
29// ----------------------------------------------------------------------------
30
31class VarArgTestCase : public CppUnit::TestCase
32{
33public:
34 VarArgTestCase() {}
35
36private:
37 CPPUNIT_TEST_SUITE( VarArgTestCase );
38 CPPUNIT_TEST( StringPrintf );
47346406 39 CPPUNIT_TEST( CharPrintf );
76fc401a
VS
40#if wxUSE_STD_STRING
41 CPPUNIT_TEST( StdString );
42#endif
eb6cb207 43 CPPUNIT_TEST( Sscanf );
2f539d95 44 CPPUNIT_TEST( RepeatedPrintf );
ad6e5c47 45 CPPUNIT_TEST( ArgsValidation );
c9f78968
VS
46 CPPUNIT_TEST_SUITE_END();
47
48 void StringPrintf();
47346406 49 void CharPrintf();
76fc401a
VS
50#if wxUSE_STD_STRING
51 void StdString();
52#endif
eb6cb207 53 void Sscanf();
2f539d95 54 void RepeatedPrintf();
ad6e5c47 55 void ArgsValidation();
c9f78968
VS
56
57 DECLARE_NO_COPY_CLASS(VarArgTestCase)
58};
59
60// register in the unnamed registry so that these tests are run by default
61CPPUNIT_TEST_SUITE_REGISTRATION( VarArgTestCase );
62
63// also include in it's own registry so that these tests can be run alone
64CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VarArgTestCase, "VarArgTestCase" );
65
66void VarArgTestCase::StringPrintf()
67{
68 wxString s, s2;
69
359bd4d1 70 // test passing literals:
c9f78968
VS
71 s.Printf("%s %i", "foo", 42);
72 CPPUNIT_ASSERT( s == "foo 42" );
9a83f860 73 s.Printf("%s %s %i", wxT("bar"), "=", 11);
359bd4d1
VS
74
75 // test passing c_str():
c9f78968
VS
76 CPPUNIT_ASSERT( s == "bar = 11" );
77 s2.Printf("(%s)", s.c_str());
78 CPPUNIT_ASSERT( s2 == "(bar = 11)" );
9a83f860 79 s2.Printf(wxT("[%s](%s)"), s.c_str(), "str");
c9f78968
VS
80 CPPUNIT_ASSERT( s2 == "[bar = 11](str)" );
81
0dc8d224
VS
82 s2.Printf("%s mailbox", wxString("Opening").c_str());
83 CPPUNIT_ASSERT( s2 == "Opening mailbox" );
84
359bd4d1 85 // test passing wxString directly:
9a83f860 86 s2.Printf(wxT("[%s](%s)"), s, "str");
c9f78968 87 CPPUNIT_ASSERT( s2 == "[bar = 11](str)" );
359bd4d1
VS
88
89 // test passing wxCharBufferType<T>:
90 s = "FooBar";
9a83f860 91 s2.Printf(wxT("(%s)"), s.mb_str());
359bd4d1 92 CPPUNIT_ASSERT( s2 == "(FooBar)" );
9a83f860 93 s2.Printf(wxT("value=%s;"), s.wc_str());
359bd4d1 94 CPPUNIT_ASSERT( s2 == "value=FooBar;" );
baf3d1dc
VS
95
96 // this tests correct passing of wxCStrData constructed from string
97 // literal:
98 bool cond = true;
9a83f860 99 s2.Printf(wxT("foo %s"), !cond ? s.c_str() : wxT("bar"));
47346406
VS
100}
101
102void VarArgTestCase::CharPrintf()
103{
104 wxString foo("foo");
105 wxString s;
106
107 // test using wchar_t:
108 s.Printf("char=%c", L'c');
1de532f5 109 CPPUNIT_ASSERT_EQUAL( "char=c", s );
47346406
VS
110
111 // test wxUniCharRef:
112 s.Printf("string[1] is %c", foo[1]);
1de532f5 113 CPPUNIT_ASSERT_EQUAL( "string[1] is o", s );
47346406
VS
114
115 // test char
116 char c = 'z';
117 s.Printf("%c to %c", 'a', c);
1de532f5 118 CPPUNIT_ASSERT_EQUAL( "a to z", s );
47346406
VS
119
120 // test char used as integer:
2452025c 121 #ifdef _MSC_VER
5098c258 122 #pragma warning(disable:4305) // truncation of constant value in VC6
2452025c
VZ
123 #pragma warning(disable:4309) // truncation of constant value
124 #endif
47346406 125 c = 240;
2452025c 126 #ifdef _MSC_VER
5098c258 127 #pragma warning(default:4305) // truncation of constant value in VC6
2452025c
VZ
128 #pragma warning(default:4309)
129 #endif
47346406 130 s.Printf("value is %i (int)", c);
1de532f5 131 CPPUNIT_ASSERT_EQUAL( wxString("value is -16 (int)"), s );
76fc401a 132
47346406
VS
133 unsigned char u = 240;
134 s.Printf("value is %i (int)", u);
1de532f5 135 CPPUNIT_ASSERT_EQUAL( "value is 240 (int)", s );
76fc401a
VS
136}
137
138#if wxUSE_STD_STRING
139void VarArgTestCase::StdString()
140{
141 // test passing std::[w]string
142 wxString s;
143
144 std::string mb("multi-byte");
145 std::string wc("widechar");
146
147 s.Printf("string %s(%i).", mb, 1);
1de532f5 148 CPPUNIT_ASSERT_EQUAL( "string multi-byte(1).", s );
76fc401a
VS
149
150 s.Printf("string %s(%i).", wc, 2);
1de532f5 151 CPPUNIT_ASSERT_EQUAL( "string widechar(2).", s );
c9f78968 152}
76fc401a 153#endif // wxUSE_STD_STRING
eb6cb207
VS
154
155void VarArgTestCase::Sscanf()
156{
157 int i = 0;
158 char str[20];
159 wchar_t wstr[20];
160
161 wxString input("42 test");
162
163 wxSscanf(input, "%d %s", &i, &str);
164 CPPUNIT_ASSERT( i == 42 );
165 CPPUNIT_ASSERT( wxStrcmp(str, "test") == 0 );
166
167 i = 0;
168 wxSscanf(input, L"%d %s", &i, &wstr);
169 CPPUNIT_ASSERT( i == 42 );
170 CPPUNIT_ASSERT( wxStrcmp(wstr, "test") == 0 );
171}
2f539d95
VS
172
173void VarArgTestCase::RepeatedPrintf()
174{
175 wxCharBuffer buffer(2);
176 char *p = buffer.data();
177 *p = 'h';
178 p++;
179 *p = 'i';
180
181 wxString s;
38914d5a 182 s = wxString::Format("buffer %s, len %d", buffer, (int)wxStrlen(buffer));
2f539d95
VS
183 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s);
184
38914d5a 185 s = wxString::Format("buffer %s, len %d", buffer, (int)wxStrlen(buffer));
2f539d95
VS
186 CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s);
187}
ad6e5c47
VS
188
189void VarArgTestCase::ArgsValidation()
190{
191 void *ptr = this;
192 int written;
193 short int swritten;
194
195 // these are valid:
196 wxString::Format("a string(%s,%s), ptr %p, int %i",
197 wxString(), "foo", "char* as pointer", 1);
198
01307821
VZ
199 // Microsoft has helpfully disabled support for "%n" in their CRT by
200 // default starting from VC8 and somehow even calling
1cf9a80c
VZ
201 // _set_printf_count_output() doesn't help here, so don't use "%n" at all
202 // with it.
203#if wxCHECK_VISUALC_VERSION(8)
204 #define wxNO_PRINTF_PERCENT_N
205#endif // VC8+
206
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
216 #endif
217#endif
218
219#ifndef wxNO_PRINTF_PERCENT_N
ad6e5c47
VS
220 wxString::Format("foo%i%n", 42, &written);
221 CPPUNIT_ASSERT_EQUAL( 5, written );
1cf9a80c 222#endif
ad6e5c47
VS
223
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) );
228
32f6c515
VZ
229 // for some reason assert is not generated with VC6, don't know what's
230 // going there so disable it for now to make the test suite pass when using
231 // this compiler until someone has time to debug this (FIXME-VC6)
232#ifndef __VISUALC6__
ad6e5c47 233 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr) );
32f6c515 234#endif
ad6e5c47 235
1cf9a80c
VZ
236 // we don't check wxNO_PRINTF_PERCENT_N here as these expressions should
237 // result in an assert in our code before the CRT functions are even called
ad6e5c47
VS
238 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written) );
239 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr) );
240 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten) );
241
71e33c75
VZ
242 // the following test (correctly) fails at compile-time with <type_traits>
243 // and it also (wrongly) fails when using VC6 because it somehow tries to
244 // use (inaccessible) VarArgTestCase copy ctor (FIXME-VC6)
245#if !defined(HAVE_TYPE_TRAITS) && !defined(HAVE_TR1_TYPE_TRAITS) && \
246 !defined(__VISUALC6__)
ad6e5c47
VS
247 VarArgTestCase& somePOD = *this;
248 WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", somePOD) );
249#endif
3b12da35
VS
250
251 // %c should accept integers too
252 wxString::Format("%c", 80);
253 wxString::Format("%c", wxChar(80) + wxChar(1));
b113edcd
VS
254
255 // check size_t handling
256 size_t len = sizeof(*this);
257#ifdef __WXMSW__
258 wxString::Format("%Iu", len);
259#else
260 wxString::Format("%zu", len);
261#endif
ad6e5c47 262}