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