diff --git a/src/lib/test/event-log.hpp b/src/lib/test/event-log.hpp index c734df09f..16c7536c1 100644 --- a/src/lib/test/event-log.hpp +++ b/src/lib/test/event-log.hpp @@ -59,6 +59,7 @@ #include #include #include +#include @@ -170,6 +171,16 @@ namespace test{ }; } + auto + findRegExp (string regExpDef) + { + std::regex regExp(regExpDef); + return [=](Entry const& entry) + { + return std::regex_search(string(entry), regExp); + }; + } + auto findEvent (string match) { @@ -304,10 +315,14 @@ namespace test{ return *this; } + /** find a match with the given regular expression */ EventMatch& beforeMatch (string regExp) { - UNIMPLEMENTED("process combined relational regular expression match"); + solution_.underlying().switchForwards(); + solution_.setNewFilter(findRegExp(regExp)); + evaluateQuery ("find-RegExp(\""+regExp+"\")"); + return *this; } /** find a match for an "event" _after_ the current point of reference @@ -366,7 +381,10 @@ namespace test{ EventMatch& afterMatch (string regExp) { - UNIMPLEMENTED("process combined relational regular expression match backwards"); + solution_.underlying().switchBackwards(); + solution_.setNewFilter(findRegExp(regExp)); + evaluateQuery ("find-RegExp(\""+regExp+"\")", "before"); + return *this; } EventMatch& @@ -741,10 +759,18 @@ namespace test{ return matcher; } + /** start a query to match with a regular expression + * @param regExp definition + * @remarks the expression will work against the full + * `string` representation of the log entries. + * Meaning, it can also match type and attributes + */ EventMatch verifyMatch (string regExp) const { - UNIMPLEMENTED("start matching sequence for regular expression match"); + EventMatch matcher(*log_); + matcher.beforeMatch (regExp); + return matcher; } /** start a query to match for some event. diff --git a/tests/library/test/test-event-log-test.cpp b/tests/library/test/test-event-log-test.cpp index c25814fac..a6c7e8330 100644 --- a/tests/library/test/test-event-log-test.cpp +++ b/tests/library/test/test-event-log-test.cpp @@ -73,6 +73,7 @@ namespace test{ verify_callLogging(); verify_eventLogging(); verify_genericLogging(); + verify_regExpMatch(); } @@ -313,79 +314,38 @@ namespace test{ } - /** @test prints TODO */ void - checkTODO () + verify_regExpMatch () { -#if false ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #975 - log.verifyEvent("ctor"); - log.verify("ctor").arg("dummy"); + EventLog log("Lovely spam!"); + log.note ("type=spam", "egg and bacon" + , "egg sausage and bacon" + , "egg and spam" + , "egg bacon and spam" + , "egg bacon sausage and spam" + , "spam bacon sausage and spam" + , "spam egg spam spam bacon and spam" + , "spam sausage spam spam bacon spam tomato and spam"); + log.fatal("Lobster Thermidor a Crevette with a mornay sauce served in a Provencale manner " + "with shallots and aubergines garnished with truffle pate, brandy and with a fried egg on top and spam"); - CHECK ("dummy" == log.getID().getSym()); - CHECK ("ID-dummy" = string(log.getID())); + CHECK (log.verify("spam").before("(spam|").before("egg on top and spam")); + CHECK (log.ensureNot("and spam").after("(spam|").after("spam!").after("bacon")); - VERIFY_ERROR (ASSERTION, log.verifyCall("reset")); + // note: each consecutive match starts with the same element, on which the previous one succeeded + CHECK (log.verify("spam").before("spam").before("spam").before("spam").before("spam").before("bacon")); - log.reset(); - log.verify("reset"); - log.verifyCall("reset"); - log.verifyEvent("reset"); - log.verify("reset").after("ctor"); - log.verify("ctor").before("reset"); - VERIFY_ERROR (ASSERTION, log.verify("reset").before("ctor")); - VERIFY_ERROR (ASSERTION, log.verify("ctor").after("reset")); + // RegExp on full String representation + CHECK (log.verifyMatch("spam.+spam")); + CHECK (log.verifyMatch("spam.+spam").beforeMatch("spam(?!spam)")); + CHECK (log.verifyEvent("fatal","spam").afterMatch("(spam.*){15}")); - log.verify("reset").before("reset"); - log.verify("reset").beforeEvent("reset"); - log.verifyCall("reset").before("reset"); - log.verifyCall("reset").beforeEvent("reset"); - VERIFY_ERROR (ASSERTION, log.verifyCall("reset").afterCall("reset")); - VERIFY_ERROR (ASSERTION, log.verifyCall("reset").afterEvent("reset")); - VERIFY_ERROR (ASSERTION, log.verifyEvent("reset").afterEvent("reset")); + // Cover all arguments with sequence of regular expressions + CHECK (log.verify("spam").argMatch("^egg ", "^spam .+spam$")); + CHECK (log.verifyMatch("Rec.+fatal").afterMatch("{.+}").argMatch("bacon$","and spam$")); - CHECK (!log.isTouched()); - CHECK (!log.isExpanded()); - - log.noteMsg("dolorem ipsum quia dolor sit amet consectetur adipisci velit."); - log.verifyNote("Msg"); - log.verifyCall("noteMsg"); - log.verifyCall("noteMsg").arg("lorem ipsum"); - log.verifyCall("noteMsg").argMatch("dolor.+dolor\\s+"); - log.verifyMatch("Rec\\(note.+kind = Msg.+msg = dolorem ipsum"); - - EventLog log = log.getLog(); - log.verify("ctor") - .before("reset") - .before("lorem ipsum"); - - MockElm foo("foo"), bar; - foo.verify("ctor").arg("foo"); - bar.verify("ctor").arg(); - - bar.ensureNot("foo"); - log.ensureNot("foo"); - log.ensureNot("foo"); - VERIFY_ERROR (ASSERTION, foo.ensureNot("foo")); - - log.joinInto(bar).joinInto(foo); - log.verifyEvent("logJoin").arg(bar.getID()) - .beforeEvent("logJoin").arg("foo"); - - log.verifyEvent("logJoin").arg(bar.getID()) - .beforeEvent("logJoin").arg("foo"); - log.verify("ctor").arg("foo"); - log.verify("ctor").arg("foo"); - log.verify("ctor").arg("dummy") - .before("ctor").arg(bar.getID()) - .before("ctor").arg("foo"); - - log.kill(); - foo.noteMsg("dummy killed"); - log.verifyEvent("dtor").on("dummy") - .beforeCall("noteMsg").on("foo"); - // and when actually no exception is raised, this is an ASSERTION failure - VERIFY_ERROR (ASSERTION, VERIFY_ERROR (EXCEPTION, dontThrow() )); -#endif ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #975 + // argument match must cover all arguments... + CHECK (log.ensureNot("spam").arg("sausage|egg")); } };