Activity-Lang: draft a diagnostic helper

...for coverage of the Activity-Language,
various invocations of unspecific functions must be verified,
with the additional twist that the implementation avoids indirections
and is thus hard to rig for tests.

Solution-Idea: provide a λ-mock to log any invocation into the
Event-Log helper, which was created some years ago to trace GUI communication...
This commit is contained in:
Fischlurch 2023-07-31 21:53:16 +02:00
parent 26c2e835c3
commit db1adb63a7
6 changed files with 204 additions and 25 deletions

View file

@ -70,7 +70,7 @@ namespace meta {
* prior to C++11. Unfortunately these trailing NullType
* entries do not play well with other variadic defs.
* @deprecated when we switch our primary type sequence type
* to variadic parameters, this type will be obsoleted.
* to variadic parameters, this type will be obsoleted. ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic
*/
template<typename...TYPES>
struct TySeq
@ -99,7 +99,7 @@ namespace meta {
* template definitions.
* @note the result type is a TySec, to keep it apart from our
* legacy (non-variadic) lib::meta::Types
* @deprecated necessary for the transition to variadic sequences
* @deprecated necessary for the transition to variadic sequences ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic
*/
template<typename SEQ>
struct StripNullType;

View file

@ -290,12 +290,6 @@ namespace test{
, std::forward<ARGS>(args));
}
string
getID() const
{
return log_->front().get("this");
}
public:
explicit
@ -316,6 +310,14 @@ namespace test{
// standard copy operations acceptable
/// @return logID defined with the ctor to distinguish this log instance
string
getID() const
{
return log_->front().get("this");
}
/** Merge this log into another log, forming a combined log
* @param otherLog target to integrate this log's contents into.
* @return reference to the merged new log instance

View file

@ -269,8 +269,8 @@ namespace wrapper {
discard();
}
};
/**
* Specialisation of the ItemWrapper to deal with references,
* as if they were pointer values. Allows the reference value
@ -332,6 +332,29 @@ namespace wrapper {
};
/**
* Fallback-specialisation for `ItemWrapper<void>`.
* @remark This can be relevant when ItemWrapper is used to capture function results,
* yet the given function has return type `void` and used for its side-effects.
*/
template<>
class ItemWrapper<void>
{
public:
ItemWrapper()
{ }
// using default copy and assignment
operator bool() const { return true; }
bool isValid () const { return true; }
void reset () { /* NOP */ }
/** @warning does nothing */
void operator*() const { /* NOP */ }
};
/** allow equality comparison if the wrapped types are comparable */
template<typename TY>

View file

@ -27,7 +27,8 @@
#include "lib/test/run.hpp"
#include "activity-detector.hpp"
//#include "lib/time/timevalue.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/time/timevalue.hpp"
//#include "lib/format-cout.hpp"
//#include "lib/util.hpp"
@ -46,7 +47,8 @@ namespace test {
// using lib::time::FrameRate;
// using lib::time::Offset;
// using lib::time::Time;
using lib::time::Time;
using lib::time::FSecs;
@ -77,7 +79,15 @@ namespace test {
void
simpleUsage()
{
ActivityDetector spectre;
ActivityDetector detector("spectre");
auto trap = detector.buildDiagnosticFun<int(double,Time)>("trap")
.returning(55);
CHECK (55 == trap (1.23, Time{FSecs{3,2}}));
CHECK (detector == "Rec(EventLogHeader| this = ActivityDetector(spectre) ), "
"Rec(call| fun = trap, this = ActivityDetector(spectre) |{1.23, 0:00:01.500})"_expect);
}

View file

@ -46,6 +46,8 @@
#include "vault/common.hpp"
//#include "lib/test/test-helper.hpp"
#include "lib/test/event-log.hpp"
//#include "steam/play/dummy-play-connection.hpp"
//#include "steam/fixture/node-graph-attachment.hpp"
//#include "steam/fixture/segmentation.hpp"
@ -58,10 +60,16 @@
//#include "lib/time/timevalue.hpp"
//#include "lib/diff/gen-node.hpp"
//#include "lib/linked-elements.hpp"
#include "lib/meta/variadic-helper.hpp"
#include "lib/wrapper.hpp"
#include "lib/format-util.hpp"
//#include "lib/itertools.hpp"
//#include "lib/depend.hpp"
//#include "lib/util.hpp"
#include "lib/util.hpp"
#include <functional>
#include <utility>
#include <string>
//#include <tuple>
//#include <map>
@ -70,19 +78,36 @@ namespace vault{
namespace gear {
namespace test {
using std::string;
// using std::make_tuple;
// using lib::diff::GenNode;
// using lib::diff::MakeRec;
// using lib::time::TimeValue;
// using lib::time::Time;
// using lib::HashVal;
// using util::isnil;
using util::isnil;
// using util::isSameObject;
// using fixture::Segmentation;
// using vault::RealClock;
// using vault::gear::Job;
// using vault::gear::JobClosure;
namespace {
template<template<typename...> class X, typename...ARGS>
struct _RebindTypeSeq
{
using Type = X<ARGS...>;
};
template<template<typename...> class X
,template<typename...> class U
,typename...ARGS>
struct _RebindTypeSeq<X, U<ARGS...>>
{
using Type = X<ARGS...>;
};
}
/**
@ -92,15 +117,85 @@ namespace test {
class ActivityDetector
: util::NonCopyable
{
void* zombiePoolFactor_;
using EventLog = lib::test::EventLog;
EventLog eventLog_;
/**
* A Mock functor, logging all invocations into the EventLog
*/
template<typename RET, typename...ARGS>
class DiagnosticFun
{
using RetVal = lib::wrapper::ItemWrapper<RET>;
string id_;
EventLog* log_;
RetVal retVal_;
public:
DiagnosticFun (string id, EventLog& masterLog)
: id_{id}
, log_{&masterLog}
, retVal_{}
{ }
/** prepare a response value to return from the mock invocation */
DiagnosticFun&&
returning (RET&& riggedResponse)
{
retVal_ = std::forward<RET> (riggedResponse);
return std::move (*this);
}
/** mock function call operator: logs all invocations */
RET
operator() (ARGS const& ...args)
{
log_->call (log_->getID(), id_, args...);
return *retVal_;
}
};
public:
/* == walking deadline implementation == */
ActivityDetector()
: zombiePoolFactor_{}
ActivityDetector(string id)
: eventLog_{"ActivityDetector" + (isnil (id)? string{}: "("+id+")")}
{ }
operator string() const
{
return util::join (eventLog_);
}
void
clear(string newID)
{
if (isnil (newID))
eventLog_.clear();
else
eventLog_.clear (newID);
}
/**
* Generic testing helper: build a λ-mock, logging all invocations
* @tparam SIG signature of the functor to be generated
* @param id human readable ID, to designate invocations in the log
* @return a function object with signature #SIG
*/
template<typename SIG>
auto
buildDiagnosticFun (string id)
{
using Ret = typename lib::meta::_Fun<SIG>::Ret;
using Args = typename lib::meta::_Fun<SIG>::Args;
using ArgsX = typename lib::meta::StripNullType<Args>::Seq; ////////////////////////////////////TICKET #987 : make lib::meta::Types<TYPES...> variadic
using SigTypes = typename lib::meta::Prepend<Ret, ArgsX>::Seq;
using Functor = typename _RebindTypeSeq<DiagnosticFun, SigTypes>::Type;
return Functor{id, eventLog_};
}
private:
};

View file

@ -81627,13 +81627,62 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204967974" ID="ID_284088835" MODIFIED="1690070044262" TEXT="ActivityDetector">
<linktarget COLOR="#794f4b" DESTINATION="ID_284088835" ENDARROW="Default" ENDINCLINATION="-685;-107;" ID="Arrow_ID_1213725911" SOURCE="ID_1647246120" STARTARROW="None" STARTINCLINATION="518;48;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204985122" ID="ID_1020676746" MODIFIED="1689204995475" TEXT="Rahmen schaffen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689205014901" ID="ID_221497246" MODIFIED="1689205024996" TEXT="Instantiierung und Lebenszyklus">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689204985122" ID="ID_1020676746" MODIFIED="1690832427037" TEXT="Rahmen schaffen">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1689205014901" ID="ID_221497246" MODIFIED="1690832378644" TEXT="Instantiierung und Lebenszyklus">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1690817530037" ID="ID_497096743" MODIFIED="1690832373134" TEXT="kopierbares Objekt auf dem Stack">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1690817567303" ID="ID_258782505" MODIFIED="1690832374652" TEXT="default: this = ActivityDetector">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1690817626368" ID="ID_865927183" MODIFIED="1690832375691" TEXT="operator string() &#x27fc; join (event log)">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1689205007909" ID="ID_403603899" MODIFIED="1690832380383" TEXT="EventLog einbinden">
<icon BUILTIN="button_ok"/>
<node CREATED="1690832456039" ID="ID_314321104" MODIFIED="1690832525330">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
stabile Benennung: <font color="#1c5d6a" face="Monospaced">this = ActivityDetector(ID)</font>
</p>
</body>
</html></richcontent>
</node>
</node>
<node COLOR="#338800" CREATED="1690832398754" ID="ID_864386000" MODIFIED="1690832423318" TEXT="logging mock-&#x3bb;">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1690832539878" ID="ID_1163728085" MODIFIED="1690832566800" TEXT="Problem: brauche einen generischen Funktor mit vorgegebener Signatur">
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#435e98" CREATED="1690832634093" ID="ID_1752068820" MODIFIED="1690832811893" TEXT="Problem&#xb2;: _Fun liefert Types&lt;ARGS...&gt;">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1690832673285" ID="ID_1336668998" MODIFIED="1690832758349" TEXT="daraus kann ich nicht ohne Weiteres einen Funktions-Operator gewinnen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
wieder mal das l&#228;stige Problem mit den variadischen Templates: der Argument-Pack ist selber kein Typ, sondern man kann darauf nur matchen
</p>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1690832692447" ID="ID_1143189958" MODIFIED="1690832715493" TEXT="L&#xf6;sung: generisches Argument-Pack-Rebinding">
<icon BUILTIN="idea"/>
<node CREATED="1690832761614" ID="ID_1920220300" MODIFIED="1690832775036" TEXT="Template-Template-Parameter">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1690832776060" ID="ID_135731051" MODIFIED="1690832801676" TEXT="X&lt;ARGS...&gt; &#x27fc; U&lt;ARGS...&gt;"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690832821366" ID="ID_958989562" MODIFIED="1690832834253" TEXT="als generisches Util extrahieren">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689205007909" ID="ID_403603899" MODIFIED="1689205011845" TEXT="EventLog einbinden">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689205029658" ID="ID_1144318045" MODIFIED="1689205033146" TEXT="Verifikationen">
<icon BUILTIN="flag-yellow"/>