Patch 1053127 - Test fixes.
[wxWidgets.git] / tests / formatconverter / formatconvertertest.cpp
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
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
56 extern wxString wxConvertFormat(const wxChar *format);
57 #endif
58
59 using CppUnit::TestCase;
60 using std::string;
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
69 class 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
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
116 void 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"));
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"));
128 }
129
130 void 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
139 void 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
148 void FormatConverterTestCase::format_s()
149 {
150 #ifdef CAN_TEST
151 doTest(_T("s"), _T("ls"));
152 #endif
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!"));
158 }
159
160 void FormatConverterTestCase::format_hs()
161 {
162 #ifdef CAN_TEST
163 doTest(_T("hs"), _T("hs"));
164 #endif
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!"));
170 }
171
172 void FormatConverterTestCase::format_ls()
173 {
174 #ifdef CAN_TEST
175 doTest(_T("ls"), _T("ls"));
176 #endif
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!"));
182 }
183
184 void 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"));
190 CPPUNIT_ASSERT(wxString::Format(_T("%2c"), _T('x')) == _T(" x"));
191 CPPUNIT_ASSERT(wxString::Format(_T("%-2c"), _T('x')) == _T("x "));
192 }
193
194 void FormatConverterTestCase::format_hc()
195 {
196 #ifdef CAN_TEST
197 doTest(_T("hc"), _T("hc"));
198 #endif
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 "));
202 }
203
204 void 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"));
210 CPPUNIT_ASSERT(wxString::Format(_T("%2lc"), L'x') == _T(" x"));
211 CPPUNIT_ASSERT(wxString::Format(_T("%-2lc"), L'x') == _T("x "));
212 }
213
214 #ifdef CAN_TEST
215
216 void FormatConverterTestCase::format_S() { doTest(_T("S"), _T("s")); }
217 void FormatConverterTestCase::format_hS() { doTest(_T("hS"), _T("s")); }
218 void FormatConverterTestCase::format_lS() { doTest(_T("lS"), _T("ls")); }
219
220 void FormatConverterTestCase::format_C() { doTest(_T("C"), _T("c")); }
221 void FormatConverterTestCase::format_hC() { doTest(_T("hC"), _T("c")); }
222 void 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 //
228 void 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
265 void 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
288 void 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
301 CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase);
302
303 // also include in it's own registry so that these tests can be run alone
304 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase,
305 "FormatConverterTestCase");
306