Utopia  2
Framework for studying models of complex & adaptive systems.
exceptions.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_CORE_TESTTOOLS_EXCEPTIONS_HH
2 #define UTOPIA_CORE_TESTTOOLS_EXCEPTIONS_HH
3 
4 #include <string>
5 #include <functional>
6 #include <string_view>
7 #include <type_traits>
8 
9 #include <boost/test/unit_test.hpp>
10 #include <boost/core/demangle.hpp>
11 
12 #include "../exceptions.hh"
13 #include "utils.hh"
14 
15 
16 namespace Utopia::TestTools {
17 
24 
41 template<typename ExcT, typename Callable=std::function<void()>>
42 void check_exception(Callable&& func,
43  const std::string_view match = "",
44  const LocationInfo loc = {})
45 {
46  // Check if Callable can be invoked
47  static_assert(std::is_invocable_v<Callable>,
48  "Callable needs to be invocable without any arguments!");
49 
50  // We need to handle the case where ExcT is std::exception separately,
51  // because it produces the -Wexceptions compiler warning (which currently
52  // cannot be pragma-ignored for gcc).
53  if constexpr (std::is_same<ExcT, std::exception>()) {
54  try {
55  func();
56  BOOST_ERROR(loc << "Should have thrown but did not!");
57  }
58  catch (ExcT& e) {
59  if (not match.empty() and not contains(e.what(), match)) {
60  BOOST_ERROR(loc << "Did not throw expected error message!\n"
61  " Expected match : " << match << "\n"
62  " But got : " << e.what() << "\n");
63  }
64  // else: everything ok
65  }
66  catch (...) {
67  BOOST_ERROR(loc << "Threw non-std::exception!");
68  }
69  }
70  else {
71  // For ExcT not being std::exception, also catch std::exception and
72  // supply type information, which can be useful if some other than the
73  // expected type was thrown.
74  try {
75  func();
76  BOOST_ERROR(loc << "Should have thrown but did not!");
77  }
78  catch (ExcT& e) {
79  if (not match.empty() and not contains(e.what(), match)) {
80  BOOST_ERROR(loc << "Did not throw expected error message!\n"
81  " Expected match : " << match << "\n"
82  " But got : " << e.what() << "\n");
83  }
84  // else: everything ok
85  }
86  catch (std::exception& e) {
87  BOOST_ERROR(loc << "Threw error of unexpected type ("
88  << boost::core::demangle(typeid(e).name())
89  << ") with message: " << e.what());
90  }
91  catch (...) {
92  BOOST_ERROR(loc << "Threw non-std::exception!");
93  }
94  }
95 }
96 
97 
98 // end group TestTools
103 } // namespace Utopia::TestTools
104 
105 #endif // UTOPIA_CORE_TESTTOOLS_EXCEPTIONS_HH
void check_exception(Callable &&func, const std::string_view match="", const LocationInfo loc={})
Checks if a callable throws with the expected error type and message.
Definition: exceptions.hh:42
Definition: config.hh:19
bool contains(const std::string_view s, const std::string_view match)
Returns true if the match string is contained within the given string.
Definition: utils.hh:19
Bundles and handles file location information: file path and line number.
Definition: utils.hh:25