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