doctest: Update to 2.4.4

Make ClassDB test macros enforce their msg to be constructed as String,
since doctest 2.4.2 changes the message passing to vararg.
This commit is contained in:
Rémi Verschelde 2021-01-08 11:17:36 +01:00
parent 0abbefd94a
commit 7917cb12df
No known key found for this signature in database
GPG Key ID: C3336907360768E1
3 changed files with 236 additions and 110 deletions

View File

@ -42,10 +42,10 @@
#include "tests/test_macros.h"
#define TEST_COND DOCTEST_CHECK_FALSE_MESSAGE
#define TEST_FAIL DOCTEST_FAIL
#define TEST_FAIL_COND DOCTEST_REQUIRE_FALSE_MESSAGE
#define TEST_FAIL_COND_WARN DOCTEST_WARN_FALSE_MESSAGE
#define TEST_COND(cond, msg) DOCTEST_CHECK_FALSE_MESSAGE(cond, String(msg))
#define TEST_FAIL(cond, msg) DOCTEST_FAIL(cond, String(msg))
#define TEST_FAIL_COND(cond, msg) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, String(msg))
#define TEST_FAIL_COND_WARN(cond, msg) DOCTEST_WARN_FALSE_MESSAGE(cond, String(msg))
namespace TestClassDB {

View File

@ -55,12 +55,14 @@ Files extracted from upstream source:
## doctest
- Upstream: https://github.com/onqtam/doctest
- Version: 8424be5 (2.4.1)
- Version: 2.4.4 (97d5a9447e66cd5e107b7a6c463be4a468a40496, 2020)
- License: MIT
Extracted from .zip provided. Extracted license and header only.
## enet
- Upstream: http://enet.bespin.org

View File

@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH 1
#define DOCTEST_VERSION_STR "2.4.1"
#define DOCTEST_VERSION_PATCH 4
#define DOCTEST_VERSION_STR "2.4.4"
#define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
@ -368,7 +368,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
@ -747,6 +747,7 @@ struct ContextOptions //!OCLINT too many fields
bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
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_debug_output; // no output in the debug console when a debugger is attached
bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
@ -806,7 +807,7 @@ namespace detail {
} // namespace has_insertion_operator_impl
template<class T>
using has_insertion_operator = has_insertion_operator_impl::check<T>;
using has_insertion_operator = has_insertion_operator_impl::check<const T>;
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);
@ -1035,6 +1036,7 @@ namespace detail {
template <typename L, typename R>
String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
const DOCTEST_REF_WRAP(R) rhs) {
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
return toString(lhs) + op + toString(rhs);
}
@ -1122,6 +1124,7 @@ namespace detail {
#define DOCTEST_COMPARISON_RETURN_TYPE bool
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
@ -1541,12 +1544,24 @@ namespace detail {
MessageBuilder() = delete;
~MessageBuilder();
// the preferred way of chaining parameters for stringification
template <typename T>
MessageBuilder& operator<<(const T& in) {
MessageBuilder& operator,(const T& in) {
toStream(m_stream, in);
return *this;
}
// kept here just for backwards-compatibility - the comma operator should be preferred now
template <typename T>
MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
// the `,` operator has the lowest operator precedence - if `<<` is used by the user then
// the `,` operator will be called last which is not what we want and thus the `*` operator
// is used first (has higher operator precedence compared to `<<`) so that we guarantee that
// an operator of the MessageBuilder class is called first before the rest of the parameters
template <typename T>
MessageBuilder& operator*(const T& in) { return this->operator,(in); }
bool log();
void react();
};
@ -1962,38 +1977,38 @@ int registerReporter(const char* name, int priority, bool isReporter) {
DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
// for logging
#define DOCTEST_INFO(expression) \
#define DOCTEST_INFO(...) \
DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), expression)
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), __VA_ARGS__)
#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, expression) \
#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, ...) \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626) \
auto lambda_name = [&](std::ostream* s_name) { \
doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
mb_name.m_stream = s_name; \
mb_name << expression; \
mb_name * __VA_ARGS__; \
}; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name)
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x)
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \
#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
do { \
doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
mb << x; \
mb * __VA_ARGS__; \
DOCTEST_ASSERT_LOG_AND_REACT(mb); \
} while(false)
// 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_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
// clang-format on
#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x)
#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x)
#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x)
#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
@ -2036,12 +2051,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
// clang-format off
#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(false)
#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(false)
#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(false)
#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
// clang-format on
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
@ -2051,8 +2066,8 @@ int registerReporter(const char* name, int priority, bool isReporter) {
__LINE__, #expr, #__VA_ARGS__, message); \
try { \
DOCTEST_CAST_TO_VOID(expr) \
} catch(const doctest::detail::remove_const< \
doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
} catch(const typename doctest::detail::remove_const< \
typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
_DOCTEST_RB.translateException(); \
_DOCTEST_RB.m_threw_as = true; \
} catch(...) { _DOCTEST_RB.translateException(); } \
@ -2103,21 +2118,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
#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(false)
#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(false)
#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(false)
#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(false)
#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(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(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(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(false)
#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(false)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false)
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false)
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false)
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false)
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
// clang-format on
#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
@ -2230,21 +2245,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<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) (static_cast<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) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
@ -2335,14 +2350,14 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
#define DOCTEST_INFO(x) (static_cast<void>(0))
#define DOCTEST_INFO(...) (static_cast<void>(0))
#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0))
#define DOCTEST_MESSAGE(x) (static_cast<void>(0))
#define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0))
#define DOCTEST_FAIL(x) (static_cast<void>(0))
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_MESSAGE(...) (static_cast<void>(0))
#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
#define DOCTEST_FAIL(...) (static_cast<void>(0))
#define DOCTEST_WARN(...) (static_cast<void>(0))
#define DOCTEST_CHECK(...) (static_cast<void>(0))
@ -2351,12 +2366,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))
#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
@ -2374,21 +2389,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<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) (static_cast<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) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_EQ(...) (static_cast<void>(0))
#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
@ -2754,9 +2769,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <map>
#include <exception>
#include <stdexcept>
#ifdef DOCTEST_CONFIG_POSIX_SIGNALS
#include <csignal>
#endif // DOCTEST_CONFIG_POSIX_SIGNALS
#include <cfloat>
#include <cctype>
#include <cstdint>
@ -3071,6 +3084,7 @@ String::String() {
String::~String() {
if(!isOnStack())
delete[] data.ptr;
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
String::String(const char* in)
@ -3112,6 +3126,7 @@ String& String::operator+=(const String& other) {
if(total_size < len) {
// append to the current stack space
memcpy(buf + my_old_size, other.c_str(), other_size + 1);
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
setLast(last - total_size);
} else {
// alloc new chunk
@ -3153,6 +3168,7 @@ String& String::operator+=(const String& other) {
return *this;
}
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String String::operator+(const String& other) const { return String(*this) += other; }
String::String(String&& other) {
@ -3307,6 +3323,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
// depending on the current options this will remove the path of filenames
const char* skipPathFromFilename(const char* file) {
#ifndef DOCTEST_CONFIG_DISABLE
if(getContextOptions()->no_path_in_filenames) {
auto back = std::strrchr(file, '\\');
auto forward = std::strrchr(file, '/');
@ -3316,6 +3333,7 @@ const char* skipPathFromFilename(const char* file) {
return forward + 1;
}
}
#endif // DOCTEST_CONFIG_DISABLE
return file;
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
@ -3334,6 +3352,7 @@ IContextScope::~IContextScope() = default;
#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(char* in) { return toString(static_cast<const char*>(in)); }
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(bool in) { return in ? "true" : "false"; }
@ -3406,6 +3425,7 @@ bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs
bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
String toString(const Approx& in) {
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
return String("Approx( ") + doctest::toString(in.m_value) + " )";
}
const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
@ -3698,11 +3718,15 @@ namespace detail {
}
bool TestCase::operator<(const TestCase& other) const {
// this will be used only to differentiate between test cases - not relevant for sorting
if(m_line != other.m_line)
return m_line < other.m_line;
const int file_cmp = m_file.compare(other.m_file);
if(file_cmp != 0)
return file_cmp < 0;
const int name_cmp = strcmp(m_name, other.m_name);
if(name_cmp != 0)
return name_cmp < 0;
return m_template_id < other.m_template_id;
}
} // namespace detail
@ -4009,24 +4033,40 @@ namespace {
// Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently.
SignalDefs signalDefs[] = {
{EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"},
{EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"},
{EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"},
{EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"},
{static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
"SIGILL - Illegal instruction signal"},
{static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
{static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
"SIGSEGV - Segmentation violation signal"},
{static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
};
struct FatalConditionHandler
{
static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
reportFatal(signalDefs[i].name);
break;
// Multiple threads may enter this filter/handler at once. We want the error message to be printed on the
// console just once no matter how many threads have crashed.
static std::mutex mutex;
static bool execute = true;
{
std::lock_guard<std::mutex> lock(mutex);
if(execute) {
bool reported = false;
for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
reportFatal(signalDefs[i].name);
reported = true;
break;
}
}
if(reported == false)
reportFatal("Unhandled SEH exception caught");
if(isDebuggerActive() && !g_cs->no_breaks)
DOCTEST_BREAK_INTO_DEBUGGER();
}
execute = false;
}
// If its not an exception we care about, pass it along.
// This stops us from eating debugger breaks etc.
return EXCEPTION_CONTINUE_SEARCH;
std::exit(EXIT_FAILURE);
}
FatalConditionHandler() {
@ -4038,6 +4078,51 @@ namespace {
previousTop = SetUnhandledExceptionFilter(handleException);
// Pass in guarantee size to be filled
SetThreadStackGuarantee(&guaranteeSize);
// On Windows uncaught exceptions from another thread, exceptions from
// destructors, or calls to std::terminate are not a SEH exception
// The terminal handler gets called when:
// - std::terminate is called FROM THE TEST RUNNER THREAD
// - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
original_terminate_handler = std::get_terminate();
std::set_terminate([]() noexcept {
reportFatal("Terminate handler called");
if(isDebuggerActive() && !g_cs->no_breaks)
DOCTEST_BREAK_INTO_DEBUGGER();
std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
});
// SIGABRT is raised when:
// - std::terminate is called FROM A DIFFERENT THREAD
// - an exception is thrown from a destructor FROM A DIFFERENT THREAD
// - an uncaught exception is thrown FROM A DIFFERENT THREAD
prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) noexcept {
if(signal == SIGABRT) {
reportFatal("SIGABRT - Abort (abnormal termination) signal");
if(isDebuggerActive() && !g_cs->no_breaks)
DOCTEST_BREAK_INTO_DEBUGGER();
std::exit(EXIT_FAILURE);
}
});
// The following settings are taken from google test, and more
// specifically from UnitTest::Run() inside of gtest.cc
// the user does not want to see pop-up dialogs about crashes
prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
// This forces the abort message to go to stderr in all circumstances.
prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
// In the debug version, Visual Studio pops up a separate dialog
// offering a choice to debug the aborted program - we want to disable that.
prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
// In debug mode, the Windows CRT can crash with an assertion over invalid
// input (e.g. passing an invalid file descriptor). The default handling
// for these assertions is to pop up a dialog and wait for user input.
// Instead ask the CRT to dump such assertions to stderr non-interactively.
prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
}
static void reset() {
@ -4045,7 +4130,13 @@ namespace {
// Unregister handler and restore the old guarantee
SetUnhandledExceptionFilter(previousTop);
SetThreadStackGuarantee(&guaranteeSize);
previousTop = nullptr;
std::set_terminate(original_terminate_handler);
std::signal(SIGABRT, prev_sigabrt_handler);
SetErrorMode(prev_error_mode_1);
_set_error_mode(prev_error_mode_2);
_set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
_CrtSetReportMode(_CRT_ASSERT, prev_report_mode);
_CrtSetReportFile(_CRT_ASSERT, prev_report_file);
isSet = false;
}
}
@ -4053,11 +4144,25 @@ namespace {
~FatalConditionHandler() { reset(); }
private:
static UINT prev_error_mode_1;
static int prev_error_mode_2;
static unsigned int prev_abort_behavior;
static int prev_report_mode;
static _HFILE prev_report_file;
static void (*prev_sigabrt_handler)(int);
static std::terminate_handler original_terminate_handler;
static bool isSet;
static ULONG guaranteeSize;
static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
};
UINT FatalConditionHandler::prev_error_mode_1;
int FatalConditionHandler::prev_error_mode_2;
unsigned int FatalConditionHandler::prev_abort_behavior;
int FatalConditionHandler::prev_report_mode;
_HFILE FatalConditionHandler::prev_report_file;
void (*FatalConditionHandler::prev_sigabrt_handler)(int);
std::terminate_handler FatalConditionHandler::original_terminate_handler;
bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
@ -4257,6 +4362,7 @@ namespace detail {
// ###################################################################################
DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
@ -4979,7 +5085,6 @@ namespace {
}
// TODO:
// - log_contexts()
// - log_message()
// - respond to queries
// - honor remaining options
@ -4993,7 +5098,6 @@ namespace {
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)
@ -5001,16 +5105,19 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime
std::time(&rawtime);
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
std::tm* timeInfo;
timeInfo = std::gmtime(&rawtime);
std::tm timeInfo;
#ifdef DOCTEST_PLATFORM_WINDOWS
gmtime_s(&timeInfo, &rawtime);
#else // DOCTEST_PLATFORM_WINDOWS
gmtime_r(&rawtime, &timeInfo);
#endif // DOCTEST_PLATFORM_WINDOWS
char timeStamp[timeStampSize];
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
return std::string(timeStamp);
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
struct JUnitTestMessage
{
@ -5175,12 +5282,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
<< line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
fulltext_log_assert_to_stream(os, rb);
log_contexts(os);
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 {}
void log_contexts(std::ostringstream& s) {
int num_contexts = get_num_active_contexts();
if(num_contexts) {
auto contexts = get_active_contexts();
s << " logged: ";
for(int i = 0; i < num_contexts; ++i) {
s << (i == 0 ? "" : " ");
contexts[i]->stringify(&s);
s << std::endl;
}
}
}
};
DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
@ -5894,6 +6016,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
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-debug-output", "ndo", no_debug_output, 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
@ -5951,6 +6074,7 @@ void Context::clearFilters() {
// allows the user to override procedurally the int/bool options from the command line
void Context::setOption(const char* option, int value) {
setOption(option, toString(value).c_str());
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
// allows the user to override procedurally the string options from the command line
@ -6026,7 +6150,7 @@ int Context::run() {
p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
#ifdef DOCTEST_PLATFORM_WINDOWS
if(isDebuggerActive())
if(isDebuggerActive() && p->no_debug_output == false)
p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
#endif // DOCTEST_PLATFORM_WINDOWS