Lumiera  0.pre.03
»edit your freedom«
variant-test.cpp
Go to the documentation of this file.
1 /*
2  Variant(Test) - verify the lightweight typesafe union record
3 
4  Copyright (C)
5  2015, 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 
20 #include "lib/test/run.hpp"
21 #include "lib/test/test-helper.hpp"
22 #include "lib/time/timevalue.hpp"
23 #include "lib/format-cout.hpp"
24 #include "lib/variant.hpp"
25 #include "lib/util.hpp"
26 
27 #include <string>
28 
29 
30 namespace lib {
31 namespace test{
32 
33  using ::Test;
34  using meta::Types;
35  using lib::time::Time;
36  using lib::time::TimeVar;
37 
38  using util::contains;
39  using std::string;
40 
41  using error::LUMIERA_ERROR_WRONG_TYPE;
42  using error::LUMIERA_ERROR_LOGIC;
43 
44 
45  // Test fixture...
46  typedef Variant<Types<bool,int,string,Time>> TestVariant;
47 
48 
49 
50 
51  /****************************************************************************/
64  class Variant_test : public Test
65  {
66 
67  virtual void
68  run (Arg)
69  {
70  seedRand();
71  createVariant();
72  accessVariant();
73  acceptPredicate();
74  verifyAssignment();
75  }
76 
77 
78  void
79  createVariant()
80  {
81  Time someTime;
82  TestVariant v0;
83  TestVariant v1(11);
84  TestVariant v2(string("lololo"));
85  TestVariant v3(someTime);
86 
88  // TestVariant evil(3.1415);
89 
90  cout << v0 <<endl
91  << v1 <<endl
92  << v2 <<endl
93  << v3 <<endl;
94 
95  CHECK (contains (string(v0), "Variant"));
96  CHECK (contains (string(v0), "bool"));
97  CHECK (contains (string(v0), "false"));
98 
99  CHECK (contains (string(v1), "Variant"));
100  CHECK (contains (string(v1), "int"));
101  CHECK (contains (string(v1), "11"));
102 
103  CHECK (contains (string(v2), "Variant"));
104  CHECK (contains (string(v2), "string"));
105  CHECK (contains (string(v2), "lololo"));
106 
107  CHECK (contains (string(v3), "Variant"));
108  CHECK (contains (string(v3), "Time"));
109  CHECK (contains (string(v3), "0:00:00.000"));
110  }
111 
112 
113  void
114  accessVariant()
115  {
116  int someVal = rani(10000);
117  string someStr = randStr(55);
118  Time someTime = randTime();
119 
120  TestVariant v3(someTime);
121  TestVariant v2(someStr);
122  TestVariant v1 = someVal;
123  TestVariant v0; v0 = true;
124 
125  CHECK (true == v0.get<bool>() );
126  CHECK (someVal == v1.get<int>());
127  CHECK (someStr == v2.get<string>() );
128  CHECK (someTime == v3.get<Time>() );
129 
130  VERIFY_ERROR (WRONG_TYPE, v0.get<int>() );
131  VERIFY_ERROR (WRONG_TYPE, v0.get<string>() );
132  VERIFY_ERROR (WRONG_TYPE, v0.get<Time>() );
133 
134  VERIFY_ERROR (WRONG_TYPE, v1.get<bool>() );
135  VERIFY_ERROR (WRONG_TYPE, v1.get<string>() );
136  VERIFY_ERROR (WRONG_TYPE, v1.get<Time>() );
137 
138  VERIFY_ERROR (WRONG_TYPE, v2.get<bool>() );
139  VERIFY_ERROR (WRONG_TYPE, v2.get<int>() );
140  VERIFY_ERROR (WRONG_TYPE, v2.get<Time>() );
141 
142  VERIFY_ERROR (WRONG_TYPE, v3.get<bool>() );
143  VERIFY_ERROR (WRONG_TYPE, v3.get<int>() );
144  VERIFY_ERROR (WRONG_TYPE, v3.get<string>() );
145 
147  // v0.get<int>();
148  // v1.get<double>();
149  // v3.get<TimeVar>();
150 
151  struct Accessor
153  {
154  bool b_ = false;
155  int i_ = 12;
156  TimeVar t_;
157 
158  void handle (bool& b) { b_ = b; }
159  void handle (Time& t) { t_ = t; }
160 
161  void handle (int& i6)
162  {
163  i_ = i6;
164  ++i6;
165  }
166  };
167 
168  Accessor acs;
169  CHECK (!acs.b_);
170  CHECK (acs.i_ == 12);
171 
172  v0.accept (acs);
173  CHECK (acs.b_);
174  CHECK (acs.i_ == 12);
175 
176  v3.accept (acs);
177  CHECK (acs.b_);
178  CHECK (acs.i_ == 12);
179  CHECK (acs.t_ == someTime);
180 
181  v2.accept (acs);
182  // nothing changed,
183  // since we defined no accessor function
184  CHECK (acs.b_);
185  CHECK (acs.i_ == 12);
186  CHECK (acs.t_ == someTime);
187 
188  v1.accept (acs);
189  CHECK (acs.b_);
190  CHECK (acs.t_ == someTime);
191  CHECK (acs.i_ == someVal);
192 
193  // side-effect!
194  CHECK (someVal+1 == v1.get<int>());
195  v1.accept (acs);
196  CHECK (someVal+2 == v1.get<int>());
197  CHECK (someVal+1 == acs.i_);
198  }
199 
200 
201  void
202  acceptPredicate()
203  {
204  const TestVariant v1(12);
205  const TestVariant v2(string("123"));
206  const TestVariant v3(Time::NEVER);
207 
208  struct Checker
210  {
211  bool handle (int const& i) { return i % 2; }
212  bool handle (string const& s) { return s.length() % 2; }
213  }
214  check;
215 
216  CHECK (12 == v1.get<int>());
217  CHECK ("123" == v2.get<string>());
218  CHECK (Time::NEVER == v3.get<Time>());
219 
220  CHECK (!v1.accept(check));
221  CHECK ( v2.accept(check));
222  CHECK (!v3.accept(check));
223 
224  CHECK (12 == v1.get<int>());
225  CHECK ("123" == v2.get<string>());
226  CHECK (Time::NEVER == v3.get<Time>());
227  }
228 
229 
230  void
231  verifyAssignment()
232  {
233  TestVariant v1(string("boo"));
234  TestVariant v2(23);
235  TestVariant v3(42);
236 
237  v1 = string("booo");
238  v2 = v3;
239  v3 = 24;
240  CHECK ("booo" == v1.get<string>());
241  CHECK (42 == v2.get<int>());
242  CHECK (24 == v3.get<int>());
243 
244  VERIFY_ERROR (WRONG_TYPE, v1 = v2 );
245  VERIFY_ERROR (WRONG_TYPE, v1 = 22);
246  VERIFY_ERROR (WRONG_TYPE, v2 = string("2"));
247 
248  TestVariant v4 = Time();
249  TestVariant v44 = Time(0,4,4,4); // OK: copy initialisation
250  VERIFY_ERROR (LOGIC, v4 = v44); // Runtime Error: not assignable
251 
252  // v44 = Time(4,4); // does not compile: Time is not assignable
253  }
254  };
255 
256 
258  LAUNCHER (Variant_test, "unit common");
259 
260 
261 }} // namespace lib::test
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
Definition: timevalue.hpp:232
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:40
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.
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:61
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
A typesafe union record to carry embedded values of unrelated type.
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.
to be implemented by the client for visitation
Definition: variant.hpp:232
static const Time NEVER
border condition marker value. NEVER >= any time value
Definition: timevalue.hpp:314
lib::time::Time randTime()
create a random but not insane Time value between 1s ...
a family of time value like entities and their relationships.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255