63 #include <sigc++/signal.h> 87 using LERR_(WRONG_TYPE);
109 undoIt (
int,
int oldState)
111 dummyState = oldState;
116 const Symbol DUMMY_CMD_ID{
"test.AbstractTangibleTest_dummy_command"};
128 REQUIRE (
string{DUMMY_CMD_ID} == commandMsg.idi.getSym());
131 auto arg = commandMsg.data.get<Rec>().scope()->data.get<
int>();
216 CHECK (mock.verify(
"ctor"));
217 CHECK (mock.verifyEvent(
"create",
"dummy"));
218 CHECK (mock.verify(
"ctor").arg(
"dummy",
"TestNexus").on(&mock));
220 CHECK (
"dummy" == mock.getID().getSym());
223 CHECK (!mock.verifyCall(
"reset"));
227 CHECK (mock.isExpanded());
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"));
240 CHECK (mock.verify(
"reset").beforeEvent(
"reset"));
241 CHECK (mock.verifyCall(
"reset").beforeEvent(
"reset"));
242 CHECK (!mock.verifyCall(
"reset").afterEvent(
"reset"));
244 CHECK (!mock.isTouched());
245 CHECK (!mock.isExpanded());
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"));
260 MockElm foo(
"foo"), bar(
"bar");
261 foo.verify(
"ctor").arg(
"foo");
262 bar.verify(
"ctor").
arg(
"bar");
264 bar.ensureNot(
"foo");
265 log.ensureNot(
"foo");
266 mock.ensureNot(
"foo");
267 CHECK (!foo.ensureNot(
"foo"));
273 CHECK (log.verifyEvent(
"logJoin",
"bar")
274 .beforeEvent(
"logJoin",
"foo"));
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"));
286 foo.markMsg(
"dummy killed");
287 CHECK (log.verifyEvent(
"destroy",
"dummy")
288 .beforeCall(
"doMsg").on(
"foo"));
291 EventLog nexusLog = stage::test::Nexus::getLog();
292 CHECK (nexusLog.verifyEvent(
"destroy",
"dummy")
293 .beforeEvent(
"dummy successfully zombificated"));
296 CHECK (nexusLog.verifyEvent(
"dummy successfully zombificated")
297 .beforeCall(
"note").on(
"ZombieNexus").arg(
"defunct-dummy",
"expand")
298 .beforeEvent(
"error",
"sent note message to ZombieNexus"));
301 cout <<
"____Event-Log_________________\n" 302 << util::join(mock.getLog(),
"\n")
303 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
305 cout <<
"____Nexus-Log_________________\n" 306 << util::join(stage::test::Nexus::getLog(),
"\n")
307 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
316 EventLog nexusLog = stage::test::Nexus::startNewLog();
321 .captureUndo (capture)
322 .undoOperation (undoIt);
329 int prevState = dummyState;
330 int concreteParam = 1 +rand() % 100;
333 CHECK (nexusLog.ensureNot(
string(DUMMY_CMD_ID)));
337 mock.invoke (DUMMY_CMD_ID, concreteParam);
338 CHECK (dummyState == concreteParam);
339 CHECK (nexusLog.verifyCall(
"act").arg(
"«int»|" +toString(concreteParam))
340 .beforeEvent(
"bind and trigger command \""+DUMMY_CMD_ID));
344 CHECK (dummyState == prevState);
346 cout <<
"____Nexus-Log_________________\n" 347 << util::join(nexusLog,
"\n")
348 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
374 EventLog nexusLog = stage::test::Nexus::startNewLog();
376 sigc::signal<void> trigger_expand;
377 sigc::signal<void> trigger_collapse;
380 ID targetID = mock.getID();
385 CHECK (not mock.isTouched());
386 CHECK (not mock.isExpanded());
387 CHECK (mock.ensureNot(
"expanded"));
388 CHECK (nexusLog.ensureNot(
"state-mark"));
392 CHECK (mock.isTouched());
393 CHECK (mock.isExpanded());
394 CHECK (mock.verifyCall(
"expand").
arg(
true)
398 CHECK (nexusLog.verifyCall(
"note").arg(targetID,
GenNode{
"expand",
true})
399 .before(
"handling state-mark"));
403 CHECK (not mock.isExpanded());
404 CHECK (mock.isTouched());
406 CHECK (mock.verifyEvent(
"create",
"target")
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"));
415 CHECK (not mock.isExpanded());
418 CHECK (mock.ensureNot(
"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}));
429 auto stateMark =
GenNode{
"expand",
true};
432 CHECK (not mock.isExpanded());
433 CHECK (mock.ensureNot(
"mark"));
435 uiBus.mark (targetID, stateMark);
437 CHECK (nexusLog.verifyCall(
"mark").arg(targetID, stateMark)
438 .before(
"delivered mark to "+
string(targetID)).arg(stateMark));
443 CHECK (mock.isExpanded());
444 CHECK (mock.isTouched());
451 uiBus.mark (targetID,
GenNode{
"reset",
true});
455 CHECK (not mock.isTouched());
456 CHECK (not mock.isExpanded());
458 .afterEvent(
"expanded")
463 cout <<
"____Event-Log_________________\n" 464 << util::join(mock.getLog(),
"\n")
465 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
467 cout <<
"____Nexus-Log_________________\n" 468 << util::join(nexusLog,
"\n")
469 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
481 EventLog nexusLog = stage::test::Nexus::startNewLog();
484 ID targetID = mock.getID();
486 sigc::signal<void> trigger_reveal;
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"));
495 bool revealed =
false;
504 CHECK (
true == revealed);
505 CHECK (mock.isExpanded());
506 CHECK (mock.verifyEvent(
"create",
"target")
512 CHECK (nexusLog.verifyCall(
"note").arg(targetID,
GenNode{
"expand",
true})
513 .before(
"handling state-mark"));
518 auto stateMark =
GenNode{
"reveal", 47};
520 CHECK (nexusLog.ensureNot(
"reveal"));
522 uiBus.mark (targetID, stateMark);
524 CHECK (
true == revealed);
526 .afterEvent(
"expanded")
530 CHECK (nexusLog.verifyCall(
"mark").arg(targetID, stateMark)
531 .after(
"handling state-mark")
533 .beforeEvent(
"delivered mark"));
538 CHECK (mock.ensureNot(
"expanded")
540 .afterEvent(
"expanded"));
541 CHECK (nexusLog.ensureNot(
"note")
542 .afterCall(
"mark").arg(targetID, stateMark)
543 .after(
"handling state-mark"));
547 cout <<
"____Event-Log_________________\n" 548 << util::join(mock.getLog(),
"\n")
549 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
551 cout <<
"____Nexus-Log_________________\n" 552 << util::join(nexusLog,
"\n")
553 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
565 EventLog nexusLog = stage::test::Nexus::startNewLog();
568 ID targetID = mock.getID();
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());
579 uiBus.mark (targetID,
GenNode{
"Flash",
true });
582 CHECK (mock.ensureNot(
"Error"));
583 CHECK (mock.ensureNot(
"Message"));
584 CHECK (isnil(mock.getMessage()));
585 CHECK (isnil(mock.getError()));
587 uiBus.mark (targetID,
GenNode{
"Error",
"getting serious"});
589 CHECK (mock.isError());
590 CHECK (
"getting serious" == mock.getError());
591 CHECK (isnil(mock.getMessage()));
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());
598 CHECK (mock.verify(
"target")
609 CHECK (nexusLog.verifyCall(
"mark").arg(targetID,
Time::NEVER));
610 CHECK (nexusLog.ensureNot(
"delivered mark").arg(
Time::NEVER));
611 CHECK (
"getting serious" == mock.getError());
614 CHECK (isnil(mock.getMessage()));
615 CHECK (isnil(mock.getError()));
616 CHECK (not mock.isError());
619 cout <<
"____Event-Log_________________\n" 620 << util::join(mock.getLog(),
"\n")
621 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
623 cout <<
"____Nexus-Log_________________\n" 624 << util::join(nexusLog,
"\n")
625 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
663 EventLog nexusLog = stage::test::Nexus::startNewLog();
666 ID rootID = rootMock.getID();
668 rootMock.attrib[
"α"] =
"Centauri";
669 CHECK (
"Centauri" == rootMock.attrib[
"α"]);
670 CHECK (isnil (rootMock.scope));
677 ATTRIB_AL =
GenNode(
"α",
"quadrant"),
678 ATTRIB_PI =
GenNode(
"π", 3.14159265),
679 CHILD_1 = MakeRec().genNode(
"a"),
680 CHILD_2 = MakeRec().genNode(
"b");
704 uiBus.change(rootID, diffSrc.generateDiff());
708 MockElm& childA = *rootMock.scope[0];
709 MockElm& childB = *rootMock.scope[1];
711 CHECK (2 == rootMock.scope.size());
712 CHECK (rootMock.attrib[
"α"] ==
"quadrant");
713 CHECK (childA.getID() == diffSrc.CHILD_1.idi);
714 CHECK (childB.getID() == diffSrc.CHILD_2.idi);
715 CHECK (childB.attrib[
"π"] ==
"3.1415927");
718 CHECK (rootMock.verifyEvent(
"create",
"root")
732 CHECK (nexusLog.verifyCall(
"routeAdd").arg(rootMock.getID(), memLocation(rootMock))
733 .beforeCall(
"change") .argMatch(rootMock.getID(),
734 "after.+ins.+ins.+set.+mut.+ins.+emu")
735 .beforeCall(
"routeAdd").arg(childA.getID(), memLocation(childA))
736 .beforeCall(
"routeAdd").arg(childB.getID(), memLocation(childB))
737 .beforeEvent(
"applied diff to "+
string(rootMock.getID()))
740 cout <<
"____Event-Log_________________\n" 741 << util::join(rootMock.getLog(),
"\n")
742 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
744 cout <<
"____Nexus-Log_________________\n" 745 << util::join(nexusLog,
"\n")
746 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
Helper class used solely for defining a Command-Object.
type erased baseclass for building a combined hash and symbolic ID.
Generic Message with an embedded diff, to describe changes to model elements.
void slotExpand()
Expand this element and remember the expanded state.
Constructor for a specially crafted 'ref GenNode'.
void installRevealer(Revealer::RevealeItFun)
Configure the (optional) functionality to bring the UI-Element into sight.
Support for verifying the occurrence of events from unit tests.
static void setCommandHandler(CommandHandler=CommandHandler())
install a closure (custom handler function) to deal with any command invocations encountered in the t...
A fake UI backbone for investigations and unit testing.
void reset()
invoke the generic reset hook
EventMatch verifyMark(string id) const
special verification match on a "state mark" message to this element
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
Helper to log and verify the occurrence of events.
typed symbolic and hash ID for asset-like position accounting.
#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.
void verify_mockManipulation()
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
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
Generic functions to build identification schemes.
Lumiera's internal time value datatype.
Token or Atom with distinct identity.
#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
Marker types to indicate a literal string and a Symbol.
Simple test class runner.
Lumiera GTK UI implementation root.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
void slotCollapse()
Collapse or minimise this element and remember the collapsed state.
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
static ctrl::BusTerm & testUI()
get a connection point to a UI backbone faked for test
Mock UI element or controller.
static const Time NEVER
border condition marker value. NEVER >= any time value
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Handle object representing a single Command instance to be used by client code.
EventMatch verify(string match) const
start a query to match for some substring.
Bare symbolic and hash ID used for accounting of asset like entries.
Interface common to all UI elements of relevance for the Lumiera application.
EventMatch & on(string targetID)
refine filter to additionally match the 'this' attribute
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.
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 ...
generic data element node within a tree
void slotReveal()
Cause the element to be brought into sight.