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 
53 
54  namespace { /* ======= test functions to bind ========= */
55 
56  int testVal=0;
57 
58  void
59  testFunc (int val)
60  {
61  testVal += val;
62  }
63 
64  int
65  capture ()
66  {
67  return testVal;
68  }
69 
70  }
71 
72 
73 
74  /***********************************************************************/
85  class CommandMutation_test : public Test
86  {
87 
88  virtual void
89  run (Arg)
90  {
91  checkMutation();
92  checkUndoMutation();
93  checkStateCapturingMechanism();
94  }
95 
96 
101  void
103  {
104  typedef void SIG_fun(int);
105  function<SIG_fun> funky = testFunc;
106 
107  Mutation functor (funky);
108 
109  SimpleClosure<SIG_fun> nullClosure;
110  CHECK (not nullClosure.isValid());
111  cout << "empty placeholder closure: " << nullClosure << endl;
112  VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) );
113 
114  // now create a real closure....
115  Tuple<Types<int>> param = std::make_tuple (23);
116  SimpleClosure<void(int)> closed_over{param};
117 
118  CmdClosure& closure (closed_over);
119  CHECK (closure);
120 
121  cout << "param values: " << closure << endl;
122 
123  testVal = 0;
124  functor(closure);
125  CHECK (testVal == 23);
126  functor(closure);
127  CHECK (testVal == 2*23);
128  }
129 
130 
146  void
148  {
149  function<void(int)> undo_func = testFunc;
150  function<int(void)> cap_func = capture;
151 
152  typedef MementoTie<void(),int> MemHolder;
153 
154  MemHolder mementoHolder (undo_func,cap_func);
155  UndoMutation undoFunctor (mementoHolder);
156  CHECK (!mementoHolder);
157 
158  SimpleClosure<void(void)> nullClosure;
159  VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor(nullClosure) );
160  VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor.captureState(nullClosure) );
161 
162  Tuple<Types<> > param;
163  SimpleClosure<void()> clo{param};
164 
165  CHECK (!mementoHolder);
166  VERIFY_ERROR (MISSING_MEMENTO, undoFunctor (clo) );
167  VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
168 
169  testVal = 11;
170  undoFunctor.captureState(clo);
171  CHECK (mementoHolder);
172  CHECK (testVal == 11);
173 
174  int mem = mementoHolder.getState();
175  cout << "saved state: " << mem << endl;
176 
177  undoFunctor(clo);
178  CHECK (testVal == 11 + 11);
179  undoFunctor(clo);
180  CHECK (testVal == 11 + 11 + 11);
181  undoFunctor.captureState(clo);
182  CHECK (33 == mementoHolder.getState());
183  undoFunctor(clo);
184  CHECK (testVal == 33 + 33);
185  testVal = 9;
186  undoFunctor(clo);
187  CHECK (testVal == 42);
188  }
189 
190 
193  void
195  {
196  typedef MementoTie<void(),int> MemHolder;
197 
198  MemHolder mementoHolder (testFunc, capture);
199 
200  function<void()> bound_undo_func = mementoHolder.tieUndoFunc();
201  function<void()> bound_cap_func = mementoHolder.tieCaptureFunc();
202 
203 
204  int rr (rand() % 100);
205  testVal = rr;
206  bound_cap_func(); // invoke state capturing
207  CHECK (rr == mementoHolder.getState());
208 
209  testVal = 10; // meanwhile "somehow" mutate the state
210  bound_undo_func(); // invoking the undo() feeds back the memento
211  CHECK (testVal == 10+rr);
212  }
213  };
214 
215 
217  LAUNCHER (CommandMutation_test, "unit controller");
218 
219 
220 }}} // 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 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:89
Verify the behaviour of the type erased closure, which is used by Steam-Layer commands to implement t...