Lumiera  0.pre.03
»edityourfreedom«
event-log.hpp
Go to the documentation of this file.
1 /*
2  EVENT-LOG.hpp - test facility to verify the occurrence of expected events
3 
4  Copyright (C) Lumiera.org
5  2015, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
78 #ifndef LIB_TEST_EVENT_LOG_H
79 #define LIB_TEST_EVENT_LOG_H
80 
81 
82 #include "lib/error.hpp"
83 #include "lib/iter-cursor.hpp"
85 #include "lib/format-util.hpp"
86 #include "lib/format-cout.hpp"
87 #include "lib/diff/record.hpp"
88 #include "lib/idi/genfunc.hpp"
89 #include "lib/symbol.hpp"
90 #include "lib/util.hpp"
91 
92 #include <memory>
93 #include <vector>
94 #include <string>
95 #include <regex>
96 
97 
98 
99 namespace lib {
100 namespace test{
101 
102  using lib::Symbol;
103  using std::string;
104  using util::stringify;
105 
106  namespace {
107  using Entry = lib::diff::Record<string>;
108  using Log = std::vector<Entry>;
109 
110  auto
111  buildSearchFilter(Log const& srcSeq)
112  {
114  return iter::chainSearch (Cursor{srcSeq.begin(), srcSeq.end()});
115  }
116  }
117 
118 
129  {
130  using Filter = decltype( buildSearchFilter (std::declval<Log const&>()) );
131 
133  using RExSeq = std::vector<std::regex>;
134 
135 
138 
140  string lastMatch_;
141 
144 
146  string violation_;
147 
148 
149 
151  EventMatch(Log const& srcSeq);
152 
153  friend class EventLog;
154 
155 
156  public:
161  operator bool() const
162  {
163  if (not util::isnil (violation_))
164  {
165  cerr << "__Log_condition_violated__\n"+violation_ <<"\n";
166  return false;
167  }
168  return true;
169  }
170 
171 
172  /* query builders to continue search at current position */
173 
174  EventMatch& locate (string match);
175  EventMatch& locateMatch (string regExp);
176  EventMatch& locateEvent (string match);
177  EventMatch& locateEvent (string classifier, string match);
178  EventMatch& locateCall (string match);
179 
180 
181  /* query builders to find a match stepping forwards */
182 
183  EventMatch& before (string match);
184  EventMatch& beforeMatch (string regExp);
185  EventMatch& beforeEvent (string match);
186  EventMatch& beforeEvent (string classifier, string match);
187  EventMatch& beforeCall (string match);
188 
189 
190  /* query builders to find a match stepping backwards */
191 
192  EventMatch& after (string match);
193  EventMatch& afterMatch (string regExp);
194  EventMatch& afterEvent (string match);
195  EventMatch& afterEvent (string classifier, string match);
196  EventMatch& afterCall (string match);
197 
204  template<typename...ARGS>
205  EventMatch&
206  arg (ARGS const& ...args)
207  {
208  refineSerach_matchArguments (stringify<ArgSeq> (args...));
209  return *this;
210  }
211 
212 
223  template<typename...ARGS>
224  EventMatch&
225  argMatch (ARGS const& ...regExps)
226  {
227  refineSerach_matchArgsRegExp (stringify<RExSeq> (regExps...),
228  util::join(stringify<ArgSeq>(regExps...)));
229  return *this;
230  }
231 
232 
233 
234  /* query builders to augment and refine the currently defined search condition*/
235 
236  EventMatch& type (string typeID);
237  EventMatch& key (string key);
238  EventMatch& attrib (string key, string valueMatch);
239  EventMatch& id (string classifier);
240  EventMatch& on (string targetID);
241  EventMatch& on (const char* targetID);
242 
243  template<typename X>
244  EventMatch& on (const X *const targetObj)
245  {
246  string targetID = idi::instanceTypeID (targetObj);
247  return this->on(targetID);
248  }
249 
250  private:
251  bool foundSolution();
252  void evaluateQuery (string matchSpec, Literal rel = "after");
253 
254  void refineSerach_matchArguments (ArgSeq&& argSeq);
255  void refineSerach_matchArgsRegExp (RExSeq&& regExpSeq, string rendered_regExps);
256  };
257 
258 
259 
260 
261 
262 
263 
264 
265  /****************************************************************/
273  class EventLog
274  {
275 
277 
278 
279  void
280  log (std::initializer_list<string> const& ili)
281  {
282  log_->emplace_back(ili);
283  }
284 
285  template<typename ATTR, typename ARGS>
286  void
287  log (Symbol typeID, ATTR&& attribs, ARGS&& args)
288  {
289  log_->emplace_back(typeID, std::forward<ATTR>(attribs)
290  , std::forward<ARGS>(args));
291  }
292 
293  string
294  getID() const
295  {
296  return log_->front().get("this");
297  }
298 
299 
300  public:
301  explicit
302  EventLog (string logID);
303 
304  explicit
305  EventLog (const char* logID)
306  : EventLog(string(logID))
307  { }
308 
309  template<class X>
310  explicit
311  EventLog (const X *const obj)
312  : EventLog(idi::instanceTypeID (obj))
313  { }
314 
315 
316  // standard copy operations acceptable
317 
318 
324  EventLog& joinInto (EventLog& otherLog);
325 
326 
328  EventLog& clear();
329  EventLog& clear (string alteredLogID);
330  EventLog& clear (const char* alteredLogID);
331 
332  template<class X>
333  EventLog&
334  clear (const X *const obj)
335  {
336  return clear (idi::instanceTypeID (obj));
337  }
338 
339 
340 
341  /* ==== Logging API ==== */
342 
344 
346  EventLog& event (string text);
347 
352  EventLog& event (string classifier, string text);
353 
358  EventLog& call (string target, string function);
359 
361  EventLog& call (string target, string function, ArgSeq&& args);
362 
363  EventLog& call (const char* target, const char* function, ArgSeq&& args);
364 
366  template<typename...ARGS>
367  EventLog&
368  call (string target, string function, ARGS const& ...args)
369  {
370  return call (target, function, stringify<ArgSeq>(args...));
371  }
372 
374  template<class X, typename...ARGS>
375  EventLog&
376  call (const X *const targetObj, string function, ARGS const& ...args)
377  {
378  return call (idi::instanceTypeID (targetObj), function, args...);
379  }
380 
381  template<typename...ARGS>
382  EventLog&
383  call (const char* target, string function, ARGS const& ...args)
384  {
385  return call (string(target), function, args...);
386  }
387 
388  template<typename...ELMS>
389  EventLog&
390  note (ELMS const& ...initialiser)
391  {
392  log_->emplace_back (stringify<ArgSeq> (initialiser...));
393  return *this;
394  }
395 
396 
398  EventLog& warn (string text);
399 
401  EventLog& error (string text);
402 
404  EventLog& fatal (string text);
405 
408  EventLog& create (string text);
409 
410 
413  EventLog& destroy (string text);
414 
415 
416 
417 
418  /* ==== Iteration ==== */
419 
420  bool
421  empty() const
422  {
423  return 1 >= log_->size(); // do not count the log header
424  }
425 
426 
428 
430  typedef const Entry value_type;
431 
432  const_iterator begin() const { return Iter(log_->begin(), log_->end()); }
433  const_iterator end() const { return Iter(); }
434 
435  friend const_iterator begin (EventLog const& log) { return log.begin(); }
436  friend const_iterator end (EventLog const& log) { return log.end(); }
437 
438 
439 
440 
441  /* ==== Query/Verification API ==== */
442 
451  EventMatch verify (string match) const;
452 
459  EventMatch verifyMatch (string regExp) const;
460 
468  EventMatch verifyEvent (string match) const;
469 
473  EventMatch verifyEvent (string classifier, string match) const;
474 
475  template<typename X>
476  EventMatch
477  verifyEvent (string classifier, X const& something) const
478  {
479  return verifyEvent (classifier, util::toString (something));
480  }
481 
485  EventMatch verifyCall (string match) const;
486 
488  EventMatch
489  ensureNot (string match) const;
490 
491 
492 
493 
495  friend bool
496  operator== (EventLog const& l1, EventLog const& l2)
497  {
498  return l1.log_ == l2.log_
499  or (l1.log_ and l2.log_
500  and *l1.log_ == *l2.log_);
501  }
502  friend bool
503  operator!= (EventLog const& l1, EventLog const& l2)
504  {
505  return not (l1 == l2);
506  }
507  };
508 
509 
510 
511 }} // namespace lib::test
512 #endif /*LIB_TEST_EVENT_LOG_H*/
EventMatch & type(string typeID)
refine filter to additionally require a matching log entry type
Definition: event-log.cpp:527
std::vector< std::regex > RExSeq
Definition: event-log.hpp:133
EventMatch & locateCall(string match)
basic search for some specific function invocation
Definition: event-log.cpp:363
const_iterator end() const
Definition: event-log.hpp:433
lib::diff::RecordSetup< string >::Storage ArgSeq
Definition: event-log.hpp:343
string violation_
record when the underlying query has failed
Definition: event-log.hpp:146
Automatically use custom string conversion in C++ stream output.
bool operator!=(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Filter solution_
match predicate evaluator
Definition: event-log.hpp:137
EventLog(const char *logID)
Definition: event-log.hpp:305
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:174
EventMatch & on(const X *const targetObj)
Definition: event-log.hpp:244
Definition: run.hpp:49
friend const_iterator end(EventLog const &log)
Definition: event-log.hpp:436
decltype(buildSearchFilter(std::declval< Log const & >())) Filter
Definition: event-log.hpp:130
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
Definition: event-log.cpp:436
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
Helper to log and verify the occurrence of events.
Definition: event-log.hpp:273
EventMatch verifyEvent(string classifier, X const &something) const
Definition: event-log.hpp:477
const_iterator begin() const
Definition: event-log.hpp:432
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
EventMatch & beforeMatch(string regExp)
find a match with the given regular expression
Definition: event-log.cpp:393
EventMatch & after(string match)
find a match (substring match) of the given text in an EventLog entry before the current position...
Definition: event-log.cpp:452
An iterator with the ability to switch direction.
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
Definition: event-log.hpp:206
string join(CON &&coll, string const &delim=", ")
enumerate a collection&#39;s contents, separated by delimiter.
EventMatch & locateMatch(string regExp)
basic search like locate() but with the given regular expression
Definition: event-log.cpp:330
lib::diff::RecordSetup< string >::Storage ArgSeq
Definition: event-log.hpp:132
EventMatch & afterCall(string match)
find a function invocation backwards, before the current point of reference
Definition: event-log.cpp:487
void log(Symbol typeID, ATTR &&attribs, ARGS &&args)
Definition: event-log.hpp:287
Implementation namespace for support and library code.
EventMatch & afterEvent(string match)
Definition: event-log.cpp:468
Generic functions to build identification schemes.
friend class EventLog
Definition: event-log.hpp:153
void evaluateQuery(string matchSpec, Literal rel="after")
this is actually called after each refinement of the filter and matching conditions.
Definition: event-log.cpp:286
EventMatch & attrib(string key, string valueMatch)
refine filter to additionally match on a specific attribute
Definition: event-log.cpp:549
EventMatch(Log const &srcSeq)
Definition: event-log.cpp:256
Token or Atom with distinct identity.
Definition: symbol.hpp:116
Special collection to represent object-like data.
const Entry value_type
Definition: event-log.hpp:430
Evaluation mechanism to apply a sequence of conditions onto a linear search.
bool foundSolution()
core of the evaluation machinery: apply a filter predicate and then pull through the log to find a ac...
Definition: event-log.cpp:270
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
Definition: event-log.cpp:415
Marker types to indicate a literal string and a Symbol.
EventLog & call(const char *target, string function, ARGS const &...args)
Definition: event-log.hpp:383
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
EventLog(const X *const obj)
Definition: event-log.hpp:311
EventMatch & afterMatch(string regExp)
Definition: event-log.cpp:460
bool look_for_match_
support for positive and negative queries.
Definition: event-log.hpp:143
EventMatch & argMatch(ARGS const &...regExps)
refine filter to additionally cover all arguments with a series of regular expressions.
Definition: event-log.hpp:225
bool isnil(lib::time::Duration const &dur)
Definition: timevalue.hpp:642
EventMatch & id(string classifier)
refine filter to additionally match on the ID attribute
Definition: event-log.cpp:560
auto chainSearch(SRC &&srcData)
setup a chain search configuration by suitably wrapping the given container.
void refineSerach_matchArguments(ArgSeq &&argSeq)
Definition: event-log.cpp:500
CON stringify(ELMS const &...elms)
convert a sequence of elements to string
Lumiera error handling (C++ interface).
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
Definition: genfunc.hpp:125
EventLog & clear(const X *const obj)
Definition: event-log.hpp:334
EventMatch & locate(string match)
basic search function: continue linear lookup over the elements of the EventLog to find a match (subs...
Definition: event-log.cpp:319
EventLog & call(const X *const targetObj, string function, ARGS const &...args)
Log a function call on given object ("`this`")...
Definition: event-log.hpp:376
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
std::shared_ptr< Log > log_
Definition: event-log.hpp:276
void refineSerach_matchArgsRegExp(RExSeq &&regExpSeq, string rendered_regExps)
Definition: event-log.cpp:515
bool empty() const
Definition: event-log.hpp:421
EventLog & note(ELMS const &...initialiser)
Definition: event-log.hpp:390
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
EventLog & call(string target, string function, ARGS const &...args)
Log a function call with arbitrary arguments.
Definition: event-log.hpp:368
void log(std::initializer_list< string > const &ili)
Definition: event-log.hpp:280
EventMatch & on(string targetID)
refine filter to additionally match the &#39;this&#39; attribute
Definition: event-log.cpp:571
object-like record of data.
Definition: record.hpp:143
EventMatch & key(string key)
refine filter to additionally require the presence an attribute
Definition: event-log.cpp:538
string lastMatch_
record last match for diagnostics
Definition: event-log.hpp:140
EventMatch & before(string match)
find a match (substring match) of the given text in an EventLog entry after the current position ...
Definition: event-log.cpp:382
string getID() const
Definition: event-log.hpp:294
friend const_iterator begin(EventLog const &log)
Definition: event-log.hpp:435
EventMatch & locateEvent(string match)
basic search for a matching "event"
Definition: event-log.cpp:343