Lumiera  0.pre.03
»edit your freedom«
command-clone-builder-test.cpp
Go to the documentation of this file.
1 /*
2  CommandCloneBuilder(Test) - verify building an implementation clone
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"
34 #include "lib/symbol.hpp"
35 #include "lib/util.hpp"
36 #include "lib/p.hpp"
37 
39 
40 
41 namespace steam {
42 namespace control {
43 namespace test {
44 
45  using namespace lib::meta;
46 
47  typedef lib::P<CommandImpl> PCmdImpl;
48 
49 
50  namespace { // test config...
51  HandlingPattern::ID TEST_HANDLING_PATTERN = HandlingPattern::DUMMY;
52  }
53 
54 
55 
56 
57 
58 
59  /****************************************************************************/
73  class CommandCloneBuilder_test : public Test
74  {
75 
76 
77  virtual void
78  run (Arg)
79  {
81  CHECK (&registry);
82  uint cnt_inst = registry.instance_count();
83 
84  {
85  PCmdImpl source = buildTestImplFrame (registry);
86  PCmdImpl clone = registry.createCloneImpl (*source);
87 
88  verifySeparation (source, clone);
89  }
90 
91  CHECK (cnt_inst == registry.instance_count());
92  }
93 
94 
95 
96  PCmdImpl
97  buildTestImplFrame (CommandRegistry& registry)
98  {
99  // simulate what normally happens within a CommandDef
100  typedef void Sig_oper(int);
101  typedef long Sig_capt(int);
102  typedef void Sig_undo(int,long);
103 
104  function<Sig_oper> o_Fun (command1::operate);
105  function<Sig_capt> c_Fun (command1::capture);
106  function<Sig_undo> u_Fun (command1::undoIt);
107 
108  CHECK (o_Fun && c_Fun && u_Fun);
109  PCmdImpl cmd = registry.newCommandImpl(o_Fun,c_Fun,u_Fun);
110 
111  // make ready for execution
112  bindRandArgument (*cmd);
113  CHECK (cmd->canExec());
114  return cmd;
115  }
116 
117 
119  void
121  {
122  typedef Types<int> ArgType;
123  TypedArguments<Tuple<ArgType>> arg (std::make_tuple (rand() % 10000));
124  cmd.setArguments (arg);
125  CHECK (cmd.canExec());
126  }
127 
128 
134  void
135  verifySeparation (PCmdImpl orig, PCmdImpl copy)
136  {
137  CHECK (orig && copy);
138  CHECK (orig->canExec());
139  CHECK (copy->canExec());
140 
141 
142  // prepare for command invocation on implementation level....
143  HandlingPattern const& testExec = HandlingPattern::get(TEST_HANDLING_PATTERN);
144  command1::check_ = 0;
145 
146  bindRandArgument (*orig);
147  CHECK ( orig->canExec());
148  CHECK (!orig->canUndo());
149  testExec.exec (*orig, "Execute original"); // EXEC 1
150  long state_after_exec1 = command1::check_;
151  CHECK (command1::check_ > 0);
152  CHECK (orig->canUndo());
153 
154  CHECK (!copy->canUndo());
155  testExec.exec (*copy, "Execute clone"); // EXEC 2
156  CHECK (command1::check_ != state_after_exec1);
157  CHECK (copy->canUndo());
158 
159  // invoke UNDO on the clone
160  testExec.undo (*copy, "Undo clone"); // UNDO 2
161  CHECK (command1::check_ == state_after_exec1);
162 
163  // invoke UNDO on original
164  testExec.undo (*orig, "Undo original"); // UNDO 1
165  CHECK (command1::check_ ==0);
166  }
167 
168  };
169 
170 
172  LAUNCHER (CommandCloneBuilder_test, "function controller");
173 
174 
175 }}} // namespace steam::control::test
Definition: run.hpp:49
Implementation helper to bind Steam-Layer commands with arbitrary argument tuples.
shared_ptr< CommandImpl > newCommandImpl(function< SIG_OPER > &operFunctor, function< SIG_CAPT > &captFunctor, function< SIG_UNDO > &undoFunctor)
set up a new command implementation frame
bool canExec() const
< state check: sufficiently defined to be invoked
Top level of the command implementation.
Managing command definitions and the storage of individual command objects.
Customised refcounting smart pointer.
Registry managing command implementation objects (Singleton).
Steam-Layer implementation namespace root.
Metaprogramming with tuples-of-types and the std::tuple record.
Marker types to indicate a literal string and a Symbol.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void bindRandArgument(CommandImpl &cmd)
Helper: create random command parameter binding.
Pre-defined command execution skeletons.
Some dummy command functions used for building unit test cases.
shared_ptr< CommandImpl > createCloneImpl(CommandImpl const &refObject)
create an allocation for holding a clone of the given CommandImpl data.
Definition: command.cpp:226
Steam-Layer Command implementation.
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:78
static HandlingPattern const & get(ID id)
retrieve the pre-configured pattern
Interface: Operation Skeleton how to invoke or undo a command.
static lib::Depend< CommandRegistry > instance
storage for the singleton factory used to access CommandRegistry