]> git.saurik.com Git - wxWidgets.git/blob - tests/formatconverter/formatconverter.cpp
Above 2.3.0 SetBitmap is still for owner drawn only.
[wxWidgets.git] / tests / formatconverter / formatconverter.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 namespace std;
60 using 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
70 class 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
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
117 void 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"));
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"));
129 }
130
131 void 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
140 void 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
149 void FormatConverterTestCase::format_s()
150 {
151 #ifdef CAN_TEST
152 doTest(_T("s"), _T("ls"));
153 #endif
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!"));
159 }
160
161 void FormatConverterTestCase::format_hs()
162 {
163 #ifdef CAN_TEST
164 doTest(_T("hs"), _T("hs"));
165 #endif
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!"));
171 }
172
173 void FormatConverterTestCase::format_ls()
174 {
175 #ifdef CAN_TEST
176 doTest(_T("ls"), _T("ls"));
177 #endif
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!"));
183 }
184
185 void 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"));
191 CPPUNIT_ASSERT(wxString::Format(_T("%2c"), _T('x')) == _T(" x"));
192 CPPUNIT_ASSERT(wxString::Format(_T("%-2c"), _T('x')) == _T("x "));
193 }
194
195 void FormatConverterTestCase::format_hc()
196 {
197 #ifdef CAN_TEST
198 doTest(_T("hc"), _T("hc"));
199 #endif
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 "));
203 }
204
205 void 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"));
211 CPPUNIT_ASSERT(wxString::Format(_T("%2lc"), L'x') == _T(" x"));
212 CPPUNIT_ASSERT(wxString::Format(_T("%-2lc"), L'x') == _T("x "));
213 }
214
215 #ifdef CAN_TEST
216
217 void FormatConverterTestCase::format_S() { doTest(_T("S"), _T("s")); }
218 void FormatConverterTestCase::format_hS() { doTest(_T("hS"), _T("s")); }
219 void FormatConverterTestCase::format_lS() { doTest(_T("lS"), _T("ls")); }
220
221 void FormatConverterTestCase::format_C() { doTest(_T("C"), _T("c")); }
222 void FormatConverterTestCase::format_hC() { doTest(_T("hC"), _T("c")); }
223 void 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 //
229 void 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
266 void 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
289 void 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
302 CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase);
303
304 // also include in it's own registry so that these tests can be run alone
305 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase,
306 "FormatConverterTestCase");
307