Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
command-use2-test.cpp
Go to the documentation of this file.
1 /*
2  CommandUse2(Test) - usage aspects II
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"
30 #include "proc/control/command.hpp"
33 #include "lib/format-string.hpp"
34 #include "lib/format-obj.hpp"
35 #include "lib/util.hpp"
36 
38 
39 extern "C" {
41 }
44 
45 #include <functional>
46 #include <boost/ref.hpp>
47 #include <boost/lexical_cast.hpp>
48 #include <string>
49 
50 
51 namespace proc {
52 namespace control {
53 namespace test {
54 
55 
56  using util::_Fmt;
57  using std::string;
58  using std::function;
59  using std::bind;
60  using std::ref;
61  using boost::lexical_cast;
62  using util::contains;
63 
64 
65  using lumiera::error::LERR_(EXTERNAL);
66 
67 
73  template<typename TY>
74  inline bool
75  protocolled (TY val2check)
76  {
77  return contains ( command2::check_.str()
78  , util::toString (val2check)
79  );
80  }
81 
82 
83 
84 
85  /***********************************************************************/
93  class CommandUse2_test : public Test
94  {
95 
96  int randVal_;
97 
98  string randomTxt()
99  {
100  _Fmt fmt ("invoked( %2d )");
101 
102  randVal_ = rand() % 100;
103  return fmt % randVal_;
104  }
105 
106  bool blowUp_;
107 
108 
109  virtual void
110  run (Arg)
111  {
112  command2::check_.seekp(0);
113  uint cnt_defs = Command::definition_count();
114  uint cnt_inst = Command::instance_count();
115 
116  function<string()> randFun = bind (&CommandUse2_test::randomTxt, this);
117 
118  // prepare a command definition (prototype)
119  CommandDef ("test.command2")
121  .captureUndo (command2::capture)
122  .undoOperation (command2::undoIt)
123  .bind (randFun, &blowUp_);
124 
125  //note : blowUp_ is bound via pointer,
126  // thus we can provoke an exception at will.
127  blowUp_ = false;
128 
129 
131 // check_ThrowOnError(); //////////////////////////////////////////////////////////////////////TICKET #211
133 
134 
135  Command::remove ("test.command2");
136  Command::remove ("test.command2.1");
137  CHECK (cnt_defs == Command::definition_count());
138  CHECK (cnt_inst == Command::instance_count());
139  }
140 
141 
142 
143  void
145  {
146  Command com = Command::get("test.command2");
147 
148  CHECK (!protocolled("invoked"));
149 
150  bool success = com();
151 
152  CHECK (success);
153  CHECK (protocolled("invoked"));
154  CHECK (protocolled(randVal_));
155 
156  success = com.undo();
157  CHECK (success); // UNDO invoked successfully
158  CHECK (!protocolled(randVal_));
159  CHECK (protocolled("UNDO"));
160 
161  blowUp_ = true;
162  string current = command2::check_.str();
163 
164  success = com();
165  CHECK (not success); // NOT executed successfully (exception thrown and caught)
166  CHECK (command2::check_.str() == current);
167  CHECK (!lumiera_error_peek()); // already absorbed
168 
169  success = com.undo();
170  CHECK (not success); // UNDO failed (exception thrown and caught)
171  CHECK (command2::check_.str() == current);
172 
173  blowUp_ = false;
174  }
175 
176 
177 
178  void
180  {
181  Command com = Command::get("test.command2");
182 
183  blowUp_ = false;
185  CHECK (protocolled(randVal_));
186 
187  blowUp_ = true;
188  string current = command2::check_.str();
190 
191  VERIFY_ERROR( EXTERNAL, com.exec (doThrow) );
192  CHECK (command2::check_.str() == current);
193 
194  // we can achieve the same effect,
195  // after changing the default HandlingPatern for this command instance
197  com.storeDef ("test.command2.1");
198 
199  Command com2 = Command::get("test.command2.1");
200  VERIFY_ERROR( EXTERNAL, com2() );
201  CHECK (command2::check_.str() == current);
202 
203  blowUp_ = false;
204  com2();
205  CHECK (command2::check_.str() > current);
206  CHECK (protocolled(randVal_));
207 
208  com2.undo();
209  CHECK (!protocolled(randVal_));
210  }
211 
212 
213 
223  void
225  {
226  CHECK (not ProcDispatcher::instance().isRunning());
229 #define __DELAY__ usleep(10000);
230 
231  bool thread_has_ended{false};
232  ProcDispatcher::instance().start ([&] (string*) { thread_has_ended = true; });
233 
234  CHECK (ProcDispatcher::instance().isRunning());
235  CHECK (not thread_has_ended);
236 
237  //----Session-Loop-Thread-is-running------------------------
238 
239  string cmdID {"test.command2"};
240  string prevExecLog = command2::check_.str();
241 
242  // previous test cases prepared the arguments
243  // so that we can just trigger command execution.
244  // In the real application, this call is issued
245  // from CoreService when receiving a command
246  // invocation message over the UI-Bus
247  SessionCommand::facade().invoke(cmdID);
248 
249  __DELAY__ // wait a moment for the other thread to dispatch the command...
250  CHECK (prevExecLog != command2::check_.str());
251 
252  //----Session-Loop-Thread-is-running------------------------
253 
254  // shut down the ProcDispatcher...
255  CHECK (ProcDispatcher::instance().isRunning());
256  ProcDispatcher::instance().requestStop();
257 
258  __DELAY__ // wait a moment for the other thread to terminate...
259  CHECK (not ProcDispatcher::instance().isRunning());
260  CHECK (thread_has_ended);
261 
263  }
264  };
265 
266 
268  LAUNCHER (CommandUse2_test, "function controller");
269 
270 
271 }}} // namespace proc::control::test
auto operation(FUN operation_to_define)
ExecResult exec()
Definition: command.hpp:240
static size_t definition_count()
Definition: command.cpp:296
lumiera_err lumiera_error_peek(void)
Check current error state without clearing it Please avoid this function and use lumiera_error() if p...
Definition: error-state.c:142
#define __DELAY__
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:174
static HandlingPattern const & get(ID id)
retrieve the pre-configured pattern
Definition: run.hpp:49
Front-end for printf-style string template interpolation.
void throwOnError()
Check the lumiera error state, which maybe was set by C-code.
Definition: error.hpp:239
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify a statement indeed raises an exception.
HandlingPattern::ID setHandlingPattern(HandlingPattern::ID)
define a handling pattern to be used by default
Definition: command.cpp:479
A front-end for using printf-style formatting.
Helper class used solely for defining a Command-Object.
bool protocolled(TY val2check)
diagnostics: checks if the given value has been written to the test protocol (string stream) of comma...
static lib::Depend< SessionCommand > facade
static storage for the facade access front-end
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
Definition: util.hpp:205
std::vector< string > & Arg
Definition: run.hpp:54
#define LERR_(_NAME_)
Definition: error.hpp:58
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
LAUNCHER(ArgumentTupleAccept_test,"unit controller")
Register this test class...
Proc-Layer command frontend.
A collection of frequently used helper functions to support unit testing.
static size_t instance_count()
Definition: command.cpp:305
static Command get(Symbol cmdID)
Access existing command for use.
Definition: command.cpp:127
void undoIt(FunS, bool *fail, string previousProtocol)
Pre-defined command execution skeletons.
void lumiera_interfaceregistry_destroy(void)
Interface: Operation Skeleton how to invoke or undo a command.
void lumiera_interfaceregistry_init(void)
Initialise the interface registry.
static lib::Depend< ProcDispatcher > instance
storage for Singleton access
Global registry for interfaces (extension points).
Simple functions to represent objects, for debugging and diagnostics.
void operate(FunS func, bool *fail)
Some dummy command functions used for building unit test cases.
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:125
static bool remove(Symbol cmdID)
Definition: command.cpp:248
Command storeDef(Symbol newCmdID) const
create a clone definition
Definition: command.cpp:190
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63
Actually defining a command and binding it to execution parameters.
Dispatch and execute mutation operations on the High-level model.
ExecResult undo()
Definition: command.hpp:246
Major public Interface to the Session subsystem of Lumiera GUI.