Lumiera  0.pre.03
»edit your freedom«
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 
79 #ifndef LIB_TEST_EVENT_LOG_H
80 #define LIB_TEST_EVENT_LOG_H
81 
82 
83 #include "lib/error.hpp"
84 #include "lib/iter-cursor.hpp"
86 #include "lib/format-util.hpp"
87 #include "lib/format-cout.hpp"
88 #include "lib/diff/record.hpp"
89 #include "lib/idi/genfunc.hpp"
90 #include "lib/symbol.hpp"
91 #include "lib/util.hpp"
92 
93 #include <memory>
94 #include <vector>
95 #include <string>
96 #include <regex>
97 
98 
99 
100 namespace lib {
101 namespace test{
102 
103  using lib::Symbol;
104  using std::string;
105  using util::collectStr;
106 
107  namespace {
109  using Log = std::vector<Entry>;
110 
111  auto
112  buildSearchFilter(Log const& srcSeq)
113  {
115  return iter::chainSearch (Cursor{srcSeq.begin(), srcSeq.end()});
116  }
117  }
118 
119 
130  {
131  using Filter = decltype( buildSearchFilter (std::declval<Log const&>()) );
132 
134  using RExSeq = std::vector<std::regex>;
135 
136 
138  Filter solution_;
139 
141  string lastMatch_;
142 
145 
147  string violation_;
148 
149 
150 
152  EventMatch(Log const& srcSeq);
153 
154  friend class EventLog;
155 
156 
157  public:
162  operator bool() const
163  {
164  if (not util::isnil (violation_))
165  {
166  cerr << "__Log_condition_violated__\n"+violation_ <<"\n";
167  return false;
168  }
169  return true;
170  }
171 
172 
173  /* query builders to continue search at current position */
174 
175  EventMatch& locate (string match);
176  EventMatch& locateMatch (string regExp);
177  EventMatch& locateEvent (string match);
178  EventMatch& locateEvent (string classifier, string match);
179  EventMatch& locateCall (string match);
180 
181 
182  /* query builders to find a match stepping forwards */
183 
184  EventMatch& before (string match);
185  EventMatch& beforeMatch (string regExp);
186  EventMatch& beforeEvent (string match);
187  EventMatch& beforeEvent (string classifier, string match);
188  EventMatch& beforeCall (string match);
189 
190 
191  /* query builders to find a match stepping backwards */
192 
193  EventMatch& after (string match);
194  EventMatch& afterMatch (string regExp);
195  EventMatch& afterEvent (string match);
196  EventMatch& afterEvent (string classifier, string match);
197  EventMatch& afterCall (string match);
198 
205  template<typename...ARGS>
206  EventMatch&
207  arg (ARGS const& ...args)
208  {
209  refineSerach_matchArguments (collectStr<ArgSeq> (args...));
210  return *this;
211  }
212 
213 
224  template<typename...ARGS>
225  EventMatch&
226  argMatch (ARGS const& ...regExps)
227  {
228  refineSerach_matchArgsRegExp (collectStr<RExSeq> (regExps...),
229  util::join(collectStr<ArgSeq>(regExps...)));
230  return *this;
231  }
232 
234  template<typename ARG>
235  EventMatch&
236  argPos (size_t idx, ARG const& arg)
237  {
238  refineSerach_matchArgument (idx, util::toString(arg));
239  return *this;
240  }
241 
242 
243  /* query builders to augment and refine the currently defined search condition*/
244 
245  EventMatch& type (string typeID);
246  EventMatch& key (string key);
247  EventMatch& attrib (string key, string valueMatch);
248  EventMatch& id (string classifier);
249  EventMatch& on (string targetID);
250  EventMatch& on (const char* targetID);
251 
252  template<typename X>
253  EventMatch& on (const X *const targetObj)
254  {
255  string targetID = idi::instanceTypeID (targetObj);
256  return this->on(targetID);
257  }
258 
259  private:
260  bool foundSolution();
261  void evaluateQuery (string matchSpec, Literal rel = "after");
262 
263  void refineSerach_matchArgument (size_t idx, string match);
264  void refineSerach_matchArguments (ArgSeq&& argSeq);
265  void refineSerach_matchArgsRegExp (RExSeq&& regExpSeq, string rendered_regExps);
266  };
267 
268 
269 
270 
271 
272 
273 
274 
275  /****************************************************************/
284  class EventLog
285  {
286 
288 
289 
290  void
291  log (std::initializer_list<string> const& ili)
292  {
293  log_->emplace_back(ili);
294  }
295 
296  template<typename ATTR, typename ARGS>
297  void
298  log (Symbol typeID, ATTR&& attribs, ARGS&& args)
299  {
300  log_->emplace_back(typeID, std::forward<ATTR>(attribs)
301  , std::forward<ARGS>(args));
302  }
303 
304 
305  public:
306  explicit
307  EventLog (string logID);
308 
309  explicit
310  EventLog (const char* logID)
311  : EventLog(string(logID))
312  { }
313 
314  template<class X>
315  explicit
316  EventLog (const X *const obj)
318  { }
319 
320 
321  // standard copy operations acceptable
322 
323 
325  string
326  getID() const
327  {
328  return log_->front().get("this");
329  }
330 
331 
337  EventLog& joinInto (EventLog& otherLog);
338 
339 
341  EventLog& clear();
342  EventLog& clear (string alteredLogID);
343  EventLog& clear (const char* alteredLogID);
344 
345  template<class X>
346  EventLog&
347  clear (const X *const obj)
348  {
349  return clear (idi::instanceTypeID (obj));
350  }
351 
352 
353 
354  /* ==== Logging API ==== */
355 
357 
359  EventLog& event (string text);
360 
365  EventLog& event (string classifier, string text);
366 
371  EventLog& call (string target, string function);
372 
374  EventLog& call (string target, string function, ArgSeq&& args);
375 
376  EventLog& call (const char* target, const char* function, ArgSeq&& args);
377 
379  template<typename...ARGS>
380  EventLog&
381  call (string target, string function, ARGS const& ...args)
382  {
383  return call (target, function, collectStr<ArgSeq>(args...));
384  }
385 
387  template<class X, typename...ARGS>
388  EventLog&
389  call (const X *const targetObj, string function, ARGS const& ...args)
390  {
391  return call (idi::instanceTypeID (targetObj), function, args...);
392  }
393 
394  template<typename...ARGS>
395  EventLog&
396  call (const char* target, string function, ARGS const& ...args)
397  {
398  return call (string(target), function, args...);
399  }
400 
401  template<typename...ELMS>
402  EventLog&
403  note (ELMS const& ...initialiser)
404  {
405  log_->emplace_back (collectStr<ArgSeq> (initialiser...));
406  return *this;
407  }
408 
409 
411  EventLog& warn (string text);
412 
414  EventLog& error (string text);
415 
417  EventLog& fatal (string text);
418 
421  EventLog& create (string text);
422 
423 
426  EventLog& destroy (string text);
427 
428 
430  template<typename X, typename...ARGS>
431  EventLog&
432  addAttrib (string const& key, X&& initialiser, ARGS&& ...args)
433  {
434  REQUIRE (not isnil (*log_));
435  mutateInPlace (log_->back())
436  .attrib(key,initialiser, std::forward<ARGS>(args)...);
437  return *this;
438  }
439 
440 
441 
442 
443  /* ==== Iteration ==== */
444 
445  bool
446  empty() const
447  {
448  return 1 >= log_->size(); // do not count the log header
449  }
450 
451 
453 
454  typedef Iter const_iterator;
455  typedef const Entry value_type;
456 
457  const_iterator begin() const { return Iter(log_->begin(), log_->end()); }
458  const_iterator end() const { return Iter(); }
459 
460  friend const_iterator begin (EventLog const& log) { return log.begin(); }
461  friend const_iterator end (EventLog const& log) { return log.end(); }
462 
463 
464 
465 
466  /* ==== Query/Verification API ==== */
467 
476  EventMatch verify (string match) const;
477 
484  EventMatch verifyMatch (string regExp) const;
485 
493  EventMatch verifyEvent (string match) const;
494 
498  EventMatch verifyEvent (string classifier, string match) const;
499 
500  template<typename X>
501  EventMatch
502  verifyEvent (string classifier, X const& something) const
503  {
504  return verifyEvent (classifier, util::toString (something));
505  }
506 
510  EventMatch verifyCall (string match) const;
511 
513  EventMatch
514  ensureNot (string match) const;
515 
516 
517 
518 
520  friend bool
521  operator== (EventLog const& l1, EventLog const& l2)
522  {
523  return l1.log_ == l2.log_
524  or (l1.log_ and l2.log_
525  and *l1.log_ == *l2.log_);
526  }
527  friend bool
528  operator!= (EventLog const& l1, EventLog const& l2)
529  {
530  return not (l1 == l2);
531  }
532  };
533 
534 
535 
536 }} // namespace lib::test
537 #endif /*LIB_TEST_EVENT_LOG_H*/
void refineSerach_matchArgument(size_t idx, string match)
Definition: event-log.cpp:511
EventMatch & type(string typeID)
refine filter to additionally require a matching log entry type
Definition: event-log.cpp:548
EventMatch & locateCall(string match)
basic search for some specific function invocation
Definition: event-log.cpp:374
string violation_
record when the underlying query has failed
Definition: event-log.hpp:147
Automatically use custom string conversion in C++ stream output.
Filter solution_
match predicate evaluator
Definition: event-log.hpp:138
Definition: run.hpp:49
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
Definition: event-log.cpp:447
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:85
CON collectStr(ELMS const &...elms)
convert a sequence of elements to string
Helper to log and verify the occurrence of events.
Definition: event-log.hpp:284
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:404
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:463
An iterator with the ability to switch direction.
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
Definition: event-log.hpp:207
EventMatch & locateMatch(string regExp)
basic search like locate() but with the given regular expression
Definition: event-log.cpp:341
EventMatch & afterCall(string match)
find a function invocation backwards, before the current point of reference
Definition: event-log.cpp:498
Implementation namespace for support and library code.
Generic functions to build identification schemes.
void evaluateQuery(string matchSpec, Literal rel="after")
this is actually called after each refinement of the filter and matching conditions.
Definition: event-log.cpp:297
EventMatch & attrib(string key, string valueMatch)
refine filter to additionally match on a specific attribute
Definition: event-log.cpp:570
EventMatch(Log const &srcSeq)
Definition: event-log.cpp:267
Token or Atom with distinct identity.
Definition: symbol.hpp:126
Special collection to represent object-like data.
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:281
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
Definition: event-log.cpp:426
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...
EventMatch & argPos(size_t idx, ARG const &arg)
refine filter to additionally require match on a specific positional argument
Definition: event-log.hpp:236
bool look_for_match_
support for positive and negative queries.
Definition: event-log.hpp:144
EventMatch & argMatch(ARGS const &...regExps)
refine filter to additionally cover all arguments with a series of regular expressions.
Definition: event-log.hpp:226
EventMatch & id(string classifier)
refine filter to additionally match on the ID attribute
Definition: event-log.cpp:581
void refineSerach_matchArguments(ArgSeq &&argSeq)
Definition: event-log.cpp:521
Lumiera error handling (C++ interface).
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
Definition: genfunc.hpp:125
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:330
EventLog & addAttrib(string const &key, X &&initialiser, ARGS &&...args)
Qualify the latest entry: set further attribute(s)
Definition: event-log.hpp:432
EventLog & call(const X *const targetObj, string function, ARGS const &...args)
Log a function call on given object ("`this`")...
Definition: event-log.hpp:389
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
void refineSerach_matchArgsRegExp(RExSeq &&regExpSeq, string rendered_regExps)
Definition: event-log.cpp:536
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:381
EventMatch & on(string targetID)
refine filter to additionally match the &#39;this&#39; attribute
Definition: event-log.cpp:592
object-like record of data.
Definition: record.hpp:150
EventMatch & key(string key)
refine filter to additionally require the presence an attribute
Definition: event-log.cpp:559
string lastMatch_
record last match for diagnostics
Definition: event-log.hpp:141
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:393
string getID() const
Definition: event-log.hpp:326
EventMatch & locateEvent(string match)
basic search for a matching "event"
Definition: event-log.cpp:354