Lumiera  0.pre.03
»edit your freedom«
format-string-test.cpp
Go to the documentation of this file.
1 /*
2  FormatString(Test) - validate string template formatting (printf style)
3 
4  Copyright (C)
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
21 #include "lib/format-string.hpp"
22 #include "lib/symbol.hpp"
23 #include "lib/error.hpp"
24 #include "lib/util.hpp"
25 
26 #include <boost/lexical_cast.hpp>
27 #include <iostream>
28 
29 using boost::lexical_cast;
30 using std::cout;
31 using std::endl;
32 
33 
34 namespace util {
35 namespace test {
36 
37  namespace error = lumiera::error;
38 
39 
40 
41  /***************************************************************************/
54  class FormatString_test : public Test
55  {
56  void
57  run (Arg)
58  {
59  check_simpleInvocation();
60  check_delayedInvocation();
61  verify_typeHandling();
62  verify_customType();
63  verify_errorHandling();
64  verify_pointerHandling();
65  }
66 
67 
68 
69  void
70  check_simpleInvocation ()
71  {
72  string formatted = _Fmt("--format-template--int=%04d--double=%+5.2f--string=%-9s--")
73  % 12
74  % 1.228
75  % "Lumiera";
76  cout << formatted << endl;
77  CHECK (formatted == "--format-template--int=0012--double=+1.23--string=Lumiera --");
78  }
79 
80 
81  void
82  check_delayedInvocation ()
83  {
84  string formatString = "%p %|20T_| %u";
85  _Fmt formatter (formatString);
86 
87  uint val = rani (100);
88  void *pt = &val;
89 
90  formatter % pt;
91  formatter % val;
92 
93  cout << formatter << endl;
94  }
95 
96 
97  void
98  verify_typeHandling ()
99  {
100  int i(-12);
101  CHECK (_Fmt("%d") % i == "-12" );
102  CHECK (_Fmt("%6d") % i == " -12" );
103  CHECK (_Fmt("%-6d") % i == "-12 " );
104  CHECK (_Fmt("%+-6d") % -i == "+12 " );
105  CHECK (_Fmt("%+06d") % -i == "+00012" );
106  CHECK (_Fmt("%06X") % -i == "00000C" );
107  CHECK (_Fmt("%#x") % -i == "0xc" );
108 
109  uint u(12);
110  CHECK (_Fmt("%d") % u == "12" );
111  CHECK (_Fmt("%6d") % u == " 12" );
112  CHECK (_Fmt("%-6d") % u == "12 " );
113  CHECK (_Fmt("%-+6d") % u == "12 " );
114  CHECK (_Fmt("%+06d") % u == "000012" );
115 
116  short sh(-123);
117  CHECK (_Fmt("%6d") % sh == " -123" );
118 
119  ushort ush(123);
120  CHECK (_Fmt("%6d") % ush == " 123" );
121 
122  long l(-123);
123  CHECK (_Fmt("%6d") % l == " -123" );
124 
125  ulong ul(123);
126  CHECK (_Fmt("%6d") % ul == " 123" );
127 
128  int64_t ll(5e+9);
129  CHECK (_Fmt("%d") % ll == "5000000000" );
130  CHECK (_Fmt("%5.3d") %ll == "5000000000" );
131  CHECK (_Fmt("%10.3e") %ll == "5000000000" );
132 
133  uint64_t ull(ll);
134  CHECK (_Fmt("%d") % ull == "5000000000" );
135 
136  float f(12.34);
137  CHECK (_Fmt("%g") % f == "12.34" );
138  CHECK (_Fmt("%d") % f == "12.34" );
139  CHECK (_Fmt("%.3f") % f == "12.340" );
140  CHECK (_Fmt("%.1e") % f == "1.2e+01");
141  CHECK (_Fmt("%.0f") % f == "12" );
142 
143  double d(-12.34);
144  CHECK (_Fmt("%g") % d == "-12.34" );
145 
146  char c(0x40);
147  CHECK (_Fmt("%d") % c == "@" );
148  CHECK (_Fmt("%x") % c == "@" );
149  CHECK (_Fmt("%o") % c == "@" );
150  CHECK (_Fmt("%c") % c == "@" );
151  CHECK (_Fmt("%s") % c == "@" );
152  CHECK (_Fmt("%d") % short(c) == "64" );
153  CHECK (_Fmt("%x") % short(c) == "40" );
154  CHECK (_Fmt("%o") % short(c) == "100" );
155  CHECK (_Fmt("%c") % short(c) == "6" );
156  CHECK (_Fmt("%s") % short(c) == "64" );
157 
158  uchar uc(0xff);
159  CHECK (_Fmt("%d") % uint(uc) == "255" );
160  CHECK (_Fmt("%x") % uint(uc) == "ff" );
161  CHECK (_Fmt("%X") % uint(uc) == "FF" );
162  CHECK (_Fmt("%c") % uint(uc) == "2" );
163  CHECK (_Fmt("%s") % uint(uc) == "255" );
164  CHECK (_Fmt("%d") % uc == "\xFF");
165  CHECK (_Fmt("%x") % uc == "\xFF");
166  CHECK (_Fmt("%X") % uc == "\xFF");
167  CHECK (_Fmt("%c") % uc == "\xFF");
168  CHECK (_Fmt("%s") % uc == "\xFF");
169 
170  c = char(uc);
171  CHECK (_Fmt("%c") % c == "\xFF");
172 
173  string str("Lumiera");
174  CHECK (_Fmt("%s") % str == "Lumiera" );
175  CHECK (_Fmt("%10s") % str == " Lumiera" );
176  CHECK (_Fmt("%7.4s") %str == " Lumi" );
177  CHECK (_Fmt("%10c") % str == " L" );
178 
179  const char* pch("edit");
180  CHECK (_Fmt("%s") % pch == "edit" );
181  CHECK (_Fmt("%10s") % pch == " edit" );
182  CHECK (_Fmt("%7.3s") %pch == " edi" );
183  CHECK (_Fmt("%10c") % pch == " e" );
184 
185  lib::Literal lit("your");
186  CHECK (_Fmt("%s") % lit == "your" );
187  CHECK (_Fmt("%10s") % lit == " your" );
188  CHECK (_Fmt("%7.2s") %lit == " yo" );
189  CHECK (_Fmt("%10c") % lit == " y" );
190 
191  lib::Symbol sym("freedom");
192  CHECK (_Fmt("%s") % sym == "freedom" );
193  CHECK (_Fmt("%10s") % sym == " freedom" );
194  CHECK (_Fmt("%7.5s") %sym == " freed" );
195  CHECK (_Fmt("%10c") % sym == " f" );
196  }
197 
198 
199  /* == some custom types to test with == */
200 
201  struct Silent
202  {
203  int i_;
204 
205  Silent(int i) : i_(i) { }
206  };
207 
208  struct Verbose
209  : Silent
210  {
211  using Silent::Silent;
212  virtual ~Verbose() { }
213 
214  virtual
215  operator string() const
216  {
217  return _Fmt("Number-%03d") % i_;
218  }
219  };
220 
221  struct Explosive
222  : Verbose
223  {
224  using Verbose::Verbose;
225 
226  operator string() const
227  {
228  if (23 == i_)
229  throw error::State("encountered Fantomas");
230  else
231  return Verbose::operator string();
232  }
233  };
234 
235 
236  void
237  verify_customType ()
238  {
239  Silent s(12);
240  Verbose v(13);
241  Explosive x(23);
242 
243  Silent& rs1 = v;
244  Silent& rs2 = x;
245 
246  Verbose& rv = x;
247 
248  string typeDisplay = _Fmt("%s") % s;
249  cout << typeDisplay << endl;
250  CHECK (contains (typeDisplay, "test"));
251  CHECK (contains (typeDisplay, "FormatString_test"));
252  CHECK (contains (typeDisplay, "Silent"));
253 
254  CHECK (_Fmt("!!%s!!") % v == "!!Number-013!!");
255  CHECK (_Fmt("!!%s!!") % x == "!!<string conversion failed: LUMIERA_ERROR_STATE:unforeseen state (encountered Fantomas).>!!");
256 
257  CHECK (contains (_Fmt("%s") % rs1, "Silent"));
258  CHECK (contains (_Fmt("%s") % rs2, "Silent"));
259 
260  CHECK (_Fmt("!!%s!!") % rv == "!!<string conversion failed: LUMIERA_ERROR_STATE:unforeseen state (encountered Fantomas).>!!");
261 
262  x.i_ = 42;
263  CHECK (_Fmt("!!%s!!") % rv == "!!Number-042!!");
264  CHECK (_Fmt("!!%s!!") % x == "!!Number-042!!");
265 
266  lib::Symbol sym("42");
267  CHECK (_Fmt("!!%s!!") % sym == "!!42!!"); // but especially Symbol datatype is explicitly treated like a string
268  }
269 
270 
271  void
272  verify_errorHandling ()
273  {
274  cout << _Fmt("__nix_") % 1 % 2 << endl;
275  cout << _Fmt("__%d__") << endl;
276  cout << _Fmt("__%d__") % 1 << endl;
277  cout << _Fmt("__%d__") % 1 % 2 << endl;
278 
279  const char* evil = NULL;
280  cout << _Fmt("__%d__") % evil << endl;
281  cout << _Fmt("__%d__") % "dirt" << endl;
282  cout << _Fmt("__%d__") % "1234" << endl;
283  cout << _Fmt("__%d__") % "0xff" << endl;
284 
285  VERIFY_ERROR(FORMAT_SYNTAX, _Fmt("%madness"));
286  }
287 
288 
289  void
290  verify_pointerHandling ()
291  {
292  int i(-12); int * pi = & i;
293  uint u(12); uint * pu = & u;
294  short sh(-123); short * psh = & sh;
295  ushort ush(123); ushort * push = &ush;
296  long l(-123); long * pl = & l;
297  ulong ul(123); ulong * pul = & ul;
298  int64_t ll(5e+9); int64_t * pll = & ll;
299  uint64_t ull(ll); uint64_t * pull = &ull;
300  float f(12.34); float * pf = & f;
301  double d(-12.34); double * pd = & d;
302  uchar uc(0xff); uchar * puc = & uc;
303  string str("Lumiera"); string * pstr = &str;
304 
305  CHECK (_Fmt("%d") % i == _Fmt("%d") % pi);
306  CHECK (_Fmt("%d") % u == _Fmt("%d") % pu);
307  CHECK (_Fmt("%d") % sh == _Fmt("%d") % psh);
308  CHECK (_Fmt("%d") % ush == _Fmt("%d") % push);
309  CHECK (_Fmt("%d") % l == _Fmt("%d") % pl);
310  CHECK (_Fmt("%d") % ul == _Fmt("%d") % pul);
311  CHECK (_Fmt("%d") % ll == _Fmt("%d") % pll);
312  CHECK (_Fmt("%d") % ull == _Fmt("%d") % pull);
313  CHECK (_Fmt("%e") % f == _Fmt("%e") % pf);
314  CHECK (_Fmt("%e") % d == _Fmt("%e") % pd);
315  CHECK (_Fmt("%g") % uc == _Fmt("%g") % puc);
316  CHECK (_Fmt("%s") % str == _Fmt("%s") % pstr);
317 
318  char c('a');
319  char pc[2] = {'a', '\0'};
320  CHECK (_Fmt("%g") % c == _Fmt("%g") % pc);
321 
322  Verbose v(42);
323  Verbose *pv = &v;
324  void *vv = pv;
325  CHECK (_Fmt("__%s__") % v == "__Number-042__");
326  CHECK (_Fmt("__%s__") % pv == "__Number-042__");
327  CHECK (_Fmt("__%s__") % vv != "__Number-042__");
328 
329  string address = lexical_cast<string>(pv);
330  CHECK (_Fmt("__%s__") % vv == "__"+address+"__");
331 
332  pv = NULL;
333  vv = NULL;
334  CHECK (_Fmt("__%s__") % pv == "__"+BOTTOM_INDICATOR+"__");
335  CHECK (_Fmt("__%s__") % vv == "__0__");
336  }
337  };
338 
339  LAUNCHER (FormatString_test, "unit meta");
340 
341 
342 }} // namespace util::test
343 
Definition: run.hpp:40
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
Front-end for printf-style string template interpolation.
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
Definition: util.hpp:230
A front-end for using printf-style formatting.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Token or Atom with distinct identity.
Definition: symbol.hpp:117
Marker types to indicate a literal string and a Symbol.
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
Lumiera error handling (C++ interface).