Unverified Commit 97fe455a authored by Niels Lohmann's avatar Niels Lohmann

Merge branch 'develop' of https://github.com/nlohmann/json into develop

parents d028eff9 be32cc4f
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Viktor Kirilov Copyright (c) 2016-2020 Viktor Kirilov
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
// //
// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
// //
// Copyright (c) 2016-2019 Viktor Kirilov // Copyright (c) 2016-2020 Viktor Kirilov
// //
// Distributed under the MIT Software License // Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at // See accompanying file LICENSE.txt or copy at
...@@ -47,9 +47,9 @@ ...@@ -47,9 +47,9 @@
// ================================================================================================= // =================================================================================================
#define DOCTEST_VERSION_MAJOR 2 #define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 3 #define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH 7 #define DOCTEST_VERSION_PATCH 1
#define DOCTEST_VERSION_STR "2.3.7" #define DOCTEST_VERSION_STR "2.4.1"
#define DOCTEST_VERSION \ #define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
...@@ -301,11 +301,23 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' ...@@ -301,11 +301,23 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_NOINLINE __declspec(noinline) #define DOCTEST_NOINLINE __declspec(noinline)
#define DOCTEST_UNUSED #define DOCTEST_UNUSED
#define DOCTEST_ALIGNMENT(x) #define DOCTEST_ALIGNMENT(x)
#else // MSVC #elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
#define DOCTEST_NOINLINE
#define DOCTEST_UNUSED
#define DOCTEST_ALIGNMENT(x)
#else
#define DOCTEST_NOINLINE __attribute__((noinline)) #define DOCTEST_NOINLINE __attribute__((noinline))
#define DOCTEST_UNUSED __attribute__((unused)) #define DOCTEST_UNUSED __attribute__((unused))
#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x))) #define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
#endif // MSVC #endif
#ifndef DOCTEST_NORETURN
#define DOCTEST_NORETURN [[noreturn]]
#endif // DOCTEST_NORETURN
#ifndef DOCTEST_NOEXCEPT
#define DOCTEST_NOEXCEPT noexcept
#endif // DOCTEST_NOEXCEPT
// ================================================================================================= // =================================================================================================
// == FEATURE DETECTION END ======================================================================== // == FEATURE DETECTION END ========================================================================
...@@ -347,8 +359,20 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' ...@@ -347,8 +359,20 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#ifndef DOCTEST_BREAK_INTO_DEBUGGER #ifndef DOCTEST_BREAK_INTO_DEBUGGER
// should probably take a look at https://github.com/scottt/debugbreak // should probably take a look at https://github.com/scottt/debugbreak
#ifdef DOCTEST_PLATFORM_MAC #ifdef DOCTEST_PLATFORM_LINUX
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
// Break at the location of the failing check if possible
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#else
#include <signal.h>
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
#endif
#elif DOCTEST_MSVC #elif DOCTEST_MSVC
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
#elif defined(__MINGW32__) #elif defined(__MINGW32__)
...@@ -357,7 +381,7 @@ extern "C" __declspec(dllimport) void __stdcall DebugBreak(); ...@@ -357,7 +381,7 @@ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
DOCTEST_GCC_SUPPRESS_WARNING_POP DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() #define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
#else // linux #else // linux
#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0) #define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
#endif // linux #endif // linux
#endif // DOCTEST_BREAK_INTO_DEBUGGER #endif // DOCTEST_BREAK_INTO_DEBUGGER
...@@ -367,6 +391,9 @@ DOCTEST_GCC_SUPPRESS_WARNING_POP ...@@ -367,6 +391,9 @@ DOCTEST_GCC_SUPPRESS_WARNING_POP
#endif // DOCTEST_CONFIG_USE_IOSFWD #endif // DOCTEST_CONFIG_USE_IOSFWD
#ifdef DOCTEST_CONFIG_USE_STD_HEADERS #ifdef DOCTEST_CONFIG_USE_STD_HEADERS
#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#include <iosfwd> #include <iosfwd>
#include <cstddef> #include <cstddef>
#include <ostream> #include <ostream>
...@@ -629,7 +656,7 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file); ...@@ -629,7 +656,7 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
struct DOCTEST_INTERFACE TestCaseData struct DOCTEST_INTERFACE TestCaseData
{ {
const char* m_file; // the file in which the test was registered String m_file; // the file in which the test was registered
unsigned m_line; // the line where the test was registered unsigned m_line; // the line where the test was registered
const char* m_name; // name of the test case const char* m_name; // name of the test case
const char* m_test_suite; // the test suite in which the test was added const char* m_test_suite; // the test suite in which the test was added
...@@ -721,6 +748,7 @@ struct ContextOptions //!OCLINT too many fields ...@@ -721,6 +748,7 @@ struct ContextOptions //!OCLINT too many fields
bool no_path_in_filenames; // if the path to files should be removed from the output bool no_path_in_filenames; // if the path to files should be removed from the output
bool no_line_numbers; // if source code line numbers should be omitted from the output bool no_line_numbers; // if source code line numbers should be omitted from the output
bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
bool help; // to print the help bool help; // to print the help
bool version; // to print the version bool version; // to print the version
...@@ -731,7 +759,6 @@ struct ContextOptions //!OCLINT too many fields ...@@ -731,7 +759,6 @@ struct ContextOptions //!OCLINT too many fields
}; };
namespace detail { namespace detail {
#if defined(DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || defined(DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS)
template <bool CONDITION, typename TYPE = void> template <bool CONDITION, typename TYPE = void>
struct enable_if struct enable_if
{}; {};
...@@ -739,7 +766,6 @@ namespace detail { ...@@ -739,7 +766,6 @@ namespace detail {
template <typename TYPE> template <typename TYPE>
struct enable_if<true, TYPE> struct enable_if<true, TYPE>
{ typedef TYPE type; }; { typedef TYPE type; };
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
// clang-format off // clang-format off
template<class T> struct remove_reference { typedef T type; }; template<class T> struct remove_reference { typedef T type; };
...@@ -748,6 +774,14 @@ namespace detail { ...@@ -748,6 +774,14 @@ namespace detail {
template<class T> struct remove_const { typedef T type; }; template<class T> struct remove_const { typedef T type; };
template<class T> struct remove_const<const T> { typedef T type; }; template<class T> struct remove_const<const T> { typedef T type; };
#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
template<class T> struct is_enum : public std::is_enum<T> {};
template<class T> struct underlying_type : public std::underlying_type<T> {};
#else
// Use compiler intrinsics
template<class T> struct is_enum { constexpr static bool value = __is_enum(T); };
template<class T> struct underlying_type { typedef __underlying_type(T) type; };
#endif
// clang-format on // clang-format on
template <typename T> template <typename T>
...@@ -756,33 +790,23 @@ namespace detail { ...@@ -756,33 +790,23 @@ namespace detail {
{ static const bool value = false; }; { static const bool value = false; };
namespace has_insertion_operator_impl { namespace has_insertion_operator_impl {
typedef char no; std::ostream &os();
typedef char yes[2]; template<class T>
DOCTEST_REF_WRAP(T) val();
struct any_t template<class, class = void>
{ struct check {
template <typename T> static constexpr bool value = false;
// cppcheck-suppress noExplicitConstructor
any_t(const DOCTEST_REF_WRAP(T));
}; };
yes& testStreamable(std::ostream&); template<class T>
no testStreamable(no); struct check<T, decltype(os() << val<T>(), void())> {
static constexpr bool value = true;
no operator<<(const std::ostream&, const any_t&);
template <typename T>
struct has_insertion_operator
{
static std::ostream& s;
static const DOCTEST_REF_WRAP(T) t;
static const bool value = sizeof(decltype(testStreamable(s << t))) == sizeof(yes);
}; };
} // namespace has_insertion_operator_impl } // namespace has_insertion_operator_impl
template <typename T> template<class T>
struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T> using has_insertion_operator = has_insertion_operator_impl::check<T>;
{};
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);
...@@ -846,7 +870,7 @@ struct StringMaker<R C::*> ...@@ -846,7 +870,7 @@ struct StringMaker<R C::*>
} }
}; };
template <typename T> template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
String toString(const DOCTEST_REF_WRAP(T) value) { String toString(const DOCTEST_REF_WRAP(T) value) {
return StringMaker<T>::convert(value); return StringMaker<T>::convert(value);
} }
...@@ -873,6 +897,12 @@ DOCTEST_INTERFACE String toString(int long long in); ...@@ -873,6 +897,12 @@ DOCTEST_INTERFACE String toString(int long long in);
DOCTEST_INTERFACE String toString(int long long unsigned in); DOCTEST_INTERFACE String toString(int long long unsigned in);
DOCTEST_INTERFACE String toString(std::nullptr_t in); DOCTEST_INTERFACE String toString(std::nullptr_t in);
template <typename T, typename detail::enable_if<detail::is_enum<T>::value, bool>::type = true>
String toString(const DOCTEST_REF_WRAP(T) value) {
typedef typename detail::underlying_type<T>::type UT;
return toString(static_cast<UT>(value));
}
#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183 // see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183
DOCTEST_INTERFACE String toString(const std::string& in); DOCTEST_INTERFACE String toString(const std::string& in);
...@@ -987,7 +1017,7 @@ namespace detail { ...@@ -987,7 +1017,7 @@ namespace detail {
DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at); DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
[[noreturn]] DOCTEST_NORETURN
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
DOCTEST_INTERFACE void throwException(); DOCTEST_INTERFACE void throwException();
...@@ -1284,12 +1314,12 @@ namespace detail { ...@@ -1284,12 +1314,12 @@ namespace detail {
template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } }; template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
// clang-format on // clang-format on
DOCTEST_BINARY_RELATIONAL_OP(0, eq) DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
DOCTEST_BINARY_RELATIONAL_OP(1, ne) DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
DOCTEST_BINARY_RELATIONAL_OP(2, gt) DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
DOCTEST_BINARY_RELATIONAL_OP(3, lt) DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
DOCTEST_BINARY_RELATIONAL_OP(4, ge) DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
DOCTEST_BINARY_RELATIONAL_OP(5, le) DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)
struct DOCTEST_INTERFACE ResultBuilder : public AssertData struct DOCTEST_INTERFACE ResultBuilder : public AssertData
{ {
...@@ -1418,7 +1448,7 @@ namespace detail { ...@@ -1418,7 +1448,7 @@ namespace detail {
return true; return true;
} catch(...) {} //!OCLINT - empty catch statement } catch(...) {} //!OCLINT - empty catch statement
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
((void)res); // to silence -Wunused-parameter static_cast<void>(res); // to silence -Wunused-parameter
return false; return false;
} }
...@@ -1737,12 +1767,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -1737,12 +1767,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS #endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS #ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
#define DOCTEST_CAST_TO_VOID(x) \ #define DOCTEST_CAST_TO_VOID(...) \
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \ DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \
static_cast<void>(x); \ static_cast<void>(__VA_ARGS__); \
DOCTEST_GCC_SUPPRESS_WARNING_POP DOCTEST_GCC_SUPPRESS_WARNING_POP
#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS #else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
#define DOCTEST_CAST_TO_VOID(x) x; #define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS #endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
// registers the test by initializing a dummy var with a function // registers the test by initializing a dummy var with a function
...@@ -1953,7 +1983,7 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -1953,7 +1983,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
mb << x; \ mb << x; \
DOCTEST_ASSERT_LOG_AND_REACT(mb); \ DOCTEST_ASSERT_LOG_AND_REACT(mb); \
} while((void)0, 0) } while(false)
// clang-format off // clang-format off
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) #define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
...@@ -1982,7 +2012,7 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -1982,7 +2012,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
do { \ do { \
DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \ DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
} while((void)0, 0) } while(false)
#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
...@@ -2006,12 +2036,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2006,12 +2036,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
// clang-format off // clang-format off
#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while((void)0, 0) #define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while((void)0, 0) #define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while((void)0, 0) #define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while((void)0, 0) #define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while((void)0, 0) #define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while((void)0, 0) #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
// clang-format on // clang-format on
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
...@@ -2028,66 +2058,66 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2028,66 +2058,66 @@ int registerReporter(const char* name, int priority, bool isReporter) {
} catch(...) { _DOCTEST_RB.translateException(); } \ } catch(...) { _DOCTEST_RB.translateException(); } \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} \ } \
} while((void)0, 0) } while(false)
#define DOCTEST_ASSERT_THROWS_WITH(expr, assert_type, ...) \ #define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \
do { \ do { \
if(!doctest::getContextOptions()->no_throw) { \ if(!doctest::getContextOptions()->no_throw) { \
doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #expr, "", __VA_ARGS__); \ __LINE__, expr_str, "", __VA_ARGS__); \
try { \ try { \
DOCTEST_CAST_TO_VOID(expr) \ DOCTEST_CAST_TO_VOID(expr) \
} catch(...) { _DOCTEST_RB.translateException(); } \ } catch(...) { _DOCTEST_RB.translateException(); } \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} \ } \
} while((void)0, 0) } while(false)
#define DOCTEST_ASSERT_NOTHROW(expr, assert_type) \ #define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \
do { \ do { \
doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #expr); \ __LINE__, #__VA_ARGS__); \
try { \ try { \
DOCTEST_CAST_TO_VOID(expr) \ DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
} catch(...) { _DOCTEST_RB.translateException(); } \ } catch(...) { _DOCTEST_RB.translateException(); } \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0) } while(false)
// clang-format off // clang-format off
#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_WARN_THROWS, "") #define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_CHECK_THROWS, "") #define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_REQUIRE_THROWS, "") #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")
#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__) #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__) #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__) #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)
#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_WARN_THROWS_WITH, __VA_ARGS__) #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_CHECK_THROWS_WITH, __VA_ARGS__) #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__) #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)
#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__) #define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__) #define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__) #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)
#define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_WARN_NOTHROW) #define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_CHECK_NOTHROW) #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_REQUIRE_NOTHROW) #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while((void)0, 0) #define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while(false)
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while((void)0, 0) #define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while(false)
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while((void)0, 0) #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while(false)
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while((void)0, 0) #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while((void)0, 0) #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while((void)0, 0) #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while((void)0, 0) #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while((void)0, 0) #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while((void)0, 0) #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while((void)0, 0) #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while((void)0, 0) #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while((void)0, 0) #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while((void)0, 0) #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while(false)
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while((void)0, 0) #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while(false)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while((void)0, 0) #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
// clang-format on // clang-format on
#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
...@@ -2100,7 +2130,7 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2100,7 +2130,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
_DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \ _DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
__VA_ARGS__)) \ __VA_ARGS__)) \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0) } while(false)
#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
do { \ do { \
...@@ -2108,7 +2138,7 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2108,7 +2138,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
__LINE__, #__VA_ARGS__); \ __LINE__, #__VA_ARGS__); \
DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__)) \ DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__)) \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0) } while(false)
#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
...@@ -2184,37 +2214,37 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2184,37 +2214,37 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
#define DOCTEST_WARN_THROWS(expr) ((void)0) #define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(expr) ((void)0) #define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) #define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW(expr) ((void)0) #define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) #define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
...@@ -2305,86 +2335,86 @@ int registerReporter(const char* name, int priority, bool isReporter) { ...@@ -2305,86 +2335,86 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) #define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) #define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
#define DOCTEST_INFO(x) ((void)0) #define DOCTEST_INFO(x) (static_cast<void>(0))
#define DOCTEST_CAPTURE(x) ((void)0) #define DOCTEST_CAPTURE(x) (static_cast<void>(0))
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) ((void)0) #define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) ((void)0) #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_AT(file, line, x) ((void)0) #define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_MESSAGE(x) ((void)0) #define DOCTEST_MESSAGE(x) (static_cast<void>(0))
#define DOCTEST_FAIL_CHECK(x) ((void)0) #define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0))
#define DOCTEST_FAIL(x) ((void)0) #define DOCTEST_FAIL(x) (static_cast<void>(0))
#define DOCTEST_WARN(...) ((void)0) #define DOCTEST_WARN(...) (static_cast<void>(0))
#define DOCTEST_CHECK(...) ((void)0) #define DOCTEST_CHECK(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE(...) ((void)0) #define DOCTEST_REQUIRE(...) (static_cast<void>(0))
#define DOCTEST_WARN_FALSE(...) ((void)0) #define DOCTEST_WARN_FALSE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_FALSE(...) ((void)0) #define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE(...) ((void)0) #define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))
#define DOCTEST_WARN_MESSAGE(cond, msg) ((void)0) #define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_MESSAGE(cond, msg) ((void)0) #define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) ((void)0) #define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) ((void)0) #define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) ((void)0) #define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) ((void)0) #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS(expr) ((void)0) #define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(expr) ((void)0) #define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) #define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW(expr) ((void)0) #define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) #define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0) #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_EQ(...) ((void)0) #define DOCTEST_WARN_EQ(...) (static_cast<void>(0))
#define DOCTEST_CHECK_EQ(...) ((void)0) #define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_EQ(...) ((void)0) #define DOCTEST_REQUIRE_EQ(...) (static_cast<void>(0))
#define DOCTEST_WARN_NE(...) ((void)0) #define DOCTEST_WARN_NE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_NE(...) ((void)0) #define DOCTEST_CHECK_NE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NE(...) ((void)0) #define DOCTEST_REQUIRE_NE(...) (static_cast<void>(0))
#define DOCTEST_WARN_GT(...) ((void)0) #define DOCTEST_WARN_GT(...) (static_cast<void>(0))
#define DOCTEST_CHECK_GT(...) ((void)0) #define DOCTEST_CHECK_GT(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_GT(...) ((void)0) #define DOCTEST_REQUIRE_GT(...) (static_cast<void>(0))
#define DOCTEST_WARN_LT(...) ((void)0) #define DOCTEST_WARN_LT(...) (static_cast<void>(0))
#define DOCTEST_CHECK_LT(...) ((void)0) #define DOCTEST_CHECK_LT(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_LT(...) ((void)0) #define DOCTEST_REQUIRE_LT(...) (static_cast<void>(0))
#define DOCTEST_WARN_GE(...) ((void)0) #define DOCTEST_WARN_GE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_GE(...) ((void)0) #define DOCTEST_CHECK_GE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_GE(...) ((void)0) #define DOCTEST_REQUIRE_GE(...) (static_cast<void>(0))
#define DOCTEST_WARN_LE(...) ((void)0) #define DOCTEST_WARN_LE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_LE(...) ((void)0) #define DOCTEST_CHECK_LE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_LE(...) ((void)0) #define DOCTEST_REQUIRE_LE(...) (static_cast<void>(0))
#define DOCTEST_WARN_UNARY(...) ((void)0) #define DOCTEST_WARN_UNARY(...) (static_cast<void>(0))
#define DOCTEST_CHECK_UNARY(...) ((void)0) #define DOCTEST_CHECK_UNARY(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_UNARY(...) ((void)0) #define DOCTEST_REQUIRE_UNARY(...) (static_cast<void>(0))
#define DOCTEST_WARN_UNARY_FALSE(...) ((void)0) #define DOCTEST_WARN_UNARY_FALSE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_UNARY_FALSE(...) ((void)0) #define DOCTEST_CHECK_UNARY_FALSE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_UNARY_FALSE(...) ((void)0) #define DOCTEST_REQUIRE_UNARY_FALSE(...) (static_cast<void>(0))
#endif // DOCTEST_CONFIG_DISABLE #endif // DOCTEST_CONFIG_DISABLE
...@@ -2751,7 +2781,11 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN ...@@ -2751,7 +2781,11 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#ifdef __AFXDLL #ifdef __AFXDLL
#include <AfxWin.h> #include <AfxWin.h>
#else #else
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <windows.h>
#else // MINGW
#include <Windows.h> #include <Windows.h>
#endif // MINGW
#endif #endif
#include <io.h> #include <io.h>
...@@ -2762,6 +2796,12 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN ...@@ -2762,6 +2796,12 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#endif // DOCTEST_PLATFORM_WINDOWS #endif // DOCTEST_PLATFORM_WINDOWS
// this is a fix for https://github.com/onqtam/doctest/issues/348
// https://mail.gnome.org/archives/xml/2012-January/msg00000.html
#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
#define STDOUT_FILENO fileno(stdout)
#endif // HAVE_UNISTD_H
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
// counts the number of elements in a C array // counts the number of elements in a C array
...@@ -2913,7 +2953,7 @@ typedef timer_large_integer::type ticks_t; ...@@ -2913,7 +2953,7 @@ typedef timer_large_integer::type ticks_t;
//unsigned int getElapsedMilliseconds() const { //unsigned int getElapsedMilliseconds() const {
// return static_cast<unsigned int>(getElapsedMicroseconds() / 1000); // return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
//} //}
double getElapsedSeconds() const { return static_cast<double>((getCurrentTicks() - m_ticks)) / 1000000.0; } double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }
private: private:
ticks_t m_ticks = 0; ticks_t m_ticks = 0;
...@@ -3450,7 +3490,7 @@ namespace detail { ...@@ -3450,7 +3490,7 @@ namespace detail {
} }
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
[[noreturn]] void throwException() { DOCTEST_NORETURN void throwException() {
g_cs->shouldLogCurrentException = false; g_cs->shouldLogCurrentException = false;
throw TestFailureException(); throw TestFailureException();
} // NOLINT(cert-err60-cpp) } // NOLINT(cert-err60-cpp)
...@@ -3464,8 +3504,8 @@ namespace { ...@@ -3464,8 +3504,8 @@ namespace {
// matching of a string against a wildcard mask (case sensitivity configurable) taken from // matching of a string against a wildcard mask (case sensitivity configurable) taken from
// https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
int wildcmp(const char* str, const char* wild, bool caseSensitive) { int wildcmp(const char* str, const char* wild, bool caseSensitive) {
const char* cp = nullptr; const char* cp = str;
const char* mp = nullptr; const char* mp = wild;
while((*str) && (*wild != '*')) { while((*str) && (*wild != '*')) {
if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
...@@ -3554,6 +3594,10 @@ namespace detail { ...@@ -3554,6 +3594,10 @@ namespace detail {
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
} }
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
Subcase::~Subcase() { Subcase::~Subcase() {
if(m_entered) { if(m_entered) {
// only mark the subcase stack as passed if no subcases have been skipped // only mark the subcase stack as passed if no subcases have been skipped
...@@ -3561,7 +3605,7 @@ namespace detail { ...@@ -3561,7 +3605,7 @@ namespace detail {
g_cs->subcasesPassed.insert(g_cs->subcasesStack); g_cs->subcasesPassed.insert(g_cs->subcasesStack);
g_cs->subcasesStack.pop_back(); g_cs->subcasesStack.pop_back();
#if __cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411 #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
if(std::uncaught_exceptions() > 0 if(std::uncaught_exceptions() > 0
#else #else
if(std::uncaught_exception() if(std::uncaught_exception()
...@@ -3578,6 +3622,10 @@ namespace detail { ...@@ -3578,6 +3622,10 @@ namespace detail {
} }
} }
DOCTEST_CLANG_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP
DOCTEST_MSVC_SUPPRESS_WARNING_POP
Subcase::operator bool() const { return m_entered; } Subcase::operator bool() const { return m_entered; }
Result::Result(bool passed, const String& decomposition) Result::Result(bool passed, const String& decomposition)
...@@ -3652,7 +3700,7 @@ namespace detail { ...@@ -3652,7 +3700,7 @@ namespace detail {
bool TestCase::operator<(const TestCase& other) const { bool TestCase::operator<(const TestCase& other) const {
if(m_line != other.m_line) if(m_line != other.m_line)
return m_line < other.m_line; return m_line < other.m_line;
const int file_cmp = std::strcmp(m_file, other.m_file); const int file_cmp = m_file.compare(other.m_file);
if(file_cmp != 0) if(file_cmp != 0)
return file_cmp < 0; return file_cmp < 0;
return m_template_id < other.m_template_id; return m_template_id < other.m_template_id;
...@@ -3662,13 +3710,9 @@ namespace { ...@@ -3662,13 +3710,9 @@ namespace {
using namespace detail; using namespace detail;
// for sorting tests by file/line // for sorting tests by file/line
bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) { bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
#if DOCTEST_MSVC
// this is needed because MSVC gives different case for drive letters // this is needed because MSVC gives different case for drive letters
// for __FILE__ when evaluated in a header and a source file // for __FILE__ when evaluated in a header and a source file
const int res = doctest::stricmp(lhs->m_file, rhs->m_file); const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
#else // MSVC
const int res = std::strcmp(lhs->m_file, rhs->m_file);
#endif // MSVC
if(res != 0) if(res != 0)
return res < 0; return res < 0;
if(lhs->m_line != rhs->m_line) if(lhs->m_line != rhs->m_line)
...@@ -3723,8 +3767,8 @@ namespace { ...@@ -3723,8 +3767,8 @@ namespace {
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
void color_to_stream(std::ostream& s, Color::Enum code) { void color_to_stream(std::ostream& s, Color::Enum code) {
((void)s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
((void)code); // for DOCTEST_CONFIG_COLORS_NONE static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
#ifdef DOCTEST_CONFIG_COLORS_ANSI #ifdef DOCTEST_CONFIG_COLORS_ANSI
if(g_no_colors || if(g_no_colors ||
(isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false)) (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
...@@ -3830,7 +3874,28 @@ namespace detail { ...@@ -3830,7 +3874,28 @@ namespace detail {
#ifdef DOCTEST_IS_DEBUGGER_ACTIVE #ifdef DOCTEST_IS_DEBUGGER_ACTIVE
bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); } bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }
#else // DOCTEST_IS_DEBUGGER_ACTIVE #else // DOCTEST_IS_DEBUGGER_ACTIVE
#ifdef DOCTEST_PLATFORM_MAC #ifdef DOCTEST_PLATFORM_LINUX
class ErrnoGuard {
public:
ErrnoGuard() : m_oldErrno(errno) {}
~ErrnoGuard() { errno = m_oldErrno; }
private:
int m_oldErrno;
};
// See the comments in Catch2 for the reasoning behind this implementation:
// https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102
bool isDebuggerActive() {
ErrnoGuard guard;
std::ifstream in("/proc/self/status");
for(std::string line; std::getline(in, line);) {
static const int PREFIX_LEN = 11;
if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
}
}
return false;
}
#elif defined(DOCTEST_PLATFORM_MAC)
// The following function is taken directly from the following technical note: // The following function is taken directly from the following technical note:
// https://developer.apple.com/library/archive/qa/qa1361/_index.html // https://developer.apple.com/library/archive/qa/qa1361/_index.html
// Returns true if the current process is being debugged (either // Returns true if the current process is being debugged (either
...@@ -3857,7 +3922,7 @@ namespace detail { ...@@ -3857,7 +3922,7 @@ namespace detail {
// We're being debugged if the P_TRACED flag is set. // We're being debugged if the P_TRACED flag is set.
return ((info.kp_proc.p_flag & P_TRACED) != 0); return ((info.kp_proc.p_flag & P_TRACED) != 0);
} }
#elif DOCTEST_MSVC || defined(__MINGW32__) #elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)
bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
#else #else
bool isDebuggerActive() { return false; } bool isDebuggerActive() { return false; }
...@@ -3897,11 +3962,15 @@ namespace detail { ...@@ -3897,11 +3962,15 @@ namespace detail {
g_infoContexts.push_back(this); g_infoContexts.push_back(this);
} }
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
// destroy cannot be inlined into the destructor because that would mean calling stringify after // destroy cannot be inlined into the destructor because that would mean calling stringify after
// ContextScope has been destroyed (base class destructors run after derived class destructors). // ContextScope has been destroyed (base class destructors run after derived class destructors).
// Instead, ContextScope calls this method directly from its destructor. // Instead, ContextScope calls this method directly from its destructor.
void ContextScopeBase::destroy() { void ContextScopeBase::destroy() {
#if __cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411 #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
if(std::uncaught_exceptions() > 0) { if(std::uncaught_exceptions() > 0) {
#else #else
if(std::uncaught_exception()) { if(std::uncaught_exception()) {
...@@ -3913,19 +3982,13 @@ namespace detail { ...@@ -3913,19 +3982,13 @@ namespace detail {
g_infoContexts.pop_back(); g_infoContexts.pop_back();
} }
DOCTEST_CLANG_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP
DOCTEST_MSVC_SUPPRESS_WARNING_POP
} // namespace detail } // namespace detail
namespace { namespace {
using namespace detail; using namespace detail;
std::ostream& file_line_to_stream(std::ostream& s, const char* file, int line,
const char* tail = "") {
const auto opt = getContextOptions();
s << Color::LightGrey << skipPathFromFilename(file) << (opt->gnu_file_line ? ":" : "(")
<< (opt->no_line_numbers ? 0 : line) // 0 or the real num depending on the option
<< (opt->gnu_file_line ? ":" : "):") << tail;
return s;
}
#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) #if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
struct FatalConditionHandler struct FatalConditionHandler
{ {
...@@ -4232,7 +4295,7 @@ namespace { ...@@ -4232,7 +4295,7 @@ namespace {
using namespace detail; using namespace detail;
template <typename Ex> template <typename Ex>
[[noreturn]] void throw_exception(Ex const& e) { DOCTEST_NORETURN void throw_exception(Ex const& e) {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
throw e; throw e;
#else // DOCTEST_CONFIG_NO_EXCEPTIONS #else // DOCTEST_CONFIG_NO_EXCEPTIONS
...@@ -4242,9 +4305,11 @@ namespace { ...@@ -4242,9 +4305,11 @@ namespace {
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
} }
#ifndef DOCTEST_INTERNAL_ERROR
#define DOCTEST_INTERNAL_ERROR(msg) \ #define DOCTEST_INTERNAL_ERROR(msg) \
throw_exception(std::logic_error( \ throw_exception(std::logic_error( \
__FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg)) __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
#endif // DOCTEST_INTERNAL_ERROR
// clang-format off // clang-format off
...@@ -4275,8 +4340,8 @@ namespace { ...@@ -4275,8 +4340,8 @@ namespace {
public: public:
ScopedElement( XmlWriter* writer ); ScopedElement( XmlWriter* writer );
ScopedElement( ScopedElement&& other ) noexcept; ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;
ScopedElement& operator=( ScopedElement&& other ) noexcept; ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;
~ScopedElement(); ~ScopedElement();
...@@ -4493,11 +4558,11 @@ namespace { ...@@ -4493,11 +4558,11 @@ namespace {
: m_writer( writer ) : m_writer( writer )
{} {}
XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT
: m_writer( other.m_writer ){ : m_writer( other.m_writer ){
other.m_writer = nullptr; other.m_writer = nullptr;
} }
XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {
if ( m_writer ) { if ( m_writer ) {
m_writer->endElement(); m_writer->endElement();
} }
...@@ -4676,7 +4741,7 @@ namespace { ...@@ -4676,7 +4741,7 @@ namespace {
tc = &in; tc = &in;
xml.startElement("TestCase") xml.startElement("TestCase")
.writeAttribute("name", in.m_name) .writeAttribute("name", in.m_name)
.writeAttribute("filename", skipPathFromFilename(in.m_file)) .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str()))
.writeAttribute("line", line(in.m_line)) .writeAttribute("line", line(in.m_line))
.writeAttribute("description", in.m_description); .writeAttribute("description", in.m_description);
...@@ -4707,7 +4772,7 @@ namespace { ...@@ -4707,7 +4772,7 @@ namespace {
for(unsigned i = 0; i < in.num_data; ++i) { for(unsigned i = 0; i < in.num_data; ++i) {
xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name) xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
.writeAttribute("testsuite", in.data[i]->m_test_suite) .writeAttribute("testsuite", in.data[i]->m_test_suite)
.writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file)) .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str()))
.writeAttribute("line", line(in.data[i]->m_line)); .writeAttribute("line", line(in.data[i]->m_line));
} }
xml.scopedElement("OverallResultsTestCases") xml.scopedElement("OverallResultsTestCases")
...@@ -4863,6 +4928,263 @@ namespace { ...@@ -4863,6 +4928,263 @@ namespace {
DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter); DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter);
void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {
if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==
0) //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) "
<< Color::None;
if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional
s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n";
} else if((rb.m_at & assertType::is_throws_as) &&
(rb.m_at & assertType::is_throws_with)) { //!OCLINT
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
<< rb.m_exception_string << "\", " << rb.m_exception_type << " ) " << Color::None;
if(rb.m_threw) {
if(!rb.m_failed) {
s << "threw as expected!\n";
} else {
s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n";
}
} else {
s << "did NOT throw at all!\n";
}
} else if(rb.m_at &
assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", "
<< rb.m_exception_type << " ) " << Color::None
<< (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" :
"threw a DIFFERENT exception: ") :
"did NOT throw at all!")
<< Color::Cyan << rb.m_exception << "\n";
} else if(rb.m_at &
assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
<< rb.m_exception_string << "\" ) " << Color::None
<< (rb.m_threw ? (!rb.m_failed ? "threw as expected!" :
"threw a DIFFERENT exception: ") :
"did NOT throw at all!")
<< Color::Cyan << rb.m_exception << "\n";
} else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan
<< rb.m_exception << "\n";
} else {
s << (rb.m_threw ? "THREW exception: " :
(!rb.m_failed ? "is correct!\n" : "is NOT correct!\n"));
if(rb.m_threw)
s << rb.m_exception << "\n";
else
s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n";
}
}
// TODO:
// - log_contexts()
// - log_message()
// - respond to queries
// - honor remaining options
// - more attributes in tags
struct JUnitReporter : public IReporter
{
XmlWriter xml;
std::mutex mutex;
Timer timer;
std::vector<String> deepestSubcaseStackNames;
struct JUnitTestCaseData
{
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime
static std::string getCurrentTimestamp() {
// Beware, this is not reentrant because of backward compatibility issues
// Also, UTC only, again because of backward compatibility (%z is C++11)
time_t rawtime;
std::time(&rawtime);
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
std::tm* timeInfo;
timeInfo = std::gmtime(&rawtime);
char timeStamp[timeStampSize];
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
return std::string(timeStamp);
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
struct JUnitTestMessage
{
JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details)
: message(_message), type(_type), details(_details) {}
JUnitTestMessage(const std::string& _message, const std::string& _details)
: message(_message), type(), details(_details) {}
std::string message, type, details;
};
struct JUnitTestCase
{
JUnitTestCase(const std::string& _classname, const std::string& _name)
: classname(_classname), name(_name), time(0), failures() {}
std::string classname, name;
double time;
std::vector<JUnitTestMessage> failures, errors;
};
void add(const std::string& classname, const std::string& name) {
testcases.emplace_back(classname, name);
}
void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
for(auto& curr: nameStack)
if(curr.size())
testcases.back().name += std::string("/") + curr.c_str();
}
void addTime(double time) {
if(time < 1e-4)
time = 0;
testcases.back().time = time;
totalSeconds += time;
}
void addFailure(const std::string& message, const std::string& type, const std::string& details) {
testcases.back().failures.emplace_back(message, type, details);
++totalFailures;
}
void addError(const std::string& message, const std::string& details) {
testcases.back().errors.emplace_back(message, details);
++totalErrors;
}
std::vector<JUnitTestCase> testcases;
double totalSeconds = 0;
int totalErrors = 0, totalFailures = 0;
};
JUnitTestCaseData testCaseData;
// caching pointers/references to objects of these types - safe to do
const ContextOptions& opt;
const TestCaseData* tc = nullptr;
JUnitReporter(const ContextOptions& co)
: xml(*co.cout)
, opt(co) {}
unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
// =========================================================================================
// WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
// =========================================================================================
void report_query(const QueryData&) override {}
void test_run_start() override {}
void test_run_end(const TestRunStats& p) override {
// remove .exe extension - mainly to have the same output on UNIX and Windows
std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
#ifdef DOCTEST_PLATFORM_WINDOWS
if(binary_name.rfind(".exe") != std::string::npos)
binary_name = binary_name.substr(0, binary_name.length() - 4);
#endif // DOCTEST_PLATFORM_WINDOWS
xml.startElement("testsuites");
xml.startElement("testsuite").writeAttribute("name", binary_name)
.writeAttribute("errors", testCaseData.totalErrors)
.writeAttribute("failures", testCaseData.totalFailures)
.writeAttribute("tests", p.numAsserts);
if(opt.no_time_in_output == false) {
xml.writeAttribute("time", testCaseData.totalSeconds);
xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp());
}
if(opt.no_version == false)
xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR);
for(const auto& testCase : testCaseData.testcases) {
xml.startElement("testcase")
.writeAttribute("classname", testCase.classname)
.writeAttribute("name", testCase.name);
if(opt.no_time_in_output == false)
xml.writeAttribute("time", testCase.time);
// This is not ideal, but it should be enough to mimic gtest's junit output.
xml.writeAttribute("status", "run");
for(const auto& failure : testCase.failures) {
xml.scopedElement("failure")
.writeAttribute("message", failure.message)
.writeAttribute("type", failure.type)
.writeText(failure.details, false);
}
for(const auto& error : testCase.errors) {
xml.scopedElement("error")
.writeAttribute("message", error.message)
.writeText(error.details);
}
xml.endElement();
}
xml.endElement();
xml.endElement();
}
void test_case_start(const TestCaseData& in) override {
testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
timer.start();
}
void test_case_reenter(const TestCaseData& in) override {
testCaseData.addTime(timer.getElapsedSeconds());
testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
deepestSubcaseStackNames.clear();
timer.start();
testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
}
void test_case_end(const CurrentTestCaseStats&) override {
testCaseData.addTime(timer.getElapsedSeconds());
testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
deepestSubcaseStackNames.clear();
}
void test_case_exception(const TestCaseException& e) override {
std::lock_guard<std::mutex> lock(mutex);
testCaseData.addError("exception", e.error_string.c_str());
}
void subcase_start(const SubcaseSignature& in) override {
std::lock_guard<std::mutex> lock(mutex);
deepestSubcaseStackNames.push_back(in.m_name);
}
void subcase_end() override {}
void log_assert(const AssertData& rb) override {
if(!rb.m_failed) // report only failures & ignore the `success` option
return;
std::lock_guard<std::mutex> lock(mutex);
std::ostringstream os;
os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(")
<< line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
fulltext_log_assert_to_stream(os, rb);
testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
}
void log_message(const MessageData&) override {}
void test_case_skipped(const TestCaseData&) override {}
};
DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
struct Whitespace struct Whitespace
{ {
int nrSpaces; int nrSpaces;
...@@ -4881,6 +5203,7 @@ namespace { ...@@ -4881,6 +5203,7 @@ namespace {
std::ostream& s; std::ostream& s;
bool hasLoggedCurrentTestStart; bool hasLoggedCurrentTestStart;
std::vector<SubcaseSignature> subcasesStack; std::vector<SubcaseSignature> subcasesStack;
size_t currentSubcaseLevel;
std::mutex mutex; std::mutex mutex;
// caching pointers/references to objects of these types - safe to do // caching pointers/references to objects of these types - safe to do
...@@ -4939,23 +5262,40 @@ namespace { ...@@ -4939,23 +5262,40 @@ namespace {
s << "\n"; s << "\n";
} }
// this was requested to be made virtual so users could override it
virtual void file_line_to_stream(const char* file, int line,
const char* tail = "") {
s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(")
<< (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option
<< (opt.gnu_file_line ? ":" : "):") << tail;
}
void logTestStart() { void logTestStart() {
if(hasLoggedCurrentTestStart) if(hasLoggedCurrentTestStart)
return; return;
separator_to_stream(); separator_to_stream();
file_line_to_stream(s, tc->m_file, tc->m_line, "\n"); file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n");
if(tc->m_description) if(tc->m_description)
s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n"; s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n";
if(tc->m_test_suite && tc->m_test_suite[0] != '\0') if(tc->m_test_suite && tc->m_test_suite[0] != '\0')
s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n"; s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n";
if(strncmp(tc->m_name, " Scenario:", 11) != 0) if(strncmp(tc->m_name, " Scenario:", 11) != 0)
s << Color::None << "TEST CASE: "; s << Color::Yellow << "TEST CASE: ";
s << Color::None << tc->m_name << "\n"; s << Color::None << tc->m_name << "\n";
for(auto& curr : subcasesStack) for(size_t i = 0; i < currentSubcaseLevel; ++i) {
if(curr.m_name[0] != '\0') if(subcasesStack[i].m_name[0] != '\0')
s << " " << curr.m_name << "\n"; s << " " << subcasesStack[i].m_name << "\n";
}
if(currentSubcaseLevel != subcasesStack.size()) {
s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None;
for(size_t i = 0; i < subcasesStack.size(); ++i) {
if(subcasesStack[i].m_name[0] != '\0')
s << " " << subcasesStack[i].m_name << "\n";
}
}
s << "\n"; s << "\n";
...@@ -5166,25 +5506,28 @@ namespace { ...@@ -5166,25 +5506,28 @@ namespace {
separator_to_stream(); separator_to_stream();
s << std::dec; s << std::dec;
auto totwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));
auto passwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
auto failwidth = int(std::ceil(log10((std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));
const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6) s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth)
<< p.numTestCasesPassingFilters << " | " << p.numTestCasesPassingFilters << " | "
<< ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None : << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
Color::Green) Color::Green)
<< std::setw(6) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed" << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
<< Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None) << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)
<< std::setw(6) << p.numTestCasesFailed << " failed" << Color::None << " | "; << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
if(opt.no_skipped_summary == false) { if(opt.no_skipped_summary == false) {
const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters; const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
s << (numSkipped == 0 ? Color::None : Color::Yellow) << std::setw(6) << numSkipped s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
<< " skipped" << Color::None; << " skipped" << Color::None;
} }
s << "\n"; s << "\n";
s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(6) s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth)
<< p.numAsserts << " | " << p.numAsserts << " | "
<< ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green) << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)
<< std::setw(6) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
<< " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(6) << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
<< p.numAssertsFailed << " failed" << Color::None << " |\n"; << p.numAssertsFailed << " failed" << Color::None << " |\n";
s << Color::Cyan << "[doctest] " << Color::None s << Color::Cyan << "[doctest] " << Color::None
<< "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green) << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
...@@ -5194,9 +5537,13 @@ namespace { ...@@ -5194,9 +5537,13 @@ namespace {
void test_case_start(const TestCaseData& in) override { void test_case_start(const TestCaseData& in) override {
hasLoggedCurrentTestStart = false; hasLoggedCurrentTestStart = false;
tc = &in; tc = &in;
subcasesStack.clear();
currentSubcaseLevel = 0;
} }
void test_case_reenter(const TestCaseData&) override {} void test_case_reenter(const TestCaseData&) override {
subcasesStack.clear();
}
void test_case_end(const CurrentTestCaseStats& st) override { void test_case_end(const CurrentTestCaseStats& st) override {
// log the preamble of the test case only if there is something // log the preamble of the test case only if there is something
...@@ -5235,7 +5582,7 @@ namespace { ...@@ -5235,7 +5582,7 @@ namespace {
void test_case_exception(const TestCaseException& e) override { void test_case_exception(const TestCaseException& e) override {
logTestStart(); logTestStart();
file_line_to_stream(s, tc->m_file, tc->m_line, " "); file_line_to_stream(tc->m_file.c_str(), tc->m_line, " ");
successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require : successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require :
assertType::is_check); assertType::is_check);
s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ") s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ")
...@@ -5256,12 +5603,13 @@ namespace { ...@@ -5256,12 +5603,13 @@ namespace {
void subcase_start(const SubcaseSignature& subc) override { void subcase_start(const SubcaseSignature& subc) override {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
subcasesStack.push_back(subc); subcasesStack.push_back(subc);
++currentSubcaseLevel;
hasLoggedCurrentTestStart = false; hasLoggedCurrentTestStart = false;
} }
void subcase_end() override { void subcase_end() override {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
subcasesStack.pop_back(); --currentSubcaseLevel;
hasLoggedCurrentTestStart = false; hasLoggedCurrentTestStart = false;
} }
...@@ -5273,55 +5621,10 @@ namespace { ...@@ -5273,55 +5621,10 @@ namespace {
logTestStart(); logTestStart();
file_line_to_stream(s, rb.m_file, rb.m_line, " "); file_line_to_stream(rb.m_file, rb.m_line, " ");
successOrFailColoredStringToStream(!rb.m_failed, rb.m_at); successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);
if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==
0) //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) "
<< Color::None;
if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional fulltext_log_assert_to_stream(s, rb);
s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n";
} else if((rb.m_at & assertType::is_throws_as) &&
(rb.m_at & assertType::is_throws_with)) { //!OCLINT
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
<< rb.m_exception_string << "\", " << rb.m_exception_type << " ) " << Color::None;
if(rb.m_threw) {
if(!rb.m_failed) {
s << "threw as expected!\n";
} else {
s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n";
}
} else {
s << "did NOT throw at all!\n";
}
} else if(rb.m_at &
assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", "
<< rb.m_exception_type << " ) " << Color::None
<< (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" :
"threw a DIFFERENT exception: ") :
"did NOT throw at all!")
<< Color::Cyan << rb.m_exception << "\n";
} else if(rb.m_at &
assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
<< rb.m_exception_string << "\" ) " << Color::None
<< (rb.m_threw ? (!rb.m_failed ? "threw as expected!" :
"threw a DIFFERENT exception: ") :
"did NOT throw at all!")
<< Color::Cyan << rb.m_exception << "\n";
} else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan
<< rb.m_exception << "\n";
} else {
s << (rb.m_threw ? "THREW exception: " :
(!rb.m_failed ? "is correct!\n" : "is NOT correct!\n"));
if(rb.m_threw)
s << rb.m_exception << "\n";
else
s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n";
}
log_contexts(); log_contexts();
} }
...@@ -5331,7 +5634,7 @@ namespace { ...@@ -5331,7 +5634,7 @@ namespace {
logTestStart(); logTestStart();
file_line_to_stream(s, mb.m_file, mb.m_line, " "); file_line_to_stream(mb.m_file, mb.m_line, " ");
s << getSuccessOrFailColor(false, mb.m_severity) s << getSuccessOrFailColor(false, mb.m_severity)
<< getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity, << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
"MESSAGE") << ": "; "MESSAGE") << ": ";
...@@ -5592,6 +5895,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { ...@@ -5592,6 +5895,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
// clang-format on // clang-format on
if(withDefaults) { if(withDefaults) {
...@@ -5778,9 +6082,9 @@ int Context::run() { ...@@ -5778,9 +6082,9 @@ int Context::run() {
if(tc.m_skip && !p->no_skip) if(tc.m_skip && !p->no_skip)
skip_me = true; skip_me = true;
if(!matchesAny(tc.m_file, p->filters[0], true, p->case_sensitive)) if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive))
skip_me = true; skip_me = true;
if(matchesAny(tc.m_file, p->filters[1], false, p->case_sensitive)) if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive))
skip_me = true; skip_me = true;
if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive)) if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))
skip_me = true; skip_me = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment