Lumiera  0.pre.03
»edit your freedom«
command-mutation-test.cpp
Go to the documentation of this file.
1 /*
2  CommandMutation(Test) - checking the functor and undo-functor used within Steam-commands
3 
4  Copyright (C) Lumiera.org
5  2009, 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"
34 #include "lib/meta/typelist.hpp"
35 #include "lib/format-cout.hpp"
36 
37 #include <functional>
38 #include <cstdlib>
39 #include <string>
40 
41 using std::function;
42 using std::string;
43 using std::rand;
44 
45 
46 namespace steam {
47 namespace control {
48 namespace test {
49 
50  using namespace lib::meta;
51  using control::CmdClosure;
52  using LERR_(MISSING_MEMENTO);
53  using LERR_(UNBOUND_ARGUMENTS);
54 
55 
56  namespace { /* ======= test functions to bind ========= */
57 
58  int testVal=0;
59 
60  void
61  testFunc (int val)
62  {
63  testVal += val;
64  }
65 
66  int
67  capture ()
68  {
69  return testVal;
70  }
71 
72  }
73 
74 
75 
76  /***********************************************************************/
87  class CommandMutation_test : public Test
88  {
89 
90  virtual void
91  run (Arg)
92  {
93  checkMutation();
94  checkUndoMutation();
95  checkStateCapturingMechanism();
96  }
97 
98 
103  void
105  {
106  typedef void SIG_fun(int);
107  function<SIG_fun> funky = testFunc;
108 
109  Mutation functor (funky);
110 
111  SimpleClosure<SIG_fun> nullClosure;
112  CHECK (not nullClosure.isValid());
113  cout << "empty placeholder closure: " << nullClosure << endl;
114  VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) );
115 
116  // now create a real closure....
117  Tuple<Types<int>> param = std::make_tuple (23);
118  SimpleClosure<void(int)> closed_over{param};
119 
120  CmdClosure& closure (closed_over);
121  CHECK (closure);
122 
123  cout << "param values: " << closure << endl;
124 
125  testVal = 0;
126  functor(closure);
127  CHECK (testVal == 23);
128  functor(closure);
129  CHECK (testVal == 2*23);
130  }
131 
132 
148  void
150  {
151  function<void(int)> undo_func = testFunc;
152  function<int(void)> cap_func = capture;
153 
154  typedef MementoTie<void(),int> MemHolder;
155 
156  MemHolder mementoHolder (undo_func,cap_func);
157  UndoMutation undoFunctor (mementoHolder);
158  CHECK (!mementoHolder);
159 
160  SimpleClosure<void(void)> nullClosure;
161  VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor(nullClosure) );
162  VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor.captureState(nullClosure) );
163 
164  Tuple<Types<> > param;
165  SimpleClosure<void()> clo{param};
166 
167  CHECK (!mementoHolder);
168  VERIFY_ERROR (MISSING_MEMENTO, undoFunctor (clo) );
169  VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
170 
171  testVal = 11;
172  undoFunctor.captureState(clo);
173  CHECK (mementoHolder);
174  CHECK (testVal == 11);
175 
176  int mem = mementoHolder.getState();
177  cout << "saved state: " << mem << endl;
178 
179  undoFunctor(clo);
180  CHECK (testVal == 11 + 11);
181  undoFunctor(clo);
182  CHECK (testVal == 11 + 11 + 11);
183  undoFunctor.captureState(clo);
184  CHECK (33 == mementoHolder.getState());
185  undoFunctor(clo);
186  CHECK (testVal == 33 + 33);
187  testVal = 9;
188  undoFunctor(clo);
189  CHECK (testVal == 42);
190  }
191 
192 
195  void
197  {
198  typedef MementoTie<void(),int> MemHolder;
199 
200  MemHolder mementoHolder (testFunc, capture);
201 
202  function<void()> bound_undo_func = mementoHolder.tieUndoFunc();
203  function<void()> bound_cap_func = mementoHolder.tieCaptureFunc();
204 
205 
206  int rr (rand() % 100);
207  testVal = rr;
208  bound_cap_func(); // invoke state capturing
209  CHECK (rr == mementoHolder.getState());
210 
211  testVal = 10; // meanwhile "somehow" mutate the state
212  bound_undo_func(); // invoking the undo() feeds back the memento
213  CHECK (testVal == 10+rr);
214  }
215  };
216 
217 
219  LAUNCHER (CommandMutation_test, "unit controller");
220 
221 
222 }}} // namespace steam::control::test
Automatically use custom string conversion in C++ stream output.
A template metaprogramming technique for manipulating collections of types.
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Definition: run.hpp:49
Core of a Steam-Layer command: functor containing the operation to be executed.
Proof-of-concept implementation of CmdClosure.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Steam-Layer implementation namespace root.
Metaprogramming with tuples-of-types and the std::tuple record.
Specialised version of the command Mutation functor, used to implement the UNDO functionality.
A special binding used by Steam-Layer commands for capturing UNDO state information.
Simple test class runner.
Dummy / proof-of-concept implementation of CmdClosure.
A collection of frequently used helper functions to support unit testing.
Unspecific command functor for implementing Steam-Layer Command.
virtual bool isValid() const override
does this closure hold a valid argument tuple?
Binding together state capturing and execution of the undo operation.
Definition: memento-tie.hpp:88
Verify the behaviour of the type erased closure, which is used by Steam-Layer commands to implement t...