define first test case to cover the UI-Bus side of basic element interactions

this test is intended as counterpart to
AbstractTangible_test::verify_mockManipulation()

It creates a mock element and verifies bidirectional
connnectivity to the UI-Bus
This commit is contained in:
Fischlurch 2016-01-02 01:23:09 +01:00
parent 603f9e2b7d
commit d27d9f79c2
3 changed files with 89 additions and 22 deletions

View file

@ -89,8 +89,10 @@ namespace test {
* - message casting
* - error state indication
*
* @see BusTerm_test
* @see SessionElementQuery_test
* @see gui::model::SessionFacade
* @see tangible.hpp
* @see ui-bus.hpp
*/
class AbstractTangible_test : public Test
{
@ -111,19 +113,19 @@ namespace test {
* with the ability to stand-in for actual elements present in the real GUI.
* This allows us to rig a emulated test user interface to cover interactions
* involving some communication from or to interface elements. After setting up
* a [MockElm] with a suitable name / ID, we're able to operate this element
* programmatically and to send messages and responses from the core "up"
* to this mocked interface. And since this mock element embodies an
* [event log](\ref EventLog), the unit test code can verify the occurrence
* of expected events, invocations and responses.
* a [mock UI-element](\ref MockElm) with a suitable name / ID, we're able to
* operate this element programmatically and to send messages and responses
* from the core "up" to this mocked interface. And since this mock element
* embodies an [event log](\ref EventLog), the unit test code can verify
* the occurrence of expected events, invocations and responses.
*
* \par connectivity
* ### connectivity
* Any mock element will automatically connect against the [Test-Nexus](test/test-nexus.hpp),
* so to be suitably rigged for unit testing. This means, there is no _live connection_
* to the session, but any command- or other messages will be captured and can be
* retrieved or verified from the test code. Since lifecycle and robustness in
* "post mortem" situations tend to be tricky for UI code, we provide a dedicated
* ["zombification"](\ref gui::test::TestNexus::zombificate()) feature: a \ref MockElm can be
* ["zombification" feature](\ref gui::test::TestNexus::zombificate): a \ref MockElm can be
* turned into an _almost dead_ state, while still hanging around. It will be detached from the
* "living" Test-Nexus and re-wired to some special, hidden "Zombie Nexus", causing any
* further messaging activity to be logged and ignored.

View file

@ -22,7 +22,10 @@
#include "lib/test/run.hpp"
//#include "gui/model/session-facade.hpp"
#include "test/test-nexus.hpp"
#include "test/mock-elm.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/diff/gen-node.hpp"
//#include "gui/model/diagnostics.hpp"
//#include "lib/util.hpp"
@ -32,6 +35,9 @@
//#include <string>
//#include <map>
using lib::idi::EntryID;
using gui::test::MockElm;
using lib::diff::GenNode;
//using boost::lexical_cast;
//using util::contains;
//using std::string;
@ -54,18 +60,20 @@ namespace test {
/**************************************************************************//**
* @test cover the standard node element (terminal element) within the UI-Bus,
* with the help of an attached mock UI element.
*
* This test enacts the fundamental generic communication patterns
* to verify the messaging behaviour
* - attaching a [BusTerm]
* - generating a command invocation
* - argument passing
* - capture a _state mark_
* - replay a _state mark_
* - cast messages and error states downstream
* - generic operating of interface states
* - detaching on element destruction
* with the help of an attached mock UI element. Contrary to the related
* [ui-element test](AbstractTangible_test), here we focus on the bus side
* of the standard interactions.
*
* This test enacts the fundamental generic communication patterns
* to verify the messaging behaviour
* - attaching a \ref BusTerm
* - generating a command invocation
* - argument passing
* - capture a _state mark_
* - replay a _state mark_
* - cast messages and error states downstream
* - generic operating of interface states
* - detaching on element destruction
*
* @see AbstractTangible_test
* @see gui::model::Tangible
@ -88,10 +96,66 @@ namespace test {
}
/** @test build a new BusTerm and verify connectivity.
* Every [tangible UI-element](\ref Tangible) bears an embedded BusTerm
* member. Since the latter _requires another, up-link BusTerm_ on construction,
* connection to the [UI-Bus](ui-bus.hpp) is structurally ensured. Moreover,
* when hooking up a new UI-element, the initialisation of the embedded BusTerm
* will cause a down-link connection to be installed into the central routing
* table within the \ref Nexus, the hub of the UI-Bus. Routing and addressing
* is based on the UI-element's unique EntryID, destruction of the element,
* through invocation of BusTerm's dtor, will ensure deregistration
* from the Hub.
*/
void
attachNewBusTerm ()
{
UNIMPLEMENTED ("build a new BusTerm and verify connectivity");
// our dummy will be linked with this identity
EntryID<MockElm> elmID{"zeitgeist"};
// Access the log on the Test-Nexus hub
EventLog nexusLog = gui::test::Nexus::getLog();
CHECK (nexusLog.ensureNot("zeitgeist"));
MockElm mock(elmID);
CHECK (nexusLog.verifyCall("routeAdd").on("TestNexus").arg(elmID,"MockElm")
.beforeEvent("TestNexus", "add route to bID-zeitgeist"));
EventLog elmLog = mock.getLog();
CHECK (elmLog.verifyCall("ctor").on(&mock)
.beforeEvent("create", "zeitgeist"));
// now verify there is indeed bidirectional connectivity...
CHECK (elmLog.ensureNot("collapsed"));
CHECK (elmLog.ensureNot("doFlash"));
CHECK (nexusLog.ensureNot("zeitgeist").arg("collapse"));
CHECK (nexusLog.ensureNot("zeitgeist").arg("Flash"));
// invoke action on element to cause upstream message (with a "state mark")
mock.slotCollapse();
CHECK (elmLog.verifyEvent("collapsed"));
CHECK (nexusLog.verifyCall("note").on("TestNexus").arg("zeitgeist", "collapse"));
// send a note down to the mock element
gui::test::Nexus::testUI().note (elmID, GenNode("Flash", 23));
CHECK (nexusLog.verifyCall("note").on("TestNexus").arg(elmID, "Flash")
.beforeEvent("TestNexus", "note to bID-zeitgeist"));
CHECK (elmLog.verifyCall("doFlash").on("zeitgeist"));
// kill the zeitgeist and verify disconnection
mock.kill();
CHECK (elmLog.verifyEvent("destroy","zeitgeist"));
CHECK (nexusLog.verifyCall("routeDetach").on("TestNexus").arg(elmID)
.beforeEvent("TestNexus", "remove route to bID-zeitgeist"));
gui::test::Nexus::testUI().note (elmID, GenNode("Flash", 88));
CHECK (nexusLog.verify("remove route to bID-zeitgeist")
.beforeCall("note").on("TestNexus").arg(elmID, "Flash")
.beforeEvent("warn","discarding note to unknown bID-zeitgeist"));
CHECK (elmLog.ensureNot("Flash")
.afterEvent("destroy","zeitgeist"));
}

View file

@ -177,6 +177,7 @@ namespace test{
log().call(this, "routeAdd", identity, newNode);
log().error ("attempt to connect against ZombieNexus");
cerr << "connect("<<string(identity)<<" -> ZombieNexus" <<endl;
return *this;
}
virtual void