54 #include <sigc++/signal.h> 78 using LERR_(WRONG_TYPE);
100 undoIt (
int,
int oldState)
102 dummyState = oldState;
107 const Symbol DUMMY_CMD_ID{
"test.AbstractTangibleTest_dummy_command"};
119 REQUIRE (
string{DUMMY_CMD_ID} == commandMsg.idi.getSym());
122 auto arg = commandMsg.data.get<Rec>().scope()->data.get<
int>();
209 CHECK (mock.verify(
"ctor"));
210 CHECK (mock.verifyEvent(
"create",
"dummy"));
211 CHECK (mock.verify(
"ctor").arg(
"dummy",
"TestNexus").on(&mock));
213 CHECK (
"dummy" == mock.getID().getSym());
216 CHECK (!mock.verifyCall(
"reset"));
220 CHECK (mock.isExpanded());
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"));
233 CHECK (mock.verify(
"reset").beforeEvent(
"reset"));
234 CHECK (mock.verifyCall(
"reset").beforeEvent(
"reset"));
235 CHECK (!mock.verifyCall(
"reset").afterEvent(
"reset"));
237 CHECK (!mock.isTouched());
238 CHECK (!mock.isExpanded());
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"));
253 MockElm foo(
"foo"), bar(
"bar");
254 foo.verify(
"ctor").arg(
"foo");
255 bar.verify(
"ctor").
arg(
"bar");
257 bar.ensureNot(
"foo");
258 log.ensureNot(
"foo");
259 mock.ensureNot(
"foo");
260 CHECK (!foo.ensureNot(
"foo"));
266 CHECK (log.verifyEvent(
"logJoin",
"bar")
267 .beforeEvent(
"logJoin",
"foo"));
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"));
279 foo.markMsg(
"dummy killed");
280 CHECK (log.verifyEvent(
"destroy",
"dummy")
281 .beforeCall(
"doMsg").on(
"foo"));
284 EventLog nexusLog = stage::test::Nexus::getLog();
285 CHECK (nexusLog.verifyEvent(
"destroy",
"dummy")
286 .beforeEvent(
"dummy successfully zombificated"));
289 CHECK (nexusLog.verifyEvent(
"dummy successfully zombificated")
290 .beforeCall(
"note").on(
"ZombieNexus").arg(
"defunct-dummy",
"expand")
291 .beforeEvent(
"error",
"sent note message to ZombieNexus"));
294 cout <<
"____Event-Log_________________\n" 295 << util::join(mock.getLog(),
"\n")
296 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
298 cout <<
"____Nexus-Log_________________\n" 299 << util::join(stage::test::Nexus::getLog(),
"\n")
300 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
309 EventLog nexusLog = stage::test::Nexus::startNewLog();
314 .captureUndo (capture)
315 .undoOperation (undoIt);
322 int prevState = dummyState;
323 int concreteParam = 1 +
rani(100);
326 CHECK (nexusLog.ensureNot(
string(DUMMY_CMD_ID)));
330 mock.invoke (DUMMY_CMD_ID, concreteParam);
331 CHECK (dummyState == concreteParam);
332 CHECK (nexusLog.verifyCall(
"act").arg(
"«int»|" +toString(concreteParam))
333 .beforeEvent(
"bind and trigger command \""+DUMMY_CMD_ID));
337 CHECK (dummyState == prevState);
339 cout <<
"____Nexus-Log_________________\n" 340 << util::join(nexusLog,
"\n")
341 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
367 EventLog nexusLog = stage::test::Nexus::startNewLog();
369 sigc::signal<void> trigger_expand;
370 sigc::signal<void> trigger_collapse;
373 ID targetID = mock.getID();
378 CHECK (not mock.isTouched());
379 CHECK (not mock.isExpanded());
380 CHECK (mock.ensureNot(
"expanded"));
381 CHECK (nexusLog.ensureNot(
"state-mark"));
385 CHECK (mock.isTouched());
386 CHECK (mock.isExpanded());
387 CHECK (mock.verifyCall(
"expand").
arg(
true)
391 CHECK (nexusLog.verifyCall(
"note").arg(targetID,
GenNode{
"expand",
true})
392 .before(
"handling state-mark"));
396 CHECK (not mock.isExpanded());
397 CHECK (mock.isTouched());
399 CHECK (mock.verifyEvent(
"create",
"target")
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"));
408 CHECK (not mock.isExpanded());
411 CHECK (mock.ensureNot(
"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}));
422 auto stateMark =
GenNode{
"expand",
true};
425 CHECK (not mock.isExpanded());
426 CHECK (mock.ensureNot(
"mark"));
428 uiBus.mark (targetID, stateMark);
430 CHECK (nexusLog.verifyCall(
"mark").arg(targetID, stateMark)
431 .before(
"delivered mark to "+
string(targetID)).arg(stateMark));
436 CHECK (mock.isExpanded());
437 CHECK (mock.isTouched());
444 uiBus.mark (targetID,
GenNode{
"reset",
true});
448 CHECK (not mock.isTouched());
449 CHECK (not mock.isExpanded());
451 .afterEvent(
"expanded")
456 cout <<
"____Event-Log_________________\n" 457 << util::join(mock.getLog(),
"\n")
458 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
460 cout <<
"____Nexus-Log_________________\n" 461 << util::join(nexusLog,
"\n")
462 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
474 EventLog nexusLog = stage::test::Nexus::startNewLog();
477 ID targetID = mock.getID();
479 sigc::signal<void> trigger_reveal;
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"));
488 bool revealed =
false;
497 CHECK (
true == revealed);
498 CHECK (mock.isExpanded());
499 CHECK (mock.verifyEvent(
"create",
"target")
505 CHECK (nexusLog.verifyCall(
"note").arg(targetID,
GenNode{
"expand",
true})
506 .before(
"handling state-mark"));
511 auto stateMark =
GenNode{
"reveal", 47};
513 CHECK (nexusLog.ensureNot(
"reveal"));
515 uiBus.mark (targetID, stateMark);
517 CHECK (
true == revealed);
519 .afterEvent(
"expanded")
523 CHECK (nexusLog.verifyCall(
"mark").arg(targetID, stateMark)
524 .after(
"handling state-mark")
526 .beforeEvent(
"delivered mark"));
531 CHECK (mock.ensureNot(
"expanded")
533 .afterEvent(
"expanded"));
534 CHECK (nexusLog.ensureNot(
"note")
535 .afterCall(
"mark").arg(targetID, stateMark)
536 .after(
"handling state-mark"));
540 cout <<
"____Event-Log_________________\n" 541 << util::join(mock.getLog(),
"\n")
542 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
544 cout <<
"____Nexus-Log_________________\n" 545 << util::join(nexusLog,
"\n")
546 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
558 EventLog nexusLog = stage::test::Nexus::startNewLog();
561 ID targetID = mock.getID();
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());
572 uiBus.mark (targetID,
GenNode{
"Flash",
true });
575 CHECK (mock.ensureNot(
"Error"));
576 CHECK (mock.ensureNot(
"Message"));
577 CHECK (isnil(mock.getMessage()));
578 CHECK (isnil(mock.getError()));
580 uiBus.mark (targetID,
GenNode{
"Error",
"getting serious"});
582 CHECK (mock.isError());
583 CHECK (
"getting serious" == mock.getError());
584 CHECK (isnil(mock.getMessage()));
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());
591 CHECK (mock.verify(
"target")
602 CHECK (nexusLog.verifyCall(
"mark").arg(targetID,
Time::NEVER));
603 CHECK (nexusLog.ensureNot(
"delivered mark").arg(
Time::NEVER));
604 CHECK (
"getting serious" == mock.getError());
607 CHECK (isnil(mock.getMessage()));
608 CHECK (isnil(mock.getError()));
609 CHECK (not mock.isError());
612 cout <<
"____Event-Log_________________\n" 613 << util::join(mock.getLog(),
"\n")
614 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
616 cout <<
"____Nexus-Log_________________\n" 617 << util::join(nexusLog,
"\n")
618 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
656 EventLog nexusLog = stage::test::Nexus::startNewLog();
659 ID rootID = rootMock.getID();
661 rootMock.attrib[
"α"] =
"Centauri";
662 CHECK (
"Centauri" == rootMock.attrib[
"α"]);
663 CHECK (isnil (rootMock.scope));
670 ATTRIB_AL =
GenNode(
"α",
"quadrant"),
671 ATTRIB_PI =
GenNode(
"π", 3.14159265),
672 CHILD_1 = MakeRec().genNode(
"a"),
673 CHILD_2 = MakeRec().genNode(
"b");
697 uiBus.change(rootID, diffSrc.generateDiff());
701 MockElm& childA = *rootMock.scope[0];
702 MockElm& childB = *rootMock.scope[1];
704 CHECK (2 == rootMock.scope.size());
705 CHECK (rootMock.attrib[
"α"] ==
"quadrant");
706 CHECK (childA.getID() == diffSrc.CHILD_1.idi);
707 CHECK (childB.getID() == diffSrc.CHILD_2.idi);
708 CHECK (childB.attrib[
"π"] ==
"3.1415927");
711 CHECK (rootMock.verifyEvent(
"create",
"root")
725 CHECK (nexusLog.verifyCall(
"routeAdd").arg(rootMock.getID(), memLocation(rootMock))
726 .beforeCall(
"change") .argMatch(rootMock.getID(),
727 "after.+ins.+ins.+set.+mut.+ins.+emu")
728 .beforeCall(
"routeAdd").arg(childA.getID(), memLocation(childA))
729 .beforeCall(
"routeAdd").arg(childB.getID(), memLocation(childB))
730 .beforeEvent(
"applied diff to "+
string(rootMock.getID()))
733 cout <<
"____Event-Log_________________\n" 734 << util::join(rootMock.getLog(),
"\n")
735 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
737 cout <<
"____Nexus-Log_________________\n" 738 << util::join(nexusLog,
"\n")
739 <<
"\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.
int rani(uint bound=_iBOUND())
#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.
Simplistic 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.