Lumiera  0.pre.03
»edit your freedom«
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
abstract-tangible-test.cpp
Go to the documentation of this file.
1 /*
2  AbstractTangible(Test) - cover the operations of any tangible UI element
3 
4  Copyright (C)
5  2015, 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 
14 
38 #include "lib/test/run.hpp"
39 #include "lib/test/test-helper.hpp"
40 #include "lib/test/event-log.hpp"
41 #include "test/mock-elm.hpp"
42 #include "test/test-nexus.hpp"
43 #include "lib/idi/genfunc.hpp"
44 #include "lib/idi/entry-id.hpp"
47 #include "lib/diff/tree-diff.hpp"
48 #include "lib/time/timevalue.hpp"
49 #include "lib/format-cout.hpp"
50 #include "lib/symbol.hpp"
51 #include "lib/error.hpp"
52 #include "lib/util.hpp"
53 
54 #include <sigc++/signal.h>
55 
56 
57 using lib::Symbol;
58 using util::isnil;
59 using util::toString;
60 using lib::time::Time;
63 using lib::idi::EntryID;
64 using lib::diff::Rec;
65 using lib::diff::MakeRec;
66 using lib::diff::GenNode;
67 using lib::diff::DataCap;
71 
72 
73 
74 namespace stage {
75 namespace model {
76 namespace test {
77 
78  using LERR_(WRONG_TYPE);
79  using ID = lib::idi::BareEntryID const&;
80 
81  namespace { // test fixture...
82 
83  /* === dummy operation to be invoked through the command system === */
84 
85  int dummyState = 0;
86 
87  void
88  operate (int val)
89  {
90  dummyState = val;
91  }
92 
93  int
94  capture (int)
95  {
96  return dummyState;
97  }
98 
99  void
100  undoIt (int, int oldState)
101  {
102  dummyState = oldState;
103  }
104 
105 
106 
107  const Symbol DUMMY_CMD_ID{"test.AbstractTangibleTest_dummy_command"};
108 
109 
116  void
117  processCommandInvocation (GenNode const& commandMsg)
118  {
119  REQUIRE (string{DUMMY_CMD_ID} == commandMsg.idi.getSym());
120 
121  auto cmd = Command::get (DUMMY_CMD_ID);
122  auto arg = commandMsg.data.get<Rec>().scope()->data.get<int>();
123  cmd.bind (arg);
124  cmd();
125  }
126 
127 
128  }//(End) test fixture
129 
130 
131 
132 
133 
134 
135  /***********************************************************************/
164  class AbstractTangible_test : public Test
165  {
166 
167  virtual void
168  run (Arg)
169  {
170  seedRand();
171 
173  invokeCommand();
174  markState();
175  revealer();
176  notify();
177  mutate();
178  }
179 
180 
203  void
205  {
207  MockElm mock("dummy");
208 
209  CHECK (mock.verify("ctor"));
210  CHECK (mock.verifyEvent("create","dummy"));
211  CHECK (mock.verify("ctor").arg("dummy","TestNexus").on(&mock));
212 
213  CHECK ("dummy" == mock.getID().getSym());
214  CHECK (EntryID<MockElm>("dummy") == mock.getID());
215 
216  CHECK (!mock.verifyCall("reset"));
217 
218  // start manipulating state....
219  mock.slotExpand();
220  CHECK (mock.isExpanded());
221 
222  mock.reset();
223  CHECK (mock.verify("reset"));
224  CHECK (mock.verifyCall("reset"));
225  CHECK (mock.verifyCall("reset").on(&mock));
226  CHECK (mock.verifyCall("reset").on("dummy"));
227  CHECK (mock.verifyEvent("reset"));
228  CHECK (mock.verify("reset").after("ctor"));
229  CHECK (mock.verify("ctor").before("reset"));
230  CHECK (mock.ensureNot("reset").before("ctor"));
231  CHECK (mock.ensureNot("ctor").after("reset"));
232 
233  CHECK (mock.verify("reset").beforeEvent("reset"));
234  CHECK (mock.verifyCall("reset").beforeEvent("reset"));
235  CHECK (!mock.verifyCall("reset").afterEvent("reset"));
236 
237  CHECK (!mock.isTouched());
238  CHECK (!mock.isExpanded());
239 
240  mock.markMsg("qui dolorem ipsum quia dolor sit amet consectetur adipisci velit.");
241  CHECK (mock.verifyMark("Message", "dolor"));
242  CHECK (mock.verifyCall("doMsg"));
243  CHECK (mock.verifyCall("doMsg").arg("lorem ipsum"));
244  CHECK (mock.verifyCall("doMsg").argMatch("dolor.+dolor\\s+"));
245  CHECK (mock.verifyMatch("Rec\\(mark.+ID = Message.+\\{.+lorem ipsum"));
246 
247  EventLog log = mock.getLog();
248  log.verify("ctor")
249  .before("reset")
250  .before("lorem ipsum");
251 
252  // create further mock elements...
253  MockElm foo("foo"), bar("bar");
254  foo.verify("ctor").arg("foo");
255  bar.verify("ctor").arg("bar");
256 
257  bar.ensureNot("foo");
258  log.ensureNot("foo");
259  mock.ensureNot("foo");
260  CHECK (!foo.ensureNot("foo"));
261 
262  // now join the logs together,
263  // allowing to watch the combined events
264  bar.joinLog(mock);
265  foo.joinLog(mock);
266  CHECK (log.verifyEvent("logJoin","bar")
267  .beforeEvent("logJoin","foo"));
268 
269  CHECK (mock.verifyEvent("logJoin","bar")
270  .beforeEvent("logJoin","foo"));
271  CHECK (mock.verifyEvent("create","foo"));
272  CHECK (log.verifyEvent("create","foo"));
273  CHECK (log.verifyEvent("create","dummy")
274  .beforeEvent("create","bar")
275  .beforeEvent("create","foo"));
276 
277 
278  mock.kill();
279  foo.markMsg("dummy killed");
280  CHECK (log.verifyEvent("destroy","dummy")
281  .beforeCall("doMsg").on("foo"));
282 
283  // Access the log on the Test-Nexus hub
284  EventLog nexusLog = stage::test::Nexus::getLog();
285  CHECK (nexusLog.verifyEvent("destroy","dummy")
286  .beforeEvent("dummy successfully zombificated"));
287 
288  mock.slotExpand(); // attempt to operate the zombie
289  CHECK (nexusLog.verifyEvent("dummy successfully zombificated")
290  .beforeCall("note").on("ZombieNexus").arg("defunct-dummy", "expand")
291  .beforeEvent("error","sent note message to ZombieNexus"));
292 
293 
294  cout << "____Event-Log_________________\n"
295  << util::join(mock.getLog(), "\n")
296  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
297 
298  cout << "____Nexus-Log_________________\n"
299  << util::join(stage::test::Nexus::getLog(), "\n")
300  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
301  }
302 
303 
304 
305  void
306  invokeCommand ()
307  {
309  EventLog nexusLog = stage::test::Nexus::startNewLog();
310 
311  // Setup test stage: define a command/action "in Steam"
312  CommandDef (DUMMY_CMD_ID)
313  .operation (operate)
314  .captureUndo (capture)
315  .undoOperation (undoIt);
316 
318 
319  // the UI element to trigger this command invocation
320  MockElm mock("uiElm");
321 
322  int prevState = dummyState;
323  int concreteParam = 1 + rani(100);
324 
325  // on bus no traces from this command yet...
326  CHECK (nexusLog.ensureNot(string(DUMMY_CMD_ID)));
327 
328 
329  // message to bind parameter data and finally trigger the command
330  mock.invoke (DUMMY_CMD_ID, concreteParam);
331  CHECK (dummyState == concreteParam); // command was indeed invoked
332  CHECK (nexusLog.verifyCall("act").arg("«int»|" +toString(concreteParam))
333  .beforeEvent("bind and trigger command \""+DUMMY_CMD_ID));
334 
335  // verify proper binding, including UNDO state capture
336  Command::get (DUMMY_CMD_ID).undo();
337  CHECK (dummyState == prevState);
338 
339  cout << "____Nexus-Log_________________\n"
340  << util::join(nexusLog, "\n")
341  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
342 
343 
344  // reset to default (NOP) handler
346  }
347 
348 
363  void
365  {
367  EventLog nexusLog = stage::test::Nexus::startNewLog();
368 
369  sigc::signal<void> trigger_expand;
370  sigc::signal<void> trigger_collapse;
371 
372  MockElm mock("target");
373  ID targetID = mock.getID();
374 
375  trigger_expand.connect (sigc::mem_fun(mock, &Tangible::slotExpand));
376  trigger_collapse.connect (sigc::mem_fun(mock, &Tangible::slotCollapse));
377 
378  CHECK (not mock.isTouched());
379  CHECK (not mock.isExpanded());
380  CHECK (mock.ensureNot("expanded"));
381  CHECK (nexusLog.ensureNot("state-mark"));
382 
383  trigger_expand(); // emit signal
384 
385  CHECK (mock.isTouched());
386  CHECK (mock.isExpanded());
387  CHECK (mock.verifyCall("expand").arg(true)
388  .beforeEvent("expanded"));
389 
390  // and now the important part: state mark notification was sent over the bus...
391  CHECK (nexusLog.verifyCall("note").arg(targetID, GenNode{"expand", true})
392  .before("handling state-mark"));
393 
394 
395  trigger_collapse(); // emit other signal
396  CHECK (not mock.isExpanded());
397  CHECK (mock.isTouched());
398 
399  CHECK (mock.verifyEvent("create", "target")
400  .beforeEvent("expanded")
401  .beforeEvent("collapsed"));
402  CHECK (nexusLog.verifyCall("note").arg(targetID, GenNode{"expand", true})
403  .before("handling state-mark")
404  .beforeCall("note").arg(targetID, GenNode{"expand", false})
405  .before("handling state-mark"));
406 
407  trigger_collapse();
408  CHECK (not mock.isExpanded());
409 
410  // but note: redundant state changes do not cause sending of further state marks
411  CHECK (mock.ensureNot("collapsed")
412  .beforeCall("expand")
413  .beforeEvent("collapsed"));
414  CHECK (nexusLog.ensureNot("handling state-mark")
415  .beforeCall("note").arg(targetID, GenNode{"expand", false})
416  .before("handling state-mark")
417  .beforeCall("note").arg(targetID, GenNode{"expand", false}));
418 
419 
420 
421  // Second part: replay of a state mark via UI-Bus....
422  auto stateMark = GenNode{"expand", true};
423  auto& uiBus = stage::test::Nexus::testUI();
424 
425  CHECK (not mock.isExpanded());
426  CHECK (mock.ensureNot("mark"));
427 
428  uiBus.mark (targetID, stateMark);
429 
430  CHECK (nexusLog.verifyCall("mark").arg(targetID, stateMark)
431  .before("delivered mark to "+string(targetID)).arg(stateMark));
432 
433  CHECK (mock.verifyMark("expand", "true")
434  .beforeCall("expand").arg(true)
435  .beforeEvent("expanded"));
436  CHECK (mock.isExpanded());
437  CHECK (mock.isTouched());
438 
439  // the default handler defined in model::Tangible
440  // already supports some rather generic state changes,
441  // like e.g. a reset to the element's default state.
442  // Note that the actual implementation doReset()
443  // is a virtual function, here implemented in MockElm.
444  uiBus.mark (targetID, GenNode{"reset", true});
445  // note: payload is irrelevant for "reset" mark
446 
447  // and we're back to pristine state...
448  CHECK (not mock.isTouched());
449  CHECK (not mock.isExpanded());
450  CHECK (mock.verifyMark("reset", "true")
451  .afterEvent("expanded")
452  .beforeCall("reset")
453  .beforeEvent("reset"));
454 
455 
456  cout << "____Event-Log_________________\n"
457  << util::join(mock.getLog(), "\n")
458  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
459 
460  cout << "____Nexus-Log_________________\n"
461  << util::join(nexusLog, "\n")
462  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
463  }
464 
465 
470  void
472  {
474  EventLog nexusLog = stage::test::Nexus::startNewLog();
475 
476  MockElm mock("target");
477  ID targetID = mock.getID();
478 
479  sigc::signal<void> trigger_reveal;
480  trigger_reveal.connect (sigc::mem_fun(mock, &Tangible::slotReveal));
481 
482  CHECK (not mock.isTouched());
483  CHECK (not mock.isExpanded());
484  CHECK (mock.ensureNot("reveal"));
485  CHECK (mock.ensureNot("expanded"));
486  CHECK (nexusLog.ensureNot("state-mark"));
487 
488  bool revealed = false;
489  mock.installRevealer([&]()
490  { // NOTE: our mock "implementation" of the »reveal yourself« functionality
491  mock.slotExpand(); // explicitly prompts the element to expand itself,
492  revealed = true; // and then via closure sets a flag we can verify.
493  });
494 
495  trigger_reveal();
496 
497  CHECK (true == revealed);
498  CHECK (mock.isExpanded());
499  CHECK (mock.verifyEvent("create","target")
500  .beforeCall("reveal")
501  .beforeCall("expand").arg(true)
502  .beforeEvent("expanded"));
503 
504  // invoking the slotExpand() also emitted a state mark to persist that expansion state...
505  CHECK (nexusLog.verifyCall("note").arg(targetID, GenNode{"expand", true})
506  .before("handling state-mark"));
507 
508 
509  // second test: the same can be achieved via UI-Bus message...
510  revealed = false;
511  auto stateMark = GenNode{"reveal", 47}; // (payload argument irrelevant)
512  auto& uiBus = stage::test::Nexus::testUI();
513  CHECK (nexusLog.ensureNot("reveal"));
514 
515  uiBus.mark (targetID, stateMark); // send the state mark message to reveal the element
516 
517  CHECK (true == revealed);
518  CHECK (mock.verifyMark("reveal", 47)
519  .afterEvent("expanded")
520  .beforeCall("reveal")
521  .beforeCall("expand").arg(true));
522 
523  CHECK (nexusLog.verifyCall("mark").arg(targetID, stateMark)
524  .after("handling state-mark")
525  .before("reveal")
526  .beforeEvent("delivered mark"));
527 
528  // Note the fine point: the target element /was/ already expanded
529  // and thus there is no second "expanded" event, nor is there a
530  // second state mark emitted into the UI-Bus...
531  CHECK (mock.ensureNot("expanded")
532  .afterCall("reveal")
533  .afterEvent("expanded"));
534  CHECK (nexusLog.ensureNot("note")
535  .afterCall("mark").arg(targetID, stateMark)
536  .after("handling state-mark"));
537 
538 
539 
540  cout << "____Event-Log_________________\n"
541  << util::join(mock.getLog(), "\n")
542  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
543 
544  cout << "____Nexus-Log_________________\n"
545  << util::join(nexusLog, "\n")
546  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
547  }
548 
549 
554  void
556  {
558  EventLog nexusLog = stage::test::Nexus::startNewLog();
559 
560  MockElm mock("target");
561  ID targetID = mock.getID();
562  auto& uiBus = stage::test::Nexus::testUI();
563 
564  CHECK (mock.ensureNot("Flash"));
565  CHECK (mock.ensureNot("Error"));
566  CHECK (mock.ensureNot("Message"));
567  CHECK (isnil(mock.getMessage()));
568  CHECK (isnil(mock.getError()));
569  CHECK (not mock.isError());
570 
571  // now send a "Flash" mark via UI-Bus....
572  uiBus.mark (targetID, GenNode{"Flash", true });
573  CHECK (mock.verifyMark("Flash"));
574 
575  CHECK (mock.ensureNot("Error"));
576  CHECK (mock.ensureNot("Message"));
577  CHECK (isnil(mock.getMessage()));
578  CHECK (isnil(mock.getError()));
579 
580  uiBus.mark (targetID, GenNode{"Error", "getting serious"});
581  CHECK (mock.verifyMark("Error", "serious"));
582  CHECK (mock.isError());
583  CHECK ("getting serious" == mock.getError());
584  CHECK (isnil(mock.getMessage()));
585 
586  uiBus.mark (targetID, GenNode{"Message", "by mistake"});
587  CHECK (mock.verifyMark("Message", "mistake"));
588  CHECK ("by mistake" == mock.getMessage());
589  CHECK ("getting serious" == mock.getError());
590 
591  CHECK (mock.verify("target")
592  .before("Flash")
593  .before("serious")
594  .before("mistake"));
595 
596  // type mismatch: when receiving a "Message" mark, we expect a string payload
597  VERIFY_ERROR(WRONG_TYPE, uiBus.mark(targetID, GenNode{"Message", Time::NEVER }))
598 
599  // the type error happens while resolving the payload,
600  // and thus the actual "doMsg()" function on the target was not invoked
601  CHECK (mock.ensureNot(string(Time::NEVER)));
602  CHECK (nexusLog.verifyCall("mark").arg(targetID, Time::NEVER));
603  CHECK (nexusLog.ensureNot("delivered mark").arg(Time::NEVER));
604  CHECK ("getting serious" == mock.getError());
605 
606  mock.reset();
607  CHECK (isnil(mock.getMessage()));
608  CHECK (isnil(mock.getError()));
609  CHECK (not mock.isError());
610 
611 
612  cout << "____Event-Log_________________\n"
613  << util::join(mock.getLog(), "\n")
614  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
615 
616  cout << "____Nexus-Log_________________\n"
617  << util::join(nexusLog, "\n")
618  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
619  }
620 
621 
622 
652  void
654  {
656  EventLog nexusLog = stage::test::Nexus::startNewLog();
657 
658  MockElm rootMock("root");
659  ID rootID = rootMock.getID();
660 
661  rootMock.attrib["α"] = "Centauri";
662  CHECK ("Centauri" == rootMock.attrib["α"]);
663  CHECK (isnil (rootMock.scope));
664 
665 
666  // simulated source for structural diff
668  {
669  const GenNode
670  ATTRIB_AL = GenNode("α", "quadrant"),
671  ATTRIB_PI = GenNode("π", 3.14159265),
672  CHILD_1 = MakeRec().genNode("a"),
673  CHILD_2 = MakeRec().genNode("b");
674 
675  auto
676  generateDiff()
677  {
678  using lib::diff::Ref;
679 
680  return MutationMessage{ after(Ref::ATTRIBS) // start after the existing attributes (of root)
681  , ins(CHILD_1) // insert first child (with name "a")
682  , ins(CHILD_2) // insert second child (with name "b")
683  , set(ATTRIB_AL) // assign a new value to attribute "α" <- "quadrant"
684  , mut(CHILD_2) // open nested scope of child "b" for recursive mutation
685  , ins(ATTRIB_PI) // ..within nested scope, add a new attribute "π" := 3.14159265
686  , emu(CHILD_2) // leave nested scope
687  };
688  }
689  }
690  diffSrc;
691 
692 
693  auto& uiBus = stage::test::Nexus::testUI();
694 
695 
696  // send a Diff message via UI-Bus to the rootMock
697  uiBus.change(rootID, diffSrc.generateDiff());
698 
699 
700  // Verify the rootMock has been properly altered....
701  MockElm& childA = *rootMock.scope[0];
702  MockElm& childB = *rootMock.scope[1];
703 
704  CHECK (2 == rootMock.scope.size()); // we've got two children now
705  CHECK (rootMock.attrib["α"] == "quadrant"); // alpha attribute has been reassigned
706  CHECK (childA.getID() == diffSrc.CHILD_1.idi); // children have the expected IDs
707  CHECK (childB.getID() == diffSrc.CHILD_2.idi);
708  CHECK (childB.attrib["π"] == "3.1415927"); // and the second child got attribute Pi
709 
710 
711  CHECK (rootMock.verifyEvent("create","root")
712  .beforeCall("buildMutator").on(&rootMock)
713  .beforeEvent("diff","root accepts mutation...") // start of diff mutation
714  .beforeEvent("diff","create child \"a\"") // insert first child
715  .beforeEvent("create", "a")
716  .beforeEvent("diff","create child \"b\"") // insert second child
717  .beforeEvent("create", "b")
718  .beforeEvent("diff","set Attrib α <-quadrant") // assign value to existing attribute α
719  .beforeCall("buildMutator").on(&childB) // establish nested mutator for second child
720  .beforeEvent("diff","b accepts mutation...")
721  .beforeEvent("diff",">>Scope>> b") // recursively mutate second child
722  .beforeEvent("diff","++Attrib++ π = 3.1415927")); // insert new attribute π within nested scope
723 
724 
725  CHECK (nexusLog.verifyCall("routeAdd").arg(rootMock.getID(), memLocation(rootMock)) // rootMock was attached to Nexus
726  .beforeCall("change") .argMatch(rootMock.getID(),
727  "after.+ins.+ins.+set.+mut.+ins.+emu") // diff message sent via UI-Bus
728  .beforeCall("routeAdd").arg(childA.getID(), memLocation(childA)) // first new child was attached to Nexus
729  .beforeCall("routeAdd").arg(childB.getID(), memLocation(childB)) // second new child was attached to Nexus
730  .beforeEvent("applied diff to "+string(rootMock.getID()))
731  );
732 
733  cout << "____Event-Log_________________\n"
734  << util::join(rootMock.getLog(), "\n")
735  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
736 
737  cout << "____Nexus-Log_________________\n"
738  << util::join(nexusLog, "\n")
739  << "\n───╼━━━━━━━━━╾────────────────"<<endl;
740  }
741 
742 
743 
744  static string
745  memLocation (Tangible& uiElm)
746  {
747  return lib::idi::instanceTypeID (&uiElm);
748  }
749  };
750 
751 
753  LAUNCHER (AbstractTangible_test, "unit stage");
754 
755 
756 }}}// namespace stage::model::test
Helper class used solely for defining a Command-Object.
type erased baseclass for building a combined hash and symbolic ID.
Definition: entry-id.hpp:133
Generic Message with an embedded diff, to describe changes to model elements.
void slotExpand()
Expand this element and remember the expanded state.
Definition: tangible.cpp:161
Automatically use custom string conversion in C++ stream output.
Constructor for a specially crafted &#39;ref GenNode&#39;.
Definition: gen-node.hpp:840
void installRevealer(Revealer::RevealeItFun)
Configure the (optional) functionality to bring the UI-Element into sight.
Definition: tangible.hpp:288
Support for verifying the occurrence of events from unit tests.
Definition: run.hpp:40
static void setCommandHandler(CommandHandler=CommandHandler())
install a closure (custom handler function) to deal with any command invocations encountered in the t...
Definition: test-nexus.cpp:408
A fake UI backbone for investigations and unit testing.
void reset()
invoke the generic reset hook
Definition: tangible.cpp:65
EventMatch verifyMark(string id) const
special verification match on a "state mark" message to this element
Definition: mock-elm.hpp:435
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
Definition: event-log.cpp:438
Helper to log and verify the occurrence of events.
Definition: event-log.hpp:275
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:126
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
#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
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
Definition: event-log.hpp:198
Opaque message to effect a structural change on a target, which is likewise only known in an abstract...
EventMatch & afterCall(string match)
find a function invocation backwards, before the current point of reference
Definition: event-log.cpp:489
Generic functions to build identification schemes.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
Token or Atom with distinct identity.
Definition: symbol.hpp:117
#define MARK_TEST_FUN
Macro to mark the current test function in STDOUT.
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
Definition: event-log.cpp:417
Marker types to indicate a literal string and a Symbol.
Simplistic test class runner.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:191
A collection of frequently used helper functions to support unit testing.
void slotCollapse()
Collapse or minimise this element and remember the collapsed state.
Definition: tangible.cpp:173
A token language to represent structural changes in a tree like hierarchical data structure...
Lumiera error handling (C++ interface).
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
Definition: genfunc.hpp:116
static ctrl::BusTerm & testUI()
get a connection point to a UI backbone faked for test
Definition: test-nexus.cpp:366
Mock UI element or controller.
Definition: mock-elm.hpp:99
static const Time NEVER
border condition marker value. NEVER >= any time value
Definition: timevalue.hpp:314
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Definition: gen-node.hpp:865
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:115
EventMatch verify(string match) const
start a query to match for some substring.
Definition: event-log.cpp:752
Bare symbolic and hash ID used for accounting of asset like entries.
Interface common to all UI elements of relevance for the Lumiera application.
Definition: tangible.hpp:156
EventMatch & on(string targetID)
refine filter to additionally match the &#39;this&#39; attribute
Definition: event-log.cpp:583
void processCommandInvocation(GenNode const &commandMsg)
dummy Command handler, which can be hooked up to the TestNexus and causes a real command invocation o...
Actually defining a command and binding it to execution parameters.
a family of time value like entities and their relationships.
object-like record of data.
Definition: record.hpp:141
A generic interface element instrumented for unit testing.
EventMatch & before(string match)
find a match (substring match) of the given text in an EventLog entry after the current position ...
Definition: event-log.cpp:384
generic data element node within a tree
Definition: gen-node.hpp:222
void slotReveal()
Cause the element to be brought into sight.
Definition: tangible.cpp:213