44 #ifndef LIB_DIFF_TEST_MUTATION_TARGET_H 45 #define LIB_DIFF_TEST_MUTATION_TARGET_H 72 using iter_stl::eachElm;
87 identify (
const T*
const entity)
97 renderAttribute (
GenNode const& elm)
99 return elm.idi.getSym()
105 renderChild (
GenNode const& elm)
113 return n.isNamed()? renderAttribute(n)
119 renderRecord (
Rec const& record)
125 + (Rec::TYPE_NIL==record.getType()?
"" : record.getType())
126 + (isnil(record.attribs())?
"" :
"| "+join (
transformIterator (record.attribs(), renderAttribute))+
" ")
127 + (isnil(record.scope())?
"" :
"|{"+join (
transformIterator (record.scope(), renderChild))+
"}")
136 struct StringRenderer
137 :
public Variant<DataValues>::Visitor
139 string representation{
""};
141 #define STRINGIFY_CONTENT(_TY_) \ 142 virtual void handle (_TY_& val) override { representation = util::toString (val); } 144 STRINGIFY_CONTENT (
int)
145 STRINGIFY_CONTENT (int64_t)
146 STRINGIFY_CONTENT (
short)
147 STRINGIFY_CONTENT (
char)
148 STRINGIFY_CONTENT (
bool)
149 STRINGIFY_CONTENT (
double)
150 STRINGIFY_CONTENT (
string)
160 handle (
Rec & rec)
override 162 representation = renderRecord (rec);
166 handle (
RecRef & ref)
override 169 representation = renderRecord (ref);
171 representation = util::BOTTOM_INDICATOR;
175 StringRenderer visitor;
176 unConst(content).accept (visitor);
177 return visitor.representation;
198 using VecG = std::vector<GenNode>;
203 VecG prev_content_{};
207 using iterator =
typename iter_stl::_SeqT<VecG>::Range;
208 using const_iterator =
typename iter_stl::_SeqT<const VecG>::Range;
210 const_iterator begin()
const {
return eachElm(content_); }
211 const_iterator end()
const {
return const_iterator(); }
213 iterator srcIter() {
return eachElm(prev_content_); }
214 iterator lastElm() {
return iterator(VecG::iterator(&content_.back()), content_.end());}
217 friend const_iterator begin (
TestMutationTarget const& target) {
return target.begin(); }
225 initMutation (
string mutatorID)
227 prev_content_.clear();
228 swap (content_, prev_content_);
229 log_.event (
"attachMutator "+mutatorID);
234 inject (
GenNode&& elm,
string operationID)
236 content_.emplace_back (forward<GenNode>(elm));
237 log_.event (operationID, renderNode (content_.back()));
243 while (pos and not pos->matches(targetID))
251 if (!empty() and content_.back().matches(targetID))
254 return search (targetID, eachElm(content_));
258 logSkip (
GenNode const& content)
260 log_.event (
"skipSrc", isnil(content.idi.getSym())? util::BOTTOM_INDICATOR : renderNode(content));
264 logAssignment (
GenNode const& target,
string oldPayload)
266 log_.event (
"assignElm",
_Fmt{
"%s: %s ⤅ %s"}
267 % target.idi.getSym()
273 logMutation (
GenNode const& target)
275 log_.event (
"mutateChild",
_Fmt{
"%s: start mutation...%s"}
276 % target.idi.getSym()
281 logScopeCompletion (iterator processingPos)
283 log_.event (
"completeScope",
_Fmt{
"⤴ scope%s completed / %d waste elm(s)"}
284 % (processingPos?
" NOT":
"")
285 % prev_content_.size());
294 return content_.empty();
312 verify (
string match)
const 314 return getLog().verify(match);
318 verifyMatch (
string regExp)
const 320 return getLog().verifyMatch(regExp);
324 verifyEvent (
string match)
const 326 return getLog().verifyEvent(match);
330 verifyEvent (
string classifier,
string match)
const 332 return getLog().verifyEvent (classifier,match);
336 verifyCall (
string match)
const 338 return getLog().verifyCall(match);
342 ensureNot (
string match)
const 344 return getLog().ensureNot(match);
363 using Iter = TestMutationTarget::iterator;
370 : PAR{forward<PAR> (chain)}
382 pos_ = target_.initMutation (identify(
this));
396 target_.inject (
GenNode{n},
"injectNew");
397 return PAR::injectNew (n);
412 return PAR::matchSrc(n)
422 GenNode const& skippedElm = *pos_;
424 target_.logSkip (skippedElm);
433 bool isSrcMatch = pos_ and n.
matches(*pos_);
436 target_.inject (move(*pos_),
"acceptSrc");
439 return PAR::acceptSrc(n)
447 Iter found = TestMutationTarget::search (ref.idi, pos_);
450 target_.inject (move(*found),
"findSrc");
452 return PAR::findSrc(ref)
460 bool foundTarget =
true;
463 for ( ; pos_; ++pos_)
464 target_.inject (move(*pos_),
"accept_until END");
467 for ( ; pos_ and pos_->isNamed(); ++pos_)
468 target_.inject (move(*pos_),
"accept_until after ATTRIBS");
471 string logMsg{
"accept_until "+spec.idi.getSym()};
472 while (pos_ and not TestWireTap::matchSrc(spec))
474 target_.inject (move(*pos_), logMsg);
477 if (TestWireTap::matchSrc(spec))
479 target_.inject (move(*pos_), logMsg);
485 return PAR::accept_until(spec)
494 Iter targetElm = target_.locate (spec.idi);
497 string logOldPayload{
render(targetElm->data)};
499 target_.logAssignment (*targetElm, logOldPayload);
501 return PAR::assignElm(spec)
510 if (PAR::mutateChild (spec, targetBuff))
514 Iter targetElm = target_.locate (spec.idi);
518 target_.logMutation (*targetElm);
530 target_.logScopeCompletion (pos_);
531 return PAR::completeScope()
532 and isnil(this->pos_);
541 return chainedBuilder<TestWireTap<PAR>> (dummy);
virtual bool completeScope()
verify all our pending (old) source elements where mentioned.
string showContent() const
render payload content for diagnostics
virtual bool assignElm(GenNode const &spec)
locate element already accepted into the target sequence and assign the designated payload value to i...
string render(DataCap const &)
Builder-DSL to create and configure a concrete TreeMutator.
Support for verifying the occurrence of events from unit tests.
Test adapter to watch and verify how the TreeMutator binds to custom tree data structures.
Any copy and copy construction prohibited.
inline string literal This is a marker type to indicate that
Helper to log and verify the occurrence of events.
A front-end for using printf-style formatting.
virtual bool accept_until(GenNode const &spec)
repeatedly accept, until after the designated location
Implementation namespace for support and library code.
Generic functions to build identification schemes.
Lumiera's internal time value datatype.
virtual bool matchSrc(GenNode const &n) override
ensure the next recorded source element matches on a formal level with given spec ...
static Builder< TreeMutator > build()
DSL: start building a custom adapted tree mutator, where the operations are tied by closures or wrapp...
SUB & emplace(SUB &&implementation)
move-construct an instance of a subclass into the opaque buffer
string showSrcBuffer() const
render elements waiting in source buffer to be accepted
Mix-Ins to allow or prohibit various degrees of copying and cloning.
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
Special collection to represent object-like data.
static const Ref END
symbolic ID ref "_END_"
Marker types to indicate a literal string and a Symbol.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
wrapped record reference.
virtual void skipSrc(GenNode const &n) override
skip next recorded src element without touching it
Lumiera error handling (C++ interface).
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor...
bool matches(GenNode const &o) const
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Offset measures a distance in time.
Customisable intermediary to abstract generic tree mutation operations.
virtual bool mutateChild(GenNode const &spec, TreeMutator::Handle targetBuff)
locate the designated target element and build a suitable sub-mutator for this element into the provi...
Duration is the internal Lumiera time metric.
virtual bool findSrc(GenNode const &ref) override
locate designated element and accept it at current position
A time interval anchored at a specific point in time.
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
object-like record of data.
virtual bool injectNew(GenNode const &n) override
record in the test target that a new child element is being inserted at current position ...
generic data element node within a tree
virtual bool acceptSrc(GenNode const &n) override
accept existing element, when matching the given spec