64 using Filter = decltype( buildSearchFilter (std::declval<Log const&>()) );
67 using RExSeq = std::vector<std::regex>;
73 return [=](Entry
const&
entry)
75 return contains (
string(
entry), match);
80 findRegExp (
string regExpDef)
82 std::regex regExp(regExpDef);
83 return [=](Entry
const&
entry)
85 return std::regex_search(
string(
entry), regExp);
90 findEvent (
string match)
92 return [=](Entry
const&
entry)
94 return (
entry.getType() ==
"event" 95 or
entry.getType() ==
"error" 96 or
entry.getType() ==
"create" 97 or
entry.getType() ==
"destroy" 98 or
entry.getType() ==
"logJoin" 100 and not isnil(
entry.scope())
101 and contains (*
entry.scope(), match);
106 findEvent (
string classifier,
string match)
108 return [=](Entry
const&
entry)
110 return (
entry.getType() == classifier
111 or (
entry.hasAttribute(
"ID") and contains (
entry.get(
"ID"), classifier))
113 and not isnil(
entry.scope())
114 and contains (*
entry.scope(), match);
119 findCall (
string match)
121 return [=](Entry
const&
entry)
123 return entry.getType() ==
"call" 124 and contains (
entry.get(
"fun"), match);
140 return [=](Entry
const&
entry)
142 auto scope =
entry.scope();
143 for (
auto const& match : argSeq)
144 if (isnil (scope) or not contains(*scope, match))
157 return [=](Entry
const&
entry)
159 return idx <
entry.childSize()
160 and contains (
entry.child(idx), match);
177 return [=](Entry
const&
entry)
179 auto scope =
entry.scope();
180 for (
auto const& rex : regExpSeq)
182 if (isnil (scope))
return false;
183 while (scope and std::regex_search(*scope, rex))
196 return [=](Entry
const&
entry)
198 return contains (
entry.getType(), typeID);
207 return [=](Entry
const&
entry)
209 return entry.hasAttribute(key);
218 return [=](Entry
const&
entry)
220 return entry.hasAttribute(key)
221 and contains (
entry.get(key), valueMatch);
230 FORWARD, BACKWARD, CURRENT
233 template<
typename COND>
235 attachNextSerchStep (Filter& solution, COND&& searchCond, Direction direction)
237 if (CURRENT == direction)
238 solution.search (forward<COND> (searchCond));
240 solution.addStep ([predicate{forward<COND> (searchCond)}, direction]
243 filter.reverse (BACKWARD == direction);
246 filter.setNewFilter (predicate);
250 template<
typename COND>
252 refineSerach (Filter& solution, COND&& additionalCond)
254 solution.addStep ([predicate{forward<COND> (additionalCond)}]
257 filter.andFilter (predicate);
268 : solution_{buildSearchFilter (srcSeq)}
332 attachNextSerchStep (
solution_, find(match), CURRENT);
343 attachNextSerchStep (
solution_, findRegExp(regExp), CURRENT);
356 attachNextSerchStep (
solution_, findEvent(match), CURRENT);
364 attachNextSerchStep (
solution_, findEvent(classifier,match), CURRENT);
365 evaluateQuery (
"match-event(ID=\""+classifier+
"\", \""+match+
"\")");
376 attachNextSerchStep (
solution_, findCall(match), CURRENT);
395 attachNextSerchStep (
solution_, find(match), FORWARD);
406 attachNextSerchStep (
solution_, findRegExp(regExp), FORWARD);
428 attachNextSerchStep (
solution_, findEvent(match), FORWARD);
436 attachNextSerchStep (
solution_, findEvent(classifier,match), FORWARD);
437 evaluateQuery (
"match-event(ID=\""+classifier+
"\", \""+match+
"\")");
449 attachNextSerchStep (
solution_, findCall(match), FORWARD);
465 attachNextSerchStep (
solution_, find(match), BACKWARD);
471 EventMatch::afterMatch (
string regExp)
473 attachNextSerchStep (
solution_, findRegExp(regExp), BACKWARD);
479 EventMatch::afterEvent (
string match)
481 attachNextSerchStep (
solution_, findEvent(match), BACKWARD);
487 EventMatch::afterEvent (
string classifier,
string match)
489 attachNextSerchStep (
solution_, findEvent(classifier,match), BACKWARD);
490 evaluateQuery (
"match-event(ID=\""+classifier+
"\", \""+match+
"\")",
"before");
500 attachNextSerchStep (
solution_, findCall(match), BACKWARD);
514 evaluateQuery (
"match-argument(["+util::toString(idx)+
"]="+match+
")");
523 string argList(util::join(argSeq));
573 evaluateQuery (
"match-attribute("+key+
"=\""+valueMatch+
"\")");
613 EventLog::EventLog (
string logID)
616 log({
"type=EventLogHeader",
"this="+logID});
636 Log& target = *otherLog.log_;
637 target.reserve (target.size() + log_->size() + 1);
638 target.emplace_back (log_->front());
639 auto p = log_->begin();
640 while (++p != log_->end())
641 target.emplace_back (std::move(*p));
642 this->log_->resize(1);
643 this->log({
"type=joined", otherLog.
getID()});
644 otherLog.log({
"type=logJoin", this->getID()});
645 this->log_ = otherLog.log_;
654 string originalLogID = this->getID();
655 return this->clear (originalLogID);
669 log_.reset (
new Log);
670 log({
"type=EventLogHeader",
"this="+alteredLogID});
677 return clear (
string{alteredLogID});
687 log (
"event", ArgSeq{}, ArgSeq{text});
694 log (
"event", ArgSeq{
"ID="+classifier}, ArgSeq{text});
701 return call(target,
function, ArgSeq());
707 log (
"call", ArgSeq{
"fun="+
function,
"this="+target}, std::forward<ArgSeq>(args));
712 EventLog::call (
const char* target,
const char*
function, ArgSeq&& args)
714 return call (
string(target),
string(
function), std::forward<ArgSeq>(args));
721 log({
"type=warn", text});
728 log({
"type=error", text});
735 log({
"type=fatal", text});
744 log({
"type=create", text});
751 log({
"type=destroy", text});
void refineSerach_matchArgument(size_t idx, string match)
EventMatch & type(string typeID)
refine filter to additionally require a matching log entry type
EventLog & event(string text)
log some text as event
EventMatch & locateCall(string match)
basic search for some specific function invocation
auto ensureAttribute(string key)
refinement filter to ensure a specific attribute is present on the log entry
string violation_
record when the underlying query has failed
Filter solution_
match predicate evaluator
EventLog & warn(string text)
Log a warning entry.
Support for verifying the occurrence of events from unit tests.
bool filter(Placement< DummyMO > const &candidate)
a filter predicate to pick some objects from a resultset.
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
inline string literal This is a marker type to indicate that
Helper to log and verify the occurrence of events.
EventMatch & beforeMatch(string regExp)
find a match with the given regular expression
EventLog & create(string text)
Log the creation of an object.
EventMatch & after(string match)
find a match (substring match) of the given text in an EventLog entry before the current position...
EventMatch & locateMatch(string regExp)
basic search like locate() but with the given regular expression
EventMatch verifyEvent(string match) const
start a query to match for some event.
EventMatch & afterCall(string match)
find a function invocation backwards, before the current point of reference
Implementation namespace for support and library code.
auto matchArgsRegExp(RExSeq &®ExpSeq)
refinement filter, to cover all arguments by regular expression(s)
void evaluateQuery(string matchSpec, Literal rel="after")
this is actually called after each refinement of the filter and matching conditions.
EventMatch & attrib(string key, string valueMatch)
refine filter to additionally match on a specific attribute
EventMatch(Log const &srcSeq)
auto matchArgument(size_t idx, string match)
refinement filter to match a specific positional argument
Token or Atom with distinct identity.
EventMatch verifyCall(string match) const
start a query to match especially a function call
EventMatch ensureNot(string match) const
start a query to ensure the given expression does not match.
auto matchAttribute(string key, string valueMatch)
refinement filter to ensure a specific attribute is present on the log entry
bool foundSolution()
core of the evaluation machinery: apply a filter predicate and then pull through the log to find a ac...
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
EventLog & clear()
purge log contents while retaining just the original Header-ID
auto matchArguments(ArgSeq &&argSeq)
this filter functor is for refinement of an existing filter
EventLog & call(string target, string function)
Log occurrence of a function call with no arguments.
EventLog & joinInto(EventLog &otherLog)
Merge this log into another log, forming a combined log.
bool look_for_match_
support for positive and negative queries.
EventMatch & id(string classifier)
refine filter to additionally match on the ID attribute
void refineSerach_matchArguments(ArgSeq &&argSeq)
Lumiera error handling (C++ interface).
EventMatch & locate(string match)
basic search function: continue linear lookup over the elements of the EventLog to find a match (subs...
EventLog & fatal(string text)
Log a fatal failure.
EventMatch verify(string match) const
start a query to match for some substring.
void refineSerach_matchArgsRegExp(RExSeq &®ExpSeq, string rendered_regExps)
EventLog & destroy(string text)
Log the destruction of an object.
EventMatch verifyMatch(string regExp) const
start a query to match with a regular expression
EventMatch & on(string targetID)
refine filter to additionally match the 'this' attribute
auto matchType(string typeID)
refinement filter to match on the given typeID
EventMatch & key(string key)
refine filter to additionally require the presence an attribute
string lastMatch_
record last match for diagnostics
EventMatch & before(string match)
find a match (substring match) of the given text in an EventLog entry after the current position ...
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
EventMatch & locateEvent(string match)
basic search for a matching "event"
EventLog & error(string text)
Log an error note.