summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/exception.h28
-rw-r--r--libadhocutil/unittests/Jamfile.jam10
-rw-r--r--libadhocutil/unittests/testException.cpp97
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());
+ }
+}
+