Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
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)
5 2015, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
70#ifndef LIB_TEST_EVENT_LOG_H
71#define LIB_TEST_EVENT_LOG_H
72
73
74#include "lib/error.hpp"
75#include "lib/iter-cursor.hpp"
77#include "lib/format-util.hpp"
78#include "lib/format-cout.hpp"
79#include "lib/diff/record.hpp"
80#include "lib/idi/genfunc.hpp"
81#include "lib/symbol.hpp"
82#include "lib/util.hpp"
83
84#include <memory>
85#include <vector>
86#include <string>
87#include <regex>
88
89
90
91namespace lib {
92namespace test{
93
94 using lib::Symbol;
95 using std::string;
96 using util::collectStr;
97
98 namespace {
100 using Log = std::vector<Entry>;
101
102 auto
103 buildSearchFilter(Log const& srcSeq)
104 {
106 return iter::chainSearch (Cursor{srcSeq.begin(), srcSeq.end()});
107 }
108 }
109
110
121 {
122 using Filter = decltype( buildSearchFilter (std::declval<Log const&>()) );
123
125 using RExSeq = std::vector<std::regex>;
126
127
130
133
136
139
140
141
143 EventMatch(Log const& srcSeq);
144
145 friend class EventLog;
146
147
148 public:
153 operator bool() const
154 {
155 if (not util::isnil (violation_))
156 {
157 cerr << "__Log_condition_violated__\n"+violation_ <<"\n";
158 return false;
159 }
160 return true;
161 }
162
163
164 /* query builders to continue search at current position */
165
166 EventMatch& locate (string match);
167 EventMatch& locateMatch (string regExp);
168 EventMatch& locateEvent (string match);
169 EventMatch& locateEvent (string classifier, string match);
170 EventMatch& locateCall (string match);
171
172
173 /* query builders to find a match stepping forwards */
174
175 EventMatch& before (string match);
176 EventMatch& beforeMatch (string regExp);
177 EventMatch& beforeEvent (string match);
178 EventMatch& beforeEvent (string classifier, string match);
179 EventMatch& beforeCall (string match);
180
181
182 /* query builders to find a match stepping backwards */
183
184 EventMatch& after (string match);
185 EventMatch& afterMatch (string regExp);
186 EventMatch& afterEvent (string match);
187 EventMatch& afterEvent (string classifier, string match);
188 EventMatch& afterCall (string match);
189
196 template<typename...ARGS>
198 arg (ARGS const& ...args)
199 {
200 refineSerach_matchArguments (collectStr<ArgSeq> (args...));
201 return *this;
202 }
203
204
215 template<typename...ARGS>
217 argMatch (ARGS const& ...regExps)
218 {
219 refineSerach_matchArgsRegExp (collectStr<RExSeq> (regExps...),
220 util::join(collectStr<ArgSeq>(regExps...)));
221 return *this;
222 }
223
225 template<typename ARG>
227 argPos (size_t idx, ARG const& arg)
228 {
230 return *this;
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 (CStr 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_matchArgument (size_t idx, string match);
255 void refineSerach_matchArguments (ArgSeq&& argSeq);
256 void refineSerach_matchArgsRegExp (RExSeq&& regExpSeq, string rendered_regExps);
257 };
258
259
260
261
262
263
264
265
266 /****************************************************************/
276 {
277
278 std::shared_ptr<Log> log_;
279
280
281 void
282 log (std::initializer_list<string> const& ili)
283 {
284 log_->emplace_back(ili);
285 }
286
287 template<typename ATTR, typename ARGS>
288 void
289 log (Symbol typeID, ATTR&& attribs, ARGS&& args)
290 {
291 log_->emplace_back(typeID, std::forward<ATTR>(attribs)
292 , std::forward<ARGS>(args));
293 }
294
295
296 public:
297 explicit
298 EventLog (string logID);
299
300 explicit
302 : EventLog(string(logID))
303 { }
304
305 template<class X>
306 explicit
307 EventLog (const X *const obj)
308 : EventLog(idi::instanceTypeID (obj))
309 { }
310
311
312 // standard copy operations acceptable
313
314
316 string
317 getID() const
318 {
319 return log_->front().get("this");
320 }
321
322
328 EventLog& joinInto (EventLog& otherLog);
329
330
332 EventLog& clear();
333 EventLog& clear (string alteredLogID);
334 EventLog& clear (CStr alteredLogID);
335
336 template<class X>
337 EventLog&
338 clear (const X *const obj)
339 {
340 return clear (idi::instanceTypeID (obj));
341 }
342
343
344
345 /* ==== Logging API ==== */
346
348
350 EventLog& event (string text);
351
356 EventLog& event (string classifier, string text);
357
358 template<typename...ELMS>
359 EventLog&
360 event (string classifier, ELMS const& ...initialiser)
361 {
362 log ("event", ArgSeq{"ID="+classifier}, collectStr<ArgSeq> (initialiser...));
363 return *this;
364 }
365
370 EventLog& call (string target, string function);
371
373 EventLog& call (string target, string function, ArgSeq&& args);
374
375 EventLog& call (CStr target, CStr function, ArgSeq&& args);
376
378 template<typename...ARGS>
379 EventLog&
380 call (string target, string function, ARGS const& ...args)
381 {
382 return call (target, function, collectStr<ArgSeq>(args...));
383 }
384
386 template<class X, typename...ARGS>
387 EventLog&
388 call (const X *const targetObj, string function, ARGS const& ...args)
389 {
390 return call (idi::instanceTypeID (targetObj), function, args...);
391 }
392
393 template<typename...ARGS>
394 EventLog&
395 call (CStr target, string function, ARGS const& ...args)
396 {
397 return call (string(target), function, args...);
398 }
399
400 template<typename...ELMS>
401 EventLog&
402 note (ELMS const& ...initialiser)
403 {
404 log_->emplace_back (collectStr<ArgSeq> (initialiser...));
405 return *this;
406 }
407
408
410 EventLog& warn (string text);
411
413 EventLog& error (string text);
414
416 EventLog& fatal (string text);
417
420 EventLog& create (string text);
421
422
425 EventLog& destroy (string text);
426
427
429 template<typename X, typename...ARGS>
430 EventLog&
431 addAttrib (string const& key, X&& initialiser, ARGS&& ...args)
432 {
433 REQUIRE (not isnil (*log_));
434 mutateInPlace (log_->back())
435 .attrib(key,initialiser, std::forward<ARGS>(args)...);
436 return *this;
437 }
438
439
440
441
442 /* ==== Iteration ==== */
443
444 bool
445 empty() const
446 {
447 return 1 >= log_->size(); // do not count the log header
448 }
449
450
452
454 typedef const Entry value_type;
455
456 const_iterator begin() const { return Iter(log_->begin(), log_->end()); }
457 const_iterator end() const { return Iter(); }
458
459 friend const_iterator begin (EventLog const& log) { return log.begin(); }
460 friend const_iterator end (EventLog const& log) { return log.end(); }
461
462
463
464
465 /* ==== Query/Verification API ==== */
466
475 EventMatch verify (string match) const;
476
483 EventMatch verifyMatch (string regExp) const;
484
492 EventMatch verifyEvent (string match) const;
493
497 EventMatch verifyEvent (string classifier, string match) const;
498
499 template<typename X>
501 verifyEvent (string classifier, X const& something) const
502 {
503 return verifyEvent (classifier, util::toString (something));
504 }
505
509 EventMatch verifyCall (string match) const;
510
513 ensureNot (string match) const;
514
515
516
517
519 friend bool
520 operator== (EventLog const& l1, EventLog const& l2)
521 {
522 return l1.log_ == l2.log_
523 or (l1.log_ and l2.log_
524 and *l1.log_ == *l2.log_);
525 }
526 friend bool
527 operator!= (EventLog const& l1, EventLog const& l2)
528 {
529 return not (l1 == l2);
530 }
531 };
532
533
534
535}} // namespace lib::test
536#endif /*LIB_TEST_EVENT_LOG_H*/
Inline string literal.
Definition symbol.hpp:78
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
Token or Atom with distinct identity.
Definition symbol.hpp:120
object-like record of data.
Definition record.hpp:142
Helper to log and verify the occurrence of events.
EventLog & call(string target, string function, ARGS const &...args)
Log a function call with arbitrary arguments.
EventLog & warn(string text)
Log a warning entry.
EventLog & event(string classifier, ELMS const &...initialiser)
EventLog(CStr logID)
const_iterator begin() const
friend const_iterator end(EventLog const &log)
lib::diff::RecordSetup< string >::Storage ArgSeq
EventLog & addAttrib(string const &key, X &&initialiser, ARGS &&...args)
Qualify the latest entry: set further attribute(s)
string getID() const
EventLog & destroy(string text)
Log the destruction of an object.
EventLog & event(string text)
log some text as event
const Entry value_type
bool empty() const
friend bool operator!=(EventLog const &l1, EventLog const &l2)
EventMatch verify(string match) const
start a query to match for some substring.
EventLog & error(string text)
Log an error note.
void log(Symbol typeID, ATTR &&attribs, ARGS &&args)
friend const_iterator begin(EventLog const &log)
EventLog & clear(const X *const obj)
EventLog & clear()
purge log contents while retaining just the original Header-ID
EventMatch verifyCall(string match) const
start a query to match especially a function call
EventMatch verifyEvent(string match) const
start a query to match for some event.
EventLog & joinInto(EventLog &otherLog)
Merge this log into another log, forming a combined log.
EventMatch verifyMatch(string regExp) const
start a query to match with a regular expression
lib::RangeIter< Log::const_iterator > Iter
EventMatch verifyEvent(string classifier, X const &something) const
std::shared_ptr< Log > log_
const_iterator end() const
EventLog & create(string text)
Log the creation of an object.
EventMatch ensureNot(string match) const
start a query to ensure the given expression does not match.
void log(std::initializer_list< string > const &ili)
friend bool operator==(EventLog const &l1, EventLog const &l2)
equality comparison is based on the actual log contents
EventLog & note(ELMS const &...initialiser)
EventLog & call(CStr target, string function, ARGS const &...args)
EventLog & call(string target, string function)
Log occurrence of a function call with no arguments.
EventLog & fatal(string text)
Log a fatal failure.
EventLog & call(const X *const targetObj, string function, ARGS const &...args)
Log a function call on given object ("`this`")...
EventLog(const X *const obj)
bool foundSolution()
core of the evaluation machinery: apply a filter predicate and then pull through the log to find a ac...
EventMatch & type(string typeID)
refine filter to additionally require a matching log entry type
bool look_for_match_
support for positive and negative queries.
EventMatch & beforeMatch(string regExp)
find a match with the given regular expression
void refineSerach_matchArgument(size_t idx, string match)
std::vector< std::regex > RExSeq
EventMatch & afterCall(string match)
find a function invocation backwards, before the current point of reference
string violation_
record when the underlying query has failed
lib::diff::RecordSetup< string >::Storage ArgSeq
EventMatch & id(string classifier)
refine filter to additionally match on the ID attribute
EventMatch & locateMatch(string regExp)
basic search like locate() but with the given regular expression
EventMatch & arg(ARGS const &...args)
refine filter to additionally require specific arguments
EventMatch & argMatch(ARGS const &...regExps)
refine filter to additionally cover all arguments with a series of regular expressions.
EventMatch & on(const X *const targetObj)
EventMatch & locateEvent(string match)
basic search for a matching "event"
EventMatch & before(string match)
find a match (substring match) of the given text in an EventLog entry after the current position
EventMatch & beforeEvent(string match)
find a match for an "event" after the current point of reference
void refineSerach_matchArgsRegExp(RExSeq &&regExpSeq, string rendered_regExps)
EventMatch & locate(string match)
basic search function: continue linear lookup over the elements of the EventLog to find a match (subs...
void refineSerach_matchArguments(ArgSeq &&argSeq)
Filter solution_
match predicate evaluator
EventMatch & locateCall(string match)
basic search for some specific function invocation
EventMatch & argPos(size_t idx, ARG const &arg)
refine filter to additionally require match on a specific positional argument
EventMatch & afterEvent(string match)
EventMatch & after(string match)
find a match (substring match) of the given text in an EventLog entry before the current position,...
EventMatch & attrib(string key, string valueMatch)
refine filter to additionally match on a specific attribute
EventMatch & on(string targetID)
refine filter to additionally match the ‘'this’` attribute
EventMatch & key(string key)
refine filter to additionally require the presence an attribute
EventMatch & beforeCall(string match)
find a match for some function invocation after the current point of reference
decltype(buildSearchFilter(std::declval< Log const & >())) Filter
EventMatch & afterMatch(string regExp)
void evaluateQuery(string matchSpec, Literal rel="after")
this is actually called after each refinement of the filter and matching conditions.
string lastMatch_
record last match for diagnostics
Lumiera error handling (C++ interface).
const char * CStr
Definition error.hpp:42
Automatically use custom string conversion in C++ stream output.
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
Generic functions to build identification schemes.
Evaluation mechanism to apply a sequence of conditions onto a linear search.
An iterator with the ability to switch direction.
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
Definition genfunc.hpp:116
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
CON collectStr(ELMS const &...elms)
convert a sequence of elements to string
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
string join(COLL &&coll, string const &delim=", ")
enumerate a collection's contents, separated by delimiter.
bool isnil(lib::time::Duration const &dur)
Special collection to represent object-like data.
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...