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