diff options
-rw-r--r-- | libadhocutil/exception.h | 28 | ||||
-rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 10 | ||||
-rw-r--r-- | libadhocutil/unittests/testException.cpp | 97 |
3 files changed, 135 insertions, 0 deletions
diff --git a/libadhocutil/exception.h b/libadhocutil/exception.h new file mode 100644 index 0000000..a63439b --- /dev/null +++ b/libadhocutil/exception.h @@ -0,0 +1,28 @@ +#ifndef ADHOCUTIL_EXCEPTION_H +#define ADHOCUTIL_EXCEPTION_H + +#include <exception> +#include <string> +#include <boost/optional.hpp> + +namespace AdHoc { + template <typename BaseException> + class Exception : public BaseException { + public: + inline const char * what() const throw() override + { + if (!msg) { + msg = message(); + } + return msg->c_str(); + } + + private: + virtual std::string message() const throw() = 0; + mutable boost::optional<std::string> msg; + }; + typedef Exception<std::exception> StdException; +} + +#endif + diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam index b4ec60a..0961f31 100644 --- a/libadhocutil/unittests/Jamfile.jam +++ b/libadhocutil/unittests/Jamfile.jam @@ -164,3 +164,13 @@ run testFactory ; +run + testException.cpp + : : : + <define>BOOST_TEST_DYN_LINK + <library>..//adhocutil + <library>boost_utf + : + testException + ; + diff --git a/libadhocutil/unittests/testException.cpp b/libadhocutil/unittests/testException.cpp new file mode 100644 index 0000000..5794468 --- /dev/null +++ b/libadhocutil/unittests/testException.cpp @@ -0,0 +1,97 @@ +#define BOOST_TEST_MODULE Excetion +#include <boost/test/unit_test.hpp> + +#include <exception.h> +#include <buffer.h> + +using namespace AdHoc; + +class Ex1 : public AdHoc::StdException { + public: + Ex1(const char * f, int l) : file(f), line(l) { } + + private: + std::string message() const throw() override + { + return stringf("Something something at %s:%d", file, line); + } + + const char * file; + const int line; +}; + +class OtherBaseException : public std::exception { }; + +class Ex2 : public AdHoc::Exception<OtherBaseException> { + public: + Ex2(const char * f, int l) : file(f), line(l) { } + + private: + std::string message() const throw() override + { + return stringf("Something other something at %s:%d", file, line); + } + + const char * file; + const int line; +}; + +class Ex3 : public AdHoc::StdException { + private: + // LCOV_EXCL_START + std::string message() const throw() override + { + // Never called + std::abort(); + } + // LCOV_EXCL_STOP +}; + +void failing1() +{ + throw Ex1(__PRETTY_FUNCTION__, 1); +} + +void failing2() +{ + throw Ex2(__PRETTY_FUNCTION__, 2); +} + +void failing3() +{ + throw Ex3(); +} + +BOOST_AUTO_TEST_CASE( throwCatch ) +{ + BOOST_REQUIRE_THROW(failing1(), Ex1); + BOOST_REQUIRE_THROW(failing1(), std::exception); + + BOOST_REQUIRE_THROW(failing2(), Ex2); + BOOST_REQUIRE_THROW(failing2(), OtherBaseException); + BOOST_REQUIRE_THROW(failing2(), std::exception); + + BOOST_REQUIRE_THROW(failing3(), Ex3); + BOOST_REQUIRE_THROW(failing3(), std::exception); +} + +BOOST_AUTO_TEST_CASE( message1 ) +{ + try { + failing1(); + } + catch (const std::exception & ex) { + BOOST_REQUIRE_EQUAL("Something something at void failing1():1", ex.what()); + } +} + +BOOST_AUTO_TEST_CASE( message2 ) +{ + try { + failing2(); + } + catch (const std::exception & ex) { + BOOST_REQUIRE_EQUAL("Something other something at void failing2():2", ex.what()); + } +} + |