Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
digxel-test.cpp
Go to the documentation of this file.
1/*
2 Digxel(Test) - cover behaviour of a generic number-element holder
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/format-cout.hpp"
21#include "lib/format-string.hpp"
23#include "lib/time/digxel.hpp"
24#include "lib/random.hpp"
25#include "lib/util.hpp"
26
27using lumiera::error::LUMIERA_ERROR_ASSERTION;
29using util::isnil;
30using lib::rani;
31
32
33namespace lib {
34namespace time{
35namespace test{
36
37 namespace { // Test data and setup
38
39 const uint REPEAT = 40;
40 const uint RAND_RANGE = 100;
41 const uint RAND_DENOM = 3;
42 const uint TIMING_CNT = 10000000;
43
44 inline double
46 {
47 double arbitrary = 1 + rani(RAND_RANGE);
48 arbitrary /= 1 + rani(RAND_DENOM);
49
50 static double prevVal;
51 if (arbitrary != prevVal)
52 {
53 prevVal = arbitrary;
54 return arbitrary;
55 }
56 else
57 return randomFrac();
58 }
59
60 inline uint
61 isOdd (uint i)
62 {
63 return i % 2;
64 }
65
66
67
68 /* === special Digxel configuration for this test === */
69
71 : digxel::PrintfFormatter<double, 11>
72 {
73 VerySpecialFormat() : digxel::PrintfFormatter<double,11>("##%+5.1f ##") { }
74 };
75
77
78
79 double sum(0),
80 checksum(0);
81
82 void
83 sideeffectSum (TestDigxel* digxel, double val)
84 {
85 sum += val;
86 digxel->setValueRaw (val);
87 }
88
89 double preval(0), newval(0);
90
91 void
92 protocollingMutator (TestDigxel* digxel, double val)
93 {
94 preval = newval;
95 newval = val;
96 digxel->setValueRaw (val);
97 }
98
99 void
100 limitingMutator (TestDigxel* digxel, double value2set)
101 {
102 digxel->setValueRaw ((+1 < value2set) ? +1.0
103 : (-1 > value2set) ? -1.0
104 : value2set);
105 }
106
107 void
108 trivialMutator (TestDigxel* digxel, double value2set)
109 {
110 digxel->setValueRaw (value2set);
111 }
112
113 void
115 {
116 /* do nothing */
117 }
118
119 }//(End)Test setup
120
121
122
123
124
125
126
127 /*******************************************************************/
137 class Digxel_test : public Test
138 {
139 virtual void
140 run (Arg arg)
141 {
142 seedRand();
143
145 checkMutation ();
149 checkCopy ();
151
152 if (!isnil (arg))
154 }
155
156
157 void
159 {
160 TestDigxel digi;
161 CHECK (0 == digi);
162 CHECK ("## +0.0 ##" == string(digi));
163 cout << "empty____" << digi << endl;
164
165 digi = -88.77;
166 CHECK (-88.77 == digi);
167 CHECK ("##-88.8 ##" == string(digi));
168 cout << "value____" << digi << endl;
169 }
170
171
172 void
174 {
175 TestDigxel digi;
176
177 // configure what the Digxel does on "mutation"
178 digi.installMutator (sideeffectSum, digi);
179
180 CHECK (0 == digi);
181 sum = checksum = 0;
182 for (uint i=0; i < REPEAT; ++i)
183 {
184 double arbitrary = randomFrac();
185 checksum += arbitrary; // for verification
186 //
187 digi = arbitrary; //...causes invocation of mutation functor
188
189 CHECK (sum == checksum, "divergence after adding %f in iteration %d", arbitrary, i);
190 CHECK (digi == arbitrary);
191 }
192 CHECK (0 < sum);
193 }
194
195
196 void
198 {
199 TestDigxel digi;
200
201 // using the default mutator
202 CHECK (0 == digi);
203 digi = 12.3;
204 CHECK (12.3 == digi);
205
206 // a special mutator to limit the value
207 digi.installMutator (limitingMutator, digi);
208 CHECK (12.3 == digi);
209 digi = 12.3;
210 CHECK (12.3 == digi); // triggered on real change only
211 digi = 12.2;
212 CHECK (1 == digi);
213
214 digi = 0.5;
215 CHECK (0.5 == digi);
216 digi = -0.678;
217 CHECK (-0.678 == digi);
218 digi = -9.1011;
219 CHECK (-1 == digi);
220
221 digi.setValueRaw(12.3); // bypassing mutator
222 CHECK (12.3 == digi);
223 }
224
225
231 void
233 {
234 TestDigxel digi;
235 digi.installMutator (protocollingMutator, digi);
236
237 digi = 12.3;
238 CHECK ( 0.0 == preval and 12.3 == newval);
239 digi += 10;
240 CHECK (12.3 == preval and 22.3 == newval);
241 digi -= 5;
242 CHECK (22.3 == preval and 17.3 == newval);
243 ++digi;
244 CHECK (17.3 == preval and 18.3 == newval);
245 digi++;
246 CHECK (18.3 == preval and 19.3 == newval);
247 --digi;
248 CHECK (19.3 == preval and 18.3 == newval);
249 digi--;
250 CHECK (18.3 == preval and 17.3 == newval);
251
252 double val = ++digi;
253 CHECK (18.3 == digi and 18.3 == val);
254 val = digi++;
255 CHECK (19.3 == digi and 18.3 == val);
256 val = --digi;
257 CHECK (18.3 == digi and 18.3 == val);
258 val = digi--;
259 CHECK (17.3 == digi and 18.3 == val);
260 }
261
262
263 void
265 {
266 TestDigxel d1;
267 TestDigxel d2;
268
269 CHECK (d1 == d2);
270
271 double someValue = d1 + randomFrac();
272 d1 = someValue;
273
274 CHECK (d1 == someValue);
275 CHECK (d1 != d2);
276 CHECK (d2 != d1);
277
278 d2 = d1 + 22;
279 CHECK (d1 < d2);
280 CHECK (d1 <= d2);
281
282 CHECK (!(d1 > d2));
283 CHECK (!(d1 >= d2));
284 CHECK (!(d1 == d2));
285 }
286
287
288 void
290 {
291 TestDigxel d1;
292
293 double someValue = randomFrac();
294
295 d1 = someValue;
296 CHECK (d1 == someValue);
297
298 TestDigxel d2(d1);
299 CHECK (d2 == someValue);
300 CHECK (not isSameObject (d1, d2));
301
302 d1 = randomFrac();
303 CHECK (d1 != d2);
304 CHECK (d2 == someValue);
305 }
306
307
310 void
312 {
313 TestDigxel digi;
314 digi = 123456789.12345678;
315
316 string formatted;
317#if false
318 VERIFY_ERROR (ASSERTION, formatted = digi.show() ); // should trigger assertion
319 formatted = digi.show(); // second time doesn't reformat
320#endif
321
322 CHECK (formatted.length() <= digi.maxlen());
323 }
324
325
335 void
337 {
338 TestDigxel digi;
339 digi = 1;
340
341 clock_t start(0), stop(0);
342 util::_Fmt resultDisplay("timings(%s)%|36T.|%4.0fns\n");
343
344#define START_TIMINGS start=clock();
345#define DISPLAY_TIMINGS(ID)\
346 stop = clock(); \
347 uint ID = stop-start;\
348 cout << resultDisplay % STRINGIFY (ID) % (double(ID)/CLOCKS_PER_SEC/TIMING_CNT*1e9) ;
349
350
352 for (uint i=0; i < TIMING_CNT; ++i)
353 {
354 isOdd (i);
355 }
356 DISPLAY_TIMINGS (empty_loop)
357
358
360 for (uint i=0; i < TIMING_CNT; ++i)
361 {
362 digi = 1;
363 isOdd (i);
364 }
365 DISPLAY_TIMINGS (without_reformatting)
366
367
369 for (uint i=0; i < TIMING_CNT; ++i)
370 {
371 digi = isOdd (i);
372 }
373 DISPLAY_TIMINGS (with_reformatting)
374
375
376 digi.installMutator (emptyMutator, digi);
377
379 for (uint i=0; i < TIMING_CNT; ++i)
380 {
381 digi = isOdd (i);
382 }
383 DISPLAY_TIMINGS (with_empty_mutator)
384
385
386 digi.installMutator (trivialMutator, digi);
387
389 for (uint i=0; i < TIMING_CNT; ++i)
390 {
391 digi = isOdd (i);
392 }
393 DISPLAY_TIMINGS (with_trivial_mutator)
394
395
396 digi.installMutator (&TestDigxel::setValueRaw, digi);
397
399 for (uint i=0; i < TIMING_CNT; ++i)
400 {
401 digi = isOdd (i);
402 }
403 DISPLAY_TIMINGS (with_memfun_mutator)
404
405
406 CHECK (without_reformatting < with_reformatting);
407 }
408 };
409
410
412 LAUNCHER (Digxel_test, "unit common");
413
414
415
416}}} // namespace lib::time::test
A number element for building structured numeric displays.
Definition digxel.hpp:217
Default / base implementation for Digxel formatting.
Definition digxel.hpp:90
virtual void run(Arg arg)
A front-end for using printf-style formatting.
#define DISPLAY_TIMINGS(ID)
#define START_TIMINGS
A self-contained numeric element for building structured numeric displays.
Automatically use custom string conversion in C++ stream output.
Front-end for printf-style string template interpolation.
unsigned int uint
Definition integral.hpp:29
void sideeffectSum(TestDigxel *digxel, double val)
void trivialMutator(TestDigxel *digxel, double value2set)
Digxel< double, VerySpecialFormat > TestDigxel
void protocollingMutator(TestDigxel *digxel, double val)
void limitingMutator(TestDigxel *digxel, double value2set)
Implementation namespace for support and library code.
int rani(uint bound=_iBOUND())
Definition random.hpp:135
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
bool isnil(lib::time::Duration const &dur)
Generating (pseudo) random numbers with controlled seed.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...