]> git.saurik.com Git - wxWidgets.git/blame - tests/formatconverter/formatconvertertest.cpp
Adding technotes about the release system and about adding apps/screenshots to the...
[wxWidgets.git] / tests / formatconverter / formatconvertertest.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 38// For compilers that support precompilation, includes "wx/wx.h".
8899b155 39#include "testprec.h"
7d5ab151
VS
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
7d5ab151
VS
50// wxFormatConverter can only be tested in a Unicode non-Windows debug build
51//
52#if defined(wxNEED_PRINTF_CONVERSION) && defined(__WXDEBUG__)
53#define CAN_TEST
54extern wxString wxConvertFormat(const wxChar *format);
55#endif
56
3e5f6c1c
WS
57using CppUnit::TestCase;
58using std::string;
7d5ab151
VS
59
60///////////////////////////////////////////////////////////////////////////////
61// The test case
62//
63// wxFormatConverter only changes %s, %c, %S and %C, all others are treated
64// equally, therefore it is enough to choose just one other for testing, %d
65// will do.
66
67class FormatConverterTestCase : public TestCase
68{
69 CPPUNIT_TEST_SUITE(FormatConverterTestCase);
70 CPPUNIT_TEST(format_d);
71 CPPUNIT_TEST(format_hd);
72 CPPUNIT_TEST(format_ld);
73 CPPUNIT_TEST(format_s);
74 CPPUNIT_TEST(format_hs);
75 CPPUNIT_TEST(format_ls);
76 CPPUNIT_TEST(format_c);
77 CPPUNIT_TEST(format_hc);
78 CPPUNIT_TEST(format_lc);
79#ifdef CAN_TEST
80 CPPUNIT_TEST(format_S);
81 CPPUNIT_TEST(format_hS);
82 CPPUNIT_TEST(format_lS);
83 CPPUNIT_TEST(format_C);
84 CPPUNIT_TEST(format_hC);
85 CPPUNIT_TEST(format_lC);
86 CPPUNIT_TEST(testLonger);
87#endif
88 CPPUNIT_TEST_SUITE_END();
89
7d5ab151
VS
90 void format_d();
91 void format_hd();
92 void format_ld();
93 void format_s();
94 void format_hs();
95 void format_ls();
96 void format_c();
97 void format_hc();
98 void format_lc();
99
100#ifdef CAN_TEST
101 void format_S();
102 void format_hS();
103 void format_lS();
104 void format_C();
105 void format_hC();
106 void format_lC();
107 void testLonger();
108
109 void doTest(const wxChar *input, const wxChar *expected);
110 void check(const wxString& input, const wxString& expected);
111#endif
112};
113
114void FormatConverterTestCase::format_d()
115{
116#ifdef CAN_TEST
117 doTest(_T("d"), _T("d"));
118#endif
119 CPPUNIT_ASSERT(wxString::Format(_T("%d"), 255) == _T("255"));
8dae9169
VS
120 CPPUNIT_ASSERT(wxString::Format(_T("%05d"), 255) == _T("00255"));
121 CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), 255) == _T(" 255"));
122 CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), -255) == _T(" -255"));
123 CPPUNIT_ASSERT(wxString::Format(_T("%-5d"), -255) == _T("-255 "));
124 CPPUNIT_ASSERT(wxString::Format(_T("%+5d"), 255) == _T(" +255"));
125 CPPUNIT_ASSERT(wxString::Format(_T("%*d"), 5, 255) == _T(" 255"));
7d5ab151
VS
126}
127
128void FormatConverterTestCase::format_hd()
129{
130#ifdef CAN_TEST
131 doTest(_T("hd"), _T("hd"));
132#endif
133 short s = 32767;
134 CPPUNIT_ASSERT(wxString::Format(_T("%hd"), s) == _T("32767"));
135}
136
137void FormatConverterTestCase::format_ld()
138{
139#ifdef CAN_TEST
140 doTest(_T("ld"), _T("ld"));
141#endif
142 long l = 2147483647L;
143 CPPUNIT_ASSERT(wxString::Format(_T("%ld"), l) == _T("2147483647"));
144}
145
146void FormatConverterTestCase::format_s()
147{
148#ifdef CAN_TEST
149 doTest(_T("s"), _T("ls"));
150#endif
8dae9169
VS
151 CPPUNIT_ASSERT(wxString::Format(_T("%s!"), _T("test")) == _T("test!"));
152 CPPUNIT_ASSERT(wxString::Format(_T("%6s!"), _T("test")) == _T(" test!"));
153 CPPUNIT_ASSERT(wxString::Format(_T("%-6s!"), _T("test")) == _T("test !"));
154 CPPUNIT_ASSERT(wxString::Format(_T("%.6s!"), _T("test")) == _T("test!"));
155 CPPUNIT_ASSERT(wxString::Format(_T("%6.4s!"), _T("testing")) == _T(" test!"));
7d5ab151
VS
156}
157
158void FormatConverterTestCase::format_hs()
159{
160#ifdef CAN_TEST
161 doTest(_T("hs"), _T("hs"));
162#endif
8dae9169
VS
163 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hs!")), "test") == _T("test!"));
164 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6hs!")), "test") == _T(" test!"));
165 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-6hs!")), "test") == _T("test !"));
166 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%.6hs!")), "test") == _T("test!"));
167 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6.4hs!")), "testing") == _T(" test!"));
7d5ab151
VS
168}
169
170void FormatConverterTestCase::format_ls()
171{
172#ifdef CAN_TEST
173 doTest(_T("ls"), _T("ls"));
174#endif
8dae9169
VS
175 CPPUNIT_ASSERT(wxString::Format(_T("%ls!"), L"test") == _T("test!"));
176 CPPUNIT_ASSERT(wxString::Format(_T("%6ls!"), L"test") == _T(" test!"));
177 CPPUNIT_ASSERT(wxString::Format(_T("%-6ls!"), L"test") == _T("test !"));
178 CPPUNIT_ASSERT(wxString::Format(_T("%.6ls!"), L"test") == _T("test!"));
179 CPPUNIT_ASSERT(wxString::Format(_T("%6.4ls!"), L"testing") == _T(" test!"));
7d5ab151
VS
180}
181
182void FormatConverterTestCase::format_c()
183{
184#ifdef CAN_TEST
185 doTest(_T("c"), _T("lc"));
186#endif
187 CPPUNIT_ASSERT(wxString::Format(_T("%c"), _T('x')) == _T("x"));
8dae9169
VS
188 CPPUNIT_ASSERT(wxString::Format(_T("%2c"), _T('x')) == _T(" x"));
189 CPPUNIT_ASSERT(wxString::Format(_T("%-2c"), _T('x')) == _T("x "));
7d5ab151
VS
190}
191
192void FormatConverterTestCase::format_hc()
193{
194#ifdef CAN_TEST
195 doTest(_T("hc"), _T("hc"));
196#endif
8dae9169
VS
197 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hc")), 'x') == _T("x"));
198 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%2hc")), 'x') == _T(" x"));
199 CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-2hc")), 'x') == _T("x "));
7d5ab151
VS
200}
201
202void FormatConverterTestCase::format_lc()
203{
204#ifdef CAN_TEST
205 doTest(_T("lc"), _T("lc"));
206#endif
207 CPPUNIT_ASSERT(wxString::Format(_T("%lc"), L'x') == _T("x"));
8dae9169
VS
208 CPPUNIT_ASSERT(wxString::Format(_T("%2lc"), L'x') == _T(" x"));
209 CPPUNIT_ASSERT(wxString::Format(_T("%-2lc"), L'x') == _T("x "));
7d5ab151
VS
210}
211
212#ifdef CAN_TEST
213
214void FormatConverterTestCase::format_S() { doTest(_T("S"), _T("s")); }
215void FormatConverterTestCase::format_hS() { doTest(_T("hS"), _T("s")); }
216void FormatConverterTestCase::format_lS() { doTest(_T("lS"), _T("ls")); }
217
218void FormatConverterTestCase::format_C() { doTest(_T("C"), _T("c")); }
219void FormatConverterTestCase::format_hC() { doTest(_T("hC"), _T("c")); }
220void FormatConverterTestCase::format_lC() { doTest(_T("lC"), _T("lc")); }
221
222// It's possible that although a format converts correctly alone, it leaves
223// the converter in a bad state that will affect subsequent formats, so
224// check with a selection of longer patterns.
225//
226void FormatConverterTestCase::testLonger()
227{
228 struct {
229 const wxChar *input;
230 const wxChar *expected;
231 } formats[] = {
232 { _T("%d"), _T("%d"), },
233 { _T("%*hd"), _T("%*hd") },
234 { _T("%.4ld"), _T("%.4ld") },
235 { _T("%-.*s"), _T("%-.*ls") },
236 { _T("%.*hs"), _T("%.*hs"), },
237 { _T("%-.9ls"), _T("%-.9ls") },
238 { _T("%-*c"), _T("%-*lc") },
239 { _T("%3hc"), _T("%3hc") },
240 { _T("%-5lc"), _T("%-5lc") }
241 };
242 size_t i, j;
243
244 // exclude patterns that don't translate correctly alone from the test
245 for (i = 0; i < WXSIZEOF(formats); i++)
246 if (wxConvertFormat(formats[i].input) != formats[i].expected)
247 formats[i].input = NULL;
248
249 // test all possible pairs of the above patterns
250 for (i = 0; i < WXSIZEOF(formats); i++) {
251 if (formats[i].input) {
252 wxString input(formats[i].input);
253 wxString expected(formats[i].expected);
254
255 for (j = 0; j < WXSIZEOF(formats); j++)
256 if (formats[j].input)
257 check(input + formats[j].input,
258 expected + formats[j].expected);
259 }
260 }
261}
262
263void FormatConverterTestCase::doTest(const wxChar *input,
264 const wxChar *expected)
265{
266 static const wxChar *flag_width[] =
267 { _T(""), _T("*"), _T("10"), _T("-*"), _T("-10"), NULL };
268 static const wxChar *precision[] =
269 { _T(""), _T(".*"), _T(".10"), NULL };
270 static const wxChar *empty[] =
271 { _T(""), NULL };
272
273 // no precision for %c or %C
274 const wxChar **precs = wxTolower(input[wxStrlen(input)-1]) == _T('c') ?
275 empty : precision;
276
277 wxString fmt(_T("%"));
278
279 // try the test for a variety of combinations of flag, width and precision
280 for (const wxChar **prec = precs; *prec; prec++)
281 for (const wxChar **width = flag_width; *width; width++)
282 check(fmt + *width + *prec + input,
283 fmt + *width + *prec + expected);
284}
285
286void FormatConverterTestCase::check(const wxString& input,
287 const wxString& expected)
288{
289 wxString result = wxConvertFormat(input);
290 wxString msg = _T("input: '") + input +
291 _T("', result: '") + result +
292 _T("', expected: '") + expected + _T("'");
293 CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expected);
294}
295
296#endif // CAN_TEST
297
298// register in the unnamed registry so that these tests are run by default
299CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase);
300
301// also include in it's own registry so that these tests can be run alone
302CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase,
303 "FormatConverterTestCase");
304