Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
command-argument-test.cpp
Go to the documentation of this file.
1/*
2 CommandArgument(Test) - checking storage of specifically typed command arguments
3
4 Copyright (C)
5 2009, 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"
23#include "lib/format-string.hpp"
24#include "lib/format-cout.hpp"
25#include "lib/util-foreach.hpp"
26#include "lib/util.hpp"
27
28#include <functional>
29#include <sstream>
30#include <cstdlib>
31#include <string>
32#include <tuple>
33#include <array>
34
35using util::_Fmt;
36using util::isnil;
37using util::for_each;
38using lib::time::Time;
41using std::string;
42using std::ostringstream;
43using std::make_tuple;
44using std::rand;
45
46
47namespace steam {
48namespace control {
49namespace test {
50
53 using namespace lib::meta;
54 using LERR_(MISSING_MEMENTO);
55
56
57
58 namespace { // test helpers
59
60 ostringstream protocol;
61
62
67 template<typename TY>
68 struct Tracker
69 {
71 static int instanceCnt;
72
73 Tracker (TY init = TY()) : element_(init) { ++instanceCnt; }
74 Tracker (Tracker const& otr) : element_(otr.element_) { ++instanceCnt; }
75 ~Tracker() { --instanceCnt; }
76
77 Tracker& operator= (Tracker const&) = default;
78
79 TY&
81 {
82 return element_;
83 }
84
85 operator string() const { return util::toString(element_); }
86
87
88 friend bool
90 {
91 return tra1.element_ == tra2.element_;
92 }
93 };
94
95 template<typename TY>
96 int Tracker<TY>::instanceCnt (0);
97
98
102 struct Sint5
103 {
104 std::array<int,5> i5i;
105
106 friend bool
107 operator== (Sint5 const& i1, Sint5 const& i2)
108 {
109 return i1.i5i == i2.i5i;
110 }
111 };
112
113
114
115 /* === functions to implement test-"operation" & UNDO === */
116
117 void
119 {
120 static _Fmt fmt ("doIt( Time=%s \"%s\" rand=%2d )");
121 cout << "invoke operation..." << endl;
122 protocol << fmt % *time % *str % rand;
123 }
124
127 {
128 cout << "capture state..." << endl;
129 return protocol.str() + *xstr;
130 }
131
132 void
134 {
135 cout << "undo... memento=" << memento << endl;
136 protocol << "undoIt(time="<<time<<")----memento-:"<< *memento;
137 }
138
139
141 void dummyU (int,int,int) { }
142 int dummyC (int u,int o) { return u + rani(o-u+1); }
143
144
145
146 void
148 {
149 cout << clo << endl;
150 }
151
152 void
154 {
155 TODO ("implement serialisation/de-serialisation-Check");
156 cout << "would be serialised....." << clo << endl;
157
158 // serialise, then de-serialise into a new instance and compare both
159 }
160
161
162 int
164 {
165 return 10 + rani(90);
166 }
167
168
169 } // test-helper implementation
170
171
172
173
174
175
177
178 /***********************************************************************/
184 class CommandArgument_test : public Test
185 {
186
187 virtual void
188 run (Arg)
189 {
190 seedRand();
192 Tracker<TimeVar>::instanceCnt = 0;
193 Tracker<string>::instanceCnt = 0;
194
197 testTuples.clear();
198
200
201 // verify all dtors properly called...
202 CHECK (0 == Tracker<TimeVar>::instanceCnt);
203 CHECK (0 == Tracker<string>::instanceCnt);
204 }
205
206
209
210
211
212
214 void
216 {
217 typedef StorageHolder<void(), bool> A1;
218 typedef StorageHolder<void(int), void*> A2;
219 typedef StorageHolder<void(int,TimeVar), int> A3;
220 typedef StorageHolder<void(int,TimeVar), Sint5> A4;
221
222 typedef StorageHolder<void(TTime,Tstr,int), Tstr> A5;
223
224
225 A1* arg1 = new A1(); tup.manage (arg1);
226 A2* arg2 = new A2(); tup.manage (arg2);
227 A3* arg3 = new A3(); tup.manage (arg3);
228 A4* arg4 = new A4(); tup.manage (arg4);
229 A5* arg5 = new A5(); tup.manage (arg5);
230
231 CHECK (isnil (*arg1));
232 CHECK (isnil (*arg2));
233 CHECK (isnil (*arg3));
234 CHECK (isnil (*arg4));
235 CHECK (isnil (*arg5));
236
237 for_each (tup, showIt);
238
239 arg1->storeTuple (std::tuple<>());
240 arg2->storeTuple (make_tuple (rani(10)));
241 arg3->storeTuple (make_tuple (rani(10), TimeVar(randTime())));
242 arg4->storeTuple (make_tuple (rani(10), TimeVar(randTime())));
243
244 arg5->storeTuple (make_tuple (TTime (randTime()), Tstr("glorious"), twoRandomDigits() ));
245
246 CHECK (!arg5->canUndo());
247
248 arg5->tie(undoIt, captureState)
249 .tieCaptureFunc() // bind capturing function to memento storage,
250 (TTime(), Tstr("destruction"), 11); // then invoke the bound capturing mechanism
251
252 CHECK (arg5->canUndo());
253 CHECK (*arg5->memento() == "destruction");
254
255 VERIFY_ERROR(MISSING_MEMENTO, arg4->memento().i5i[3] = 513 );
256
257 for_each (tup, showIt);
258 }
259
260
261
265 void
267 {
268 for_each (tup, checkSerialisation);
269 }
270
271
272
276 void
278 {
279 typedef void SIG_do(Tracker<TimeVar>, Tracker<string>, int);
281 using MemHolder = MementoTie<SIG_do, Tracker<string>>;
282
283 Args args;
284 CHECK (isnil (args));
285 cout << showSizeof(args) << endl;
286
287 // store a set of parameter values, later to be used on invocation
288 args.storeTuple (
289 make_tuple (TTime(randTime()), Tstr("Lumiera rocks"), twoRandomDigits() ));
290 CHECK (!isnil (args));
291 cout << args << endl;
292
293 CHECK (!args.canUndo());
294 VERIFY_ERROR(MISSING_MEMENTO, args.memento() );
295
296 MemHolder& memHolder = args.tie(undoIt,captureState);
297 CHECK (!memHolder); // no stored memento....
298 CHECK (!args.canUndo());
299
301 function<SIG_do> undoFun = memHolder.tieUndoFunc();
302 function<SIG_do> captFun = memHolder.tieCaptureFunc();
303
304 typedef function<void()> OpFun;
305
306 // now close all the functions with the stored parameter values...
310
311 protocol.seekp(0);
312 protocol << "START...";
313
315 cout << "captured state: " << args.memento() << endl;
317 CHECK (!isnil (*args.memento()));
318 CHECK (args.canUndo());
319 cout << args << endl;
320
322 cout << protocol.str() << endl;
324 cout << protocol.str() << endl;
325
326 // Commands can serve as prototype to be copied....
327 Args argsCopy (args);
329 protocol.seekp(0);
330 protocol << "RESET...";
331
332 args.storeTuple (
333 make_tuple (TTime(TimeValue(123456)), Tstr("unbelievable"), twoRandomDigits() ));
334 cout << "modified: " << args << endl;
335 cout << "copied : " << argsCopy << endl; // holds still the old params & memento
336
338 cout << protocol.str() << endl;
339 }
340
341 };
342
343
344
346 LAUNCHER (CommandArgument_test, "unit controller");
347
348
349}}} // namespace steam::control::test
Simple vector based collection of pointers, managing lifecycle of the pointed-to objects.
basic constant internal time value.
a mutable time value, behaving like a plain number, allowing copy and re-accessing
Lumiera's internal time value datatype.
virtual void invoke(CmdFunctor const &)=0
invoke functor using the stored parameter values
This is "the" top level CmdClosure implementation.
A front-end for using printf-style formatting.
A passive container record holding the actual command arguments & UNDO state.
#define LERR_(_NAME_)
Definition error.hpp:45
Automatically use custom string conversion in C++ stream output.
Front-end for printf-style string template interpolation.
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
string showSizeof(size_t siz, string name)
for printing sizeof().
lib::time::Time randTime()
create a random but not insane Time value between 1s ... 10min + 500ms
void undoIt(Tracker< TimeVar > time, Tracker< string >, int, Tracker< string > memento)
ostringstream protocol
used to verify the test function calls
void doIt(Tracker< TimeVar > time, Tracker< string > str, int rand)
Tracker< string > captureState(Tracker< TimeVar >, Tracker< string > xstr, int)
FunErasure< StoreFunction > CmdFunctor
A neutral container internally holding the functor used to implement the Command.
Steam-Layer implementation namespace root.
Test runner and basic definitions for tests.
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
disable_if< can_IterForEach< Container >, FUN > for_each(Container const &coll, FUN doIt)
operate on all elements of a STL container.
bool isnil(lib::time::Duration const &dur)
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
Managing lifecycle for a collection of objects.
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.
Perform operations "for each element" of a collection.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...