42#ifndef DOCTEST_LIBRARY_INCLUDED
43#define DOCTEST_LIBRARY_INCLUDED
49#define DOCTEST_VERSION_MAJOR 2
50#define DOCTEST_VERSION_MINOR 4
51#define DOCTEST_VERSION_PATCH 12
54#define DOCTEST_TOSTR_IMPL(x) #x
55#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
57#define DOCTEST_VERSION_STR \
58 DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "." \
59 DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." \
60 DOCTEST_TOSTR(DOCTEST_VERSION_PATCH)
62#define DOCTEST_VERSION \
63 (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
72#define DOCTEST_CPLUSPLUS _MSVC_LANG
74#define DOCTEST_CPLUSPLUS __cplusplus
77#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))
80#if defined(_MSC_VER) && defined(_MSC_FULL_VER)
81#if _MSC_VER == _MSC_FULL_VER / 10000
82#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
85 DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
88#if defined(__clang__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
89#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
90#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \
91 !defined(__INTEL_COMPILER)
92#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
94#if defined(__INTEL_COMPILER)
95#define DOCTEST_ICC DOCTEST_COMPILER(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
102#define DOCTEST_CLANG 0
115#if DOCTEST_CLANG && !DOCTEST_ICC
116#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
117#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
118#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)
119#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
120#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \
121 DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)
123#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
124#define DOCTEST_CLANG_SUPPRESS_WARNING(w)
125#define DOCTEST_CLANG_SUPPRESS_WARNING_POP
126#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
130#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
131#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
132#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)
133#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
134#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \
135 DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)
137#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
138#define DOCTEST_GCC_SUPPRESS_WARNING(w)
139#define DOCTEST_GCC_SUPPRESS_WARNING_POP
140#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
144#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
145#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
146#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
147#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \
148 DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)
150#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
151#define DOCTEST_MSVC_SUPPRESS_WARNING(w)
152#define DOCTEST_MSVC_SUPPRESS_WARNING_POP
153#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
162#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \
163 DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \
164 DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \
165 DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \
166 DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \
167 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \
168 DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \
169 DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \
171 DOCTEST_GCC_SUPPRESS_WARNING_PUSH \
172 DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \
173 DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \
174 DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \
175 DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \
176 DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \
177 DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \
178 DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \
179 DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \
181 DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
183 DOCTEST_MSVC_SUPPRESS_WARNING(4514) \
184 DOCTEST_MSVC_SUPPRESS_WARNING(4571) \
185 DOCTEST_MSVC_SUPPRESS_WARNING(4710) \
186 DOCTEST_MSVC_SUPPRESS_WARNING(4711) \
188 DOCTEST_MSVC_SUPPRESS_WARNING(4616) \
189 DOCTEST_MSVC_SUPPRESS_WARNING(4619) \
190 DOCTEST_MSVC_SUPPRESS_WARNING(4996) \
191 DOCTEST_MSVC_SUPPRESS_WARNING(4706) \
192 DOCTEST_MSVC_SUPPRESS_WARNING(4512) \
193 DOCTEST_MSVC_SUPPRESS_WARNING(4127) \
194 DOCTEST_MSVC_SUPPRESS_WARNING(4820) \
195 DOCTEST_MSVC_SUPPRESS_WARNING(4625) \
196 DOCTEST_MSVC_SUPPRESS_WARNING(4626) \
197 DOCTEST_MSVC_SUPPRESS_WARNING(5027) \
198 DOCTEST_MSVC_SUPPRESS_WARNING(5026) \
199 DOCTEST_MSVC_SUPPRESS_WARNING(4640) \
200 DOCTEST_MSVC_SUPPRESS_WARNING(5045) \
201 DOCTEST_MSVC_SUPPRESS_WARNING(5264) \
203 DOCTEST_MSVC_SUPPRESS_WARNING(26439) \
204 DOCTEST_MSVC_SUPPRESS_WARNING(26495) \
205 DOCTEST_MSVC_SUPPRESS_WARNING(26451) \
206 DOCTEST_MSVC_SUPPRESS_WARNING(26444) \
207 DOCTEST_MSVC_SUPPRESS_WARNING(26812)
209#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \
210 DOCTEST_CLANG_SUPPRESS_WARNING_POP \
211 DOCTEST_GCC_SUPPRESS_WARNING_POP \
212 DOCTEST_MSVC_SUPPRESS_WARNING_POP
228#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \
229 DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
230 DOCTEST_MSVC_SUPPRESS_WARNING(4548) \
231 DOCTEST_MSVC_SUPPRESS_WARNING(4265) \
232 DOCTEST_MSVC_SUPPRESS_WARNING(4986) \
233 DOCTEST_MSVC_SUPPRESS_WARNING(4350) \
234 DOCTEST_MSVC_SUPPRESS_WARNING(4668) \
235 DOCTEST_MSVC_SUPPRESS_WARNING(4365) \
236 DOCTEST_MSVC_SUPPRESS_WARNING(4774) \
237 DOCTEST_MSVC_SUPPRESS_WARNING(4820) \
238 DOCTEST_MSVC_SUPPRESS_WARNING(4625) \
239 DOCTEST_MSVC_SUPPRESS_WARNING(4626) \
240 DOCTEST_MSVC_SUPPRESS_WARNING(5027) \
241 DOCTEST_MSVC_SUPPRESS_WARNING(5026) \
242 DOCTEST_MSVC_SUPPRESS_WARNING(4623) \
243 DOCTEST_MSVC_SUPPRESS_WARNING(5039) \
244 DOCTEST_MSVC_SUPPRESS_WARNING(5045) \
245 DOCTEST_MSVC_SUPPRESS_WARNING(5105) \
246 DOCTEST_MSVC_SUPPRESS_WARNING(4738) \
247 DOCTEST_MSVC_SUPPRESS_WARNING(5262)
249#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP
271#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
272#define DOCTEST_CONFIG_NO_WINDOWS_SEH
274#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
275#define DOCTEST_CONFIG_WINDOWS_SEH
277#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)
278#undef DOCTEST_CONFIG_WINDOWS_SEH
281#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \
282 !defined(__EMSCRIPTEN__) && !defined(__wasi__)
283#define DOCTEST_CONFIG_POSIX_SIGNALS
285#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)
286#undef DOCTEST_CONFIG_POSIX_SIGNALS
289#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
290#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) \
292#define DOCTEST_CONFIG_NO_EXCEPTIONS
296#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
297#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
298#define DOCTEST_CONFIG_NO_EXCEPTIONS
302#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)
303#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
307#define DOCTEST_CONFIG_NO_MULTITHREADING
310#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)
311#define DOCTEST_CONFIG_IMPLEMENT
314#if defined(_WIN32) || defined(__CYGWIN__)
316#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)
317#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)
319#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))
320#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))
323#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default")))
324#define DOCTEST_SYMBOL_IMPORT
327#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
328#ifdef DOCTEST_CONFIG_IMPLEMENT
329#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT
331#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT
334#define DOCTEST_INTERFACE
340#define DOCTEST_INTERFACE_DECL
341#define DOCTEST_INTERFACE_DEF DOCTEST_INTERFACE
343#define DOCTEST_INTERFACE_DECL DOCTEST_INTERFACE
344#define DOCTEST_INTERFACE_DEF
350#define DOCTEST_NOINLINE __declspec(noinline)
351#define DOCTEST_UNUSED
352#define DOCTEST_ALIGNMENT(x)
353#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
354#define DOCTEST_NOINLINE
355#define DOCTEST_UNUSED
356#define DOCTEST_ALIGNMENT(x)
358#define DOCTEST_NOINLINE __attribute__((noinline))
359#define DOCTEST_UNUSED __attribute__((unused))
360#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
363#ifdef DOCTEST_CONFIG_NO_CONTRADICTING_INLINE
364#define DOCTEST_INLINE_NOINLINE inline
366#define DOCTEST_INLINE_NOINLINE inline DOCTEST_NOINLINE
369#ifndef DOCTEST_NORETURN
370#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
371#define DOCTEST_NORETURN
373#define DOCTEST_NORETURN [[noreturn]]
377#ifndef DOCTEST_NOEXCEPT
378#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
379#define DOCTEST_NOEXCEPT
381#define DOCTEST_NOEXCEPT noexcept
385#ifndef DOCTEST_CONSTEXPR
386#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
387#define DOCTEST_CONSTEXPR const
388#define DOCTEST_CONSTEXPR_FUNC inline
390#define DOCTEST_CONSTEXPR constexpr
391#define DOCTEST_CONSTEXPR_FUNC constexpr
395#ifndef DOCTEST_NO_SANITIZE_INTEGER
396#if DOCTEST_CLANG >= DOCTEST_COMPILER(3, 7, 0)
397#define DOCTEST_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer")))
399#define DOCTEST_NO_SANITIZE_INTEGER
407#define DOCTEST_DECLARE_INTERFACE(name) \
410 name(const name&) = delete; \
411 name(name&&) = delete; \
412 name& operator=(const name&) = delete; \
413 name& operator=(name&&) = delete;
415#define DOCTEST_DEFINE_INTERFACE(name) \
416 name::~name() = default;
419#define DOCTEST_CAT_IMPL(s1, s2) s1##s2
420#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)
422#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)
424#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)
427#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
428#define DOCTEST_REF_WRAP(x) x&
430#define DOCTEST_REF_WRAP(x) x
434#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
435#define DOCTEST_PLATFORM_MAC
436#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
437#define DOCTEST_PLATFORM_IPHONE
439#define DOCTEST_PLATFORM_WINDOWS
440#elif defined(__wasi__)
441#define DOCTEST_PLATFORM_WASI
443#define DOCTEST_PLATFORM_LINUX
450#define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \
451 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
452 static const int var = doctest::detail::consume(&var, __VA_ARGS__); \
453 DOCTEST_CLANG_SUPPRESS_WARNING_POP
455#ifndef DOCTEST_BREAK_INTO_DEBUGGER
457#ifdef DOCTEST_PLATFORM_LINUX
458#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
460#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
463#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
465#elif defined(DOCTEST_PLATFORM_MAC)
466#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
467#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
468#elif defined(__ppc__) || defined(__ppc64__)
470#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n": : : "memory","r0","r3","r4")
472#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
475#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
476#elif defined(__MINGW32__)
478extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
480#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
482#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
487#ifdef DOCTEST_CONFIG_USE_IOSFWD
488#ifndef DOCTEST_CONFIG_USE_STD_HEADERS
489#define DOCTEST_CONFIG_USE_STD_HEADERS
502#ifdef _LIBCPP_VERSION
503#ifndef DOCTEST_CONFIG_USE_STD_HEADERS
504#define DOCTEST_CONFIG_USE_STD_HEADERS
508#ifdef DOCTEST_CONFIG_USE_STD_HEADERS
509#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
510#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
525template <
class charT>
529template <
class charT,
class traits>
532template<
class traits>
535template <
class charT,
class traits>
538template <
class... Types>
540#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
544template <
class Elem,
class Traits,
class Alloc>
546using string = basic_string<char, char_traits<char>, allocator<char>>;
554#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
555#include <type_traits>
564#ifndef DOCTEST_CONFIG_STRING_SIZE_TYPE
565#define DOCTEST_CONFIG_STRING_SIZE_TYPE unsigned
611 bool isOnStack() const noexcept {
return (buf[last] & 128) == 0; }
642 const
char* c_str()
const {
return const_cast<String*
>(
this)->
c_str(); }
645 return reinterpret_cast<char*
>(buf);
659 int compare(
const char* other,
bool no_case =
false)
const;
713namespace assertType {
854 bool check(
const String& str) {
return isContains ? (content == str) : (content.string == str); }
859 } m_exception_string;
862 const char* exception_type,
const StringContains& exception_string);
886 virtual
void stringify(
std::ostream*) const = 0;
944#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
947 template <
bool COND,
typename T =
void>
950 template <
typename T>
980 template <
typename T>
985 return static_cast<T&&
>(t);
990 return static_cast<T&&
>(t);
993 template <
typename T>
997#if !DOCTEST_CLANG && defined(_MSC_VER) && _MSC_VER <= 1900
998 template <
typename T,
typename =
void>
1001 template <
typename T>
1002 struct has_global_insertion_operator<T, decltype(::operator<<(declval<std::ostream&>(), declval<const T&>()), void())> : types::true_type { };
1004 template <
typename T,
typename =
void>
1005 struct has_insertion_operator {
static DOCTEST_CONSTEXPR bool value = has_global_insertion_operator<T>::value; };
1007 template <
typename T,
bool global>
1010 template <
typename T>
1011 struct insert_hack<T, true> {
1012 static void insert(
std::ostream& os,
const T& t) { ::operator<<(os, t); }
1015 template <
typename T>
1016 struct insert_hack<T, false> {
1020 template <
typename T>
1021 using insert_hack_t = insert_hack<T, has_global_insertion_operator<T>::value>;
1023 template <
typename T,
typename =
void>
1027 template <
typename T>
1030 template <
typename T>
1040 template <
typename T>
1042#ifdef DOCTEST_CONFIG_REQUIRE_STRINGIFICATION_FOR_ALL_USED_TYPES
1049 template <
typename T>
1052 template <
typename T>
1057 template <
typename T,
size_t N>
1064 template <
typename T>
1073 template <
typename T>
1080template <
typename T>
1082 detail::has_insertion_operator<T>::value || detail::types::is_pointer<T>::value || detail::types::is_array<T>::value>
1085#ifndef DOCTEST_STRINGIFY
1086#ifdef DOCTEST_CONFIG_DOUBLE_STRINGIFY
1087#define DOCTEST_STRINGIFY(...) toString(toString(__VA_ARGS__))
1089#define DOCTEST_STRINGIFY(...) toString(__VA_ARGS__)
1093template <
typename T>
1095#if DOCTEST_CLANG == 0 && DOCTEST_GCC == 0 && DOCTEST_ICC == 0
1096 String ret = __FUNCSIG__;
1100 String ret = __PRETTY_FUNCTION__;
1102 return ret.
substr(begin, ret.
size() - begin - 1);
1106template <typename T, typename detail::types::enable_if<!detail::should_stringify_as_underlying_type<T>::value,
bool>::type =
true>
1111#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1115#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
1142template <typename T, typename detail::types::enable_if<detail::should_stringify_as_underlying_type<T>::value,
bool>::type =
true>
1149 template <
typename T>
1153#if defined(_MSC_VER) && _MSC_VER <= 1900
1154 insert_hack_t<T>::insert(*stream, in);
1156 operator<<(*stream, in);
1163 template <typename T,
size_t N>
1167 for (
size_t i = 0; i < N; i++) {
1168 if (i != 0) { *stream <<
", "; }
1182 *stream <<
String(in, in[N - 1] ? N : N - 1);
1192 template <
typename T>
1200 reinterpret_cast<const void*
>(in)
1202 *
reinterpret_cast<const void* const*
>(&in)
1216#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1217 template <
typename T>
1220 static_cast<T*
>(
nullptr)) {
1221 *
this =
static_cast<double>(
value);
1227#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1228 template <
typename T>
1229 typename std::enable_if<std::is_constructible<double, T>::value,
Approx&>::type epsilon(
1230 const T& newEpsilon) {
1231 m_epsilon =
static_cast<double>(newEpsilon);
1238#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1239 template <
typename T>
1240 typename std::enable_if<std::is_constructible<double, T>::value,
Approx&>::type scale(
1241 const T& newScale) {
1242 m_scale =
static_cast<double>(newScale);
1261#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1262#define DOCTEST_APPROX_PREFIX \
1263 template <typename T> friend typename std::enable_if<std::is_constructible<double, T>::value, bool>::type
1267 DOCTEST_APPROX_PREFIX operator!=(
const T& lhs,
const Approx& rhs) {
return !operator==(lhs, rhs); }
1268 DOCTEST_APPROX_PREFIX
operator!=(
const Approx& lhs,
const T& rhs) {
return !
operator==(rhs, lhs); }
1269 DOCTEST_APPROX_PREFIX
operator<=(
const T& lhs,
const Approx& rhs) {
return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; }
1270 DOCTEST_APPROX_PREFIX
operator<=(
const Approx& lhs,
const T& rhs) {
return lhs.m_value <
static_cast<double>(rhs) || lhs == rhs; }
1271 DOCTEST_APPROX_PREFIX
operator>=(
const T& lhs,
const Approx& rhs) {
return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; }
1272 DOCTEST_APPROX_PREFIX
operator>=(
const Approx& lhs,
const T& rhs) {
return lhs.m_value >
static_cast<double>(rhs) || lhs == rhs; }
1273 DOCTEST_APPROX_PREFIX operator< (
const T& lhs,
const Approx& rhs) {
return static_cast<double>(lhs) < rhs.m_value && lhs != rhs; }
1274 DOCTEST_APPROX_PREFIX operator< (
const Approx& lhs,
const T& rhs) {
return lhs.m_value <
static_cast<double>(rhs) && lhs != rhs; }
1275 DOCTEST_APPROX_PREFIX operator> (
const T& lhs,
const Approx& rhs) {
return static_cast<double>(lhs) > rhs.m_value && lhs != rhs; }
1276 DOCTEST_APPROX_PREFIX operator> (
const Approx& lhs,
const T& rhs) {
return lhs.m_value >
static_cast<double>(rhs) && lhs != rhs; }
1277#undef DOCTEST_APPROX_PREFIX
1291template <
typename F>
1297 operator bool()
const;
1308#ifndef DOCTEST_CONFIG_DISABLE
1312#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1313 template<
class T>
struct decay_array {
using type = T; };
1314 template<
class T,
unsigned N>
struct decay_array<T[N]> {
using type = T*; };
1315 template<
class T>
struct decay_array<T[]> {
using type = T*; };
1321 template<
class T>
struct can_use_op :
public not_char_pointer<typename decay_array<T>::type> {};
1331#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
1339 bool m_entered =
false;
1348 operator bool()
const;
1354 template <
typename L,
typename R>
1360#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
1369#define SFINAE_OP(ret,op) ret
1371#define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op doctest::detail::declval<R>()),ret{})
1374#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
1375 template <typename R> \
1376 DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \
1377 bool res = op_macro(doctest::detail::forward<const L>(lhs), doctest::detail::forward<R>(rhs)); \
1378 if(m_at & assertType::is_false) \
1380 if(!res || doctest::getContextOptions()->success) \
1381 return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \
1382 return Result(res); \
1388#define DOCTEST_FORBIT_EXPRESSION(rt, op) \
1389 template <typename R> \
1390 rt& operator op(const R&) { \
1391 static_assert(deferred_false<R>::value, \
1392 "Expression Too Complex Please Rewrite As Binary Comparison!"); \
1429#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1455#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1456#define DOCTEST_COMPARISON_RETURN_TYPE bool
1458#define DOCTEST_COMPARISON_RETURN_TYPE typename types::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
1459 inline bool eq(
const char* lhs,
const char* rhs) {
return String(lhs) == String(rhs); }
1460 inline bool ne(
const char* lhs,
const char* rhs) {
return String(lhs) != String(rhs); }
1461 inline bool lt(
const char* lhs,
const char* rhs) {
return String(lhs) < String(rhs); }
1462 inline bool gt(
const char* lhs,
const char* rhs) {
return String(lhs) > String(rhs); }
1463 inline bool le(
const char* lhs,
const char* rhs) {
return String(lhs) <= String(rhs); }
1464 inline bool ge(
const char* lhs,
const char* rhs) {
return String(lhs) >= String(rhs); }
1468#define DOCTEST_RELATIONAL_OP(name, op) \
1469 template <typename L, typename R> \
1470 DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \
1471 const DOCTEST_REF_WRAP(R) rhs) { \
1472 return lhs op rhs; \
1482#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1483#define DOCTEST_CMP_EQ(l, r) l == r
1484#define DOCTEST_CMP_NE(l, r) l != r
1485#define DOCTEST_CMP_GT(l, r) l > r
1486#define DOCTEST_CMP_LT(l, r) l < r
1487#define DOCTEST_CMP_GE(l, r) l >= r
1488#define DOCTEST_CMP_LE(l, r) l <= r
1490#define DOCTEST_CMP_EQ(l, r) eq(l, r)
1491#define DOCTEST_CMP_NE(l, r) ne(l, r)
1492#define DOCTEST_CMP_GT(l, r) gt(l, r)
1493#define DOCTEST_CMP_LT(l, r) lt(l, r)
1494#define DOCTEST_CMP_GE(l, r) ge(l, r)
1495#define DOCTEST_CMP_LE(l, r) le(l, r)
1498 template <
typename L>
1506 : lhs(static_cast<L&&>(in))
1512 bool res =
static_cast<bool>(lhs);
1514 if(m_at & assertType::is_false) {
1525 operator L()
const {
return lhs; }
1559#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1567#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
1581 template <
typename L>
1586 template <typename L,typename types::enable_if<!doctest::detail::types::is_rvalue_reference<L>::value,
void >::type* =
nullptr>
1594 const char* m_test_suite =
nullptr;
1595 const char* m_description =
nullptr;
1596 bool m_skip =
false;
1597 bool m_no_breaks =
false;
1598 bool m_no_output =
false;
1599 bool m_may_fail =
false;
1600 bool m_should_fail =
false;
1601 int m_expected_failures = 0;
1602 double m_timeout = 0;
1606 template <
typename T>
1637 template <typename T>
1653 template<
typename T>
1656 namespace binaryAssertComparison {
1671#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \
1672 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); } };
1685 const char* exception_type =
"",
const String& exception_string =
"");
1688 const char* exception_type,
const Contains& exception_string);
1692 template <
int comparison,
typename L,
typename R>
1702 template <
typename L>
1706 if (m_at & assertType::is_false) {
1707 m_failed = !m_failed;
1723 namespace assertAction {
1737#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \
1739 if(!is_running_in_test) { \
1741 ResultBuilder rb(at, file, line, expr); \
1742 rb.m_failed = failed; \
1743 rb.m_decomp = decomp; \
1744 failed_out_of_a_testing_context(rb); \
1745 if(isDebuggerActive() && !getContextOptions()->no_breaks) \
1746 DOCTEST_BREAK_INTO_DEBUGGER(); \
1747 if(checkIfShouldThrow(at)) \
1754#define DOCTEST_ASSERT_IN_TESTS(decomp) \
1755 ResultBuilder rb(at, file, line, expr); \
1756 rb.m_failed = failed; \
1757 if(rb.m_failed || getContextOptions()->success) \
1758 rb.m_decomp = decomp; \
1760 DOCTEST_BREAK_INTO_DEBUGGER(); \
1761 if(rb.m_failed && checkIfShouldThrow(at)) \
1764 template <
int comparison,
typename L,
typename R>
1779 template <
typename L>
1784 if(at & assertType::is_false)
1802 template <typename T>
1807 : m_translateFunction(translateFunction) {}
1810#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
1814 }
catch(
const T& ex) {
1815 res = m_translateFunction(ex);
1819 static_cast<void>(res);
1844 bool need_to_destroy{
true};
1864 if (need_to_destroy) {
1873 bool logged =
false;
1887 template <typename T>
1895 template <
typename T>
1902 template <
typename T>
1909 template <
typename L>
1915#define DOCTEST_DEFINE_DECORATOR(name, type, def) \
1919 name(type in = def) \
1921 void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \
1922 void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \
1935template <
typename T>
1940 detail::registerExceptionTranslatorImpl(&exceptionTranslator);
1954template <
typename T>
1955int registerExceptionTranslator(String (*)(T)) {
1962 struct ContextState;
1967 detail::ContextState*
p;
1969 void parseArgs(
int argc,
const char*
const* argv,
bool withDefaults =
false);
1972 explicit Context(
int argc = 0,
const char*
const* argv =
nullptr);
2001namespace TestCaseFailureReason {
2047 unsigned num_data = 0;
2091 static
int get_num_active_contexts();
2095 static
int get_num_stringified_contexts();
2096 static const
String* get_stringified_contexts();
2104 template <
typename Reporter>
2106 return new Reporter(o);
2110template <
typename Reporter>
2112 detail::registerReporterImpl(
name,
priority, detail::reporterCreator<Reporter>, isReporter);
2117#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
2118#define DOCTEST_FUNC_EMPTY [] { return false; }()
2120#define DOCTEST_FUNC_EMPTY (void)0
2124#ifndef DOCTEST_CONFIG_DISABLE
2126#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
2127#define DOCTEST_FUNC_SCOPE_BEGIN [&]
2128#define DOCTEST_FUNC_SCOPE_END ()
2129#define DOCTEST_FUNC_SCOPE_RET(v) return v
2131#define DOCTEST_FUNC_SCOPE_BEGIN do
2132#define DOCTEST_FUNC_SCOPE_END while(false)
2133#define DOCTEST_FUNC_SCOPE_RET(v) (void)0
2137#define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \
2138 if(b.log()) DOCTEST_BREAK_INTO_DEBUGGER(); \
2140 DOCTEST_FUNC_SCOPE_RET(!b.m_failed)
2142#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
2143#define DOCTEST_WRAP_IN_TRY(x) x;
2145#define DOCTEST_WRAP_IN_TRY(x) \
2148 } catch(...) { DOCTEST_RB.translateException(); }
2151#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
2152#define DOCTEST_CAST_TO_VOID(...) \
2153 DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \
2154 static_cast<void>(__VA_ARGS__); \
2155 DOCTEST_GCC_SUPPRESS_WARNING_POP
2157#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
2161#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \
2162 global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
2163 doctest::detail::regTest( \
2164 doctest::detail::TestCase( \
2165 f, __FILE__, __LINE__, \
2166 doctest_detail_test_suite_ns::getCurrentTestSuite()) * \
2169#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \
2171 struct der : public base \
2175 static DOCTEST_INLINE_NOINLINE void func() { \
2179 DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \
2181 DOCTEST_INLINE_NOINLINE void der::f()
2183#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \
2185 DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \
2188#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \
2189 static doctest::detail::funcType proxy() { return f; } \
2190 DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \
2194#define DOCTEST_TEST_CASE(decorators) \
2195 DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
2198#if DOCTEST_CPLUSPLUS >= 201703L
2199#define DOCTEST_TEST_CASE_CLASS(decorators) \
2200 DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \
2201 DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \
2204#define DOCTEST_TEST_CASE_CLASS(...) \
2205 TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER
2209#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \
2210 DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c, \
2211 DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
2214#define DOCTEST_TYPE_TO_STRING_AS(str, ...) \
2215 namespace doctest { \
2217 inline String toString<__VA_ARGS__>() { \
2221 static_assert(true, "")
2223#define DOCTEST_TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING_AS(#__VA_ARGS__, __VA_ARGS__)
2225#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
2226 template <typename T> \
2227 static void func(); \
2229 template <typename Tuple> \
2231 template <typename Type, typename... Rest> \
2232 struct iter<std::tuple<Type, Rest...>> \
2234 iter(const char* file, unsigned line, int index) { \
2235 doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
2236 doctest_detail_test_suite_ns::getCurrentTestSuite(), \
2237 doctest::toString<Type>(), \
2238 int(line) * 1000 + index) \
2240 iter<std::tuple<Rest...>>(file, line, index + 1); \
2244 struct iter<std::tuple<>> \
2246 iter(const char*, unsigned, int) {} \
2249 template <typename T> \
2252#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \
2253 DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
2254 DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))
2256#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
2257 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY), \
2258 doctest::detail::instantiationHelper( \
2259 DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0)))
2261#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
2262 DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
2263 static_assert(true, "")
2265#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
2266 DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
2267 static_assert(true, "")
2269#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
2270 DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
2271 DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
2272 template <typename T> \
2275#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \
2276 DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)
2279#define DOCTEST_SUBCASE(name) \
2280 if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
2281 doctest::detail::Subcase(name, __FILE__, __LINE__))
2284#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \
2285 namespace ns_name { namespace doctest_detail_test_suite_ns { \
2286 static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() noexcept { \
2287 DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
2288 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
2289 DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
2290 static doctest::detail::TestSuite data{}; \
2291 static bool inited = false; \
2292 DOCTEST_MSVC_SUPPRESS_WARNING_POP \
2293 DOCTEST_CLANG_SUPPRESS_WARNING_POP \
2294 DOCTEST_GCC_SUPPRESS_WARNING_POP \
2305#define DOCTEST_TEST_SUITE(decorators) \
2306 DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))
2309#define DOCTEST_TEST_SUITE_BEGIN(decorators) \
2310 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
2311 doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \
2312 static_assert(true, "")
2315#define DOCTEST_TEST_SUITE_END \
2316 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
2317 doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \
2318 using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
2321#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \
2322 inline doctest::String translatorName(signature); \
2323 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
2324 doctest::registerExceptionTranslator(translatorName)) \
2325 doctest::String translatorName(signature)
2327#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
2328 DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
2332#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \
2333 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), \
2334 doctest::registerReporter<reporter>(name, priority, true)) \
2335 static_assert(true, "")
2338#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \
2339 DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), \
2340 doctest::registerReporter<reporter>(name, priority, false)) \
2341 static_assert(true, "")
2345#define DOCTEST_INFO(...) \
2346 DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \
2347 DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \
2351#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
2352 auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \
2353 [&](std::ostream* s_name) { \
2354 doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
2355 mb_name.m_stream = s_name; \
2356 mb_name * __VA_ARGS__; \
2359#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
2361#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
2362 DOCTEST_FUNC_SCOPE_BEGIN { \
2363 doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
2366 DOCTEST_BREAK_INTO_DEBUGGER(); \
2368 } DOCTEST_FUNC_SCOPE_END
2371#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2372#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2373#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2376#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
2377#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
2378#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
2380#define DOCTEST_TO_LVALUE(...) __VA_ARGS__
2382#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
2384#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \
2385 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
2387 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2388 __LINE__, #__VA_ARGS__); \
2389 DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \
2390 doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
2392 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \
2393 DOCTEST_CLANG_SUPPRESS_WARNING_POP
2395#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
2396 DOCTEST_FUNC_SCOPE_BEGIN { \
2397 DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
2398 } DOCTEST_FUNC_SCOPE_END
2400#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \
2401 DOCTEST_FUNC_SCOPE_BEGIN { \
2402 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2403 __LINE__, #__VA_ARGS__); \
2404 DOCTEST_WRAP_IN_TRY( \
2405 DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
2407 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2408 } DOCTEST_FUNC_SCOPE_END
2410#define DOCTEST_UNARY_ASSERT(assert_type, ...) \
2411 DOCTEST_FUNC_SCOPE_BEGIN { \
2412 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2413 __LINE__, #__VA_ARGS__); \
2414 DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \
2415 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2416 } DOCTEST_FUNC_SCOPE_END
2421#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1
2423#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
2424 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
2425 doctest::detail::decomp_assert( \
2426 doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \
2427 doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
2428 << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP
2430#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \
2431 doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>( \
2432 doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)
2434#define DOCTEST_UNARY_ASSERT(assert_type, ...) \
2435 doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \
2436 #__VA_ARGS__, __VA_ARGS__)
2440#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)
2441#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)
2442#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)
2443#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)
2444#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)
2445#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
2448#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } DOCTEST_FUNC_SCOPE_END
2449#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } DOCTEST_FUNC_SCOPE_END
2450#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } DOCTEST_FUNC_SCOPE_END
2451#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2452#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2453#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2456#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)
2457#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)
2458#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)
2459#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)
2460#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)
2461#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)
2462#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)
2463#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)
2464#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)
2465#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)
2466#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)
2467#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)
2468#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)
2469#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)
2470#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)
2471#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)
2472#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)
2473#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)
2475#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)
2476#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)
2477#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)
2478#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)
2479#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)
2480#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)
2482#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2484#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
2485 DOCTEST_FUNC_SCOPE_BEGIN { \
2486 if(!doctest::getContextOptions()->no_throw) { \
2487 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2488 __LINE__, #expr, #__VA_ARGS__, message); \
2490 DOCTEST_CAST_TO_VOID(expr) \
2491 } catch(const typename doctest::detail::types::remove_const< \
2492 typename doctest::detail::types::remove_reference<__VA_ARGS__>::type>::type&) {\
2493 DOCTEST_RB.translateException(); \
2494 DOCTEST_RB.m_threw_as = true; \
2495 } catch(...) { DOCTEST_RB.translateException(); } \
2496 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2498 DOCTEST_FUNC_SCOPE_RET(false); \
2500 } DOCTEST_FUNC_SCOPE_END
2502#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \
2503 DOCTEST_FUNC_SCOPE_BEGIN { \
2504 if(!doctest::getContextOptions()->no_throw) { \
2505 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2506 __LINE__, expr_str, "", __VA_ARGS__); \
2508 DOCTEST_CAST_TO_VOID(expr) \
2509 } catch(...) { DOCTEST_RB.translateException(); } \
2510 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2512 DOCTEST_FUNC_SCOPE_RET(false); \
2514 } DOCTEST_FUNC_SCOPE_END
2516#define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \
2517 DOCTEST_FUNC_SCOPE_BEGIN { \
2518 doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2519 __LINE__, #__VA_ARGS__); \
2521 DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
2522 } catch(...) { DOCTEST_RB.translateException(); } \
2523 DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2524 } DOCTEST_FUNC_SCOPE_END
2527#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
2528#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
2529#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")
2531#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
2532#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
2533#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)
2535#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
2536#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
2537#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)
2539#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
2540#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
2541#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)
2543#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
2544#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
2545#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
2547#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2548#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2549#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2550#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2551#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2552#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2553#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2554#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2555#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2556#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2557#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2558#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2559#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2560#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2561#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2572#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
2574 template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2575 struct der : public base \
2578 template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2579 inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()
2581#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
2582 template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2583 static inline void f()
2586#define DOCTEST_TEST_CASE(name) \
2587 DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2590#define DOCTEST_TEST_CASE_CLASS(name) \
2591 DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2594#define DOCTEST_TEST_CASE_FIXTURE(x, name) \
2595 DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x, \
2596 DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2599#define DOCTEST_TYPE_TO_STRING_AS(str, ...) static_assert(true, "")
2600#define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "")
2603#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \
2604 template <typename type> \
2605 inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
2607#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \
2608 template <typename type> \
2609 inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
2611#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "")
2612#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "")
2615#define DOCTEST_SUBCASE(name)
2618#define DOCTEST_TEST_SUITE(name) namespace
2621#define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "")
2624#define DOCTEST_TEST_SUITE_END using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
2626#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
2627 template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2628 static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)
2630#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
2631#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
2633#define DOCTEST_INFO(...) (static_cast<void>(0))
2634#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
2635#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
2636#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
2637#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
2638#define DOCTEST_MESSAGE(...) (static_cast<void>(0))
2639#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
2640#define DOCTEST_FAIL(...) (static_cast<void>(0))
2642#if defined(DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED) \
2643 && defined(DOCTEST_CONFIG_ASSERTS_RETURN_VALUES)
2645#define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }()
2646#define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }()
2647#define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }()
2648#define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }()
2649#define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }()
2650#define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }()
2652#define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }()
2653#define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }()
2654#define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }()
2655#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2656#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2657#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2661#define DOCTEST_RELATIONAL_OP(name, op) \
2662 template <typename L, typename R> \
2663 bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; }
2674#define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2675#define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2676#define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2677#define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2678#define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2679#define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2680#define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2681#define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2682#define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2683#define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2684#define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2685#define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2686#define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2687#define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2688#define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2689#define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2690#define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2691#define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2692#define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }()
2693#define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }()
2694#define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }()
2695#define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2696#define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2697#define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2699#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2701#define DOCTEST_WARN_THROWS_WITH(expr, with, ...) [] { static_assert(false, "Exception translation is not available when doctest is disabled."); return false; }()
2702#define DOCTEST_CHECK_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2703#define DOCTEST_REQUIRE_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2704#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2705#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2706#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2708#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2709#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2710#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2711#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2712#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2713#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2715#define DOCTEST_WARN_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2716#define DOCTEST_CHECK_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2717#define DOCTEST_REQUIRE_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2718#define DOCTEST_WARN_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2719#define DOCTEST_CHECK_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2720#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2721#define DOCTEST_WARN_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2722#define DOCTEST_CHECK_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2723#define DOCTEST_REQUIRE_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2725#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2726#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2727#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2728#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2729#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2730#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2731#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2732#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2733#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2739#define DOCTEST_WARN(...) DOCTEST_FUNC_EMPTY
2740#define DOCTEST_CHECK(...) DOCTEST_FUNC_EMPTY
2741#define DOCTEST_REQUIRE(...) DOCTEST_FUNC_EMPTY
2742#define DOCTEST_WARN_FALSE(...) DOCTEST_FUNC_EMPTY
2743#define DOCTEST_CHECK_FALSE(...) DOCTEST_FUNC_EMPTY
2744#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_FUNC_EMPTY
2746#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2747#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2748#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2749#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2750#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2751#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2753#define DOCTEST_WARN_EQ(...) DOCTEST_FUNC_EMPTY
2754#define DOCTEST_CHECK_EQ(...) DOCTEST_FUNC_EMPTY
2755#define DOCTEST_REQUIRE_EQ(...) DOCTEST_FUNC_EMPTY
2756#define DOCTEST_WARN_NE(...) DOCTEST_FUNC_EMPTY
2757#define DOCTEST_CHECK_NE(...) DOCTEST_FUNC_EMPTY
2758#define DOCTEST_REQUIRE_NE(...) DOCTEST_FUNC_EMPTY
2759#define DOCTEST_WARN_GT(...) DOCTEST_FUNC_EMPTY
2760#define DOCTEST_CHECK_GT(...) DOCTEST_FUNC_EMPTY
2761#define DOCTEST_REQUIRE_GT(...) DOCTEST_FUNC_EMPTY
2762#define DOCTEST_WARN_LT(...) DOCTEST_FUNC_EMPTY
2763#define DOCTEST_CHECK_LT(...) DOCTEST_FUNC_EMPTY
2764#define DOCTEST_REQUIRE_LT(...) DOCTEST_FUNC_EMPTY
2765#define DOCTEST_WARN_GE(...) DOCTEST_FUNC_EMPTY
2766#define DOCTEST_CHECK_GE(...) DOCTEST_FUNC_EMPTY
2767#define DOCTEST_REQUIRE_GE(...) DOCTEST_FUNC_EMPTY
2768#define DOCTEST_WARN_LE(...) DOCTEST_FUNC_EMPTY
2769#define DOCTEST_CHECK_LE(...) DOCTEST_FUNC_EMPTY
2770#define DOCTEST_REQUIRE_LE(...) DOCTEST_FUNC_EMPTY
2772#define DOCTEST_WARN_UNARY(...) DOCTEST_FUNC_EMPTY
2773#define DOCTEST_CHECK_UNARY(...) DOCTEST_FUNC_EMPTY
2774#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_FUNC_EMPTY
2775#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2776#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2777#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2779#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2781#define DOCTEST_WARN_THROWS(...) DOCTEST_FUNC_EMPTY
2782#define DOCTEST_CHECK_THROWS(...) DOCTEST_FUNC_EMPTY
2783#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_FUNC_EMPTY
2784#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2785#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2786#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2787#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2788#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2789#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2790#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2791#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2792#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2793#define DOCTEST_WARN_NOTHROW(...) DOCTEST_FUNC_EMPTY
2794#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_FUNC_EMPTY
2795#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_FUNC_EMPTY
2797#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2798#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2799#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2800#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2801#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2802#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2803#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2804#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2805#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2806#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2807#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2808#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2809#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2810#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2811#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2819#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS
2821#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
2822#define DOCTEST_EXCEPTION_EMPTY_FUNC DOCTEST_FUNC_EMPTY
2824#define DOCTEST_EXCEPTION_EMPTY_FUNC [] { static_assert(false, "Exceptions are disabled! " \
2825 "Use DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS if you want to compile with exceptions disabled."); return false; }()
2827#undef DOCTEST_REQUIRE
2828#undef DOCTEST_REQUIRE_FALSE
2829#undef DOCTEST_REQUIRE_MESSAGE
2830#undef DOCTEST_REQUIRE_FALSE_MESSAGE
2831#undef DOCTEST_REQUIRE_EQ
2832#undef DOCTEST_REQUIRE_NE
2833#undef DOCTEST_REQUIRE_GT
2834#undef DOCTEST_REQUIRE_LT
2835#undef DOCTEST_REQUIRE_GE
2836#undef DOCTEST_REQUIRE_LE
2837#undef DOCTEST_REQUIRE_UNARY
2838#undef DOCTEST_REQUIRE_UNARY_FALSE
2840#define DOCTEST_REQUIRE DOCTEST_EXCEPTION_EMPTY_FUNC
2841#define DOCTEST_REQUIRE_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
2842#define DOCTEST_REQUIRE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
2843#define DOCTEST_REQUIRE_FALSE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
2844#define DOCTEST_REQUIRE_EQ DOCTEST_EXCEPTION_EMPTY_FUNC
2845#define DOCTEST_REQUIRE_NE DOCTEST_EXCEPTION_EMPTY_FUNC
2846#define DOCTEST_REQUIRE_GT DOCTEST_EXCEPTION_EMPTY_FUNC
2847#define DOCTEST_REQUIRE_LT DOCTEST_EXCEPTION_EMPTY_FUNC
2848#define DOCTEST_REQUIRE_GE DOCTEST_EXCEPTION_EMPTY_FUNC
2849#define DOCTEST_REQUIRE_LE DOCTEST_EXCEPTION_EMPTY_FUNC
2850#define DOCTEST_REQUIRE_UNARY DOCTEST_EXCEPTION_EMPTY_FUNC
2851#define DOCTEST_REQUIRE_UNARY_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
2855#define DOCTEST_WARN_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2856#define DOCTEST_CHECK_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2857#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2858#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2859#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2860#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2861#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2862#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2863#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2864#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2865#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2866#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2867#define DOCTEST_WARN_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2868#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2869#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2871#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2872#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2873#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2874#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2875#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2876#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2877#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2878#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2879#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2880#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2881#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2882#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2883#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2884#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2885#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2891#define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ
2892#define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ
2893#define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ
2894#define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE
2895#define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE
2896#define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE
2897#define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT
2898#define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT
2899#define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT
2900#define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT
2901#define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT
2902#define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT
2903#define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE
2904#define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE
2905#define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE
2906#define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE
2907#define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE
2908#define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE
2910#define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY
2911#define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY
2912#define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY
2913#define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE
2914#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
2915#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
2917#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
2922#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name)
2923#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name)
2924#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__)
2925#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id)
2927#define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name)
2928#define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name)
2929#define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name)
2930#define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name)
2931#define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name)
2935#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
2937#define TEST_CASE(name) DOCTEST_TEST_CASE(name)
2938#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)
2939#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
2940#define TYPE_TO_STRING_AS(str, ...) DOCTEST_TYPE_TO_STRING_AS(str, __VA_ARGS__)
2941#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
2942#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
2943#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
2944#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
2945#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
2946#define SUBCASE(name) DOCTEST_SUBCASE(name)
2947#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)
2948#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)
2949#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
2950#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
2951#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
2952#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
2953#define INFO(...) DOCTEST_INFO(__VA_ARGS__)
2954#define CAPTURE(x) DOCTEST_CAPTURE(x)
2955#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
2956#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
2957#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
2958#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)
2959#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
2960#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)
2961#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
2963#define WARN(...) DOCTEST_WARN(__VA_ARGS__)
2964#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
2965#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
2966#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
2967#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
2968#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2969#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
2970#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)
2971#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
2972#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
2973#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
2974#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
2975#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2976#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
2977#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)
2978#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
2979#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
2980#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
2981#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
2982#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2983#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
2985#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
2986#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
2987#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
2988#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
2989#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
2990#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
2991#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
2992#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
2993#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
2994#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
2995#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
2996#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
2997#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
2998#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
2999#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
3000#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
3001#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
3002#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
3003#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
3004#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
3005#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
3007#define SCENARIO(name) DOCTEST_SCENARIO(name)
3008#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)
3009#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
3010#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
3011#define GIVEN(name) DOCTEST_GIVEN(name)
3012#define WHEN(name) DOCTEST_WHEN(name)
3013#define AND_WHEN(name) DOCTEST_AND_WHEN(name)
3014#define THEN(name) DOCTEST_THEN(name)
3015#define AND_THEN(name) DOCTEST_AND_THEN(name)
3017#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)
3018#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
3019#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
3020#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)
3021#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)
3022#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
3023#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)
3024#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)
3025#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
3026#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)
3027#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)
3028#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
3029#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)
3030#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)
3031#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
3032#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)
3033#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)
3034#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
3035#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
3036#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
3037#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
3038#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
3039#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
3040#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
3043#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
3044#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
3045#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
3046#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
3047#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
3048#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
3049#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
3050#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
3051#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
3052#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
3053#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
3054#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
3055#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
3056#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
3057#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
3058#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
3059#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
3060#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
3062#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
3063#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
3064#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
3065#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
3066#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
3067#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
3069#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
3073#ifndef DOCTEST_CONFIG_DISABLE
3088#ifndef DOCTEST_SINGLE_HEADER
3089#define DOCTEST_SINGLE_HEADER
3092#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)
3094#ifndef DOCTEST_SINGLE_HEADER
3095#include "doctest_fwd.h"
3100#ifndef DOCTEST_LIBRARY_IMPLEMENTATION
3101#define DOCTEST_LIBRARY_IMPLEMENTATION
3165#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3171#ifndef DOCTEST_CONFIG_NO_MULTITHREADING
3174#define DOCTEST_DECLARE_MUTEX(name) std::mutex name;
3175#define DOCTEST_DECLARE_STATIC_MUTEX(name) static DOCTEST_DECLARE_MUTEX(name)
3176#define DOCTEST_LOCK_MUTEX(name) std::lock_guard<std::mutex> DOCTEST_ANONYMOUS(DOCTEST_ANON_LOCK_)(name);
3178#define DOCTEST_DECLARE_MUTEX(name)
3179#define DOCTEST_DECLARE_STATIC_MUTEX(name)
3180#define DOCTEST_LOCK_MUTEX(name)
3184#include <unordered_set>
3193#ifdef DOCTEST_PLATFORM_MAC
3194#include <sys/types.h>
3196#include <sys/sysctl.h>
3199#ifdef DOCTEST_PLATFORM_WINDOWS
3202#ifndef WIN32_LEAN_AND_MEAN
3203#define WIN32_LEAN_AND_MEAN
3204#define DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
3208#define DOCTEST_UNDEF_NOMINMAX
3221#include <sys/time.h>
3228#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
3229#define STDOUT_FILENO fileno(stdout)
3235#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
3237#ifdef DOCTEST_CONFIG_DISABLE
3238#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled
3240#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled
3243#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX
3244#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-"
3247#ifndef DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR
3248#define DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR ':'
3251#ifndef DOCTEST_THREAD_LOCAL
3252#if defined(DOCTEST_CONFIG_NO_MULTITHREADING) || DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
3253#define DOCTEST_THREAD_LOCAL
3255#define DOCTEST_THREAD_LOCAL thread_local
3259#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
3260#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
3263#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
3264#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
3267#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
3268#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
3270#define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
3273#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
3274#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
3277#ifndef DOCTEST_CDECL
3278#define DOCTEST_CDECL __cdecl
3283bool is_running_in_test =
false;
3286 using namespace detail;
3288 template <
typename Ex>
3290#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
3293#ifdef DOCTEST_CONFIG_HANDLE_EXCEPTION
3294 DOCTEST_CONFIG_HANDLE_EXCEPTION(e);
3296#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3297 std::cerr <<
"doctest will terminate because it needed to throw an exception.\n"
3298 <<
"The message was: " << e.what() <<
'\n';
3305#ifndef DOCTEST_INTERNAL_ERROR
3306#define DOCTEST_INTERNAL_ERROR(msg) \
3307 throw_exception(std::logic_error( \
3308 __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
3312 int stricmp(
const char*
a,
const char* b) {
3314 const int d = tolower(*
a) - tolower(*b);
3328 static Arch which() {
3331 auto ptr =
reinterpret_cast<char*
>(&x);
3340 DOCTEST_THREAD_LOCAL
class
3342 std::vector<std::streampos> stack;
3343 std::stringstream ss;
3347 stack.push_back(ss.tellp());
3353 DOCTEST_INTERNAL_ERROR(
"TLSS was empty when trying to pop!");
3355 std::streampos pos = stack.back();
3357 unsigned sz =
static_cast<unsigned>(ss.tellp() - pos);
3358 ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out);
3359 return String(ss, sz);
3364 return g_oss.push();
3371#ifndef DOCTEST_CONFIG_DISABLE
3373namespace timer_large_integer
3376#if defined(DOCTEST_PLATFORM_WINDOWS)
3377 using type = ULONGLONG;
3379 using type = std::uint64_t;
3383using ticks_t = timer_large_integer::type;
3385#ifdef DOCTEST_CONFIG_GETCURRENTTICKS
3386 ticks_t getCurrentTicks() {
return DOCTEST_CONFIG_GETCURRENTTICKS(); }
3387#elif defined(DOCTEST_PLATFORM_WINDOWS)
3388 ticks_t getCurrentTicks() {
3389 static LARGE_INTEGER hz = { {0} }, hzo = { {0} };
3391 QueryPerformanceFrequency(&hz);
3392 QueryPerformanceCounter(&hzo);
3395 QueryPerformanceCounter(&t);
3396 return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
3399 ticks_t getCurrentTicks() {
3401 gettimeofday(&t,
nullptr);
3402 return static_cast<ticks_t
>(t.tv_sec) * 1000000 +
static_cast<ticks_t
>(t.tv_usec);
3408 void start() { m_ticks = getCurrentTicks(); }
3409 unsigned int getElapsedMicroseconds()
const {
3410 return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
3415 double getElapsedSeconds()
const {
return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }
3418 ticks_t m_ticks = 0;
3421#ifdef DOCTEST_CONFIG_NO_MULTITHREADING
3422 template <
typename T>
3425 template <
typename T>
3426 using Atomic = std::atomic<T>;
3429#if defined(DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) || defined(DOCTEST_CONFIG_NO_MULTITHREADING)
3430 template <
typename T>
3431 using MultiLaneAtomic = Atomic<T>;
3443 template <
typename T>
3444 class MultiLaneAtomic
3446 struct CacheLineAlignedAtomic
3449 char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE -
sizeof(Atomic<T>)];
3451 CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];
3453 static_assert(
sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
3454 "guarantee one atomic takes exactly one cache line");
3461 T fetch_add(T
arg, std::memory_order order = std::memory_order_seq_cst)
DOCTEST_NOEXCEPT {
3462 return myAtomic().fetch_add(
arg, order);
3465 T fetch_sub(T
arg, std::memory_order order = std::memory_order_seq_cst)
DOCTEST_NOEXCEPT {
3466 return myAtomic().fetch_sub(
arg, order);
3471 T load(std::memory_order order = std::memory_order_seq_cst)
const DOCTEST_NOEXCEPT {
3473 for(
auto const& c : m_atomics) {
3474 result += c.atomic.load(order);
3484 void store(T desired, std::memory_order order = std::memory_order_seq_cst)
DOCTEST_NOEXCEPT {
3486 for(
auto& c : m_atomics) {
3487 c.atomic.store(desired, order);
3506 static Atomic<size_t> laneCounter;
3507 DOCTEST_THREAD_LOCAL
size_t tlsLaneIdx =
3508 laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;
3510 return m_atomics[tlsLaneIdx].atomic;
3516 struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
3518 MultiLaneAtomic<int> numAssertsCurrentTest_atomic;
3519 MultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;
3521 std::vector<std::vector<String>> filters =
decltype(filters)(9);
3523 std::vector<IReporter*> reporters_currently_used;
3525 assert_handler
ah =
nullptr;
3529 std::vector<String> stringifiedContexts;
3533 std::vector<SubcaseSignature> subcaseStack;
3534 std::vector<SubcaseSignature> nextSubcaseStack;
3535 std::unordered_set<unsigned long long> fullyTraversedSubcases;
3536 size_t currentSubcaseDepth;
3537 Atomic<bool> shouldLogCurrentException;
3539 void resetRunData() {
3541 numTestCasesPassingFilters = 0;
3542 numTestSuitesPassingFilters = 0;
3543 numTestCasesFailed = 0;
3545 numAssertsFailed = 0;
3546 numAssertsCurrentTest = 0;
3547 numAssertsFailedCurrentTest = 0;
3550 void finalizeTestCaseData() {
3551 seconds = timer.getElapsedSeconds();
3554 numAsserts += numAssertsCurrentTest_atomic;
3555 numAssertsFailed += numAssertsFailedCurrentTest_atomic;
3556 numAssertsCurrentTest = numAssertsCurrentTest_atomic;
3557 numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;
3559 if(numAssertsFailedCurrentTest)
3560 failure_flags |= TestCaseFailureReason::AssertFailure;
3562 if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&
3563 Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)
3564 failure_flags |= TestCaseFailureReason::Timeout;
3566 if(currentTest->m_should_fail) {
3568 failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid;
3570 failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt;
3572 }
else if(failure_flags && currentTest->m_may_fail) {
3573 failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid;
3574 }
else if(currentTest->m_expected_failures > 0) {
3575 if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {
3576 failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes;
3578 failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes;
3582 bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||
3583 (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) ||
3584 (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags);
3587 testCaseSuccess = !(failure_flags && !ok_to_fail);
3588 if(!testCaseSuccess)
3589 numTestCasesFailed++;
3593 ContextState* g_cs =
nullptr;
3598 DOCTEST_THREAD_LOCAL
bool g_no_colors;
3603char* String::allocate(size_type sz) {
3611 data.capacity = data.size + 1;
3612 data.ptr =
new char[data.capacity];
3613 data.ptr[sz] =
'\0';
3618void String::setOnHeap()
noexcept { *
reinterpret_cast<unsigned char*
>(&buf[last]) = 128; }
3619void String::setLast(size_type in)
noexcept { buf[last] = char(in); }
3620void String::setSize(size_type sz)
noexcept {
3621 if (isOnStack()) { buf[sz] =
'\0'; setLast(last - sz); }
3622 else { data.ptr[sz] =
'\0'; data.size = sz; }
3625void String::copy(
const String& other) {
3626 if(other.isOnStack()) {
3627 memcpy(buf, other.buf, len);
3629 memcpy(allocate(other.data.size), other.data.ptr, other.data.size);
3633String::String()
noexcept {
3643String::String(
const char* in)
3644 : String(in, strlen(in)) {}
3646String::String(
const char* in, size_type in_size) {
3647 memcpy(allocate(in_size), in, in_size);
3651 in.read(allocate(in_size), in_size);
3654String::String(
const String& other) { copy(other); }
3656String& String::operator=(
const String& other) {
3657 if(
this != &other) {
3667String& String::operator+=(
const String& other) {
3668 const size_type my_old_size = size();
3669 const size_type other_size = other.size();
3670 const size_type total_size = my_old_size + other_size;
3672 if(total_size < len) {
3674 memcpy(buf + my_old_size, other.c_str(), other_size + 1);
3676 setLast(last - total_size);
3679 char* temp =
new char[total_size + 1];
3681 memcpy(temp, buf, my_old_size);
3684 data.size = total_size;
3685 data.capacity = data.size + 1;
3688 memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3691 if(data.capacity > total_size) {
3693 data.size = total_size;
3694 memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3698 if(data.capacity <= total_size)
3699 data.capacity = total_size + 1;
3701 char* temp =
new char[data.capacity];
3703 memcpy(temp, data.ptr, my_old_size);
3707 data.size = total_size;
3710 memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3717String::String(String&& other)
noexcept {
3718 memcpy(buf, other.buf, len);
3719 other.buf[0] =
'\0';
3723String& String::operator=(String&& other)
noexcept {
3724 if(
this != &other) {
3727 memcpy(buf, other.buf, len);
3728 other.buf[0] =
'\0';
3734char String::operator[](size_type i)
const {
3735 return const_cast<String*
>(
this)->
operator[](i);
3738char& String::operator[](size_type i) {
3740 return reinterpret_cast<char*
>(buf)[i];
3745String::size_type String::size()
const {
3747 return last - (size_type(buf[last]) & 31);
3752String::size_type String::capacity()
const {
3755 return data.capacity;
3758String String::substr(size_type pos, size_type cnt) && {
3759 cnt = std::min(cnt, size() - pos);
3760 char* cptr = c_str();
3761 memmove(cptr, cptr + pos, cnt);
3763 return std::move(*
this);
3766String String::substr(size_type pos, size_type cnt)
const & {
3767 cnt = std::min(cnt, size() - pos);
3768 return String{ c_str() + pos, cnt };
3771String::size_type String::find(
char ch, size_type pos)
const {
3772 const char* begin = c_str();
3773 const char* end = begin + size();
3774 const char* it = begin + pos;
3775 for (; it < end && *it != ch; it++);
3776 if (it < end) {
return static_cast<size_type
>(it - begin); }
3777 else {
return npos; }
3780String::size_type String::rfind(
char ch, size_type pos)
const {
3781 const char* begin = c_str();
3782 const char* it = begin + std::min(pos, size() - 1);
3783 for (; it >= begin && *it != ch; it--);
3784 if (it >= begin) {
return static_cast<size_type
>(it - begin); }
3785 else {
return npos; }
3788int String::compare(
const char* other,
bool no_case)
const {
3790 return doctest::stricmp(c_str(), other);
3791 return std::strcmp(c_str(), other);
3794int String::compare(
const String& other,
bool no_case)
const {
3795 return compare(other.c_str(), no_case);
3798String operator+(
const String& lhs,
const String& rhs) {
return String(lhs) += rhs; }
3800bool operator==(
const String& lhs,
const String& rhs) {
return lhs.compare(rhs) == 0; }
3801bool operator!=(
const String& lhs,
const String& rhs) {
return lhs.compare(rhs) != 0; }
3802bool operator< (
const String& lhs,
const String& rhs) {
return lhs.compare(rhs) < 0; }
3803bool operator> (
const String& lhs,
const String& rhs) {
return lhs.compare(rhs) > 0; }
3804bool operator<=(
const String& lhs,
const String& rhs) {
return (lhs != rhs) ? lhs.compare(rhs) < 0 :
true; }
3805bool operator>=(
const String& lhs,
const String& rhs) {
return (lhs != rhs) ? lhs.compare(rhs) > 0 :
true; }
3809Contains::Contains(
const String& str) : string(str) { }
3811bool Contains::checkWith(
const String& other)
const {
3812 return strstr(other.c_str(),
string.c_str()) !=
nullptr;
3815String toString(
const Contains& in) {
3816 return "Contains( " + in.string +
" )";
3819bool operator==(
const String& lhs,
const Contains& rhs) {
return rhs.checkWith(lhs); }
3820bool operator==(
const Contains& lhs,
const String& rhs) {
return lhs.checkWith(rhs); }
3821bool operator!=(
const String& lhs,
const Contains& rhs) {
return !rhs.checkWith(lhs); }
3822bool operator!=(
const Contains& lhs,
const String& rhs) {
return !lhs.checkWith(rhs); }
3825 void color_to_stream(
std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)
3830 color_to_stream(
s, code);
3836const char* assertString(assertType::Enum at) {
3838 #define DOCTEST_GENERATE_ASSERT_TYPE_CASE(assert_type) case assertType::DT_ ## assert_type: return #assert_type
3839 #define DOCTEST_GENERATE_ASSERT_TYPE_CASES(assert_type) \
3840 DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN_ ## assert_type); \
3841 DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK_ ## assert_type); \
3842 DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE_ ## assert_type)
3844 DOCTEST_GENERATE_ASSERT_TYPE_CASE(
WARN);
3845 DOCTEST_GENERATE_ASSERT_TYPE_CASE(
CHECK);
3846 DOCTEST_GENERATE_ASSERT_TYPE_CASE(
REQUIRE);
3848 DOCTEST_GENERATE_ASSERT_TYPE_CASES(
FALSE);
3850 DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS);
3852 DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_AS);
3854 DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH);
3856 DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH_AS);
3858 DOCTEST_GENERATE_ASSERT_TYPE_CASES(NOTHROW);
3860 DOCTEST_GENERATE_ASSERT_TYPE_CASES(EQ);
3861 DOCTEST_GENERATE_ASSERT_TYPE_CASES(NE);
3862 DOCTEST_GENERATE_ASSERT_TYPE_CASES(GT);
3863 DOCTEST_GENERATE_ASSERT_TYPE_CASES(LT);
3864 DOCTEST_GENERATE_ASSERT_TYPE_CASES(GE);
3865 DOCTEST_GENERATE_ASSERT_TYPE_CASES(LE);
3867 DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY);
3868 DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY_FALSE);
3870 default: DOCTEST_INTERNAL_ERROR(
"Tried stringifying invalid assert type!");
3876const char* failureString(assertType::Enum at) {
3877 if(at & assertType::is_warn)
3879 if(at & assertType::is_check)
3881 if(at & assertType::is_require)
3882 return "FATAL ERROR";
3889const char* skipPathFromFilename(
const char* file) {
3890#ifndef DOCTEST_CONFIG_DISABLE
3891 if(getContextOptions()->no_path_in_filenames) {
3892 auto back = std::strrchr(file,
'\\');
3893 auto forward = std::strrchr(file,
'/');
3894 if(back || forward) {
3901 const char separator = DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR;
3902 String::size_type longest_match = 0U;
3903 for(String::size_type pos = 0U; pos < prefixes.size(); ++pos)
3905 const auto prefix_start = pos;
3906 pos = std::min(prefixes.find(separator, prefix_start), prefixes.size());
3908 const auto prefix_size = pos - prefix_start;
3909 if(prefix_size > longest_match)
3912 if(0 == std::strncmp(prefixes.c_str() + prefix_start, file, prefix_size))
3914 longest_match = prefix_size;
3918 return &file[longest_match];
3926bool SubcaseSignature::operator==(
const SubcaseSignature& other)
const {
3927 return m_line == other.m_line
3928 && std::strcmp(m_file, other.m_file) == 0
3929 && m_name == other.m_name;
3932bool SubcaseSignature::operator<(
const SubcaseSignature& other)
const {
3933 if(m_line != other.m_line)
3934 return m_line < other.m_line;
3935 if(std::strcmp(m_file, other.m_file) != 0)
3936 return std::strcmp(m_file, other.m_file) < 0;
3937 return m_name.compare(other.m_name) < 0;
3943 void filldata<const void*>::fill(
std::ostream* stream,
const void* in) {
3944 if (in) { *stream << in; }
3945 else { *stream <<
"nullptr"; }
3948 template <
typename T>
3949 String toStreamLit(T t) {
3956#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
3957String toString(
const char* in) {
return String(
"\"") + (in ? in :
"{null string}") +
"\""; }
3960#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
3962String toString(
const std::string& in) {
return in.
c_str(); }
3965String toString(String in) {
return in; }
3969String toString(
bool in) {
return in ?
"true" :
"false"; }
3971String toString(
float in) {
return toStreamLit(in); }
3972String toString(
double in) {
return toStreamLit(in); }
3973String toString(
double long in) {
return toStreamLit(in); }
3975String toString(
char in) {
return toStreamLit(
static_cast<signed>(in)); }
3976String toString(
char signed in) {
return toStreamLit(
static_cast<signed>(in)); }
3977String toString(
char unsigned in) {
return toStreamLit(
static_cast<unsigned>(in)); }
3978String toString(
short in) {
return toStreamLit(in); }
3979String toString(
short unsigned in) {
return toStreamLit(in); }
3980String toString(
signed in) {
return toStreamLit(in); }
3981String toString(
unsigned in) {
return toStreamLit(in); }
3982String toString(
long in) {
return toStreamLit(in); }
3983String toString(
long unsigned in) {
return toStreamLit(in); }
3984String toString(
long long in) {
return toStreamLit(in); }
3985String toString(
long long unsigned in) {
return toStreamLit(in); }
3987Approx::Approx(
double value)
3988 : m_epsilon(
static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
3992Approx Approx::operator()(
double value)
const {
3993 Approx approx(
value);
3994 approx.epsilon(m_epsilon);
3995 approx.scale(m_scale);
3999Approx& Approx::epsilon(
double newEpsilon) {
4000 m_epsilon = newEpsilon;
4003Approx& Approx::scale(
double newScale) {
4008bool operator==(
double lhs,
const Approx& rhs) {
4010 return std::fabs(lhs - rhs.m_value) <
4011 rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));
4013bool operator==(
const Approx& lhs,
double rhs) {
return operator==(rhs, lhs); }
4014bool operator!=(
double lhs,
const Approx& rhs) {
return !operator==(lhs, rhs); }
4015bool operator!=(
const Approx& lhs,
double rhs) {
return !operator==(rhs, lhs); }
4016bool operator<=(
double lhs,
const Approx& rhs) {
return lhs < rhs.m_value || lhs == rhs; }
4017bool operator<=(
const Approx& lhs,
double rhs) {
return lhs.m_value < rhs || lhs == rhs; }
4018bool operator>=(
double lhs,
const Approx& rhs) {
return lhs > rhs.m_value || lhs == rhs; }
4019bool operator>=(
const Approx& lhs,
double rhs) {
return lhs.m_value > rhs || lhs == rhs; }
4020bool operator<(
double lhs,
const Approx& rhs) {
return lhs < rhs.m_value && lhs != rhs; }
4021bool operator<(
const Approx& lhs,
double rhs) {
return lhs.m_value < rhs && lhs != rhs; }
4022bool operator>(
double lhs,
const Approx& rhs) {
return lhs > rhs.m_value && lhs != rhs; }
4023bool operator>(
const Approx& lhs,
double rhs) {
return lhs.m_value > rhs && lhs != rhs; }
4025String toString(
const Approx& in) {
4028const ContextOptions* getContextOptions() {
return DOCTEST_BRANCH_ON_DISABLED(
nullptr, g_cs); }
4031template <
typename F>
4032IsNaN<F>::operator bool()
const {
4033 return std::isnan(
value) ^ flipped;
4039template <
typename F>
4040String toString(IsNaN<F> in) {
return String(in.flipped ?
"! " :
"") +
"IsNaN( " +
doctest::toString(in.value) +
" )"; }
4041String toString(IsNaN<float> in) {
return toString<float>(in); }
4042String toString(IsNaN<double> in) {
return toString<double>(in); }
4043String toString(IsNaN<double long> in) {
return toString<double long>(in); }
4047#ifdef DOCTEST_CONFIG_DISABLE
4049Context::Context(
int,
const char*
const*) {}
4050Context::~Context() =
default;
4051void Context::applyCommandLine(
int,
const char*
const*) {}
4052void Context::addFilter(
const char*,
const char*) {}
4053void Context::clearFilters() {}
4054void Context::setOption(
const char*,
bool) {}
4055void Context::setOption(
const char*,
int) {}
4056void Context::setOption(
const char*,
const char*) {}
4057bool Context::shouldExit() {
return false; }
4058void Context::setAsDefaultForAssertsOutOfTestCases() {}
4059void Context::setAssertHandler(detail::assert_handler) {}
4061int Context::run() {
return 0; }
4063int IReporter::get_num_active_contexts() {
return 0; }
4064const IContextScope*
const* IReporter::get_active_contexts() {
return nullptr; }
4065int IReporter::get_num_stringified_contexts() {
return 0; }
4066const String* IReporter::get_stringified_contexts() {
return nullptr; }
4073#if !defined(DOCTEST_CONFIG_COLORS_NONE)
4074#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
4075#ifdef DOCTEST_PLATFORM_WINDOWS
4076#define DOCTEST_CONFIG_COLORS_WINDOWS
4078#define DOCTEST_CONFIG_COLORS_ANSI
4097 reporterMap& getReporters() {
4098 static reporterMap data;
4101 reporterMap& getListeners() {
4102 static reporterMap data;
4107#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \
4108 for(auto& curr_rep : g_cs->reporters_currently_used) \
4109 curr_rep->function(__VA_ARGS__)
4112 if(at & assertType::is_require)
4115 if((at & assertType::is_check)
4117 (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=
4124#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
4126 g_cs->shouldLogCurrentException =
false;
4127 throw TestFailureException();
4135 using namespace detail;
4138 int wildcmp(
const char* str,
const char* wild,
bool caseSensitive) {
4139 const char* cp = str;
4140 const char* mp = wild;
4142 while((*str) && (*wild !=
'*')) {
4143 if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
4158 }
else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
4168 while(*wild ==
'*') {
4175 bool matchesAny(
const char*
name,
const std::vector<String>& filters,
bool matchEmpty,
4176 bool caseSensitive) {
4177 if (filters.empty() && matchEmpty)
4179 for (
auto& curr : filters)
4180 if (wildcmp(
name, curr.c_str(), caseSensitive))
4186 unsigned long long hash(
unsigned long long a,
unsigned long long b) {
4187 return (
a << 5) + b;
4192 unsigned long long hash(
const char* str) {
4193 unsigned long long hash = 5381;
4195 while ((c = *str++))
4196 hash = ((hash << 5) + hash) + c;
4200 unsigned long long hash(
const SubcaseSignature& sig) {
4201 return hash(hash(hash(sig.m_file), hash(sig.m_name.c_str())), sig.m_line);
4204 unsigned long long hash(
const std::vector<SubcaseSignature>& sigs,
size_t count) {
4205 unsigned long long running = 0;
4206 auto end = sigs.begin() + count;
4207 for (
auto it = sigs.begin(); it != end; it++) {
4208 running = hash(running, hash(*it));
4213 unsigned long long hash(
const std::vector<SubcaseSignature>& sigs) {
4214 unsigned long long running = 0;
4215 for (
const SubcaseSignature& sig : sigs) {
4216 running = hash(running, hash(sig));
4222 bool Subcase::checkFilters() {
4223 if (g_cs->subcaseStack.size() <
size_t(g_cs->subcase_filter_levels)) {
4224 if (!matchesAny(m_signature.m_name.c_str(), g_cs->filters[6],
true, g_cs->case_sensitive))
4226 if (matchesAny(m_signature.m_name.c_str(), g_cs->filters[7],
false, g_cs->case_sensitive))
4232 Subcase::Subcase(
const String&
name,
const char* file,
int line)
4233 : m_signature({
name, file, line}) {
4234 if (!g_cs->reachedLeaf) {
4235 if (g_cs->nextSubcaseStack.size() <= g_cs->subcaseStack.size()
4236 || g_cs->nextSubcaseStack[g_cs->subcaseStack.size()] == m_signature) {
4238 if (checkFilters()) {
return; }
4240 g_cs->subcaseStack.push_back(m_signature);
4241 g_cs->currentSubcaseDepth++;
4243 DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
4246 if (g_cs->subcaseStack[g_cs->currentSubcaseDepth] == m_signature) {
4248 g_cs->currentSubcaseDepth++;
4250 DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
4251 }
else if (g_cs->nextSubcaseStack.size() <= g_cs->currentSubcaseDepth
4252 && g_cs->fullyTraversedSubcases.find(hash(hash(g_cs->subcaseStack, g_cs->currentSubcaseDepth), hash(m_signature)))
4253 == g_cs->fullyTraversedSubcases.end()) {
4254 if (checkFilters()) {
return; }
4256 g_cs->nextSubcaseStack.clear();
4257 g_cs->nextSubcaseStack.insert(g_cs->nextSubcaseStack.end(),
4258 g_cs->subcaseStack.begin(), g_cs->subcaseStack.begin() + g_cs->currentSubcaseDepth);
4259 g_cs->nextSubcaseStack.push_back(m_signature);
4268 Subcase::~Subcase() {
4270 g_cs->currentSubcaseDepth--;
4272 if (!g_cs->reachedLeaf) {
4274 g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
4275 g_cs->nextSubcaseStack.clear();
4276 g_cs->reachedLeaf =
true;
4277 }
else if (g_cs->nextSubcaseStack.empty()) {
4279 g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
4282#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
4283 if(std::uncaught_exceptions() > 0
4285 if(std::uncaught_exception()
4287 && g_cs->shouldLogCurrentException) {
4288 DOCTEST_ITERATE_THROUGH_REPORTERS(
4289 test_case_exception, {
"exception thrown in subcase - will translate later "
4290 "when the whole test case has been exited (cannot "
4291 "translate while there is an active exception)",
4293 g_cs->shouldLogCurrentException =
false;
4296 DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end,
DOCTEST_EMPTY);
4304 Subcase::operator bool()
const {
return m_entered; }
4306 Result::Result(
bool passed,
const String& decomposition)
4308 , m_decomp(decomposition) {}
4310 ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)
4313 TestSuite& TestSuite::operator*(
const char* in) {
4318 TestCase::TestCase(funcType test,
const char* file,
unsigned line,
const TestSuite& test_suite,
4319 const String& type,
int template_id) {
4323 m_test_suite = test_suite.m_test_suite;
4324 m_description = test_suite.m_description;
4325 m_skip = test_suite.m_skip;
4326 m_no_breaks = test_suite.m_no_breaks;
4327 m_no_output = test_suite.m_no_output;
4328 m_may_fail = test_suite.m_may_fail;
4329 m_should_fail = test_suite.m_should_fail;
4330 m_expected_failures = test_suite.m_expected_failures;
4331 m_timeout = test_suite.m_timeout;
4335 m_template_id = template_id;
4338 TestCase::TestCase(
const TestCase& other)
4344 TestCase& TestCase::operator=(const TestCase& other) {
4345 TestCaseData::operator=(other);
4346 m_test = other.m_test;
4347 m_type = other.m_type;
4348 m_template_id = other.m_template_id;
4349 m_full_name = other.m_full_name;
4351 if(m_template_id != -1)
4352 m_name = m_full_name.
c_str();
4357 TestCase& TestCase::operator*(
const char* in) {
4360 if(m_template_id != -1) {
4361 m_full_name = String(m_name) +
"<" + m_type +
">";
4363 m_name = m_full_name.
c_str();
4368 bool TestCase::operator<(
const TestCase& other)
const {
4370 if(m_line != other.m_line)
4371 return m_line < other.m_line;
4372 const int name_cmp = strcmp(m_name, other.m_name);
4374 return name_cmp < 0;
4375 const int file_cmp = m_file.compare(other.m_file);
4377 return file_cmp < 0;
4378 return m_template_id < other.m_template_id;
4382 std::set<TestCase>& getRegisteredTests() {
4383 static std::set<TestCase> data;
4388 using namespace detail;
4390 bool fileOrderComparator(
const TestCase* lhs,
const TestCase* rhs) {
4393 const int res = lhs->m_file.compare(rhs->m_file,
bool(
DOCTEST_MSVC));
4396 if(lhs->m_line != rhs->m_line)
4397 return lhs->m_line < rhs->m_line;
4398 return lhs->m_template_id < rhs->m_template_id;
4402 bool suiteOrderComparator(
const TestCase* lhs,
const TestCase* rhs) {
4403 const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
4406 return fileOrderComparator(lhs, rhs);
4410 bool nameOrderComparator(
const TestCase* lhs,
const TestCase* rhs) {
4411 const int res = std::strcmp(lhs->m_name, rhs->m_name);
4414 return suiteOrderComparator(lhs, rhs);
4418 void color_to_stream(
std::
ostream&
s, Color::Enum code) {
4419 static_cast<void>(
s);
4420 static_cast<void>(code);
4421#ifdef DOCTEST_CONFIG_COLORS_ANSI
4429 case Color::Red: col =
"[0;31m";
break;
4430 case Color::Green: col =
"[0;32m";
break;
4431 case Color::Blue: col =
"[0;34m";
break;
4432 case Color::Cyan: col =
"[0;36m";
break;
4433 case Color::Yellow: col =
"[0;33m";
break;
4434 case Color::Grey: col =
"[1;30m";
break;
4435 case Color::LightGrey: col =
"[0;37m";
break;
4436 case Color::BrightRed: col =
"[1;31m";
break;
4437 case Color::BrightGreen: col =
"[1;32m";
break;
4438 case Color::BrightWhite: col =
"[1;37m";
break;
4442 default: col =
"[0m";
4448#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
4453 static struct ConsoleHelper {
4454 HANDLE stdoutHandle;
4459 stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
4460 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
4461 GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
4462 origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED |
4463 BACKGROUND_BLUE | BACKGROUND_INTENSITY);
4464 origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED |
4465 FOREGROUND_BLUE | FOREGROUND_INTENSITY);
4469#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs)
4473 case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
break;
4474 case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED);
break;
4475 case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN);
break;
4476 case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE);
break;
4477 case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN);
break;
4478 case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN);
break;
4479 case Color::Grey: DOCTEST_SET_ATTR(0);
break;
4480 case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY);
break;
4481 case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED);
break;
4482 case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN);
break;
4483 case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
break;
4486 default: DOCTEST_SET_ATTR(ch.origFgAttrs);
4493 std::vector<const IExceptionTranslator*>& getExceptionTranslators() {
4494 static std::vector<const IExceptionTranslator*> data;
4498 String translateActiveException() {
4499#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
4501 auto& translators = getExceptionTranslators();
4502 for(
auto& curr : translators)
4503 if(curr->translate(res))
4509 }
catch(std::exception& ex) {
4511 }
catch(std::string& msg) {
4513 }
catch(
const char* msg) {
4516 return "unknown exception";
4528 int regTest(
const TestCase& tc) {
4529 getRegisteredTests().insert(tc);
4539#ifdef DOCTEST_IS_DEBUGGER_ACTIVE
4542#ifdef DOCTEST_PLATFORM_LINUX
4545 ErrnoGuard() : m_oldErrno(errno) {}
4546 ~ErrnoGuard() { errno = m_oldErrno; }
4554 std::ifstream in(
"/proc/self/status");
4555 for(std::string line; std::getline(in, line);) {
4556 static const int PREFIX_LEN = 11;
4557 if(line.compare(0, PREFIX_LEN,
"TracerPid:\t") == 0) {
4558 return line.length() > PREFIX_LEN && line[PREFIX_LEN] !=
'0';
4563#elif defined(DOCTEST_PLATFORM_MAC)
4574 info.kp_proc.p_flag = 0;
4579 mib[2] = KERN_PROC_PID;
4582 size =
sizeof(info);
4583 if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) {
4584 std::cerr <<
"\nCall to sysctl failed - unable to determine if debugger is active **\n";
4588 return ((info.kp_proc.p_flag & P_TRACED) != 0);
4590#elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)
4598 if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) ==
4599 getExceptionTranslators().end())
4600 getExceptionTranslators().push_back(et);
4603 DOCTEST_THREAD_LOCAL std::vector<IContextScope*> g_infoContexts;
4605 ContextScopeBase::ContextScopeBase() {
4606 g_infoContexts.push_back(
this);
4609 ContextScopeBase::ContextScopeBase(ContextScopeBase&& other)
noexcept {
4610 if (other.need_to_destroy) {
4613 other.need_to_destroy =
false;
4614 g_infoContexts.push_back(
this);
4624 void ContextScopeBase::destroy() {
4625#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
4626 if(std::uncaught_exceptions() > 0) {
4628 if(std::uncaught_exception()) {
4630 std::ostringstream
s;
4631 this->stringify(&
s);
4632 g_cs->stringifiedContexts.push_back(
s.str().c_str());
4634 g_infoContexts.pop_back();
4642 using namespace detail;
4644#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
4645 struct FatalConditionHandler
4647 static void reset() {}
4648 static void allocateAltStackMem() {}
4649 static void freeAltStackMem() {}
4653 void reportFatal(
const std::string&);
4655#ifdef DOCTEST_PLATFORM_WINDOWS
4665 SignalDefs signalDefs[] = {
4666 {
static_cast<DWORD
>(EXCEPTION_ILLEGAL_INSTRUCTION),
4667 "SIGILL - Illegal instruction signal"},
4668 {
static_cast<DWORD
>(EXCEPTION_STACK_OVERFLOW),
"SIGSEGV - Stack overflow"},
4669 {
static_cast<DWORD
>(EXCEPTION_ACCESS_VIOLATION),
4670 "SIGSEGV - Segmentation violation signal"},
4671 {
static_cast<DWORD
>(EXCEPTION_INT_DIVIDE_BY_ZERO),
"Divide by zero error"},
4674 struct FatalConditionHandler
4676 static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
4679 DOCTEST_DECLARE_STATIC_MUTEX(
mutex)
4680 static bool execute =
true;
4682 DOCTEST_LOCK_MUTEX(
mutex)
4684 bool reported =
false;
4685 for(
size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4686 if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
4687 reportFatal(signalDefs[i].
name);
4692 if(reported ==
false)
4693 reportFatal(
"Unhandled SEH exception caught");
4699 std::exit(EXIT_FAILURE);
4702 static void allocateAltStackMem() {}
4703 static void freeAltStackMem() {}
4705 FatalConditionHandler() {
4709 guaranteeSize = 32 * 1024;
4711 previousTop = SetUnhandledExceptionFilter(handleException);
4713 SetThreadStackGuarantee(&guaranteeSize);
4721 original_terminate_handler = std::get_terminate();
4723 reportFatal(
"Terminate handler called");
4726 std::exit(EXIT_FAILURE);
4733 prev_sigabrt_handler = std::signal(SIGABRT, [](
int signal)
DOCTEST_NOEXCEPT {
4734 if(signal == SIGABRT) {
4735 reportFatal(
"SIGABRT - Abort (abnormal termination) signal");
4738 std::exit(EXIT_FAILURE);
4746 prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
4747 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
4749 prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
4752 prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
4757 prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
4758 prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
4761 static void reset() {
4764 SetUnhandledExceptionFilter(previousTop);
4765 SetThreadStackGuarantee(&guaranteeSize);
4766 std::set_terminate(original_terminate_handler);
4767 std::signal(SIGABRT, prev_sigabrt_handler);
4768 SetErrorMode(prev_error_mode_1);
4769 _set_error_mode(prev_error_mode_2);
4770 _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
4771 static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode));
4772 static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file));
4777 ~FatalConditionHandler() { reset(); }
4780 static UINT prev_error_mode_1;
4781 static int prev_error_mode_2;
4782 static unsigned int prev_abort_behavior;
4783 static int prev_report_mode;
4784 static _HFILE prev_report_file;
4785 static void (DOCTEST_CDECL *prev_sigabrt_handler)(int);
4786 static std::terminate_handler original_terminate_handler;
4788 static ULONG guaranteeSize;
4789 static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
4792 UINT FatalConditionHandler::prev_error_mode_1;
4793 int FatalConditionHandler::prev_error_mode_2;
4794 unsigned int FatalConditionHandler::prev_abort_behavior;
4795 int FatalConditionHandler::prev_report_mode;
4796 _HFILE FatalConditionHandler::prev_report_file;
4797 void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int);
4798 std::terminate_handler FatalConditionHandler::original_terminate_handler;
4799 bool FatalConditionHandler::isSet =
false;
4800 ULONG FatalConditionHandler::guaranteeSize = 0;
4801 LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop =
nullptr;
4810 SignalDefs signalDefs[] = {{SIGINT,
"SIGINT - Terminal interrupt signal"},
4811 {SIGILL,
"SIGILL - Illegal instruction signal"},
4812 {SIGFPE,
"SIGFPE - Floating point error signal"},
4813 {SIGSEGV,
"SIGSEGV - Segmentation violation signal"},
4814 {SIGTERM,
"SIGTERM - Termination request signal"},
4815 {SIGABRT,
"SIGABRT - Abort (abnormal termination) signal"}};
4817 struct FatalConditionHandler
4820 static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];
4821 static stack_t oldSigStack;
4822 static size_t altStackSize;
4823 static char* altStackMem;
4825 static void handleSignal(
int sig) {
4826 const char*
name =
"<unknown signal>";
4827 for(
std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4828 SignalDefs& def = signalDefs[i];
4839 static void allocateAltStackMem() {
4840 altStackMem =
new char[altStackSize];
4843 static void freeAltStackMem() {
4844 delete[] altStackMem;
4847 FatalConditionHandler() {
4850 sigStack.ss_sp = altStackMem;
4851 sigStack.ss_size = altStackSize;
4852 sigStack.ss_flags = 0;
4853 sigaltstack(&sigStack, &oldSigStack);
4854 struct sigaction sa = {};
4855 sa.sa_handler = handleSignal;
4856 sa.sa_flags = SA_ONSTACK;
4857 for(
std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4858 sigaction(signalDefs[i].
id, &sa, &oldSigActions[i]);
4862 ~FatalConditionHandler() { reset(); }
4863 static void reset() {
4866 for(
std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4867 sigaction(signalDefs[i].
id, &oldSigActions[i],
nullptr);
4870 sigaltstack(&oldSigStack,
nullptr);
4876 bool FatalConditionHandler::isSet =
false;
4877 struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};
4878 stack_t FatalConditionHandler::oldSigStack = {};
4879 size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;
4880 char* FatalConditionHandler::altStackMem =
nullptr;
4888 using namespace detail;
4890#ifdef DOCTEST_PLATFORM_WINDOWS
4891#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text)
4894#define DOCTEST_OUTPUT_DEBUG_STRING(text)
4897 void addAssert(assertType::Enum at) {
4898 if((at & assertType::is_warn) == 0)
4899 g_cs->numAssertsCurrentTest_atomic++;
4902 void addFailedAssert(assertType::Enum at) {
4903 if((at & assertType::is_warn) == 0)
4904 g_cs->numAssertsFailedCurrentTest_atomic++;
4907#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH)
4908 void reportFatal(
const std::string& message) {
4909 g_cs->failure_flags |= TestCaseFailureReason::Crash;
4911 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(),
true});
4913 while (g_cs->subcaseStack.size()) {
4914 g_cs->subcaseStack.pop_back();
4915 DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end,
DOCTEST_EMPTY);
4918 g_cs->finalizeTestCaseData();
4920 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
4922 DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
4927AssertData::AssertData(assertType::Enum at,
const char* file,
int line,
const char*
expr,
4928 const char* exception_type,
const StringContains& exception_string)
4929 : m_test_case(g_cs->currentTest), m_at(at), m_file(file), m_line(line), m_expr(
expr),
4930 m_failed(true), m_threw(false), m_threw_as(false), m_exception_type(exception_type),
4931 m_exception_string(exception_string) {
4933 if (m_expr[0] ==
' ')
4939 ResultBuilder::ResultBuilder(assertType::Enum at,
const char* file,
int line,
const char*
expr,
4940 const char* exception_type,
const String& exception_string)
4941 : AssertData(at, file, line,
expr, exception_type, exception_string) { }
4943 ResultBuilder::ResultBuilder(assertType::Enum at,
const char* file,
int line,
const char*
expr,
4944 const char* exception_type,
const Contains& exception_string)
4945 : AssertData(at, file, line,
expr, exception_type, exception_string) { }
4947 void ResultBuilder::setResult(
const Result& res) {
4948 m_decomp = res.m_decomp;
4949 m_failed = !res.m_passed;
4952 void ResultBuilder::translateException() {
4954 m_exception = translateActiveException();
4957 bool ResultBuilder::log() {
4958 if(m_at & assertType::is_throws) {
4959 m_failed = !m_threw;
4960 }
else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) {
4961 m_failed = !m_threw_as || !m_exception_string.check(m_exception);
4962 }
else if(m_at & assertType::is_throws_as) {
4963 m_failed = !m_threw_as;
4964 }
else if(m_at & assertType::is_throws_with) {
4965 m_failed = !m_exception_string.check(m_exception);
4966 }
else if(m_at & assertType::is_nothrow) {
4970 if(m_exception.size())
4971 m_exception =
"\"" + m_exception +
"\"";
4973 if(is_running_in_test) {
4975 DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *
this);
4978 addFailedAssert(m_at);
4979 }
else if(m_failed) {
4984 (g_cs->currentTest ==
nullptr || !g_cs->currentTest->m_no_breaks);
4987 void ResultBuilder::react()
const {
4999 bool decomp_assert(assertType::Enum at,
const char* file,
int line,
const char*
expr,
5000 const Result& result) {
5001 bool failed = !result.m_passed;
5012 MessageBuilder::MessageBuilder(
const char* file,
int line, assertType::Enum severity) {
5016 m_severity = severity;
5019 MessageBuilder::~MessageBuilder() {
5026 bool MessageBuilder::log() {
5032 DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *
this);
5034 const bool isWarn = m_severity & assertType::is_warn;
5038 addAssert(m_severity);
5039 addFailedAssert(m_severity);
5043 (g_cs->currentTest ==
nullptr || !g_cs->currentTest->m_no_breaks);
5046 void MessageBuilder::react() {
5047 if(m_severity & assertType::is_require)
5052 using namespace detail;
5063 enum ForWhat { ForTextNodes, ForAttributes };
5065 XmlEncode( std::string
const& str, ForWhat forWhat = ForTextNodes );
5079 class ScopedElement {
5081 ScopedElement( XmlWriter*
writer );
5088 ScopedElement& writeText( std::string
const& text,
bool indent =
true );
5090 template<
typename T>
5091 ScopedElement& writeAttribute( std::string
const&
name, T
const& attribute ) {
5092 m_writer->writeAttribute(
name, attribute );
5097 mutable XmlWriter* m_writer =
nullptr;
5100#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
5107 XmlWriter( XmlWriter
const& ) =
delete;
5108 XmlWriter& operator=( XmlWriter
const& ) =
delete;
5110 XmlWriter& startElement( std::string
const&
name );
5112 ScopedElement scopedElement( std::string
const&
name );
5114 XmlWriter& endElement();
5116 XmlWriter& writeAttribute( std::string
const&
name, std::string
const& attribute );
5118 XmlWriter& writeAttribute( std::string
const&
name,
const char* attribute );
5120 XmlWriter& writeAttribute( std::string
const&
name,
bool attribute );
5122 template<
typename T>
5123 XmlWriter& writeAttribute( std::string
const&
name, T
const& attribute ) {
5124 std::stringstream rss;
5126 return writeAttribute(
name, rss.str() );
5129 XmlWriter& writeText( std::string
const& text,
bool indent =
true );
5137 void ensureTagClosed();
5139 void writeDeclaration();
5143 void newlineIfNecessary();
5145 bool m_tagIsOpen =
false;
5146 bool m_needsNewline =
false;
5147 std::vector<std::string> m_tags;
5148 std::string m_indent;
5157using uchar =
unsigned char;
5161 size_t trailingBytes(
unsigned char c) {
5162 if ((c & 0xE0) == 0xC0) {
5165 if ((c & 0xF0) == 0xE0) {
5168 if ((c & 0xF8) == 0xF0) {
5171 DOCTEST_INTERNAL_ERROR(
"Invalid multibyte utf-8 start byte encountered");
5174 uint32_t headerValue(
unsigned char c) {
5175 if ((c & 0xE0) == 0xC0) {
5178 if ((c & 0xF0) == 0xE0) {
5181 if ((c & 0xF8) == 0xF0) {
5184 DOCTEST_INTERNAL_ERROR(
"Invalid multibyte utf-8 start byte encountered");
5187 void hexEscapeChar(
std::ostream& os,
unsigned char c) {
5188 std::ios_base::fmtflags f(os.flags());
5190 << std::uppercase << std::hex << std::setfill(
'0') << std::setw(2)
5191 <<
static_cast<int>(c);
5197 XmlEncode::XmlEncode( std::string
const& str, ForWhat forWhat )
5199 m_forWhat( forWhat )
5206 for(
std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
5207 uchar c = m_str[idx];
5209 case '<': os <<
"<";
break;
5210 case '&': os <<
"&";
break;
5214 if (idx > 2 && m_str[idx - 1] ==
']' && m_str[idx - 2] ==
']')
5221 if (m_forWhat == ForAttributes)
5232 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
5233 hexEscapeChar(os, c);
5251 hexEscapeChar(os, c);
5255 auto encBytes = trailingBytes(c);
5257 if (idx + encBytes - 1 >= m_str.size()) {
5258 hexEscapeChar(os, c);
5265 uint32_t
value = headerValue(c);
5267 uchar nc = m_str[idx + n];
5268 valid &= ((nc & 0xC0) == 0x80);
5277 ( value < 0x800 && encBytes > 2) ||
5278 (0x800 <
value && value < 0x10000 && encBytes > 3) ||
5282 hexEscapeChar(os, c);
5288 os << m_str[idx + n];
5290 idx += encBytes - 1;
5297 xmlEncode.encodeTo( os );
5301 XmlWriter::ScopedElement::ScopedElement( XmlWriter*
writer )
5305 XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other )
DOCTEST_NOEXCEPT
5306 : m_writer( other.m_writer ){
5307 other.m_writer =
nullptr;
5309 XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other )
DOCTEST_NOEXCEPT {
5311 m_writer->endElement();
5313 m_writer = other.m_writer;
5314 other.m_writer =
nullptr;
5319 XmlWriter::ScopedElement::~ScopedElement() {
5321 m_writer->endElement();
5324 XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string
const& text,
bool indent ) {
5325 m_writer->writeText( text, indent );
5334 XmlWriter::~XmlWriter() {
5335 while( !m_tags.empty() )
5339 XmlWriter& XmlWriter::startElement( std::string
const&
name ) {
5341 newlineIfNecessary();
5342 m_os << m_indent <<
'<' <<
name;
5343 m_tags.push_back(
name );
5349 XmlWriter::ScopedElement XmlWriter::scopedElement( std::string
const&
name ) {
5350 ScopedElement scoped(
this );
5351 startElement(
name );
5355 XmlWriter& XmlWriter::endElement() {
5356 newlineIfNecessary();
5357 m_indent = m_indent.substr( 0, m_indent.size()-2 );
5360 m_tagIsOpen =
false;
5363 m_os << m_indent <<
"</" << m_tags.back() <<
">";
5370 XmlWriter& XmlWriter::writeAttribute( std::string
const&
name, std::string
const& attribute ) {
5371 if( !
name.empty() && !attribute.empty() )
5372 m_os <<
' ' <<
name <<
"=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) <<
'"';
5376 XmlWriter& XmlWriter::writeAttribute( std::string
const&
name,
const char* attribute ) {
5377 if( !
name.empty() && attribute && attribute[0] !=
'\0' )
5378 m_os <<
' ' <<
name <<
"=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) <<
'"';
5382 XmlWriter& XmlWriter::writeAttribute( std::string
const&
name,
bool attribute ) {
5383 m_os <<
' ' <<
name <<
"=\"" << ( attribute ?
"true" :
"false" ) <<
'"';
5387 XmlWriter& XmlWriter::writeText( std::string
const& text,
bool indent ) {
5388 if( !text.empty() ){
5389 bool tagWasOpen = m_tagIsOpen;
5391 if( tagWasOpen && indent )
5393 m_os << XmlEncode( text );
5394 m_needsNewline =
true;
5416 void XmlWriter::ensureTagClosed() {
5418 m_os <<
">" << std::endl;
5419 m_tagIsOpen =
false;
5423 void XmlWriter::writeDeclaration() {
5424 m_os <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
5427 void XmlWriter::newlineIfNecessary() {
5428 if( m_needsNewline ) {
5430 m_needsNewline =
false;
5440 struct XmlReporter :
public IReporter
5443 DOCTEST_DECLARE_MUTEX(
mutex)
5446 const ContextOptions& opt;
5447 const TestCaseData* tc =
nullptr;
5449 XmlReporter(
const ContextOptions& co)
5453 void log_contexts() {
5454 int num_contexts = get_num_active_contexts();
5456 auto contexts = get_active_contexts();
5457 std::stringstream ss;
5458 for(
int i = 0; i < num_contexts; ++i) {
5459 contexts[i]->stringify(&ss);
5460 xml.scopedElement(
"Info").writeText(ss.str());
5466 unsigned line(
unsigned l)
const {
return opt.no_line_numbers ? 0 : l; }
5468 void test_case_start_impl(
const TestCaseData& in) {
5469 bool open_ts_tag =
false;
5471 if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
5481 xml.startElement(
"TestSuite");
5482 xml.writeAttribute(
"name", in.m_test_suite);
5486 xml.startElement(
"TestCase")
5487 .writeAttribute(
"name", in.m_name)
5489 .writeAttribute(
"line", line(in.m_line))
5490 .writeAttribute(
"description", in.m_description);
5492 if(Approx(in.m_timeout) != 0)
5493 xml.writeAttribute(
"timeout", in.m_timeout);
5495 xml.writeAttribute(
"may_fail",
true);
5496 if(in.m_should_fail)
5497 xml.writeAttribute(
"should_fail",
true);
5504 void report_query(
const QueryData& in)
override {
5506 if(opt.list_reporters) {
5507 for(
auto& curr : getListeners())
5508 xml.scopedElement(
"Listener")
5509 .writeAttribute(
"priority", curr.first.first)
5510 .writeAttribute(
"name", curr.first.second);
5511 for(
auto& curr : getReporters())
5512 xml.scopedElement(
"Reporter")
5513 .writeAttribute(
"priority", curr.first.first)
5514 .writeAttribute(
"name", curr.first.second);
5515 }
else if(opt.count || opt.list_test_cases) {
5516 for(
unsigned i = 0; i < in.num_data; ++i) {
5517 xml.scopedElement(
"TestCase").writeAttribute(
"name", in.data[i]->m_name)
5518 .writeAttribute(
"testsuite", in.data[i]->m_test_suite)
5520 .writeAttribute(
"line", line(in.data[i]->m_line))
5521 .writeAttribute(
"skipped", in.data[i]->m_skip);
5523 xml.scopedElement(
"OverallResultsTestCases")
5524 .writeAttribute(
"unskipped", in.run_stats->numTestCasesPassingFilters);
5525 }
else if(opt.list_test_suites) {
5526 for(
unsigned i = 0; i < in.num_data; ++i)
5527 xml.scopedElement(
"TestSuite").writeAttribute(
"name", in.data[i]->m_test_suite);
5528 xml.scopedElement(
"OverallResultsTestCases")
5529 .writeAttribute(
"unskipped", in.run_stats->numTestCasesPassingFilters);
5530 xml.scopedElement(
"OverallResultsTestSuites")
5531 .writeAttribute(
"unskipped", in.run_stats->numTestSuitesPassingFilters);
5536 void test_run_start()
override {
5537 xml.writeDeclaration();
5541#ifdef DOCTEST_PLATFORM_WINDOWS
5542 if(binary_name.rfind(
".exe") != std::string::npos)
5543 binary_name = binary_name.substr(0, binary_name.length() - 4);
5546 xml.startElement(
"doctest").writeAttribute(
"binary", binary_name);
5547 if(opt.no_version ==
false)
5551 xml.scopedElement(
"Options")
5552 .writeAttribute(
"order_by", opt.order_by.c_str())
5553 .writeAttribute(
"rand_seed", opt.rand_seed)
5554 .writeAttribute(
"first", opt.first)
5555 .writeAttribute(
"last", opt.last)
5556 .writeAttribute(
"abort_after", opt.abort_after)
5557 .writeAttribute(
"subcase_filter_levels", opt.subcase_filter_levels)
5558 .writeAttribute(
"case_sensitive", opt.case_sensitive)
5559 .writeAttribute(
"no_throw", opt.no_throw)
5560 .writeAttribute(
"no_skip", opt.no_skip);
5563 void test_run_end(
const TestRunStats& p)
override {
5567 xml.scopedElement(
"OverallResultsAsserts")
5568 .writeAttribute(
"successes", p.numAsserts - p.numAssertsFailed)
5569 .writeAttribute(
"failures", p.numAssertsFailed);
5571 xml.startElement(
"OverallResultsTestCases")
5572 .writeAttribute(
"successes",
5573 p.numTestCasesPassingFilters - p.numTestCasesFailed)
5574 .writeAttribute(
"failures", p.numTestCasesFailed);
5575 if(opt.no_skipped_summary ==
false)
5576 xml.writeAttribute(
"skipped", p.numTestCases - p.numTestCasesPassingFilters);
5582 void test_case_start(
const TestCaseData& in)
override {
5583 test_case_start_impl(in);
5584 xml.ensureTagClosed();
5587 void test_case_reenter(
const TestCaseData&)
override {}
5589 void test_case_end(
const CurrentTestCaseStats& st)
override {
5590 xml.startElement(
"OverallResultsAsserts")
5591 .writeAttribute(
"successes",
5592 st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest)
5593 .writeAttribute(
"failures", st.numAssertsFailedCurrentTest)
5594 .writeAttribute(
"test_case_success", st.testCaseSuccess);
5596 xml.writeAttribute(
"duration", st.seconds);
5597 if(tc->m_expected_failures)
5598 xml.writeAttribute(
"expected_failures", tc->m_expected_failures);
5604 void test_case_exception(
const TestCaseException& e)
override {
5605 DOCTEST_LOCK_MUTEX(
mutex)
5607 xml.scopedElement(
"Exception")
5608 .writeAttribute(
"crash", e.is_crash)
5609 .writeText(e.error_string.c_str());
5612 void subcase_start(
const SubcaseSignature& in)
override {
5613 xml.startElement(
"SubCase")
5614 .writeAttribute(
"name", in.m_name)
5616 .writeAttribute(
"line", line(in.m_line));
5617 xml.ensureTagClosed();
5620 void subcase_end()
override { xml.endElement(); }
5622 void log_assert(
const AssertData& rb)
override {
5623 if(!rb.m_failed && !opt.success)
5626 DOCTEST_LOCK_MUTEX(
mutex)
5628 xml.startElement(
"Expression")
5629 .writeAttribute(
"success", !rb.m_failed)
5632 .writeAttribute(
"line", line(rb.m_line));
5634 xml.scopedElement(
"Original").writeText(rb.m_expr);
5637 xml.scopedElement(
"Exception").writeText(rb.m_exception.c_str());
5639 if(rb.m_at & assertType::is_throws_as)
5640 xml.scopedElement(
"ExpectedException").writeText(rb.m_exception_type);
5641 if(rb.m_at & assertType::is_throws_with)
5642 xml.scopedElement(
"ExpectedExceptionString").writeText(rb.m_exception_string.c_str());
5643 if((rb.m_at & assertType::is_normal) && !rb.m_threw)
5644 xml.scopedElement(
"Expanded").writeText(rb.m_decomp.c_str());
5651 void log_message(
const MessageData& mb)
override {
5652 DOCTEST_LOCK_MUTEX(
mutex)
5654 xml.startElement(
"Message")
5657 .writeAttribute(
"line", line(mb.m_line));
5659 xml.scopedElement(
"Text").writeText(mb.m_string.c_str());
5666 void test_case_skipped(
const TestCaseData& in)
override {
5667 if(opt.no_skipped_summary ==
false) {
5668 test_case_start_impl(in);
5669 xml.writeAttribute(
"skipped",
"true");
5677 void fulltext_log_assert_to_stream(
std::ostream&
s,
const AssertData& rb) {
5678 if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==
5680 s << Color::Cyan <<
assertString(rb.m_at) <<
"( " << rb.m_expr <<
" ) "
5683 if(rb.m_at & assertType::is_throws) {
5684 s << (rb.m_threw ?
"threw as expected!" :
"did NOT throw at all!") <<
"\n";
5685 }
else if((rb.m_at & assertType::is_throws_as) &&
5686 (rb.m_at & assertType::is_throws_with)) {
5687 s << Color::Cyan <<
assertString(rb.m_at) <<
"( " << rb.m_expr <<
", \""
5688 << rb.m_exception_string.c_str()
5689 <<
"\", " << rb.m_exception_type <<
" ) " << Color::None;
5692 s <<
"threw as expected!\n";
5694 s <<
"threw a DIFFERENT exception! (contents: " << rb.m_exception <<
")\n";
5697 s <<
"did NOT throw at all!\n";
5700 assertType::is_throws_as) {
5701 s << Color::Cyan <<
assertString(rb.m_at) <<
"( " << rb.m_expr <<
", "
5702 << rb.m_exception_type <<
" ) " << Color::None
5703 << (rb.m_threw ? (rb.m_threw_as ?
"threw as expected!" :
5704 "threw a DIFFERENT exception: ") :
5705 "did NOT throw at all!")
5706 << Color::
Cyan << rb.m_exception <<
"\n";
5708 assertType::is_throws_with) {
5709 s << Color::Cyan <<
assertString(rb.m_at) <<
"( " << rb.m_expr <<
", \""
5710 << rb.m_exception_string.c_str()
5711 <<
"\" ) " << Color::None
5712 << (rb.m_threw ? (!rb.m_failed ?
"threw as expected!" :
5713 "threw a DIFFERENT exception: ") :
5714 "did NOT throw at all!")
5715 << Color::
Cyan << rb.m_exception <<
"\n";
5716 }
else if(rb.m_at & assertType::is_nothrow) {
5717 s << (rb.m_threw ?
"THREW exception: " :
"didn't throw!") << Color::Cyan
5718 << rb.m_exception <<
"\n";
5720 s << (rb.m_threw ?
"THREW exception: " :
5721 (!rb.m_failed ?
"is correct!\n" :
"is NOT correct!\n"));
5723 s << rb.m_exception <<
"\n";
5725 s <<
" values: " <<
assertString(rb.m_at) <<
"( " << rb.m_decomp <<
" )\n";
5734 struct JUnitReporter :
public IReporter
5737 DOCTEST_DECLARE_MUTEX(
mutex)
5739 std::vector<String> deepestSubcaseStackNames;
5741 struct JUnitTestCaseData
5743 static std::string getCurrentTimestamp() {
5747 std::time(&rawtime);
5748 auto const timeStampSize =
sizeof(
"2017-01-16T17:06:45Z");
5751#ifdef DOCTEST_PLATFORM_WINDOWS
5752 gmtime_s(&timeInfo, &rawtime);
5754 gmtime_r(&rawtime, &timeInfo);
5757 char timeStamp[timeStampSize];
5758 const char*
const fmt =
"%Y-%m-%dT%H:%M:%SZ";
5760 std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
5761 return std::string(timeStamp);
5764 struct JUnitTestMessage
5766 JUnitTestMessage(
const std::string& _message,
const std::string& _type,
const std::string& _details)
5767 : message(_message), type(_type), details(_details) {}
5769 JUnitTestMessage(
const std::string& _message,
const std::string& _details)
5770 : message(_message), type(), details(_details) {}
5772 std::string message, type, details;
5775 struct JUnitTestCase
5777 JUnitTestCase(
const std::string& _classname,
const std::string& _name)
5778 : classname(_classname),
name(_name), time(0), failures() {}
5780 std::string classname,
name;
5782 std::vector<JUnitTestMessage> failures, errors;
5785 void add(
const std::string& classname,
const std::string&
name) {
5786 testcases.emplace_back(classname,
name);
5789 void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
5790 for(
auto& curr: nameStack)
5792 testcases.back().
name +=
std::string(
"/") + curr.c_str();
5795 void addTime(
double time) {
5798 testcases.back().time = time;
5799 totalSeconds += time;
5802 void addFailure(
const std::string& message,
const std::string& type,
const std::string& details) {
5803 testcases.back().failures.emplace_back(message, type, details);
5807 void addError(
const std::string& message,
const std::string& details) {
5808 testcases.back().errors.emplace_back(message, details);
5812 std::vector<JUnitTestCase> testcases;
5813 double totalSeconds = 0;
5814 int totalErrors = 0, totalFailures = 0;
5817 JUnitTestCaseData testCaseData;
5820 const ContextOptions& opt;
5821 const TestCaseData* tc =
nullptr;
5823 JUnitReporter(
const ContextOptions& co)
5827 unsigned line(
unsigned l)
const {
return opt.no_line_numbers ? 0 : l; }
5833 void report_query(
const QueryData&)
override {
5834 xml.writeDeclaration();
5837 void test_run_start()
override {
5838 xml.writeDeclaration();
5841 void test_run_end(
const TestRunStats& p)
override {
5844#ifdef DOCTEST_PLATFORM_WINDOWS
5845 if(binary_name.rfind(
".exe") != std::string::npos)
5846 binary_name = binary_name.substr(0, binary_name.length() - 4);
5848 xml.startElement(
"testsuites");
5849 xml.startElement(
"testsuite").writeAttribute(
"name", binary_name)
5850 .writeAttribute(
"errors", testCaseData.totalErrors)
5851 .writeAttribute(
"failures", testCaseData.totalFailures)
5852 .writeAttribute(
"tests", p.numAsserts);
5853 if(opt.no_time_in_output ==
false) {
5854 xml.writeAttribute(
"time", testCaseData.totalSeconds);
5855 xml.writeAttribute(
"timestamp", JUnitTestCaseData::getCurrentTimestamp());
5857 if(opt.no_version ==
false)
5860 for(
const auto& testCase : testCaseData.testcases) {
5861 xml.startElement(
"testcase")
5862 .writeAttribute(
"classname", testCase.classname)
5863 .writeAttribute(
"name", testCase.name);
5864 if(opt.no_time_in_output ==
false)
5865 xml.writeAttribute(
"time", testCase.time);
5867 xml.writeAttribute(
"status",
"run");
5869 for(
const auto& failure : testCase.failures) {
5870 xml.scopedElement(
"failure")
5871 .writeAttribute(
"message", failure.message)
5872 .writeAttribute(
"type", failure.type)
5873 .writeText(failure.details,
false);
5876 for(
const auto&
error : testCase.errors) {
5877 xml.scopedElement(
"error")
5878 .writeAttribute(
"message",
error.message)
5879 .writeText(
error.details);
5888 void test_case_start(
const TestCaseData& in)
override {
5893 void test_case_reenter(
const TestCaseData& in)
override {
5894 testCaseData.addTime(timer.getElapsedSeconds());
5895 testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
5896 deepestSubcaseStackNames.clear();
5902 void test_case_end(
const CurrentTestCaseStats&)
override {
5903 testCaseData.addTime(timer.getElapsedSeconds());
5904 testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
5905 deepestSubcaseStackNames.clear();
5908 void test_case_exception(
const TestCaseException& e)
override {
5909 DOCTEST_LOCK_MUTEX(
mutex)
5910 testCaseData.addError(
"exception", e.error_string.c_str());
5913 void subcase_start(
const SubcaseSignature& in)
override {
5914 deepestSubcaseStackNames.push_back(in.m_name);
5917 void subcase_end()
override {}
5919 void log_assert(
const AssertData& rb)
override {
5923 DOCTEST_LOCK_MUTEX(
mutex)
5925 std::ostringstream os;
5927 << line(rb.m_line) << (opt.gnu_file_line ?
":" :
"):") << std::endl;
5929 fulltext_log_assert_to_stream(os, rb);
5931 testCaseData.addFailure(rb.m_decomp.c_str(),
assertString(rb.m_at), os.str());
5934 void log_message(
const MessageData& mb)
override {
5935 if(mb.m_severity & assertType::is_warn)
5938 DOCTEST_LOCK_MUTEX(
mutex)
5940 std::ostringstream os;
5942 << line(mb.m_line) << (opt.gnu_file_line ?
":" :
"):") << std::endl;
5944 os << mb.m_string.c_str() <<
"\n";
5947 testCaseData.addFailure(mb.m_string.c_str(),
5948 mb.m_severity & assertType::is_check ?
"FAIL_CHECK" :
"FAIL", os.str());
5951 void test_case_skipped(
const TestCaseData&)
override {}
5953 void log_contexts(std::ostringstream&
s) {
5954 int num_contexts = get_num_active_contexts();
5956 auto contexts = get_active_contexts();
5959 for(
int i = 0; i < num_contexts; ++i) {
5960 s << (i == 0 ?
"" :
" ");
5961 contexts[i]->stringify(&
s);
5973 explicit Whitespace(
int nr)
5978 if(ws.nrSpaces != 0)
5979 out << std::setw(ws.nrSpaces) <<
' ';
5983 struct ConsoleReporter :
public IReporter
5986 bool hasLoggedCurrentTestStart;
5987 std::vector<SubcaseSignature> subcasesStack;
5988 size_t currentSubcaseLevel;
5989 DOCTEST_DECLARE_MUTEX(
mutex)
5992 const ContextOptions& opt;
5993 const TestCaseData* tc;
5995 ConsoleReporter(
const ContextOptions& co)
5999 ConsoleReporter(
const ContextOptions& co,
std::ostream& ostr)
6007 void separator_to_stream() {
6009 <<
"==============================================================================="
6013 const char* getSuccessOrFailString(
bool success, assertType::Enum at,
6014 const char* success_str) {
6020 Color::Enum getSuccessOrFailColor(
bool success, assertType::Enum at) {
6021 return success ? Color::BrightGreen :
6022 (at & assertType::is_warn) ? Color::Yellow : Color::
Red;
6025 void successOrFailColoredStringToStream(
bool success, assertType::Enum at,
6026 const char* success_str =
"SUCCESS") {
6027 s << getSuccessOrFailColor(success, at)
6028 << getSuccessOrFailString(success, at, success_str) <<
": ";
6031 void log_contexts() {
6032 int num_contexts = get_num_active_contexts();
6034 auto contexts = get_active_contexts();
6036 s << Color::None <<
" logged: ";
6037 for(
int i = 0; i < num_contexts; ++i) {
6038 s << (i == 0 ?
"" :
" ");
6039 contexts[i]->stringify(&
s);
6048 virtual void file_line_to_stream(
const char* file,
int line,
6049 const char* tail =
"") {
6051 << (opt.no_line_numbers ? 0 : line)
6052 << (opt.gnu_file_line ?
":" :
"):") << tail;
6055 void logTestStart() {
6056 if(hasLoggedCurrentTestStart)
6059 separator_to_stream();
6060 file_line_to_stream(tc->m_file.c_str(), tc->m_line,
"\n");
6061 if(tc->m_description)
6062 s << Color::Yellow <<
"DESCRIPTION: " << Color::None << tc->m_description <<
"\n";
6063 if(tc->m_test_suite && tc->m_test_suite[0] !=
'\0')
6064 s << Color::Yellow <<
"TEST SUITE: " << Color::None << tc->m_test_suite <<
"\n";
6065 if(strncmp(tc->m_name,
" Scenario:", 11) != 0)
6066 s << Color::Yellow <<
"TEST CASE: ";
6067 s << Color::None << tc->m_name <<
"\n";
6069 for(
size_t i = 0; i < currentSubcaseLevel; ++i) {
6070 if(subcasesStack[i].m_name[0] !=
'\0')
6071 s <<
" " << subcasesStack[i].m_name <<
"\n";
6074 if(currentSubcaseLevel != subcasesStack.size()) {
6075 s << Color::Yellow <<
"\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None;
6076 for(
size_t i = 0; i < subcasesStack.size(); ++i) {
6077 if(subcasesStack[i].m_name[0] !=
'\0')
6078 s <<
" " << subcasesStack[i].m_name <<
"\n";
6084 hasLoggedCurrentTestStart =
true;
6087 void printVersion() {
6088 if(opt.no_version ==
false)
6089 s << Color::Cyan <<
"[doctest] " << Color::None <<
"doctest version is \""
6094 if(opt.no_intro ==
false) {
6096 s << Color::Cyan <<
"[doctest] " << Color::None
6097 <<
"run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY
"help\" for options\n";
6102 int sizePrefixDisplay =
static_cast<int>(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY));
6105 s << Color::Cyan <<
"[doctest]\n" << Color::None;
6106 s << Color::Cyan <<
"[doctest] " << Color::None;
6107 s <<
"boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n";
6108 s << Color::Cyan <<
"[doctest] " << Color::None;
6109 s <<
"filter values: \"str1,str2,str3\" (comma separated strings)\n";
6110 s << Color::Cyan <<
"[doctest]\n" << Color::None;
6111 s << Color::Cyan <<
"[doctest] " << Color::None;
6112 s <<
"filters use wildcards for matching strings\n";
6113 s << Color::Cyan <<
"[doctest] " << Color::None;
6114 s <<
"something passes a filter if any of the strings in a filter matches\n";
6115#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
6116 s << Color::Cyan <<
"[doctest]\n" << Color::None;
6117 s << Color::Cyan <<
"[doctest] " << Color::None;
6118 s <<
"ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX
"\" PREFIX!!!\n";
6120 s << Color::Cyan <<
"[doctest]\n" << Color::None;
6121 s << Color::Cyan <<
"[doctest] " << Color::None;
6122 s <<
"Query flags - the program quits after them. Available:\n\n";
6123 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"h "
6124 << Whitespace(sizePrefixDisplay*0) <<
"prints this message\n";
6125 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"version "
6126 << Whitespace(sizePrefixDisplay*1) <<
"prints the version\n";
6127 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"count "
6128 << Whitespace(sizePrefixDisplay*1) <<
"prints the number of matching tests\n";
6129 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"list-test-cases "
6130 << Whitespace(sizePrefixDisplay*1) <<
"lists all matching tests by name\n";
6131 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"list-test-suites "
6132 << Whitespace(sizePrefixDisplay*1) <<
"lists all matching test suites\n";
6133 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"list-reporters "
6134 << Whitespace(sizePrefixDisplay*1) <<
"lists all registered reporters\n\n";
6136 s << Color::Cyan <<
"[doctest] " << Color::None;
6137 s <<
"The available <int>/<string> options/filters are:\n\n";
6138 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"test-case=<filters> "
6139 << Whitespace(sizePrefixDisplay*1) <<
"filters tests by their name\n";
6140 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"test-case-exclude=<filters> "
6141 << Whitespace(sizePrefixDisplay*1) <<
"filters OUT tests by their name\n";
6142 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"source-file=<filters> "
6143 << Whitespace(sizePrefixDisplay*1) <<
"filters tests by their file\n";
6144 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"source-file-exclude=<filters> "
6145 << Whitespace(sizePrefixDisplay*1) <<
"filters OUT tests by their file\n";
6146 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"test-suite=<filters> "
6147 << Whitespace(sizePrefixDisplay*1) <<
"filters tests by their test suite\n";
6148 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"test-suite-exclude=<filters> "
6149 << Whitespace(sizePrefixDisplay*1) <<
"filters OUT tests by their test suite\n";
6150 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"subcase=<filters> "
6151 << Whitespace(sizePrefixDisplay*1) <<
"filters subcases by their name\n";
6152 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"subcase-exclude=<filters> "
6153 << Whitespace(sizePrefixDisplay*1) <<
"filters OUT subcases by their name\n";
6154 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"reporters=<filters> "
6155 << Whitespace(sizePrefixDisplay*1) <<
"reporters to use (console is default)\n";
6156 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"out=<string> "
6157 << Whitespace(sizePrefixDisplay*1) <<
"output filename\n";
6158 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"order-by=<string> "
6159 << Whitespace(sizePrefixDisplay*1) <<
"how the tests should be ordered\n";
6160 s << Whitespace(sizePrefixDisplay*3) <<
" <string> - [file/suite/name/rand/none]\n";
6161 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"rand-seed=<int> "
6162 << Whitespace(sizePrefixDisplay*1) <<
"seed for random ordering\n";
6163 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"first=<int> "
6164 << Whitespace(sizePrefixDisplay*1) <<
"the first test passing the filters to\n";
6165 s << Whitespace(sizePrefixDisplay*3) <<
" execute - for range-based execution\n";
6166 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"last=<int> "
6167 << Whitespace(sizePrefixDisplay*1) <<
"the last test passing the filters to\n";
6168 s << Whitespace(sizePrefixDisplay*3) <<
" execute - for range-based execution\n";
6169 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"abort-after=<int> "
6170 << Whitespace(sizePrefixDisplay*1) <<
"stop after <int> failed assertions\n";
6171 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY
"subcase-filter-levels=<int> "
6172 << Whitespace(sizePrefixDisplay*1) <<
"apply filters for the first <int> levels\n";
6173 s << Color::Cyan <<
"\n[doctest] " << Color::None;
6174 s <<
"Bool options - can be used like flags and true is assumed. Available:\n\n";
6175 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"success=<bool> "
6176 << Whitespace(sizePrefixDisplay*1) <<
"include successful assertions in output\n";
6177 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"case-sensitive=<bool> "
6178 << Whitespace(sizePrefixDisplay*1) <<
"filters being treated as case sensitive\n";
6179 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"exit=<bool> "
6180 << Whitespace(sizePrefixDisplay*1) <<
"exits after the tests finish\n";
6181 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"duration=<bool> "
6182 << Whitespace(sizePrefixDisplay*1) <<
"prints the time duration of each test\n";
6183 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"minimal=<bool> "
6184 << Whitespace(sizePrefixDisplay*1) <<
"minimal console output (only failures)\n";
6185 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"quiet=<bool> "
6186 << Whitespace(sizePrefixDisplay*1) <<
"no console output\n";
6187 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-throw=<bool> "
6188 << Whitespace(sizePrefixDisplay*1) <<
"skips exceptions-related assert checks\n";
6189 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-exitcode=<bool> "
6190 << Whitespace(sizePrefixDisplay*1) <<
"returns (or exits) always with success\n";
6191 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-run=<bool> "
6192 << Whitespace(sizePrefixDisplay*1) <<
"skips all runtime doctest operations\n";
6193 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-intro=<bool> "
6194 << Whitespace(sizePrefixDisplay*1) <<
"omit the framework intro in the output\n";
6195 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-version=<bool> "
6196 << Whitespace(sizePrefixDisplay*1) <<
"omit the framework version in the output\n";
6197 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-colors=<bool> "
6198 << Whitespace(sizePrefixDisplay*1) <<
"disables colors in output\n";
6199 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"force-colors=<bool> "
6200 << Whitespace(sizePrefixDisplay*1) <<
"use colors even when not in a tty\n";
6201 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-breaks=<bool> "
6202 << Whitespace(sizePrefixDisplay*1) <<
"disables breakpoints in debuggers\n";
6203 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-skip=<bool> "
6204 << Whitespace(sizePrefixDisplay*1) <<
"don't skip test cases marked as skip\n";
6205 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"gnu-file-line=<bool> "
6206 << Whitespace(sizePrefixDisplay*1) <<
":n: vs (n): for line numbers in output\n";
6207 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-path-filenames=<bool> "
6208 << Whitespace(sizePrefixDisplay*1) <<
"only filenames and no paths in output\n";
6209 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"spp, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"skip-path-prefixes=<p1:p2> "
6210 << Whitespace(sizePrefixDisplay*1) <<
"whenever file paths start with this prefix, remove it from the output\n";
6211 s <<
" -" DOCTEST_OPTIONS_PREFIX_DISPLAY
"nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY
"no-line-numbers=<bool> "
6212 << Whitespace(sizePrefixDisplay*1) <<
"0 instead of real line numbers in output\n";
6216 s << Color::Cyan <<
"\n[doctest] " << Color::None;
6217 s <<
"for more information visit the project documentation\n\n";
6220 void printRegisteredReporters() {
6222 auto printReporters = [
this] (
const reporterMap& reporters,
const char* type) {
6223 if(reporters.size()) {
6224 s << Color::Cyan <<
"[doctest] " << Color::None <<
"listing all registered " << type <<
"\n";
6225 for(
auto& curr : reporters)
6226 s <<
"priority: " <<
std::setw(5) << curr.first.first
6227 <<
" name: " << curr.first.second <<
"\n";
6230 printReporters(getListeners(),
"listeners");
6231 printReporters(getReporters(),
"reporters");
6238 void report_query(
const QueryData& in)
override {
6241 }
else if(opt.help) {
6243 }
else if(opt.list_reporters) {
6244 printRegisteredReporters();
6245 }
else if(opt.count || opt.list_test_cases) {
6246 if(opt.list_test_cases) {
6247 s << Color::Cyan <<
"[doctest] " << Color::None
6248 <<
"listing all test case names\n";
6249 separator_to_stream();
6252 for(
unsigned i = 0; i < in.num_data; ++i)
6253 s << Color::None << in.data[i]->m_name <<
"\n";
6255 separator_to_stream();
6257 s << Color::Cyan <<
"[doctest] " << Color::None
6258 <<
"unskipped test cases passing the current filters: "
6259 << g_cs->numTestCasesPassingFilters <<
"\n";
6261 }
else if(opt.list_test_suites) {
6262 s << Color::Cyan <<
"[doctest] " << Color::None <<
"listing all test suites\n";
6263 separator_to_stream();
6265 for(
unsigned i = 0; i < in.num_data; ++i)
6266 s << Color::None << in.data[i]->m_test_suite <<
"\n";
6268 separator_to_stream();
6270 s << Color::Cyan <<
"[doctest] " << Color::None
6271 <<
"unskipped test cases passing the current filters: "
6272 << g_cs->numTestCasesPassingFilters <<
"\n";
6273 s << Color::Cyan <<
"[doctest] " << Color::None
6274 <<
"test suites with unskipped test cases passing the current filters: "
6275 << g_cs->numTestSuitesPassingFilters <<
"\n";
6279 void test_run_start()
override {
6284 void test_run_end(
const TestRunStats& p)
override {
6285 if(opt.minimal && p.numTestCasesFailed == 0)
6288 separator_to_stream();
6291 auto totwidth = int(std::ceil(log10(
static_cast<double>(std::max(p.numTestCasesPassingFilters,
static_cast<unsigned>(p.numAsserts))) + 1)));
6292 auto passwidth = int(std::ceil(log10(
static_cast<double>(std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed,
static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
6293 auto failwidth = int(std::ceil(log10(
static_cast<double>(std::max(p.numTestCasesFailed,
static_cast<unsigned>(p.numAssertsFailed))) + 1)));
6294 const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
6295 s << Color::Cyan <<
"[doctest] " << Color::None <<
"test cases: " << std::setw(totwidth)
6296 << p.numTestCasesPassingFilters <<
" | "
6297 << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
6299 <<
std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed <<
" passed"
6300 << Color::
None <<
" | " << (p.numTestCasesFailed > 0 ? Color::
Red : Color::
None)
6301 <<
std::setw(failwidth) << p.numTestCasesFailed <<
" failed" << Color::
None <<
" |";
6302 if(opt.no_skipped_summary ==
false) {
6303 const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
6304 s <<
" " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
6305 <<
" skipped" << Color::None;
6308 s << Color::Cyan <<
"[doctest] " << Color::None <<
"assertions: " << std::setw(totwidth)
6309 << p.numAsserts <<
" | "
6310 << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::
Green)
6311 <<
std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) <<
" passed" << Color::
None
6312 <<
" | " << (p.numAssertsFailed > 0 ? Color::
Red : Color::
None) <<
std::setw(failwidth)
6313 << p.numAssertsFailed <<
" failed" << Color::
None <<
" |\n";
6314 s << Color::Cyan <<
"[doctest] " << Color::None
6315 <<
"Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
6316 << ((p.numTestCasesFailed > 0) ?
"FAILURE!" :
"SUCCESS!") << Color::None << std::endl;
6319 void test_case_start(
const TestCaseData& in)
override {
6320 hasLoggedCurrentTestStart =
false;
6322 subcasesStack.clear();
6323 currentSubcaseLevel = 0;
6326 void test_case_reenter(
const TestCaseData&)
override {
6327 subcasesStack.clear();
6330 void test_case_end(
const CurrentTestCaseStats& st)
override {
6337 (st.failure_flags && st.failure_flags !=
static_cast<int>(TestCaseFailureReason::AssertFailure)))
6341 s << Color::None << std::setprecision(6) << std::fixed << st.seconds
6342 <<
" s: " << tc->m_name <<
"\n";
6344 if(st.failure_flags & TestCaseFailureReason::Timeout)
6345 s << Color::Red <<
"Test case exceeded time limit of " << std::setprecision(6)
6346 << std::fixed << tc->m_timeout <<
"!\n";
6348 if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) {
6349 s << Color::Red <<
"Should have failed but didn't! Marking it as failed!\n";
6350 }
else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) {
6351 s << Color::Yellow <<
"Failed as expected so marking it as not failed\n";
6352 }
else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) {
6353 s << Color::Yellow <<
"Allowed to fail so marking it as not failed\n";
6354 }
else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) {
6355 s << Color::Red <<
"Didn't fail exactly " << tc->m_expected_failures
6356 <<
" times so marking it as failed!\n";
6357 }
else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) {
6358 s << Color::Yellow <<
"Failed exactly " << tc->m_expected_failures
6359 <<
" times as expected so marking it as not failed!\n";
6361 if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) {
6362 s << Color::Red <<
"Aborting - too many failed asserts!\n";
6367 void test_case_exception(
const TestCaseException& e)
override {
6368 DOCTEST_LOCK_MUTEX(
mutex)
6374 file_line_to_stream(tc->m_file.c_str(), tc->m_line,
" ");
6375 successOrFailColoredStringToStream(
false, e.is_crash ? assertType::is_require :
6377 s << Color::Red << (e.is_crash ?
"test case CRASHED: " :
"test case THREW exception: ")
6378 << Color::Cyan << e.error_string <<
"\n";
6380 int num_stringified_contexts = get_num_stringified_contexts();
6381 if(num_stringified_contexts) {
6382 auto stringified_contexts = get_stringified_contexts();
6383 s << Color::None <<
" logged: ";
6384 for(
int i = num_stringified_contexts; i > 0; --i) {
6385 s << (i == num_stringified_contexts ?
"" :
" ")
6386 << stringified_contexts[i - 1] <<
"\n";
6389 s <<
"\n" << Color::None;
6392 void subcase_start(
const SubcaseSignature& subc)
override {
6393 subcasesStack.push_back(subc);
6394 ++currentSubcaseLevel;
6395 hasLoggedCurrentTestStart =
false;
6398 void subcase_end()
override {
6399 --currentSubcaseLevel;
6400 hasLoggedCurrentTestStart =
false;
6403 void log_assert(
const AssertData& rb)
override {
6404 if((!rb.m_failed && !opt.success) || tc->m_no_output)
6407 DOCTEST_LOCK_MUTEX(
mutex)
6411 file_line_to_stream(rb.m_file, rb.m_line,
" ");
6412 successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);
6414 fulltext_log_assert_to_stream(
s, rb);
6419 void log_message(
const MessageData& mb)
override {
6423 DOCTEST_LOCK_MUTEX(
mutex)
6427 file_line_to_stream(mb.m_file, mb.m_line,
" ");
6428 s << getSuccessOrFailColor(
false, mb.m_severity)
6429 << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
6431 s << Color::None << mb.m_string <<
"\n";
6435 void test_case_skipped(
const TestCaseData&)
override {}
6440#ifdef DOCTEST_PLATFORM_WINDOWS
6441 struct DebugOutputWindowReporter :
public ConsoleReporter
6443 DOCTEST_THREAD_LOCAL
static std::ostringstream oss;
6445 DebugOutputWindowReporter(
const ContextOptions& co)
6446 : ConsoleReporter(co, oss) {}
6448#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \
6449 void func(type arg) override { \
6450 bool with_col = g_no_colors; \
6451 g_no_colors = false; \
6452 ConsoleReporter::func(arg); \
6453 if(oss.tellp() != std::streampos{}) { \
6454 DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
6457 g_no_colors = with_col; \
6461 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end,
const TestRunStats&, in)
6462 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start,
const TestCaseData&, in)
6463 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter,
const TestCaseData&, in)
6464 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end,
const CurrentTestCaseStats&, in)
6465 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception,
const TestCaseException&, in)
6466 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start,
const SubcaseSignature&, in)
6468 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert,
const AssertData&, in)
6469 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message,
const MessageData&, in)
6470 DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped,
const TestCaseData&, in)
6473 DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss;
6477 bool parseOptionImpl(
int argc,
const char*
const* argv,
const char* pattern, String*
value) {
6479 for(
int i = argc; i > 0; --i) {
6481 auto temp = std::strstr(argv[
index], pattern);
6482 if(temp && (
value || strlen(temp) == strlen(pattern))) {
6484 bool noBadCharsFound =
true;
6485 auto curr = argv[
index];
6486 while(curr != temp) {
6487 if(*curr++ !=
'-') {
6488 noBadCharsFound =
false;
6492 if(noBadCharsFound && argv[
index][0] ==
'-') {
6495 temp += strlen(pattern);
6496 const unsigned len = strlen(temp);
6512 bool parseOption(
int argc,
const char*
const* argv,
const char* pattern, String*
value =
nullptr,
6513 const String& defaultVal = String()) {
6515 *
value = defaultVal;
6516#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
6518 if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX),
value))
6521 return parseOptionImpl(argc, argv, pattern,
value);
6525 bool parseFlag(
int argc,
const char*
const* argv,
const char* pattern) {
6526 return parseOption(argc, argv, pattern);
6530 bool parseCommaSepArgs(
int argc,
const char*
const* argv,
const char* pattern,
6531 std::vector<String>& res) {
6532 String filtersString;
6533 if(parseOption(argc, argv, pattern, &filtersString)) {
6535 std::ostringstream
s;
6536 auto flush = [&
s, &res]() {
6537 auto string =
s.str();
6538 if(
string.size() > 0) {
6539 res.push_back(
string.c_str());
6544 bool seenBackslash =
false;
6545 const char* current = filtersString.c_str();
6546 const char* end = current + strlen(current);
6547 while(current != end) {
6548 char character = *current++;
6550 seenBackslash =
false;
6551 if(character ==
',' || character ==
'\\') {
6557 if(character ==
'\\') {
6558 seenBackslash =
true;
6559 }
else if(character ==
',') {
6582 bool parseIntOption(
int argc,
const char*
const* argv,
const char* pattern, optionType type,
6585 if(!parseOption(argc, argv, pattern, &parsedValue))
6591 int theInt = std::atoi(parsedValue.c_str());
6598 const char positive[][5] = {
"1",
"true",
"on",
"yes" };
6599 const char negative[][6] = {
"0",
"false",
"off",
"no" };
6602 for (
unsigned i = 0; i < 4; i++) {
6603 if (parsedValue.compare(positive[i],
true) == 0) {
6607 if (parsedValue.compare(negative[i],
true) == 0) {
6617Context::Context(
int argc,
const char*
const* argv)
6618 : p(new detail::ContextState) {
6619 parseArgs(argc, argv,
true);
6621 p->binary_name = argv[0];
6624Context::~Context() {
6630void Context::applyCommandLine(
int argc,
const char*
const* argv) {
6631 parseArgs(argc, argv);
6633 p->binary_name = argv[0];
6637void Context::parseArgs(
int argc,
const char*
const* argv,
bool withDefaults) {
6638 using namespace detail;
6641 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"source-file=", p->filters[0]);
6642 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"sf=", p->filters[0]);
6643 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"source-file-exclude=",p->filters[1]);
6644 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"sfe=", p->filters[1]);
6645 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"test-suite=", p->filters[2]);
6646 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"ts=", p->filters[2]);
6647 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"test-suite-exclude=", p->filters[3]);
6648 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"tse=", p->filters[3]);
6649 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"test-case=", p->filters[4]);
6650 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"tc=", p->filters[4]);
6651 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"test-case-exclude=", p->filters[5]);
6652 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"tce=", p->filters[5]);
6653 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"subcase=", p->filters[6]);
6654 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"sc=", p->filters[6]);
6655 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"subcase-exclude=", p->filters[7]);
6656 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"sce=", p->filters[7]);
6657 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"reporters=", p->filters[8]);
6658 parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"r=", p->filters[8]);
6664#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
6665 if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
6666 parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
6667 p->var = static_cast<bool>(intRes); \
6668 else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
6669 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
6671 else if(withDefaults) \
6674#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
6675 if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \
6676 parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \
6678 else if(withDefaults) \
6681#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
6682 if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \
6683 parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \
6688 DOCTEST_PARSE_STR_OPTION(
"out",
"o", out,
"");
6689 DOCTEST_PARSE_STR_OPTION(
"order-by",
"ob", order_by,
"file");
6690 DOCTEST_PARSE_INT_OPTION(
"rand-seed",
"rs", rand_seed, 0);
6692 DOCTEST_PARSE_INT_OPTION(
"first",
"f", first, 0);
6693 DOCTEST_PARSE_INT_OPTION(
"last",
"l", last, UINT_MAX);
6695 DOCTEST_PARSE_INT_OPTION(
"abort-after",
"aa", abort_after, 0);
6696 DOCTEST_PARSE_INT_OPTION(
"subcase-filter-levels",
"scfl", subcase_filter_levels, INT_MAX);
6698 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"success",
"s", success,
false);
6699 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"case-sensitive",
"cs", case_sensitive,
false);
6700 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"exit",
"e", exit,
false);
6701 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"duration",
"d", duration,
false);
6702 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"minimal",
"m", minimal,
false);
6703 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"quiet",
"q", quiet,
false);
6704 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-throw",
"nt", no_throw,
false);
6705 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-exitcode",
"ne", no_exitcode,
false);
6706 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-run",
"nr", no_run,
false);
6707 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-intro",
"ni", no_intro,
false);
6708 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-version",
"nv", no_version,
false);
6709 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-colors",
"nc", no_colors,
false);
6710 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"force-colors",
"fc", force_colors,
false);
6711 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-breaks",
"nb", no_breaks,
false);
6712 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-skip",
"ns", no_skip,
false);
6713 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"gnu-file-line",
"gfl", gnu_file_line, !
bool(
DOCTEST_MSVC));
6714 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-path-filenames",
"npf", no_path_in_filenames,
false);
6715 DOCTEST_PARSE_STR_OPTION(
"strip-file-prefixes",
"sfp", strip_file_prefixes,
"");
6716 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-line-numbers",
"nln", no_line_numbers,
false);
6717 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-debug-output",
"ndo", no_debug_output,
false);
6718 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-skipped-summary",
"nss", no_skipped_summary,
false);
6719 DOCTEST_PARSE_AS_BOOL_OR_FLAG(
"no-time-in-output",
"ntio", no_time_in_output,
false);
6726 p->list_test_cases =
false;
6727 p->list_test_suites =
false;
6728 p->list_reporters =
false;
6730 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"help") ||
6731 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"h") ||
6732 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"?")) {
6736 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"version") ||
6737 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"v")) {
6741 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"count") ||
6742 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"c")) {
6746 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"list-test-cases") ||
6747 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"ltc")) {
6748 p->list_test_cases =
true;
6751 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"list-test-suites") ||
6752 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"lts")) {
6753 p->list_test_suites =
true;
6756 if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"list-reporters") ||
6757 parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX
"lr")) {
6758 p->list_reporters =
true;
6764void Context::addFilter(
const char* filter,
const char*
value) { setOption(filter,
value); }
6767void Context::clearFilters() {
6768 for(
auto& curr : p->filters)
6773void Context::setOption(
const char* option,
bool value) {
6774 setOption(option,
value ?
"true" :
"false");
6778void Context::setOption(
const char* option,
int value) {
6783void Context::setOption(
const char* option,
const char*
value) {
6784 auto argv = String(
"-") + option +
"=" +
value;
6785 auto lvalue = argv.c_str();
6786 parseArgs(1, &lvalue);
6790bool Context::shouldExit() {
return p->exit; }
6792void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; }
6794void Context::setAssertHandler(detail::assert_handler
ah) { p->ah =
ah; }
6796void Context::setCout(
std::ostream* out) { p->cout = out; }
6801 class :
public std::streambuf
6808 std::streamsize xsputn(
const char_type*, std::streamsize count)
override {
return count; }
6810 int_type overflow(int_type ch)
override {
6811 setp(std::begin(buf), std::end(buf));
6812 return traits_type::not_eof(ch);
6823 using namespace detail;
6831 g_no_colors = p->no_colors;
6835 if(p->cout ==
nullptr) {
6837 p->cout = &discardOut;
6838 }
else if(p->out.size()) {
6840 fstr.open(p->out.c_str(), std::fstream::out);
6843#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
6845 p->cout = &std::cout;
6847 return EXIT_FAILURE;
6852 FatalConditionHandler::allocateAltStackMem();
6854 auto cleanup_and_return = [&]() {
6855 FatalConditionHandler::freeAltStackMem();
6865 for(
auto& curr : p->reporters_currently_used)
6867 p->reporters_currently_used.clear();
6869 if(p->numTestCasesFailed && !p->no_exitcode)
6870 return EXIT_FAILURE;
6871 return EXIT_SUCCESS;
6875 if(p->filters[8].empty())
6876 p->filters[8].push_back(
"console");
6879 for(
auto& curr : getReporters()) {
6880 if(matchesAny(curr.first.second.c_str(), p->filters[8],
false, p->case_sensitive))
6881 p->reporters_currently_used.push_back(curr.second(*g_cs));
6887 for(
auto& curr : getListeners())
6888 p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
6890#ifdef DOCTEST_PLATFORM_WINDOWS
6892 p->reporters_currently_used.push_back(
new DebugOutputWindowReporter(*g_cs));
6896 if(p->no_run || p->version || p->help || p->list_reporters) {
6897 DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData());
6899 return cleanup_and_return();
6902 std::vector<const TestCase*> testArray;
6903 for(
auto& curr : getRegisteredTests())
6904 testArray.push_back(&curr);
6905 p->numTestCases = testArray.size();
6908 if(!testArray.empty()) {
6909 if(p->order_by.compare(
"file",
true) == 0) {
6910 std::sort(testArray.begin(), testArray.end(), fileOrderComparator);
6911 }
else if(p->order_by.compare(
"suite",
true) == 0) {
6912 std::sort(testArray.begin(), testArray.end(), suiteOrderComparator);
6913 }
else if(p->order_by.compare(
"name",
true) == 0) {
6914 std::sort(testArray.begin(), testArray.end(), nameOrderComparator);
6915 }
else if(p->order_by.compare(
"rand",
true) == 0) {
6916 std::srand(p->rand_seed);
6919 const auto first = &testArray[0];
6920 for(
size_t i = testArray.size() - 1; i > 0; --i) {
6921 int idxToSwap = std::rand() % (i + 1);
6923 const auto temp = first[i];
6925 first[i] = first[idxToSwap];
6926 first[idxToSwap] = temp;
6928 }
else if(p->order_by.compare(
"none",
true) == 0) {
6934 std::set<String> testSuitesPassingFilt;
6936 bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
6937 std::vector<const TestCaseData*> queryResults;
6940 DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start,
DOCTEST_EMPTY);
6943 for(
auto& curr : testArray) {
6944 const auto& tc = *curr;
6946 bool skip_me =
false;
6947 if(tc.m_skip && !p->no_skip)
6950 if(!matchesAny(tc.m_file.c_str(), p->filters[0],
true, p->case_sensitive))
6952 if(matchesAny(tc.m_file.c_str(), p->filters[1],
false, p->case_sensitive))
6954 if(!matchesAny(tc.m_test_suite, p->filters[2],
true, p->case_sensitive))
6956 if(matchesAny(tc.m_test_suite, p->filters[3],
false, p->case_sensitive))
6958 if(!matchesAny(tc.m_name, p->filters[4],
true, p->case_sensitive))
6960 if(matchesAny(tc.m_name, p->filters[5],
false, p->case_sensitive))
6964 p->numTestCasesPassingFilters++;
6967 if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) ||
6968 (p->first > p->numTestCasesPassingFilters))
6973 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc);
6982 if(p->list_test_cases) {
6983 queryResults.push_back(&tc);
6988 if(p->list_test_suites) {
6989 if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] !=
'\0') {
6990 queryResults.push_back(&tc);
6991 testSuitesPassingFilt.insert(tc.m_test_suite);
6992 p->numTestSuitesPassingFilters++;
6999 p->currentTest = &tc;
7001 p->failure_flags = TestCaseFailureReason::None;
7005 p->numAssertsFailedCurrentTest_atomic = 0;
7006 p->numAssertsCurrentTest_atomic = 0;
7008 p->fullyTraversedSubcases.clear();
7010 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);
7014 bool run_test =
true;
7018 p->reachedLeaf =
false;
7020 p->subcaseStack.clear();
7021 p->currentSubcaseDepth = 0;
7023 p->shouldLogCurrentException =
true;
7026 p->stringifiedContexts.clear();
7028#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
7033 FatalConditionHandler fatalConditionHandler;
7036 fatalConditionHandler.reset();
7038#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
7039 }
catch(
const TestFailureException&) {
7040 p->failure_flags |= TestCaseFailureReason::AssertFailure;
7042 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception,
7043 {translateActiveException(),
false});
7044 p->failure_flags |= TestCaseFailureReason::Exception;
7049 if(p->abort_after > 0 &&
7050 p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) {
7052 p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;
7055 if(!p->nextSubcaseStack.empty() && run_test)
7056 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);
7057 if(p->nextSubcaseStack.empty())
7061 p->finalizeTestCaseData();
7063 DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
7065 p->currentTest =
nullptr;
7068 if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after)
7074 DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
7077 qdata.run_stats = g_cs;
7078 qdata.data = queryResults.data();
7079 qdata.num_data = unsigned(queryResults.size());
7080 DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata);
7083 return cleanup_and_return();
7088int IReporter::get_num_active_contexts() {
return detail::g_infoContexts.size(); }
7089const IContextScope*
const* IReporter::get_active_contexts() {
7090 return get_num_active_contexts() ? &detail::g_infoContexts[0] :
nullptr;
7093int IReporter::get_num_stringified_contexts() {
return detail::g_cs->stringifiedContexts.size(); }
7094const String* IReporter::get_stringified_contexts() {
7095 return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] :
nullptr;
7101 getReporters().insert(reporterMap::value_type(reporterMap::key_type(
priority,
name), c));
7103 getListeners().insert(reporterMap::value_type(reporterMap::key_type(
priority,
name), c));
7111#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
7126#ifdef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
7127#undef WIN32_LEAN_AND_MEAN
7128#undef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
7131#ifdef DOCTEST_UNDEF_NOMINMAX
7133#undef DOCTEST_UNDEF_NOMINMAX
const char * c_str() const
StringContains(const String &str)
StringContains(Contains cntn)
bool check(const String &str)
bool checkWith(const String &other) const
Contains(const String &string)
Context(const Context &)=delete
Context(Context &&)=delete
Context & operator=(Context &&)=delete
void setOption(const char *option, const char *value)
void setCout(std::ostream *out)
void addFilter(const char *filter, const char *value)
void setAssertHandler(detail::assert_handler ah)
void setOption(const char *option, bool value)
Context(int argc=0, const char *const *argv=nullptr)
void parseArgs(int argc, const char *const *argv, bool withDefaults=false)
void setOption(const char *option, int value)
Context & operator=(const Context &)=delete
void applyCommandLine(int argc, const char *const *argv)
void setAsDefaultForAssertsOutOfTestCases()
size_type capacity() const
bool isOnStack() const noexcept
const char * c_str() const
size_type rfind(char ch, size_type pos=npos) const
String substr(size_type pos, size_type cnt=npos) &&
char * allocate(size_type sz)
friend DOCTEST_INTERFACE std::ostream & operator<<(std::ostream &s, const String &in)
DOCTEST_CONFIG_STRING_SIZE_TYPE size_type
size_type find(char ch, size_type pos=0) const
String substr(size_type pos, size_type cnt=npos) const &
int compare(const String &other, bool no_case=false) const
void setOnHeap() noexcept
int compare(const char *other, bool no_case=false) const
ContextScope(const L &lambda)
ContextScope(const ContextScope &)=delete
ContextScope(ContextScope &&) noexcept=default
OCLINT destructor of virtual class.
ExceptionTranslator(String(*translateFunction)(T))
bool translate(String &res) const override
#define TestSuite(Name,...)
CURL_EXTERN int void * arg
#define DOCTEST_FORBIT_EXPRESSION(rt, op)
#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH)
#define DOCTEST_STRINGIFY(...)
#define DOCTEST_BREAK_INTO_DEBUGGER()
#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
#define DOCTEST_VERSION_STR
#define DOCTEST_RELATIONAL_OP(name, op)
#define DOCTEST_CMP_LE(l, r)
#define DOCTEST_GCC_SUPPRESS_WARNING(w)
#define DOCTEST_TEST_SUITE_END
#define DOCTEST_INTERFACE_DECL
#define DOCTEST_CMP_NE(l, r)
#define DOCTEST_DEFINE_INTERFACE(name)
#define DOCTEST_MSVC_SUPPRESS_WARNING_POP
#define DOCTEST_CLANG_SUPPRESS_WARNING_POP
#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
#define DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_CMP_GT(l, r)
#define DOCTEST_BINARY_RELATIONAL_OP(n, op)
#define DOCTEST_DEFINE_DECORATOR(name, type, def)
#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
#define DOCTEST_CMP_GE(l, r)
#define DOCTEST_ASSERT_IN_TESTS(decomp)
#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro)
#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_INTERFACE
#define DOCTEST_CONFIG_STRING_SIZE_TYPE
#define DOCTEST_DECLARE_INTERFACE(name)
#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp)
#define DOCTEST_CONSTEXPR
#define DOCTEST_NO_SANITIZE_INTEGER
#define DOCTEST_CLANG_SUPPRESS_WARNING(w)
#define DOCTEST_MSVC_SUPPRESS_WARNING(w)
#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
#define DOCTEST_CMP_LT(l, r)
#define DOCTEST_INTERFACE_DEF
#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
#define DOCTEST_CONSTEXPR_FUNC
#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
#define DOCTEST_REF_WRAP(x)
#define DOCTEST_CMP_EQ(l, r)
static void atomic(lua_State *L)
static const struct @51 priority[]
static void field(LexState *ls, expdesc *v)
static void expr(LexState *ls, expdesc *v)
static int writer(lua_State *L, const void *b, size_t size, void *B)
static void error(LoadState *S, const char *why)
CURL_EXTERN CURLMcode curl_socket_t s
DOCTEST_INTERFACE std::ostream & operator<<(std::ostream &s, Color::Enum code)
@ ShouldHaveFailedButDidnt
@ DidntFailExactlyNumTimes
@ DT_CHECK_THROWS_WITH_AS
@ DT_REQUIRE_THROWS_WITH_AS
DOCTEST_INTERFACE int regTest(const TestCase &tc)
DOCTEST_INTERFACE bool isDebuggerActive()
DOCTEST_INTERFACE std::ostream * tlssPush()
DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData &ad)
DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char *file, int line, const char *expr, const DOCTEST_REF_WRAP(L) val)
DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char *file, int line, const char *expr, const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs)
DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char *file, int line, const char *expr, const Result &result)
void filloss(std::ostream *stream, const T &in)
DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator *et)
IReporter *(*)(const ContextOptions &) reporterCreatorFunc
DOCTEST_INTERFACE void throwException()
String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char *op, const DOCTEST_REF_WRAP(R) rhs)
static DOCTEST_CONSTEXPR int consume(const int *, int) noexcept
DOCTEST_INTERFACE void registerReporterImpl(const char *name, int prio, reporterCreatorFunc c, bool isReporter)
DOCTEST_INTERFACE String tlssPop()
void(*)(const AssertData &) assert_handler
String toStream(const T &in)
int instantiationHelper(const T &)
DOCTEST_CONSTEXPR_FUNC T && forward(typename types::remove_reference< T >::type &t) DOCTEST_NOEXCEPT
IReporter * reporterCreator(const ContextOptions &o)
DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at)
struct DOCTEST_INTERFACE TestCase
DOCTEST_INTERFACE int setTestSuite(const TestSuite &ts)
ContextScope< L > MakeContextScope(const L &lambda)
DOCTEST_INTERFACE doctest::detail::TestSuite & getCurrentTestSuite()
DOCTEST_INTERFACE bool is_running_in_test
DOCTEST_INTERFACE const ContextOptions * getContextOptions()
DOCTEST_INTERFACE bool operator<=(const String &lhs, const String &rhs)
DOCTEST_INTERFACE const char * skipPathFromFilename(const char *file)
DOCTEST_INTERFACE const char * failureString(assertType::Enum at)
DOCTEST_INTERFACE const char * assertString(assertType::Enum at)
DOCTEST_INTERFACE String operator+(const String &lhs, const String &rhs)
int registerExceptionTranslator(String(*translateFunction)(T))
int registerReporter(const char *name, int priority, bool isReporter)
DOCTEST_INTERFACE bool operator!=(const String &lhs, const String &rhs)
DOCTEST_INTERFACE bool operator>=(const String &lhs, const String &rhs)
DOCTEST_INTERFACE bool operator>(const String &lhs, const String &rhs)
DOCTEST_INTERFACE bool operator==(const String &lhs, const String &rhs)
DOCTEST_INTERFACE String toString(const Contains &in)
DOCTEST_INTERFACE bool operator<(const String &lhs, const String &rhs)
decltype(nullptr) nullptr_t
decltype(sizeof(void *)) size_t
basic_ostream< char, traits > & operator<<(basic_ostream< char, traits > &, const char *)
Approx & scale(double newScale)
DOCTEST_INTERFACE friend bool operator==(const Approx &lhs, double rhs)
DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx &rhs)
Approx & epsilon(double newEpsilon)
DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx &rhs)
DOCTEST_INTERFACE friend bool operator>=(const Approx &lhs, double rhs)
DOCTEST_INTERFACE friend bool operator<=(const Approx &lhs, double rhs)
Approx operator()(double value) const
DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx &rhs)
DOCTEST_INTERFACE friend bool operator!=(const Approx &lhs, double rhs)
DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx &rhs)
const char * m_exception_type
const TestCaseData * m_test_case
AssertData(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type, const StringContains &exception_string)
bool no_path_in_filenames
String strip_file_prefixes
int subcase_filter_levels
int numAssertsFailedCurrentTest
int numAssertsCurrentTest
virtual void subcase_start(const SubcaseSignature &)=0
virtual void subcase_end()=0
virtual void log_message(const MessageData &)=0
virtual void test_case_exception(const TestCaseException &)=0
virtual void test_case_end(const CurrentTestCaseStats &)=0
virtual void test_case_reenter(const TestCaseData &)=0
virtual void log_assert(const AssertData &)=0
virtual void test_run_end(const TestRunStats &)=0
virtual void test_run_start()=0
virtual void test_case_skipped(const TestCaseData &)=0
virtual void report_query(const QueryData &)=0
virtual void test_case_start(const TestCaseData &)=0
IsNaN(F f, bool flip=false)
IsNaN< F > operator!() const
assertType::Enum m_severity
OCLINT avoid private static members.
bool operator<(const SubcaseSignature &other) const
bool operator==(const SubcaseSignature &other) const
const char * m_description
const char * m_test_suite
unsigned numTestCasesFailed
unsigned numTestSuitesPassingFilters
unsigned numTestCasesPassingFilters
ContextScopeBase(ContextScopeBase &&other) noexcept
~ContextScopeBase() override=default
ContextScopeBase(const ContextScopeBase &)=delete
ContextScopeBase & operator=(const ContextScopeBase &)=delete
ContextScopeBase & operator=(ContextScopeBase &&)=delete
ExpressionDecomposer(assertType::Enum at)
Expression_lhs(L &&in, assertType::Enum at)
MessageBuilder(MessageBuilder &&)=delete
MessageBuilder & operator=(MessageBuilder &&)=delete
DOCTEST_MSVC_SUPPRESS_WARNING_POP MessageBuilder & operator<<(const T &in)
MessageBuilder(const char *file, int line, assertType::Enum severity)
MessageBuilder & operator*(const T &in)
MessageBuilder(const MessageBuilder &)=delete
MessageBuilder & operator=(const MessageBuilder &)=delete
bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R)) const
ResultBuilder(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type="", const String &exception_string="")
void translateException()
DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val)
void setResult(const Result &res)
DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs)
ResultBuilder(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type, const Contains &exception_string)
Result(bool passed, const String &decomposition=String())
static String convert(const DOCTEST_REF_WRAP(T) in)
static String convert(const DOCTEST_REF_WRAP(T))
Subcase & operator=(const Subcase &)=delete
SubcaseSignature m_signature
Subcase(const String &name, const char *file, int line)
Subcase(const Subcase &)=delete
Subcase(Subcase &&)=delete
Subcase & operator=(Subcase &&)=delete
TestCase(funcType test, const char *file, unsigned line, const TestSuite &test_suite, const String &type=String(), int template_id=-1)
TestCase(const TestCase &other)
TestCase(TestCase &&)=delete
bool operator<(const TestCase &other) const
TestSuite & operator*(const T &in)
TestSuite & operator*(const char *in)
static void fill(std::ostream *stream, const T(&in)[N])
static void fill(std::ostream *stream, const char(&in)[N])
static void fill(std::ostream *stream, const void *in)
static void fill(std::ostream *stream, const T &in)
__underlying_type(T) type