12#include "gtest/gtest.h"
17#include "libmesh/utility.h"
31template <
class ExceptionType = std::exception,
class Action =
bool>
34 const std::optional<std::string> & contains = {},
35 const bool set_throw_on_error =
false)
37 static_assert(std::is_base_of_v<std::exception, ExceptionType>,
"Not an exception");
39 std::unique_ptr<Moose::ScopedThrowOnError> scoped_throw_on_error;
40 if (set_throw_on_error)
41 scoped_throw_on_error = std::make_unique<Moose::ScopedThrowOnError>();
46 FAIL() <<
"Expected " << MooseUtils::prettyCppType<ExceptionType>() <<
" not thrown";
48 catch (std::exception
const & e)
50 if constexpr (!std::is_same_v<std::exception, ExceptionType>)
51 if (!
dynamic_cast<const ExceptionType *
>(&e))
52 FAIL() <<
"Threw " << demangle(
typeid(e).name()) <<
" instead of "
53 << MooseUtils::prettyCppType<ExceptionType>() <<
" with message '" << e.what()
58 ASSERT_TRUE(std::string(e.what()).find(*contains) != std::string::npos)
59 <<
"Exception \"" << e.what() <<
"\" does not contain \"" << *contains <<
"\"";
67template <
typename ExceptionType,
bool exact,
bool assert,
bool set_throw_on_error,
typename Func>
71 static_assert(std::is_base_of_v<std::exception, ExceptionType>,
"Not an exception");
73 std::ostringstream error;
77 std::unique_ptr<Moose::ScopedThrowOnError> scoped_throw_on_error;
78 if constexpr (set_throw_on_error)
79 scoped_throw_on_error = std::make_unique<Moose::ScopedThrowOnError>();
83 error <<
"Expected exception of type " <<
libMesh::demangle(
typeid(ExceptionType).name())
84 <<
" but no exception was thrown.";
86 catch (
const ExceptionType & ex)
91 if (std::string(ex.what()) == message)
97 if (std::string(ex.what()).find(message) != std::string::npos)
101 error <<
"Expected" << (exact ?
"" :
" partial") <<
" exception message: \"" << message
102 <<
"\"\n Actual exception message: \"" << ex.what() <<
"\"";
104 catch (
const std::exception & ex)
106 error <<
"Expected exception of type " <<
libMesh::demangle(
typeid(ExceptionType).name())
107 <<
" but exception of type " <<
libMesh::demangle(
typeid(ex).name()) <<
" was thrown.";
110 ::testing::internal::AssertHelper(
111 ::testing::TestPartResult::kNonFatalFailure, file, line, error.str().c_str()) =
112 ::testing::Message();
127 const std::filesystem::path &
path()
const {
return _path; }
138#define EXPECT_THROW_MSG(stmt, exc_type, expected_msg) \
139 ::Moose::UnitUtils::throwsWithMessage<exc_type, true, false, false>( \
140 [&]() { stmt; }, expected_msg, __FILE__, __LINE__)
143#define ASSERT_THROW_MSG(stmt, exc_type, expected_msg) \
144 ::Moose::UnitUtils::throwsWithMessage<exc_type, true, true, false>( \
145 [&]() { stmt; }, expected_msg, __FILE__, __LINE__)
148#define EXPECT_THROW_MSG_CONTAINS(stmt, exc_type, expected_substr) \
149 ::Moose::UnitUtils::throwsWithMessage<exc_type, false, false, false>( \
150 [&]() { stmt; }, expected_substr, __FILE__, __LINE__)
153#define ASSERT_THROW_MSG_CONTAINS(stmt, exc_type, expected_substr) \
154 ::Moose::UnitUtils::throwsWithMessage<exc_type, false, true, false>( \
155 [&]() { stmt; }, expected_substr, __FILE__, __LINE__)
158#define EXPECT_MOOSEERROR_MSG(stmt, expected_msg) \
159 ::Moose::UnitUtils::throwsWithMessage<MooseRuntimeError, true, false, true>( \
160 [&]() { stmt; }, expected_msg, __FILE__, __LINE__)
163#define ASSERT_MOOSEERROR_MSG(stmt, expected_msg) \
164 ::Moose::UnitUtils::throwsWithMessage<MooseRuntimeError, true, true, true>( \
165 [&]() { stmt; }, expected_msg, __FILE__, __LINE__)
168#define EXPECT_MOOSEERROR_MSG_CONTAINS(stmt, expected_substr) \
169 ::Moose::UnitUtils::throwsWithMessage<MooseRuntimeError, false, false, true>( \
170 [&]() { stmt; }, expected_substr, __FILE__, __LINE__)
173#define ASSERT_MOOSEERROR_MSG_CONTAINS(stmt, expected_substr) \
174 ::Moose::UnitUtils::throwsWithMessage<MooseRuntimeError, false, true, true>( \
175 [&]() { stmt; }, expected_substr, __FILE__, __LINE__)
Create a temporary file and delete it upon destruction.
const std::filesystem::path _path
const std::filesystem::path & path() const
static std::filesystem::path generatePath()
void assertThrows(const Action &action, const std::optional< std::string > &contains={}, const bool set_throw_on_error=false)
A helper for asserting that calling something throws an exception.
void throwsWithMessage(Func &&fn, const std::string_view message, const char *file, int line)
Helper for the [EXPECT,ASSERT]_[MOOSEERROR,THROW]_[MSG,MSG_CONTAINS] macros.
std::string demangle(const char *name)