42#include <boost/lexical_cast.hpp>
44using boost::lexical_cast;
82 using LERR_(UNBOUND_ARGUMENTS);
83 using LERR_(WRONG_TYPE);
93 uint const MAX_RAND_DELAY = 5000;
167 CHECK (nexusLog.
verifyCall(
"routeAdd").
on(
"TestNexus").
arg(elmID,
"Tangible")
168 .
beforeEvent(
"TestNexus",
"added route to bID-zeitgeist"));
184 CHECK (nexusLog.
verifyCall(
"note").
on(
"TestNexus").
arg(elmID,
"GenNode-ID(\"expand\")-DataCap|«bool»|true"));
189 .
beforeEvent(
"TestNexus",
"mark to bID-zeitgeist"));
197 .
beforeEvent(
"TestNexus",
"removed route to bID-zeitgeist"));
200 CHECK (nexusLog.
verify(
"removed route to bID-zeitgeist")
202 .
beforeEvent(
"warn",
"discarding mark to unknown bID-zeitgeist"));
207 cout <<
"____Probe-Log_________________\n"
209 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
211 cout <<
"____Nexus-Log_________________\n"
213 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
223 Symbol cmd = stage::test::Nexus::prepareMockCmd<string, TimeSpan, LuidH>();
228 string text {lib::test::randStr(12)};
253 auto cmdX = stage::test::Nexus::prepareMockCmd<>();
254 auto cmdY = stage::test::Nexus::prepareMockCmd<>();
261 cout <<
"____Nexus-Log_________________\n"
263 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
288 CHECK (stateManager.currentState(alpha,
"expand") ==
GenNode(
"expand",
true ));
289 CHECK (stateManager.currentState(bravo,
"expand") ==
GenNode(
"expand",
false ));
292 CHECK (stateManager.currentState(charly,
"expand") ==
Ref::NO);
293 CHECK (stateManager.currentState(bravo,
"extinct") ==
Ref::NO);
296 CHECK (stateManager.currentState(bruno,
"expand") ==
Ref::NO);
299 CHECK (stateManager.currentState(charly,
"expand") ==
GenNode(
"expand",
true ));
303 CHECK (stateManager.currentState(charly,
"Error") ==
GenNode(
"Error",
"overinflated"));
306 CHECK (stateManager.currentState(charly,
"expand") ==
Ref::NO);
309 cout <<
"____Nexus-Log_________________\n"
311 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
330 stateManager.replayState (alpha,
"expand");
339 stateManager.replayAllState (
"expand");
364 uiBus.mark (alpha,
GenNode{
"Message",
"Centauri"});
365 uiBus.mark (bravo,
GenNode{
"Flash",
true});
366 uiBus.mark (charly,
GenNode{
"Message",
"Delta"});
367 uiBus.mark (charly,
GenNode{
"Error",
"Echo"});
383 CHECK (nexusLog.verifyEvent(
"create",
"alpha")
384 .beforeCall(
"mark").on(
"TestNexus").arg(
"alpha",
"Centauri")
385 .beforeCall(
"doMsg").on(
"alpha").arg(
"Centauri")
386 .beforeEvent(
"mark",
"Centauri")
387 .beforeEvent(
"TestNexus",
"delivered mark to bID-alpha"));
389 CHECK (nexusLog.verifyEvent(
"TestNexus",
"delivered mark to bID-alpha")
390 .beforeCall(
"mark").on(
"TestNexus").arg(
"bravo",
"GenNode-ID(\"Flash\")-DataCap|«bool»|true")
391 .beforeCall(
"doFlash").on(
"bravo")
392 .beforeEvent(
"TestNexus",
"delivered mark to bID-bravo"));
395 CHECK (nexusLog.verifyEvent(
"TestNexus",
"delivered mark to bID-bravo")
396 .beforeCall(
"mark").on(
"TestNexus").arg(
"charly",
"GenNode-ID(\"Message\")-DataCap|«string»|Delta")
397 .beforeCall(
"doMsg").on(
"charly").arg(
"Delta")
398 .beforeEvent(
"mark",
"Delta").id(
"Message")
399 .beforeEvent(
"TestNexus",
"delivered mark to bID-charly")
400 .beforeCall(
"mark").on(
"TestNexus").arg(
"charly",
"GenNode-ID(\"Error\")-DataCap|«string»|Echo")
401 .beforeCall(
"doErr").on(
"charly").arg(
"Echo")
402 .beforeEvent(
"mark",
"Echo").id(
"Error")
403 .beforeEvent(
"TestNexus",
"delivered mark to bID-charly"));
407 uiBus.markAll (
GenNode{
"Message",
"Foxtrot"});
419 CHECK (
"Echo" == mockC.
getError());
421 CHECK (nexusLog.verifyEvent(
"mark",
"Echo").id(
"Error")
422 .beforeCall(
"markAll").on(
"TestNexus").arg(
"Foxtrot")
423 .beforeEvent(
"Broadcast",
"Foxtrot")
424 .beforeCall(
"mark").on(
"TestNexus").arg(
"bravo",
"GenNode-ID(\"Message\")-DataCap|«string»|Foxtrot")
425 .beforeCall(
"doMsg").on(
"bravo").arg(
"Foxtrot")
426 .beforeEvent(
"TestNexus",
"broadcasted mark to 3 terminals"));
430 CHECK (nexusLog.verifyCall(
"markAll").on(
"TestNexus").arg(
"Foxtrot")
431 .beforeCall(
"mark").on(
"TestNexus").arg(
"alpha",
"Foxtrot")
432 .beforeCall(
"doMsg").on(
"alpha").arg(
"Foxtrot")
433 .beforeEvent(
"TestNexus",
"successfully broadcasted"));
435 CHECK (nexusLog.verifyCall(
"markAll").on(
"TestNexus").arg(
"Foxtrot")
436 .beforeCall(
"mark").on(
"TestNexus").arg(
"bravo",
"Foxtrot")
437 .beforeCall(
"doMsg").on(
"bravo").arg(
"Foxtrot")
438 .beforeEvent(
"TestNexus",
"successfully broadcasted"));
440 CHECK (nexusLog.verifyCall(
"markAll").on(
"TestNexus").arg(
"Foxtrot")
441 .beforeCall(
"mark").on(
"TestNexus").arg(
"charly",
"Foxtrot")
442 .beforeCall(
"doMsg").on(
"charly").arg(
"Foxtrot")
443 .beforeEvent(
"TestNexus",
"successfully broadcasted"));
446 cout <<
"____Nexus-Log_________________\n"
448 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
470 uiBus.mark (alpha,
GenNode{
"Message",
"Centauri"});
471 uiBus.mark (charly,
GenNode{
"Message",
"Delta"});
472 uiBus.mark (charly,
GenNode{
"Error",
"Echo"});
480 uiBus.markAll (
GenNode{
"clearMsg",
true});
487 uiBus.mark (bravo,
GenNode{
"Message",
"miss"});
492 CHECK (stateManager.currentState(alpha,
"expand") ==
GenNode(
"expand",
false ));
493 CHECK (stateManager.currentState(bravo,
"expand") ==
GenNode(
"expand",
true ));
494 CHECK (stateManager.currentState(charly,
"expand") ==
Ref::NO);
495 CHECK (stateManager.currentState(charly,
"Error") ==
GenNode(
"Error",
"Echo"));
498 uiBus.markAll (
GenNode{
"clearErr",
true});
504 CHECK (stateManager.currentState(alpha,
"expand") ==
GenNode(
"expand",
false ));
505 CHECK (stateManager.currentState(bravo,
"expand") ==
GenNode(
"expand",
true ));
506 CHECK (stateManager.currentState(charly,
"expand") ==
Ref::NO);
507 CHECK (stateManager.currentState(charly,
"Error") ==
Ref::NO);
511 uiBus.markAll (
GenNode{
"reset",
true});
524 CHECK (stateManager.currentState(alpha,
"expand") ==
Ref::NO);
525 CHECK (stateManager.currentState(bravo,
"expand") ==
Ref::NO);
526 CHECK (stateManager.currentState(charly,
"expand") ==
Ref::NO);
527 CHECK (stateManager.currentState(charly,
"Error" ) ==
Ref::NO);
530 cout <<
"____Nexus-Log_________________\n"
532 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
565 uint64_t borgChecksum_ = 0;
570 scheduleBorg (
uint id)
574 sessionBorgs_.
push(
id);
581 return dischargeToSnapshot (sessionBorgs_);
600 SessionThread& theCube_;
603 BorgGenerator (SessionThread& motherShip,
uint id)
605 , theCube_{motherShip}
608 ++generator_instances;
613 --generator_instances;
620 firstResult ()
override
622 REQUIRE (not steps_);
623 auto plannedBorgs = theCube_.dispatchBorgs();
624 uint max = plannedBorgs.size();
627 _Fmt borgName{
"%d of %d ≺%03d.gen%03d≻"};
630 steps_.feed (after(Ref::ATTRIBS));
631 for (
uint id : plannedBorgs)
633 GenNode borg = MakeRec().
genNode(borgName % ++cur % max %
id % generatorID_);
634 steps_.feed (ins(borg));
635 steps_.feed (mut(borg));
636 steps_.feed ( ins(
GenNode{
"borgID", int(
id)}));
637 steps_.feed (emu(borg));
639 steps_.feed (after(Ref::END));
646 nextResult (DiffStep*& pos)
override
649 if (steps_) ++steps_;
661 SessionThread(function<
void(DiffSource*)> notifyGUI)
665 uint cnt = randGen_.i(MAX_RAND_BORGS);
666 for (
uint i=0; i<cnt; ++i)
669 uint id = randGen_.i(MAX_RAND_NUMBS);
672 notifyGUI (
new BorgGenerator{*
this, i});
687 MockElm rootMock(
"alpha zero");
690 rootMock.
attrib[
"α"] =
"Quadrant";
691 CHECK (
"Quadrant" == rootMock.
attrib[
"α"]);
692 CHECK (isnil (rootMock.
scope));
694 CHECK (0 == generator_instances);
703 auto notifyGUI = [&](DiffSource* diffGenerator)
705 uiDispatcher.
feed ([&, diffGenerator]()
715 SessionThread
session{notifyGUI};
716 usleep (2 * MAX_RAND_DELAY);
717 while (not isnil(uiDispatcher))
728 while (not isnil(uiDispatcher))
735 uint generatedBorgs = rootMock.
scope.size();
740 uint64_t borgChecksum = 0;
741 for (
uint i=0; i<generatedBorgs; ++i)
744 CHECK (contains (borg.
attrib,
"borgID"));
745 string borgID = borg.
attrib[
"borgID"];
746 borgChecksum += lexical_cast<int> (borgID);
747 string childID = borg.
getID().getSym();
748 CHECK (contains (childID, borgID));
749 CHECK (contains (childID,
" of "));
752 .beforeCall(
"change") .argMatch(rootMock.
getID(),
753 "after.+?_ATTRIBS_.+?"
754 "ins.+?"+childID+
".+?"
755 "mut.+?"+childID+
".+?"
756 "ins.+?borgID.+?"+borgID+
".+?"
759 .beforeEvent(
"applied diff to "+
string(rootMock.
getID()))
763 CHECK (rootMock.
attrib[
"α"] ==
"Quadrant");
767 CHECK (borgChecksum ==
session.borgChecksum_);
768 CHECK (0 == generator_instances);
772 cout <<
"____Event-Log_________________\n"
774 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
776 cout <<
"____Nexus-Log_________________\n"
778 <<
"\n───╼━━━━━━━━━╾────────────────"<<endl;
static snd_pcm_sframes_t delay
Attachment point to the UI-Bus.
A Queue for function invocations, allowing them to be dispatched on demand.
A threadsafe queue for bound void(void) functors.
CallQueue & feed(Operation &&op)
A synchronisation protection guard employing a lock scoped to the parameter type as a whole,...
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
Token or Atom with distinct identity.
Facility for monitor object based locking.
Variant of the standard case, requiring to wait and join() on the termination of this thread.
object-like record of data.
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor,...
type erased baseclass for building a combined hash and symbolic ID.
Helper to log and verify the occurrence of events.
EventMatch verify(string match) const
start a query to match for some substring.
EventMatch verifyCall(string match) const
start a query to match especially a function call
EventMatch verifyEvent(string match) const
start a query to match for some event.
EventMatch ensureNot(string match) const
start a query to ensure the given expression does not match.
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
EventMatch & afterEvent(string match)
EventMatch & on(string targetID)
refine filter to additionally match the ‘'this’` attribute
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
A time interval anchored at a specific point in time.
Lumiera's internal time value datatype.
connection point at the UI-Bus.
virtual bool mark(ID subject, GenNode const &mark)
route a state update or notification to the given subject.
Interface: handling of persistent interface state.
Interface common to all UI elements of relevance for the Lumiera application.
void invoke(Symbol cmdID, ARGS &&...)
void slotCollapse()
Collapse or minimise this element and remember the collapsed state.
void markErr(string error)
push an error state tag to the element
void reset()
invoke the generic reset hook
void slotExpand()
Expand this element and remember the expanded state.
void verifyNotifications()
static string memLocation(Tangible &uiElm)
Mock UI element or controller.
string getMessage() const
EventLog const & getLog() const
std::map< string, string > attrib
std::vector< PMockElm > scope
void kill()
commit suicide.
EventLog & joinLog(MockElm &otherMock)
static ctrl::BusTerm & testUI()
get a connection point to a UI backbone faked for test
static ctrl::StateManager & getMockStateManager()
static void setStateMarkHandler(StateMarkHandler=StateMarkHandler())
similar to the custom command handler this hook allows to install a closure to intercept any "state m...
static void setCommandHandler(CommandHandler=CommandHandler())
install a closure (custom handler function) to deal with any command invocations encountered in the t...
static bool wasInvoked(Symbol)
Test predicate: verify at least one actual invocation happened for the given commend,...
static lib::test::EventLog const & getLog()
static ctrl::StateManager & useMockStateManager()
install a standard handler for state mark messages, which is actually backed by a mock implementation...
static lib::test::EventLog const & startNewLog()
static bool wasBound(Symbol, ARGS const &...args)
Test predicate: verify by string match that the denoted command was actually bound against the given ...
Handle object representing a single Command instance to be used by client code.
Any copy and copy construction prohibited.
A front-end for using printf-style formatting.
Steam-Layer command frontend.
Bare symbolic and hash ID used for accounting of asset like entries.
Generic building block for tree shaped (meta)data structures.
Preconfigured adapters for some STL container standard usage situations.
Conveniently iterable stack and queue containers.
Lumiera unique object identifier.
A generic interface element instrumented for unit testing.
Generic Message with an embedded diff, to describe changes to model elements.
TreeDiffLanguage::DiffStep DiffStep
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
ContentSnapshot< IT > dischargeToSnapshot(IT &ii)
Take a snapshot of the given LumieraIterator, which is thereby consumed.
SeedNucleus & seedFromDefaultGen()
draw seed another Generator from the default RandomSequencer
uint const MAX_RAND_BORGS
uint const MAX_RAND_NUMBS
lib::idi::BareEntryID const & ID
Lumiera GTK UI implementation root.
Namespace of Session and user visible high-level objects.
Test runner and basic definitions for tests.
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
string join(COLL &&coll, string const &delim=", ")
enumerate a collection's contents, separated by delimiter.
bool isnil(lib::time::Duration const &dur)
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Interface: a component to maintain persistent interface state.
A Queue which can be pulled by iterating.
A Stack which can be popped by iterating.
IterStack & push(TY const &elm)
generic data element node within a tree
Opaque message to effect a structural change on a target, which is likewise only known in an abstract...
Constructor for a specially crafted 'ref GenNode'.
static const Ref NO
symbolic ID ref "_NO_"
typed symbolic and hash ID for asset-like position accounting.
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Object Monitor based synchronisation.
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
#define MARK_TEST_FUN
Macro to mark the current test function in STDOUT.
A fake UI backbone for investigations and unit testing.
Convenience front-end to simplify and codify basic thread handling.
a family of time value like entities and their relationships.
Hard wired key constants and basic definitions for communication with the GUI.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...