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