From c76ef3e52f3e4fb387592f5a80706039b9656712 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 7 Jan 2021 09:36:44 -0800 Subject: [PATCH] unittest: add testThrowsMatch() and testStrMatch() --- documentation/util.rst | 8 ++++++++ src/pvxs/unittest.h | 46 ++++++++++++++++++++++++++++++++++++++++++ src/unittest.cpp | 25 +++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/documentation/util.rst b/documentation/util.rst index 88b1867..53a4bc7 100644 --- a/documentation/util.rst +++ b/documentation/util.rst @@ -110,6 +110,12 @@ Extensions to epicsUnitTest.h :: .. doxygendefine:: testNotEq +.. doxygendefine:: testStrEq + +.. doxygendefine:: testStrMatch + +.. doxygendefine:: testArrEq + .. doxygendefine:: testShow The testEq() macro and friends expand to a function which returns a `pvxs::testCase` instance @@ -122,6 +128,8 @@ which may be used as a `std::ostream` to append text describing a test. eg. :: .. doxygenfunction:: pvxs::testThrows +.. doxygenfunction:: pvxs::testThrowsMatch + .. doxygenclass:: pvxs::testCase :members: diff --git a/src/pvxs/unittest.h b/src/pvxs/unittest.h index 265cf01..b4548ce 100644 --- a/src/pvxs/unittest.h +++ b/src/pvxs/unittest.h @@ -78,6 +78,10 @@ public: return *this; } + //! Override current pass/fail result if input matches a regular expression + //! @since UNRELEASED + testCase& setPassMatch(const std::string& expr, const std::string& inp); + //! Append to message template inline testCase& operator<<(const T& v) { @@ -145,6 +149,9 @@ testCase testNotEq(const char *sLHS, const LHS& lhs, const char *sRHS, const RHS PVXS_API testCase _testStrEq(const char *sLHS, const std::string& lhs, const char *sRHS, const std::string& rhs); +PVXS_API +testCase _testStrMatch(const char *spat, const std::string& pat, const char *sstr, const std::string& str); + template testCase testArrEq(const char *sLHS, const LHS& lhs, const char *sRHS, const RHS& rhs) { @@ -198,6 +205,40 @@ testCase testThrows(FN fn) return ret; } +/** Assert that an exception is throw with a certain message. + * + * @tparam Exception The exception type which should be thrown + * @param expr A regular expression + * @param fn A callable + * + * @returns A testCase which passes if an Exception instance was caught + * and std::exception::what() matched the provided regular expression. + * + * @code + * testThrowsMatch("happened", []() { + * testShow()<<"Now you see me"; + * throw std::runtime_error("I happened"); + * testShow()<<"Now you don't"; + * })<<"some message"; + * @endcode + * + * @since UNRELEASED + */ +template +testCase testThrowsMatch(const std::string& expr, FN fn) +{ + testCase ret(false); + try { + fn(); + ret<<"Unexpected success - "; + }catch(Exception& e){ + ret.setPassMatch(expr, e.what())<<"Expected matching (\""< + #include #include "pvxs/unittest.h" @@ -92,6 +94,20 @@ testCase::~testCase() } } +testCase& testCase::setPassMatch(const std::string& expr, const std::string& inp) +{ + std::regex ex; + try { + ex.assign(expr); + setPass(std::regex_match(inp, ex)); + + }catch(std::regex_error& e) { + setPass(false); + (*this)<<" expression error: "<