Doctest is updated to v2.4.1

parent 260be043
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
of this software and associated documentation files (the "Software"), to deal
......@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
\ No newline at end of file
......@@ -4,7 +4,7 @@
//
// 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
// See accompanying file LICENSE.txt or copy at
......@@ -47,9 +47,9 @@
// =================================================================================================
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 3
#define DOCTEST_VERSION_PATCH 7
#define DOCTEST_VERSION_STR "2.3.7"
#define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH 1
#define DOCTEST_VERSION_STR "2.4.1"
#define DOCTEST_VERSION \
(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'
#define DOCTEST_NOINLINE __declspec(noinline)
#define DOCTEST_UNUSED
#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_UNUSED __attribute__((unused))
#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 ========================================================================
......@@ -347,8 +359,20 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#ifndef DOCTEST_BREAK_INTO_DEBUGGER
// 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" : :)
#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
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
#elif defined(__MINGW32__)
......@@ -357,7 +381,7 @@ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
#else // linux
#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0)
#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
#endif // linux
#endif // DOCTEST_BREAK_INTO_DEBUGGER
......@@ -367,6 +391,9 @@ DOCTEST_GCC_SUPPRESS_WARNING_POP
#endif // DOCTEST_CONFIG_USE_IOSFWD
#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 <cstddef>
#include <ostream>
......@@ -629,7 +656,7 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
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
const char* m_name; // name of the test case
const char* m_test_suite; // the test suite in which the test was added
......@@ -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_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_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
bool help; // to print the help
bool version; // to print the version
......@@ -731,7 +759,6 @@ struct ContextOptions //!OCLINT too many fields
};
namespace detail {
#if defined(DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || defined(DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS)
template <bool CONDITION, typename TYPE = void>
struct enable_if
{};
......@@ -739,7 +766,6 @@ namespace detail {
template <typename TYPE>
struct enable_if<true, TYPE>
{ typedef TYPE type; };
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
// clang-format off
template<class T> struct remove_reference { typedef T type; };
......@@ -748,6 +774,14 @@ namespace detail {
template<class T> struct remove_const { 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
template <typename T>
......@@ -756,33 +790,23 @@ namespace detail {
{ static const bool value = false; };
namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];
std::ostream &os();
template<class T>
DOCTEST_REF_WRAP(T) val();
struct any_t
{
template <typename T>
// cppcheck-suppress noExplicitConstructor
any_t(const DOCTEST_REF_WRAP(T));
template<class, class = void>
struct check {
static constexpr bool value = false;
};
yes& testStreamable(std::ostream&);
no testStreamable(no);
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);
template<class T>
struct check<T, decltype(os() << val<T>(), void())> {
static constexpr bool value = true;
};
} // namespace has_insertion_operator_impl
template <typename T>
struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
{};
template<class T>
using has_insertion_operator = has_insertion_operator_impl::check<T>;
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);
......@@ -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) {
return StringMaker<T>::convert(value);
}
......@@ -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(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)
// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183
DOCTEST_INTERFACE String toString(const std::string& in);
......@@ -987,7 +1017,7 @@ namespace detail {
DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
[[noreturn]]
DOCTEST_NORETURN
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
DOCTEST_INTERFACE void throwException();
......@@ -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); } };
// clang-format on
DOCTEST_BINARY_RELATIONAL_OP(0, eq)
DOCTEST_BINARY_RELATIONAL_OP(1, ne)
DOCTEST_BINARY_RELATIONAL_OP(2, gt)
DOCTEST_BINARY_RELATIONAL_OP(3, lt)
DOCTEST_BINARY_RELATIONAL_OP(4, ge)
DOCTEST_BINARY_RELATIONAL_OP(5, le)
DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)
struct DOCTEST_INTERFACE ResultBuilder : public AssertData
{
......@@ -1416,9 +1446,9 @@ namespace detail {
} catch(T ex) { // NOLINT
res = m_translateFunction(ex); //!OCLINT parameter reassignment
return true;
} catch(...) {} //!OCLINT - empty catch statement
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
((void)res); // to silence -Wunused-parameter
} catch(...) {} //!OCLINT - empty catch statement
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
static_cast<void>(res); // to silence -Wunused-parameter
return false;
}
......@@ -1480,7 +1510,7 @@ namespace detail {
DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
// ContextScope base class used to allow implementing methods of ContextScope
// ContextScope base class used to allow implementing methods of ContextScope
// that don't depend on the template parameter in doctest.cpp.
class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
protected:
......@@ -1737,12 +1767,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#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") \
static_cast<void>(x); \
static_cast<void>(__VA_ARGS__); \
DOCTEST_GCC_SUPPRESS_WARNING_POP
#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
// registers the test by initializing a dummy var with a function
......@@ -1953,7 +1983,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
mb << x; \
DOCTEST_ASSERT_LOG_AND_REACT(mb); \
} while((void)0, 0)
} 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)
......@@ -1982,7 +2012,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
do { \
DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
} while((void)0, 0)
} while(false)
#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
......@@ -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__)
// 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_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while((void)0, 0)
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, 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((void)0, 0)
#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_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, 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(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)
// clang-format on
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
......@@ -2028,66 +2058,66 @@ int registerReporter(const char* name, int priority, bool isReporter) {
} catch(...) { _DOCTEST_RB.translateException(); } \
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 { \
if(!doctest::getContextOptions()->no_throw) { \
doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #expr, "", __VA_ARGS__); \
__LINE__, expr_str, "", __VA_ARGS__); \
try { \
DOCTEST_CAST_TO_VOID(expr) \
} catch(...) { _DOCTEST_RB.translateException(); } \
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 { \
doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #expr); \
__LINE__, #__VA_ARGS__); \
try { \
DOCTEST_CAST_TO_VOID(expr) \
DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
} catch(...) { _DOCTEST_RB.translateException(); } \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0)
} while(false)
// clang-format off
#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_WARN_THROWS, "")
#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_CHECK_THROWS, "")
#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS_WITH(expr, DT_REQUIRE_THROWS, "")
#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_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_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_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(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_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_REQUIRE_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, #expr, DT_CHECK_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_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_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_WARN_NOTHROW)
#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_CHECK_NOTHROW)
#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_REQUIRE_NOTHROW)
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while((void)0, 0)
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while((void)0, 0)
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while((void)0, 0)
#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_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_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((void)0, 0)
#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_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_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((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((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((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((void)0, 0)
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while((void)0, 0)
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while((void)0, 0)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while((void)0, 0)
#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
#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)
// clang-format on
#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
......@@ -2100,7 +2130,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
_DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
__VA_ARGS__)) \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0)
} while(false)
#define DOCTEST_UNARY_ASSERT(assert_type, ...) \
do { \
......@@ -2108,7 +2138,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
__LINE__, #__VA_ARGS__); \
DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__)) \
DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \
} while((void)0, 0)
} while(false)
#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
......@@ -2184,37 +2214,37 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
#define DOCTEST_WARN_THROWS(expr) ((void)0)
#define DOCTEST_CHECK_THROWS(expr) ((void)0)
#define DOCTEST_REQUIRE_THROWS(expr) ((void)0)
#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_WARN_NOTHROW(expr) ((void)0)
#define DOCTEST_CHECK_NOTHROW(expr) ((void)0)
#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0)
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
#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))
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
......@@ -2305,86 +2335,86 @@ 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) ((void)0)
#define DOCTEST_CAPTURE(x) ((void)0)
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) ((void)0)
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) ((void)0)
#define DOCTEST_ADD_FAIL_AT(file, line, x) ((void)0)
#define DOCTEST_MESSAGE(x) ((void)0)
#define DOCTEST_FAIL_CHECK(x) ((void)0)
#define DOCTEST_FAIL(x) ((void)0)
#define DOCTEST_WARN(...) ((void)0)
#define DOCTEST_CHECK(...) ((void)0)
#define DOCTEST_REQUIRE(...) ((void)0)
#define DOCTEST_WARN_FALSE(...) ((void)0)
#define DOCTEST_CHECK_FALSE(...) ((void)0)
#define DOCTEST_REQUIRE_FALSE(...) ((void)0)
#define DOCTEST_WARN_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_CHECK_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) ((void)0)
#define DOCTEST_WARN_THROWS(expr) ((void)0)
#define DOCTEST_CHECK_THROWS(expr) ((void)0)
#define DOCTEST_REQUIRE_THROWS(expr) ((void)0)
#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0)
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0)
#define DOCTEST_WARN_NOTHROW(expr) ((void)0)
#define DOCTEST_CHECK_NOTHROW(expr) ((void)0)
#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0)
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0)
#define DOCTEST_WARN_EQ(...) ((void)0)
#define DOCTEST_CHECK_EQ(...) ((void)0)
#define DOCTEST_REQUIRE_EQ(...) ((void)0)
#define DOCTEST_WARN_NE(...) ((void)0)
#define DOCTEST_CHECK_NE(...) ((void)0)
#define DOCTEST_REQUIRE_NE(...) ((void)0)
#define DOCTEST_WARN_GT(...) ((void)0)
#define DOCTEST_CHECK_GT(...) ((void)0)
#define DOCTEST_REQUIRE_GT(...) ((void)0)
#define DOCTEST_WARN_LT(...) ((void)0)
#define DOCTEST_CHECK_LT(...) ((void)0)
#define DOCTEST_REQUIRE_LT(...) ((void)0)
#define DOCTEST_WARN_GE(...) ((void)0)
#define DOCTEST_CHECK_GE(...) ((void)0)
#define DOCTEST_REQUIRE_GE(...) ((void)0)
#define DOCTEST_WARN_LE(...) ((void)0)
#define DOCTEST_CHECK_LE(...) ((void)0)
#define DOCTEST_REQUIRE_LE(...) ((void)0)
#define DOCTEST_WARN_UNARY(...) ((void)0)
#define DOCTEST_CHECK_UNARY(...) ((void)0)
#define DOCTEST_REQUIRE_UNARY(...) ((void)0)
#define DOCTEST_WARN_UNARY_FALSE(...) ((void)0)
#define DOCTEST_CHECK_UNARY_FALSE(...) ((void)0)
#define DOCTEST_REQUIRE_UNARY_FALSE(...) ((void)0)
#define DOCTEST_INFO(x) (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_WARN(...) (static_cast<void>(0))
#define DOCTEST_CHECK(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE(...) (static_cast<void>(0))
#define DOCTEST_WARN_FALSE(...) (static_cast<void>(0))
#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_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
#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_EQ(...) (static_cast<void>(0))
#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_EQ(...) (static_cast<void>(0))
#define DOCTEST_WARN_NE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_NE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NE(...) (static_cast<void>(0))
#define DOCTEST_WARN_GT(...) (static_cast<void>(0))
#define DOCTEST_CHECK_GT(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_GT(...) (static_cast<void>(0))
#define DOCTEST_WARN_LT(...) (static_cast<void>(0))
#define DOCTEST_CHECK_LT(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_LT(...) (static_cast<void>(0))
#define DOCTEST_WARN_GE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_GE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_GE(...) (static_cast<void>(0))
#define DOCTEST_WARN_LE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_LE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_LE(...) (static_cast<void>(0))
#define DOCTEST_WARN_UNARY(...) (static_cast<void>(0))
#define DOCTEST_CHECK_UNARY(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_UNARY(...) (static_cast<void>(0))
#define DOCTEST_WARN_UNARY_FALSE(...) (static_cast<void>(0))
#define DOCTEST_CHECK_UNARY_FALSE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_UNARY_FALSE(...) (static_cast<void>(0))
#endif // DOCTEST_CONFIG_DISABLE
......@@ -2751,7 +2781,11 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <windows.h>
#else // MINGW
#include <Windows.h>
#endif // MINGW
#endif
#include <io.h>
......@@ -2762,6 +2796,12 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#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
// counts the number of elements in a C array
......@@ -2872,7 +2912,7 @@ namespace detail {
namespace timer_large_integer
{
#if defined(DOCTEST_PLATFORM_WINDOWS)
typedef ULONGLONG type;
#else // DOCTEST_PLATFORM_WINDOWS
......@@ -2913,7 +2953,7 @@ typedef timer_large_integer::type ticks_t;
//unsigned int getElapsedMilliseconds() const {
// 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:
ticks_t m_ticks = 0;
......@@ -3450,7 +3490,7 @@ namespace detail {
}
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
[[noreturn]] void throwException() {
DOCTEST_NORETURN void throwException() {
g_cs->shouldLogCurrentException = false;
throw TestFailureException();
} // NOLINT(cert-err60-cpp)
......@@ -3464,8 +3504,8 @@ namespace {
// matching of a string against a wildcard mask (case sensitivity configurable) taken from
// https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
int wildcmp(const char* str, const char* wild, bool caseSensitive) {
const char* cp = nullptr;
const char* mp = nullptr;
const char* cp = str;
const char* mp = wild;
while((*str) && (*wild != '*')) {
if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
......@@ -3554,6 +3594,10 @@ namespace detail {
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() {
if(m_entered) {
// only mark the subcase stack as passed if no subcases have been skipped
......@@ -3561,7 +3605,7 @@ namespace detail {
g_cs->subcasesPassed.insert(g_cs->subcasesStack);
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
#else
if(std::uncaught_exception()
......@@ -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; }
Result::Result(bool passed, const String& decomposition)
......@@ -3652,7 +3700,7 @@ namespace detail {
bool TestCase::operator<(const TestCase& other) const {
if(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)
return file_cmp < 0;
return m_template_id < other.m_template_id;
......@@ -3662,13 +3710,9 @@ namespace {
using namespace detail;
// for sorting tests by file/line
bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
#if DOCTEST_MSVC
// this is needed because MSVC gives different case for drive letters
// for __FILE__ when evaluated in a header and a source file
const int res = doctest::stricmp(lhs->m_file, rhs->m_file);
#else // MSVC
const int res = std::strcmp(lhs->m_file, rhs->m_file);
#endif // MSVC
const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
if(res != 0)
return res < 0;
if(lhs->m_line != rhs->m_line)
......@@ -3723,8 +3767,8 @@ namespace {
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
void color_to_stream(std::ostream& s, Color::Enum code) {
((void)s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
((void)code); // for DOCTEST_CONFIG_COLORS_NONE
static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
#ifdef DOCTEST_CONFIG_COLORS_ANSI
if(g_no_colors ||
(isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
......@@ -3830,7 +3874,28 @@ namespace detail {
#ifdef DOCTEST_IS_DEBUGGER_ACTIVE
bool isDebuggerActive() { return 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:
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
// Returns true if the current process is being debugged (either
......@@ -3857,7 +3922,7 @@ namespace detail {
// We're being debugged if the P_TRACED flag is set.
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; }
#else
bool isDebuggerActive() { return false; }
......@@ -3897,11 +3962,15 @@ namespace detail {
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
// ContextScope has been destroyed (base class destructors run after derived class destructors).
// Instead, ContextScope calls this method directly from its destructor.
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) {
#else
if(std::uncaught_exception()) {
......@@ -3913,19 +3982,13 @@ namespace detail {
g_infoContexts.pop_back();
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP
DOCTEST_MSVC_SUPPRESS_WARNING_POP
} // namespace detail
namespace {
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)
struct FatalConditionHandler
{
......@@ -4232,7 +4295,7 @@ namespace {
using namespace detail;
template <typename Ex>
[[noreturn]] void throw_exception(Ex const& e) {
DOCTEST_NORETURN void throw_exception(Ex const& e) {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
throw e;
#else // DOCTEST_CONFIG_NO_EXCEPTIONS
......@@ -4242,9 +4305,11 @@ namespace {
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
}
#ifndef DOCTEST_INTERNAL_ERROR
#define DOCTEST_INTERNAL_ERROR(msg) \
throw_exception(std::logic_error( \
__FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
#endif // DOCTEST_INTERNAL_ERROR
// clang-format off
......@@ -4275,8 +4340,8 @@ namespace {
public:
ScopedElement( XmlWriter* writer );
ScopedElement( ScopedElement&& other ) noexcept;
ScopedElement& operator=( ScopedElement&& other ) noexcept;
ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;
ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;
~ScopedElement();
......@@ -4493,11 +4558,11 @@ namespace {
: m_writer( writer )
{}
XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT
: m_writer( other.m_writer ){
other.m_writer = nullptr;
}
XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {
if ( m_writer ) {
m_writer->endElement();
}
......@@ -4676,7 +4741,7 @@ namespace {
tc = &in;
xml.startElement("TestCase")
.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("description", in.m_description);
......@@ -4707,7 +4772,7 @@ namespace {
for(unsigned i = 0; i < in.num_data; ++i) {
xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
.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));
}
xml.scopedElement("OverallResultsTestCases")
......@@ -4863,6 +4928,263 @@ namespace {
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
{
int nrSpaces;
......@@ -4881,6 +5203,7 @@ namespace {
std::ostream& s;
bool hasLoggedCurrentTestStart;
std::vector<SubcaseSignature> subcasesStack;
size_t currentSubcaseLevel;
std::mutex mutex;
// caching pointers/references to objects of these types - safe to do
......@@ -4939,23 +5262,40 @@ namespace {
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() {
if(hasLoggedCurrentTestStart)
return;
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)
s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n";
if(tc->m_test_suite && tc->m_test_suite[0] != '\0')
s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n";
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";
for(auto& curr : subcasesStack)
if(curr.m_name[0] != '\0')
s << " " << curr.m_name << "\n";
for(size_t i = 0; i < currentSubcaseLevel; ++i) {
if(subcasesStack[i].m_name[0] != '\0')
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";
......@@ -5166,25 +5506,28 @@ namespace {
separator_to_stream();
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;
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 == 0 || anythingFailed) ? Color::None :
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)
<< std::setw(6) << p.numTestCasesFailed << " failed" << Color::None << " | ";
<< std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
if(opt.no_skipped_summary == false) {
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;
}
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 == 0 || anythingFailed) ? Color::None : Color::Green)
<< std::setw(6) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
<< " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(6)
<< std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
<< " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
<< p.numAssertsFailed << " failed" << Color::None << " |\n";
s << Color::Cyan << "[doctest] " << Color::None
<< "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
......@@ -5194,9 +5537,13 @@ namespace {
void test_case_start(const TestCaseData& in) override {
hasLoggedCurrentTestStart = false;
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 {
// log the preamble of the test case only if there is something
......@@ -5235,7 +5582,7 @@ namespace {
void test_case_exception(const TestCaseException& e) override {
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 :
assertType::is_check);
s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ")
......@@ -5256,12 +5603,13 @@ namespace {
void subcase_start(const SubcaseSignature& subc) override {
std::lock_guard<std::mutex> lock(mutex);
subcasesStack.push_back(subc);
++currentSubcaseLevel;
hasLoggedCurrentTestStart = false;
}
void subcase_end() override {
std::lock_guard<std::mutex> lock(mutex);
subcasesStack.pop_back();
--currentSubcaseLevel;
hasLoggedCurrentTestStart = false;
}
......@@ -5273,55 +5621,10 @@ namespace {
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);
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";
}
fulltext_log_assert_to_stream(s, rb);
log_contexts();
}
......@@ -5331,7 +5634,7 @@ namespace {
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)
<< getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
"MESSAGE") << ": ";
......@@ -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-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-time-in-output", "ntio", no_time_in_output, false);
// clang-format on
if(withDefaults) {
......@@ -5778,9 +6082,9 @@ int Context::run() {
if(tc.m_skip && !p->no_skip)
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;
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;
if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))
skip_me = true;
......@@ -5953,4 +6257,4 @@ DOCTEST_MSVC_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP
#endif // DOCTEST_LIBRARY_IMPLEMENTATION
#endif // DOCTEST_CONFIG_IMPLEMENT
#endif // DOCTEST_CONFIG_IMPLEMENT
\ No newline at end of file
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