diff --git a/src/lib/wrapper.hpp b/src/lib/wrapper.hpp index 2d111dc9f..7ee0ef197 100644 --- a/src/lib/wrapper.hpp +++ b/src/lib/wrapper.hpp @@ -235,6 +235,15 @@ namespace wrapper { return *this; } + /** implant a default-initialised instance of the payload type */ + ItemWrapper& + defaultInit() + { + discard(); + build (TY()); + return *this; + } + operator bool() const { return isValid(); @@ -306,6 +315,12 @@ namespace wrapper { return *this; } + ItemWrapper& + defaultInit() ///< @note just reset for this specialisation + { + reset(); + return *this; + } /* == value access == */ @@ -335,7 +350,7 @@ namespace wrapper { /** * Fallback-specialisation for `ItemWrapper`. * @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. + * yet the given function has return type `void` and is used for side-effects. */ template<> class ItemWrapper @@ -352,6 +367,12 @@ namespace wrapper { /** @warning does nothing */ void operator*() const { /* NOP */ } + + ItemWrapper& + defaultInit() ///< no effect for this specialisation + { + return *this; + } }; diff --git a/src/vault/gear/activity.hpp b/src/vault/gear/activity.hpp index d6cdeac78..af8a3a25e 100644 --- a/src/vault/gear/activity.hpp +++ b/src/vault/gear/activity.hpp @@ -186,7 +186,7 @@ namespace gear { { #define ASSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \ static_assert (lib::meta::has_Sig(), \ - "Execution-Context: " STRINGIFY(_FUN_) " expect function with signature: " STRINGIFY(_SIG_)); + "Execution-Context: " STRINGIFY(_EXPR_) " expect function with signature: " STRINGIFY(_SIG_)); ASSERT_MEMBER_FUNCTOR (EXE::post, Proc(Time, Activity&, EXE&)); diff --git a/tests/vault/gear/activity-detector-test.cpp b/tests/vault/gear/activity-detector-test.cpp index 1fa115651..153605942 100644 --- a/tests/vault/gear/activity-detector-test.cpp +++ b/tests/vault/gear/activity-detector-test.cpp @@ -71,6 +71,7 @@ namespace test { simpleUsage(); verifyMockInvocation(); + verifyFakeInvocation(); verifyMockJobFunctor(); verifyFakeExeContext(); watch_activation(); @@ -149,6 +150,33 @@ namespace test { + /** @test verify a variation of the instrumented functor + * to call into a custom provided _fake implementation._ + */ + void + verifyFakeInvocation() + { + ActivityDetector detector; + auto fun = detector.buildDiagnosticFun ("fakeFun"); + uint rnd = rand() % 10000; + + CHECK (0 == fun (rnd)); + + fun.returning(42); + detector.incrementSeq(); + CHECK (42 == fun (rnd)); + + fun.implementedAs ([](uint i){ return -i; }); + detector.incrementSeq(); + CHECK (-int(rnd) == fun (rnd)); + + CHECK (detector.verifyInvocation("fakeFun").seq(0) + .beforeInvocation("fakeFun").seq(1) + .beforeInvocation("fakeFun").seq(2)); + } + + + /** @test diagnostic setup to detect a JobFunctor activation * - the ActivityDetector provides specifically rigged JobFunctor instances * - these capture all invocations, based on generic invocation logging @@ -389,7 +417,7 @@ namespace test { CHECK (detector.verifyInvocation("tap-GATE").seq(0).timeArg(tt) .beforeSeqIncrement(1) - .beforeInvocation("afterGATE").seq(1).timeArg(tt) + .beforeInvocation("after-GATE").seq(1).timeArg(tt) .beforeInvocation("CTX-tick").seq(1).timeArg(tt)); } }; diff --git a/tests/vault/gear/activity-detector.hpp b/tests/vault/gear/activity-detector.hpp index c4d9cc939..90c060887 100644 --- a/tests/vault/gear/activity-detector.hpp +++ b/tests/vault/gear/activity-detector.hpp @@ -268,10 +268,12 @@ namespace test { class DiagnosticFun { using RetVal = lib::wrapper::ItemWrapper; + using ImplFun = std::function; string id_; EventLog* log_; uint const* seqNr_; + ImplFun implFun_; RetVal retVal_; public: @@ -279,8 +281,11 @@ namespace test { : id_{id} , log_{&masterLog} , seqNr_{&invocationSeqNr} + , implFun_{} , retVal_{} - { } + { + retVal_.defaultInit(); + } /** prepare a response value to return from the mock invocation */ template @@ -291,6 +296,15 @@ namespace test { return std::move (*this); } + /** use the given λ to provide (optional) implementation logic */ + template + DiagnosticFun&& + implementedAs (FUN&& customImpl) + { + implFun_ = std::forward (customImpl); + return std::move (*this); + } + // default copyable /** mock function call operator: logs all invocations */ @@ -299,7 +313,8 @@ namespace test { { log_->call (log_->getID(), id_, args...) .addAttrib (MARK_SEQ, util::toString(*seqNr_)); - return *retVal_; + return implFun_? implFun_(std::forward(args)...) + : *retVal_; } operator string() const diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 39c171189..e7fe317a3 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -80185,6 +80185,42 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +

+ Im ActivityDetector sind normalerweise die ctx-λ als reine Logging-Funktionen implementiert; aber die nun konstruierte Ausführungs-Logik setzt fest darauf, daß ein Aufruf von ctx.post() sofort in einen ActivityLang::dispatchChain() umgesetzt wird (allerdings nicht wirklich immer, sondern nur in dem Fall, daß wir das GroomingToken halten und die im post() gegebene Zeit die aktuelle Zeit ist) +

+ + +
+ + +
+ + + + + + + + +

+ FakeExecutionCtx bzw. die dort verwendete DiagnosticFun, auf die man ja tatsächlich zugreifen können sollte (um den Rückgabewert zu manipulieren) — und das wäre bei einer std::function  nicht mehr möglich... +

+ + +
+ + +
+
+