]> git.saurik.com Git - wxWidgets.git/blame - tests/formatconverter/formatconvertertest.cpp
wxRTC: save and load the 'shown' status in case there's a situation where layout...
[wxWidgets.git] / tests / formatconverter / formatconvertertest.cpp
CommitLineData
7d5ab151
VS
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/formatconverter/formatconverter.cpp
3// Purpose: Test wxFormatConverter
4// Author: Mike Wetherell
7d5ab151 5// Copyright: (c) 2004 Mike Wetherell
526954c5 6// Licence: wxWindows licence
7d5ab151
VS
7///////////////////////////////////////////////////////////////////////////////
8
9//
10// Notes:
11//
12// The conversions wxFormatConverter currently does are as follows:
13//
14// %s, %lS -> %ls
15// %S, %hS -> %s
16// %c, %lC -> %lc
17// %C, %hC -> %c
18//
19// %hs and %hc stay the same.
20//
21// %S and %C aren't actually in the ISO C or C++ standards, but they can be
22// avoided when writing portable code.
23//
24// Nor are %hs or %hc in the standards, which means wxWidgets currently doesn't
25// have a specifier for 'char' types that is ok for all builds and platforms.
26//
27// The effect of using %hs/%hc is undefined, though RTLs are quite likely
28// to just ignore the 'h', so maybe it works as required even though it's
29// not legal.
30//
31// I've put in some checks, such as this which will flag up any platforms
32// where this is not the case:
33//
9a83f860 34// CPPUNIT_ASSERT(wxString::Format(wxT("%hs"), "test") == wxT("test"));
7d5ab151
VS
35//
36
7d5ab151 37// For compilers that support precompilation, includes "wx/wx.h".
8899b155 38#include "testprec.h"
7d5ab151
VS
39
40#ifdef __BORLANDC__
41 #pragma hdrstop
42#endif
43
44// for all others, include the necessary headers
45#ifndef WX_PRECOMP
46 #include "wx/wx.h"
47#endif
48
7d5ab151 49
3e5f6c1c
WS
50using CppUnit::TestCase;
51using std::string;
7d5ab151
VS
52
53///////////////////////////////////////////////////////////////////////////////
54// The test case
55//
56// wxFormatConverter only changes %s, %c, %S and %C, all others are treated
57// equally, therefore it is enough to choose just one other for testing, %d
58// will do.
59
60class FormatConverterTestCase : public TestCase
61{
62 CPPUNIT_TEST_SUITE(FormatConverterTestCase);
63 CPPUNIT_TEST(format_d);
64 CPPUNIT_TEST(format_hd);
65 CPPUNIT_TEST(format_ld);
66 CPPUNIT_TEST(format_s);
67 CPPUNIT_TEST(format_hs);
68 CPPUNIT_TEST(format_ls);
69 CPPUNIT_TEST(format_c);
70 CPPUNIT_TEST(format_hc);
71 CPPUNIT_TEST(format_lc);
7d5ab151
VS
72 CPPUNIT_TEST(format_S);
73 CPPUNIT_TEST(format_hS);
74 CPPUNIT_TEST(format_lS);
75 CPPUNIT_TEST(format_C);
76 CPPUNIT_TEST(format_hC);
77 CPPUNIT_TEST(format_lC);
78 CPPUNIT_TEST(testLonger);
7d5ab151
VS
79 CPPUNIT_TEST_SUITE_END();
80
7d5ab151
VS
81 void format_d();
82 void format_hd();
83 void format_ld();
84 void format_s();
85 void format_hs();
86 void format_ls();
87 void format_c();
88 void format_hc();
89 void format_lc();
90
7d5ab151
VS
91 void format_S();
92 void format_hS();
93 void format_lS();
94 void format_C();
95 void format_hC();
96 void format_lC();
97 void testLonger();
98
50e27899
VS
99 void doTest(const char *input, const char *expectedScanf,
100 const char *expectedUtf8,
101 const char *expectedWcharUnix,
102 const char *expectedWcharWindows);
103 void check(const wxString& input, const wxString& expectedScanf,
104 const wxString& expectedUtf8,
105 const wxString& expectedWcharUnix,
106 const wxString& expectedWcharWindows);
7d5ab151
VS
107};
108
109void FormatConverterTestCase::format_d()
110{
50e27899 111 doTest("d", "d", "d", "d", "d");
9a83f860
VZ
112 CPPUNIT_ASSERT(wxString::Format(wxT("%d"), 255) == wxT("255"));
113 CPPUNIT_ASSERT(wxString::Format(wxT("%05d"), 255) == wxT("00255"));
114 CPPUNIT_ASSERT(wxString::Format(wxT("% 5d"), 255) == wxT(" 255"));
115 CPPUNIT_ASSERT(wxString::Format(wxT("% 5d"), -255) == wxT(" -255"));
116 CPPUNIT_ASSERT(wxString::Format(wxT("%-5d"), -255) == wxT("-255 "));
117 CPPUNIT_ASSERT(wxString::Format(wxT("%+5d"), 255) == wxT(" +255"));
118 CPPUNIT_ASSERT(wxString::Format(wxT("%*d"), 5, 255) == wxT(" 255"));
7d5ab151
VS
119}
120
121void FormatConverterTestCase::format_hd()
122{
50e27899 123 doTest("hd", "hd", "hd", "hd", "hd");
7d5ab151 124 short s = 32767;
9a83f860 125 CPPUNIT_ASSERT(wxString::Format(wxT("%hd"), s) == wxT("32767"));
7d5ab151
VS
126}
127
128void FormatConverterTestCase::format_ld()
129{
50e27899 130 doTest("ld", "ld", "ld", "ld", "ld");
7d5ab151 131 long l = 2147483647L;
9a83f860 132 CPPUNIT_ASSERT(wxString::Format(wxT("%ld"), l) == wxT("2147483647"));
7d5ab151
VS
133}
134
135void FormatConverterTestCase::format_s()
136{
50e27899 137 doTest("s", "ls", "s", "ls", "s");
9a83f860
VZ
138 CPPUNIT_ASSERT(wxString::Format(wxT("%s!"), wxT("test")) == wxT("test!"));
139 CPPUNIT_ASSERT(wxString::Format(wxT("%6s!"), wxT("test")) == wxT(" test!"));
140 CPPUNIT_ASSERT(wxString::Format(wxT("%-6s!"), wxT("test")) == wxT("test !"));
141 CPPUNIT_ASSERT(wxString::Format(wxT("%.6s!"), wxT("test")) == wxT("test!"));
142 CPPUNIT_ASSERT(wxString::Format(wxT("%6.4s!"), wxT("testing")) == wxT(" test!"));
7d5ab151
VS
143}
144
145void FormatConverterTestCase::format_hs()
146{
50e27899 147 doTest("hs", "hs", "s", "ls", "s");
9a83f860
VZ
148 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%hs!")), "test") == wxT("test!"));
149 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%6hs!")), "test") == wxT(" test!"));
150 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%-6hs!")), "test") == wxT("test !"));
151 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%.6hs!")), "test") == wxT("test!"));
152 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%6.4hs!")), "testing") == wxT(" test!"));
7d5ab151
VS
153}
154
155void FormatConverterTestCase::format_ls()
156{
50e27899 157 doTest("ls", "ls", "s", "ls", "s");
9a83f860
VZ
158 CPPUNIT_ASSERT(wxString::Format(wxT("%ls!"), L"test") == wxT("test!"));
159 CPPUNIT_ASSERT(wxString::Format(wxT("%6ls!"), L"test") == wxT(" test!"));
160 CPPUNIT_ASSERT(wxString::Format(wxT("%-6ls!"), L"test") == wxT("test !"));
161 CPPUNIT_ASSERT(wxString::Format(wxT("%.6ls!"), L"test") == wxT("test!"));
162 CPPUNIT_ASSERT(wxString::Format(wxT("%6.4ls!"), L"testing") == wxT(" test!"));
7d5ab151
VS
163}
164
165void FormatConverterTestCase::format_c()
166{
093315a1 167 doTest("c", "lc", "lc", "lc", "c");
9a83f860
VZ
168 CPPUNIT_ASSERT(wxString::Format(wxT("%c"), wxT('x')) == wxT("x"));
169 CPPUNIT_ASSERT(wxString::Format(wxT("%2c"), wxT('x')) == wxT(" x"));
170 CPPUNIT_ASSERT(wxString::Format(wxT("%-2c"), wxT('x')) == wxT("x "));
7d5ab151
VS
171}
172
173void FormatConverterTestCase::format_hc()
174{
093315a1 175 doTest("hc", "hc", "lc", "lc", "c");
9a83f860
VZ
176 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%hc")), 'x') == wxT("x"));
177 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%2hc")), 'x') == wxT(" x"));
178 CPPUNIT_ASSERT(wxString::Format(wxString(wxT("%-2hc")), 'x') == wxT("x "));
7d5ab151
VS
179}
180
181void FormatConverterTestCase::format_lc()
182{
093315a1 183 doTest("lc", "lc", "lc", "lc", "c");
9a83f860
VZ
184 CPPUNIT_ASSERT(wxString::Format(wxT("%lc"), L'x') == wxT("x"));
185 CPPUNIT_ASSERT(wxString::Format(wxT("%2lc"), L'x') == wxT(" x"));
186 CPPUNIT_ASSERT(wxString::Format(wxT("%-2lc"), L'x') == wxT("x "));
7d5ab151
VS
187}
188
7d5ab151 189
50e27899
VS
190void FormatConverterTestCase::format_S()
191 { doTest("S", "s", "s", "ls", "s"); }
192void FormatConverterTestCase::format_hS()
193 { doTest("hS", "s", "s", "ls", "s"); }
194void FormatConverterTestCase::format_lS()
195 { doTest("lS", "ls", "s", "ls", "s"); }
7d5ab151 196
50e27899 197void FormatConverterTestCase::format_C()
093315a1 198 { doTest("C", "c", "lc", "lc", "c"); }
50e27899 199void FormatConverterTestCase::format_hC()
093315a1 200 { doTest("hC", "c", "lc", "lc", "c"); }
50e27899 201void FormatConverterTestCase::format_lC()
093315a1 202 { doTest("lC", "lc", "lc", "lc", "c"); }
7d5ab151
VS
203
204// It's possible that although a format converts correctly alone, it leaves
205// the converter in a bad state that will affect subsequent formats, so
206// check with a selection of longer patterns.
207//
208void FormatConverterTestCase::testLonger()
209{
210 struct {
50e27899
VS
211 const char *input;
212 const char *expectedScanf;
213 const char *expectedWcharUnix;
214 const char *expectedWcharWindows;
215 const char *expectedUtf8;
7d5ab151 216 } formats[] = {
50e27899
VS
217 { "%d", "%d", "%d", "%d", "%d" },
218 { "%*hd", "%*hd", "%*hd", "%*hd", "%*hd" },
219 { "%.4ld", "%.4ld", "%.4ld", "%.4ld", "%.4ld" },
220 { "%-.*s", "%-.*ls", "%-.*ls", "%-.*s", "%-.*s" },
221 { "%.*hs", "%.*hs", "%.*ls", "%.*s", "%.*s" },
222 { "%-.9ls", "%-.9ls", "%-.9ls", "%-.9s", "%-.9s" },
093315a1
VZ
223 { "%-*c", "%-*lc", "%-*lc", "%-*c", "%-*lc" },
224 { "%3hc", "%3hc", "%3lc", "%3c", "%3lc" },
225 { "%-5lc", "%-5lc", "%-5lc", "%-5c", "%-5lc" }
7d5ab151
VS
226 };
227 size_t i, j;
228
7d5ab151
VS
229 // test all possible pairs of the above patterns
230 for (i = 0; i < WXSIZEOF(formats); i++) {
231 if (formats[i].input) {
232 wxString input(formats[i].input);
50e27899
VS
233 wxString expectedScanf(formats[i].expectedScanf);
234 wxString expectedUtf8(formats[i].expectedUtf8);
235 wxString expectedWcharUnix(formats[i].expectedWcharUnix);
236 wxString expectedWcharWindows(formats[i].expectedWcharWindows);
7d5ab151
VS
237
238 for (j = 0; j < WXSIZEOF(formats); j++)
239 if (formats[j].input)
240 check(input + formats[j].input,
50e27899
VS
241 expectedScanf + formats[j].expectedScanf,
242 expectedUtf8 + formats[j].expectedUtf8,
243 expectedWcharUnix + formats[j].expectedWcharUnix,
244 expectedWcharWindows + formats[j].expectedWcharWindows);
7d5ab151
VS
245 }
246 }
247}
248
50e27899
VS
249void FormatConverterTestCase::doTest(const char *input,
250 const char *expectedScanf,
251 const char *expectedUtf8,
252 const char *expectedWcharUnix,
253 const char *expectedWcharWindows)
7d5ab151
VS
254{
255 static const wxChar *flag_width[] =
9a83f860 256 { wxT(""), wxT("*"), wxT("10"), wxT("-*"), wxT("-10"), NULL };
7d5ab151 257 static const wxChar *precision[] =
9a83f860 258 { wxT(""), wxT(".*"), wxT(".10"), NULL };
7d5ab151 259 static const wxChar *empty[] =
9a83f860 260 { wxT(""), NULL };
7d5ab151
VS
261
262 // no precision for %c or %C
9a83f860 263 const wxChar **precs = wxTolower(input[wxStrlen(input)-1]) == wxT('c') ?
7d5ab151
VS
264 empty : precision;
265
9a83f860 266 wxString fmt(wxT("%"));
7d5ab151
VS
267
268 // try the test for a variety of combinations of flag, width and precision
269 for (const wxChar **prec = precs; *prec; prec++)
270 for (const wxChar **width = flag_width; *width; width++)
271 check(fmt + *width + *prec + input,
50e27899
VS
272 fmt + *width + *prec + expectedScanf,
273 fmt + *width + *prec + expectedUtf8,
274 fmt + *width + *prec + expectedWcharUnix,
275 fmt + *width + *prec + expectedWcharWindows);
7d5ab151
VS
276}
277
278void FormatConverterTestCase::check(const wxString& input,
50e27899
VS
279 const wxString& expectedScanf,
280 const wxString& expectedUtf8,
281 const wxString& expectedWcharUnix,
282 const wxString& expectedWcharWindows)
7d5ab151 283{
2452025c
VZ
284 // all of them are unused in some build configurations
285 wxUnusedVar(expectedScanf);
286 wxUnusedVar(expectedUtf8);
287 wxUnusedVar(expectedWcharUnix);
288 wxUnusedVar(expectedWcharWindows);
289
50e27899
VS
290 wxString result, msg;
291
292#ifndef __WINDOWS__
293 // on windows, wxScanf() string needs no modifications
294 result = wxScanfConvertFormatW(input.wc_str());
295
9a83f860
VZ
296 msg = wxT("input: '") + input +
297 wxT("', result (scanf): '") + result +
298 wxT("', expected: '") + expectedScanf + wxT("'");
50e27899
VS
299 CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expectedScanf);
300#endif // !__WINDOWS__
301
302#if wxUSE_UNICODE_UTF8
303 result = (const char*)wxFormatString(input);
304
9a83f860
VZ
305 msg = wxT("input: '") + input +
306 wxT("', result (UTF-8): '") + result +
307 wxT("', expected: '") + expectedUtf8 + wxT("'");
50e27899
VS
308 CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expectedUtf8);
309#endif // wxUSE_UNICODE_UTF8
310
311#if wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY
312 result = (const wchar_t*)wxFormatString(input);
313
314#ifdef __WINDOWS__
315 wxString expectedWchar(expectedWcharWindows);
316#else
317 wxString expectedWchar(expectedWcharUnix);
318#endif
319
9a83f860
VZ
320 msg = wxT("input: '") + input +
321 wxT("', result (wchar_t): '") + result +
322 wxT("', expected: '") + expectedWchar + wxT("'");
50e27899
VS
323 CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expectedWchar);
324#endif // wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY
7d5ab151
VS
325}
326
7d5ab151
VS
327
328// register in the unnamed registry so that these tests are run by default
329CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase);
330
e3778b4d 331// also include in its own registry so that these tests can be run alone
7d5ab151
VS
332CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase,
333 "FormatConverterTestCase");
334