Lumiera  0.pre.03
»edit your freedom«
command-use2-test.cpp
Go to the documentation of this file.
1 /*
2  CommandUse2(Test) - usage aspects II
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"
20 #include "lib/test/test-helper.hpp"
24 #include "lib/format-string.hpp"
25 #include "lib/format-obj.hpp"
26 #include "lib/util.hpp"
27 
29 
30 extern "C" {
32 }
35 
36 #include <functional>
37 #include <boost/ref.hpp>
38 #include <boost/lexical_cast.hpp>
39 #include <string>
40 
41 
42 namespace steam {
43 namespace control {
44 namespace test {
45 
46  using util::_Fmt;
47  using std::string;
48  using std::function;
49  using std::bind;
50  using std::ref;
51  using boost::lexical_cast;
52  using util::contains;
53 
54  using LERR_(EXTERNAL);
55 
56 
62  template<typename TY>
63  inline bool
64  protocolled (TY val2check)
65  {
66  return contains ( command2::check_.str()
67  , util::toString (val2check)
68  );
69  }
70 
71 
72 
73 
74  /***********************************************************************/
82  class CommandUse2_test : public Test
83  {
84 
85  int randVal_;
86 
87  string randomTxt()
88  {
89  _Fmt fmt ("invoked( %2d )");
90 
91  randVal_ = rani (100);
92  return fmt % randVal_;
93  }
94 
95  bool blowUp_;
96 
97 
98  virtual void
99  run (Arg)
100  {
101  seedRand();
102  command2::check_.seekp(0);
103  uint cnt_defs = Command::definition_count();
104  uint cnt_inst = Command::instance_count();
105 
106  function<string()> randFun = bind (&CommandUse2_test::randomTxt, this);
107 
108  // prepare a command definition (prototype)
109  CommandDef ("test.command2")
110  .operation (command2::operate)
111  .captureUndo (command2::capture)
112  .undoOperation (command2::undoIt)
113  .bind (randFun, &blowUp_);
114 
115  //note : blowUp_ is bound via pointer,
116  // thus we can provoke an exception at will.
117  blowUp_ = false;
118 
119 
120  check_defaultHandlingPattern();
121 // check_ThrowOnError(); //////////////////////////////////////////////////////////////////////TICKET #211
123 
124 
125  Command::remove ("test.command2");
126  Command::remove ("test.command2.1");
127  CHECK (cnt_defs == Command::definition_count());
128  CHECK (cnt_inst == Command::instance_count());
129  }
130 
131 
132 
133  void
134  check_defaultHandlingPattern()
135  {
136  Command com = Command::get("test.command2");
137 
138  CHECK (!protocolled("invoked"));
139 
140  bool success = com();
141 
142  CHECK (success);
143  CHECK (protocolled("invoked"));
144  CHECK (protocolled(randVal_));
145 
146  success = com.undo();
147  CHECK (success); // UNDO invoked successfully
148  CHECK (!protocolled(randVal_));
149  CHECK (protocolled("UNDO"));
150 
151  blowUp_ = true;
152  string current = command2::check_.str();
153 
154  success = com();
155  CHECK (not success); // NOT executed successfully (exception thrown and caught)
156  CHECK (command2::check_.str() == current);
157  CHECK (!lumiera_error_peek()); // already absorbed
158 
159  success = com.undo();
160  CHECK (not success); // UNDO failed (exception thrown and caught)
161  CHECK (command2::check_.str() == current);
162 
163  blowUp_ = false;
164  }
165 
166 
167 
168  void
169  check_ThrowOnError()
170  {
171  Command com = Command::get("test.command2");
172 
173  blowUp_ = false;
174  com.exec(HandlingPattern::SYNC_THROW);
175  CHECK (protocolled(randVal_));
176 
177  blowUp_ = true;
178  string current = command2::check_.str();
179  HandlingPattern const& doThrow = HandlingPattern::get(HandlingPattern::SYNC_THROW);
180 
181  VERIFY_ERROR( EXTERNAL, com.exec (doThrow) );
182  CHECK (command2::check_.str() == current);
183 
184  // we can achieve the same effect,
185  // after changing the default HandlingPatern for this command instance
186  com.setHandlingPattern(HandlingPattern::SYNC_THROW);
187  com.storeDef ("test.command2.1");
188 
189  Command com2 = Command::get("test.command2.1");
190  VERIFY_ERROR( EXTERNAL, com2() );
191  CHECK (command2::check_.str() == current);
192 
193  blowUp_ = false;
194  com2();
195  CHECK (command2::check_.str() > current);
196  CHECK (protocolled(randVal_));
197 
198  com2.undo();
199  CHECK (!protocolled(randVal_));
200  }
201 
202 
203 
213  void
215  {
216  CHECK (not SteamDispatcher::instance().isRunning());
219 #define __DELAY__ usleep(10000);
220 
221  bool thread_has_ended{false};
222  SteamDispatcher::instance().start ([&] (string*) { thread_has_ended = true; });
223 
224  CHECK (SteamDispatcher::instance().isRunning());
225  CHECK (not thread_has_ended);
226 
227  //----Session-Loop-Thread-is-running------------------------
228 
229  string cmdID {"test.command2"};
230  string prevExecLog = command2::check_.str();
231 
232  // previous test cases prepared the arguments
233  // so that we can just trigger command execution.
234  // In the real application, this call is issued
235  // from CoreService when receiving a command
236  // invocation message over the UI-Bus
237  SessionCommand::facade().invoke(cmdID);
238 
239  __DELAY__ // wait a moment for the other thread to dispatch the command...
240  CHECK (prevExecLog != command2::check_.str());
241 
242  //----Session-Loop-Thread-is-running------------------------
243 
244  // shut down the SteamDispatcher...
245  CHECK (SteamDispatcher::instance().isRunning());
246  SteamDispatcher::instance().requestStop();
247 
248  __DELAY__ // wait a moment for the other thread to terminate...
249  CHECK (not SteamDispatcher::instance().isRunning());
250  CHECK (thread_has_ended);
251 
252  lumiera_interfaceregistry_destroy();
253  }
254  };
255 
256 
258  LAUNCHER (CommandUse2_test, "function controller");
259 
260 
261 }}} // namespace steam::control::test
Helper class used solely for defining a Command-Object.
HandlingPattern::ID setHandlingPattern(HandlingPattern::ID)
define a handling pattern to be used by default
Definition: command.cpp:465
static lib::Depend< SteamDispatcher > instance
storage for Singleton access
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:133
static size_t definition_count()
Definition: command.cpp:289
Definition: run.hpp:40
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:233
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
Dispatch and execute mutation operations on the High-level model.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
static Command get(Symbol cmdID)
Access existing command for use.
Definition: command.cpp:120
Command storeDef(Symbol newCmdID) const
create a clone definition
Definition: command.cpp:183
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
static lib::Depend< SessionCommand > facade
static storage for the facade access front-end
static size_t instance_count()
Definition: command.cpp:298
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Steam-Layer command frontend.
A collection of frequently used helper functions to support unit testing.
bool protocolled(TY val2check)
diagnostics: checks if the given value has been written to the test protocol (string stream) of comma...
Pre-defined command execution skeletons.
void lumiera_interfaceregistry_init(void)
Initialise the interface registry.
Global registry for interfaces (extension points).
Simple functions to represent objects, for debugging and diagnostics.
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:115
static HandlingPattern const & get(ID id)
retrieve the pre-configured pattern
Actually defining a command and binding it to execution parameters.
Interface: Operation Skeleton how to invoke or undo a command.
Major public Interface to the Session subsystem of Lumiera GUI.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255