This is an automated email from the ASF dual-hosted git repository.
jdanek pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/main by this push:
new 6cb1fd4 NO-JIRA upgrade doctest.h from 2.4.6 to 2.4.7
6cb1fd4 is described below
commit 6cb1fd4d783dcdb2841d81545cce421a1773ad81
Author: Jiri Daněk <[email protected]>
AuthorDate: Wed Jan 5 12:41:06 2022 +0100
NO-JIRA upgrade doctest.h from 2.4.6 to 2.4.7
---
tests/c_unittests/doctest.h | 508 +++++++++++++++++++++++++++++---------------
1 file changed, 339 insertions(+), 169 deletions(-)
diff --git a/tests/c_unittests/doctest.h b/tests/c_unittests/doctest.h
index 42eb039..cd5b44d 100644
--- a/tests/c_unittests/doctest.h
+++ b/tests/c_unittests/doctest.h
@@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
-#define DOCTEST_VERSION_PATCH 6
-#define DOCTEST_VERSION_STR "2.4.6"
+#define DOCTEST_VERSION_PATCH 7
+#define DOCTEST_VERSION_STR "2.4.7"
#define DOCTEST_VERSION
\
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 +
DOCTEST_VERSION_PATCH)
@@ -176,6 +176,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment
operator was implicitly d
DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined
as deleted
DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly
defined as deleted
DOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is
not thread-safe
+DOCTEST_MSVC_SUPPRESS_WARNING(5045) // Spectre mitigation for memory load
// static analysis
DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw.
Declare it 'noexcept'
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
@@ -312,13 +313,29 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum
class' over 'enum'
#endif
#ifndef DOCTEST_NORETURN
+#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
+#define DOCTEST_NORETURN
+#else // DOCTEST_MSVC
#define DOCTEST_NORETURN [[noreturn]]
+#endif // DOCTEST_MSVC
#endif // DOCTEST_NORETURN
#ifndef DOCTEST_NOEXCEPT
+#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
+#define DOCTEST_NOEXCEPT
+#else // DOCTEST_MSVC
#define DOCTEST_NOEXCEPT noexcept
+#endif // DOCTEST_MSVC
#endif // DOCTEST_NOEXCEPT
+#ifndef DOCTEST_CONSTEXPR
+#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
+#define DOCTEST_CONSTEXPR const
+#else // DOCTEST_MSVC
+#define DOCTEST_CONSTEXPR constexpr
+#endif // DOCTEST_MSVC
+#endif // DOCTEST_CONSTEXPR
+
//
=================================================================================================
// == FEATURE DETECTION END
========================================================================
//
=================================================================================================
@@ -427,12 +444,14 @@ typedef basic_ostream<char, char_traits<char>> ostream;
template <class... Types>
class tuple;
#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
+DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wreserved-identifier")
// see this issue on why this is needed:
https://github.com/onqtam/doctest/issues/183
template <class _Ty>
class allocator;
template <class _Elem, class _Traits, class _Alloc>
class basic_string;
using string = basic_string<char, char_traits<char>, allocator<char>>;
+DOCTEST_CLANG_SUPPRESS_WARNING_POP
#endif // VS 2019
DOCTEST_STD_NAMESPACE_END
@@ -504,7 +523,6 @@ public:
String& operator=(const String& other);
String& operator+=(const String& other);
- String operator+(const String& other) const;
String(String&& other);
String& operator=(String&& other);
@@ -527,6 +545,8 @@ public:
int compare(const String& other, bool no_case = false) const;
};
+DOCTEST_INTERFACE String 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);
@@ -723,9 +743,8 @@ namespace detail {
struct ContextOptions //!OCLINT too many fields
{
- std::ostream* cout; // stdout stream - std::cout by default
- std::ostream* cerr; // stderr stream - std::cerr by default
- String binary_name; // the test binary name
+ std::ostream* cout = nullptr; // stdout stream
+ String binary_name; // the test binary name
const detail::TestCase* currentTest = nullptr;
@@ -744,9 +763,12 @@ struct ContextOptions //!OCLINT too many fields
bool case_sensitive; // if filtering should be case sensitive
bool exit; // if the program should be exited after the
tests are ran/whatever
bool duration; // print the time duration of each test case
+ bool minimal; // minimal console output (only test failures)
+ bool quiet; // no console output
bool no_throw; // to skip exceptions-related assertion macros
bool no_exitcode; // if the framework should return 0 as the
exitcode
bool no_run; // to not run the tests at all (can be done
with an "*" exclude)
+ bool no_intro; // to not print the intro of the framework
bool no_version; // to not print the version of the framework
bool no_colors; // if output to the console should be colorized
bool force_colors; // forces the use of colors even when a tty
cannot be detected
@@ -790,6 +812,9 @@ namespace detail {
template<class T> struct is_lvalue_reference { const static bool
value=false; };
template<class T> struct is_lvalue_reference<T&> { const static bool
value=true; };
+ template<class T> struct is_rvalue_reference { const static bool
value=false; };
+ template<class T> struct is_rvalue_reference<T&&> { const static bool
value=true; };
+
template <class T>
inline T&& forward(typename remove_reference<T>::type& t) DOCTEST_NOEXCEPT
{
@@ -811,7 +836,7 @@ namespace detail {
template<class T> struct underlying_type : public std::underlying_type<T>
{};
#else
// Use compiler intrinsics
- template<class T> struct is_enum { constexpr static bool value =
__is_enum(T); };
+ template<class T> struct is_enum { DOCTEST_CONSTEXPR static bool value =
__is_enum(T); };
template<class T> struct underlying_type { typedef __underlying_type(T)
type; };
#endif
// clang-format on
@@ -828,12 +853,12 @@ namespace detail {
template<class, class = void>
struct check {
- static constexpr bool value = false;
+ static DOCTEST_CONSTEXPR bool value = false;
};
template<class T>
struct check<T, decltype(os() << val<T>(), void())> {
- static constexpr bool value = true;
+ static DOCTEST_CONSTEXPR bool value = true;
};
} // namespace has_insertion_operator_impl
@@ -842,9 +867,10 @@ namespace detail {
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned
num);
- DOCTEST_INTERFACE std::ostream* getTlsOss(); // returns a thread-local
ostringstream
+ DOCTEST_INTERFACE std::ostream* getTlsOss(bool reset=true); // returns a
thread-local ostringstream
DOCTEST_INTERFACE String getTlsOssResult();
+
template <bool C>
struct StringMakerBase
{
@@ -854,12 +880,57 @@ namespace detail {
}
};
+ // Vector<int> and various type other than pointer or array.
+ template<typename T>
+ struct filldata
+ {
+ static void fill(const T &in) {
+ *getTlsOss() << in;
+ }
+ };
+
+ /* This method can be chained */
+ template<typename T,unsigned long N>
+ void fillstream(const T (&in)[N] ) {
+ for(unsigned long i = 0; i < N; i++) {
+ *getTlsOss(false) << in[i];
+ }
+ }
+
+ template<typename T,unsigned long N>
+ struct filldata<T[N]>
+ {
+ static void fill(const T (&in)[N]) {
+ fillstream(in);
+ *getTlsOss(false)<<"";
+ }
+ };
+
+ template<typename T>
+ void filloss(const T& in){
+ filldata<T>::fill(in);
+ }
+
+ template<typename T,unsigned long N>
+ void filloss(const T (&in)[N]) {
+ // T[N], T(&)[N], T(&&)[N] have same behaviour.
+ // Hence remove reference.
+ filldata<typename remove_reference <decltype(in)>::type >::fill(in);
+ }
+
template <>
struct StringMakerBase<true>
{
template <typename T>
static String convert(const DOCTEST_REF_WRAP(T) in) {
- *getTlsOss() << in;
+ /* When parameter "in" is a null terminated const char* it works.
+ * When parameter "in" is a T arr[N] without '\0' we can fill the
+ * stringstream with N objects (T=char).If in is char pointer *
+ * without '\0' , it would cause segfault
+ * stepping over unaccessible memory.
+ */
+
+ filloss(in);
return getTlsOssResult();
}
};
@@ -1079,12 +1150,21 @@
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
// If not it doesn't find the operator or if the operator at global scope is
defined after
// this template, the template won't be instantiated due to SFINAE. Once the
template is not
// instantiated it can look for global operator using normal conversions.
-#define SFINAE_OP(ret,op) decltype(doctest::detail::declval<L>() op
doctest::detail::declval<R>(),static_cast<ret>(0))
+#define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op
doctest::detail::declval<R>()),ret{})
#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro)
\
template <typename R>
\
- DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \
- bool res = op_macro(doctest::detail::forward<L>(lhs),
doctest::detail::forward<R>(rhs));
\
+ DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R&& rhs) {
\
+ bool res = op_macro(doctest::detail::forward<const L>(lhs),
doctest::detail::forward<const R>(rhs));
\
+ if(m_at & assertType::is_false)
\
+ res = !res;
\
+ if(!res || doctest::getContextOptions()->success)
\
+ return Result(res, stringifyBinaryExpr(lhs, op_str, rhs));
\
+ return Result(res);
\
+ }
\
+ template <typename R ,typename enable_if<
!doctest::detail::is_rvalue_reference<R>::value , void >::type* = nullptr>
\
+ DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R& rhs) {
\
+ bool res = op_macro(doctest::detail::forward<const L>(lhs),
doctest::detail::forward<const R>(rhs));
\
if(m_at & assertType::is_false)
\
res = !res;
\
if(!res || doctest::getContextOptions()->success)
\
@@ -1092,6 +1172,7 @@
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
return Result(res);
\
}
+
// more checks could be added - like in Catch:
// https://github.com/catchorg/Catch2/pull/1480/files
// https://github.com/catchorg/Catch2/pull/1481/files
@@ -1108,6 +1189,7 @@
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
bool m_passed;
String m_decomp;
+ Result() = default;
Result(bool passed, const String& decomposition = String());
// forbidding some expressions based on this table:
https://en.cppreference.com/w/cpp/language/operator_precedence
@@ -1217,7 +1299,7 @@
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
, m_at(at) {}
DOCTEST_NOINLINE operator Result() {
-// this is needed only foc MSVC 2015:
+// this is needed only for MSVC 2015:
// https://ci.appveyor.com/project/onqtam/doctest/builds/38181202
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool
bool res = static_cast<bool>(lhs);
@@ -1289,22 +1371,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
// https://github.com/catchorg/Catch2/issues/870
// https://github.com/catchorg/Catch2/issues/565
template <typename L>
- Expression_lhs<L> operator<<(L &&operand) {
- return Expression_lhs<L>(doctest::detail::forward<L>(operand),
m_at);
+ Expression_lhs<const L> operator<<(const L &&operand) {
+ return Expression_lhs<const L>(doctest::detail::forward<const
L>(operand), m_at);
+ }
+
+ template <typename L,typename
enable_if<!doctest::detail::is_rvalue_reference<L>::value,void >::type* =
nullptr>
+ Expression_lhs<const L&> operator<<(const L &operand) {
+ return Expression_lhs<const L&>(operand, m_at);
}
};
struct DOCTEST_INTERFACE TestSuite
{
- const char* m_test_suite;
- const char* m_description;
- bool m_skip;
- bool m_no_breaks;
- bool m_no_output;
- bool m_may_fail;
- bool m_should_fail;
- int m_expected_failures;
- double m_timeout;
+ const char* m_test_suite = nullptr;
+ const char* m_description = nullptr;
+ bool m_skip = false;
+ bool m_no_breaks = false;
+ bool m_no_output = false;
+ bool m_may_fail = false;
+ bool m_should_fail = false;
+ int m_expected_failures = 0;
+ double m_timeout = 0;
TestSuite& operator*(const char* in);
@@ -1573,8 +1660,10 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
protected:
ContextScopeBase();
+ ContextScopeBase(ContextScopeBase&& other);
void destroy();
+ bool need_to_destroy{true};
};
template <typename L> class ContextScope : public ContextScopeBase
@@ -1584,11 +1673,15 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
public:
explicit ContextScope(const L &lambda) : lambda_(lambda) {}
- ContextScope(ContextScope &&other) : lambda_(other.lambda_) {}
+ ContextScope(ContextScope &&other) :
ContextScopeBase(static_cast<ContextScopeBase&&>(other)),
lambda_(other.lambda_) {}
void stringify(std::ostream* s) const override { lambda_(s); }
- ~ContextScope() override { destroy(); }
+ ~ContextScope() override {
+ if (need_to_destroy) {
+ destroy();
+ }
+ }
};
struct DOCTEST_INTERFACE MessageBuilder : public MessageData
@@ -1692,6 +1785,7 @@ public:
void addFilter(const char* filter, const char* value);
void clearFilters();
+ void setOption(const char* option, bool value);
void setOption(const char* option, int value);
void setOption(const char* option, const char* value);
@@ -1701,6 +1795,8 @@ public:
void setAssertHandler(detail::assert_handler ah);
+ void setCout(std::ostream* out);
+
int run();
};
@@ -1727,6 +1823,7 @@ struct DOCTEST_INTERFACE CurrentTestCaseStats
int numAssertsFailedCurrentTest;
double seconds;
int failure_flags; // use TestCaseFailureReason::Enum
+ bool testCaseSuccess;
};
struct DOCTEST_INTERFACE TestCaseException
@@ -1835,7 +1932,7 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
#define DOCTEST_WRAP_IN_TRY(x)
\
try {
\
x;
\
- } catch(...) { _DOCTEST_RB.translateException(); }
+ } catch(...) { DOCTEST_RB.translateException(); }
#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
@@ -1849,7 +1946,7 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
// registers the test by initializing a dummy var with a function
#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators)
\
- global_prefix
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =
\
+ global_prefix
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_)) =
\
doctest::detail::regTest(
\
doctest::detail::TestCase(
\
f, __FILE__, __LINE__,
\
@@ -1878,18 +1975,18 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators)
\
static doctest::detail::funcType proxy() { return f; }
\
- DOCTEST_REGISTER_FUNCTION(inline const, proxy(), decorators)
\
+ DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators)
\
static void f()
// for registering tests
#define DOCTEST_TEST_CASE(decorators)
\
-
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),
decorators)
+
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),
decorators)
// for registering tests in classes - requires C++17 for inline variables!
#if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) &&
_MSVC_LANG >= 201703L)
#define DOCTEST_TEST_CASE_CLASS(decorators)
\
-
DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),
\
-
DOCTEST_ANONYMOUS(_DOCTEST_ANON_PROXY_), \
+
DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),
\
+
DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \
decorators)
#else // DOCTEST_TEST_CASE_CLASS
#define DOCTEST_TEST_CASE_CLASS(...)
\
@@ -1898,8 +1995,8 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
// for registering tests with a fixture
#define DOCTEST_TEST_CASE_FIXTURE(c, decorators)
\
- DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c,
\
- DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),
decorators)
+ DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c,
\
+ DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),
decorators)
// for converting types to strings without the <typeinfo> header and demangling
#define DOCTEST_TYPE_TO_STRING_IMPL(...)
\
@@ -1912,7 +2009,7 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__)
\
}
\
}
\
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func)
\
template <typename T>
\
@@ -1943,7 +2040,7 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id)
\
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR),
\
-
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_))
+
DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...)
\
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) =
\
@@ -1951,12 +2048,12 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
DOCTEST_GLOBAL_NO_WARNINGS_END()
#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...)
\
- DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id,
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id,
DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...)
\
- DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id,
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id,
DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...)
\
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon,
ITERATOR), anon); \
@@ -1965,11 +2062,11 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
static void anon()
#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...)
\
- DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T,
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__)
+ DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T,
DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)
// for subcases
#define DOCTEST_SUBCASE(name)
\
- if(const doctest::detail::Subcase &
DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
+ if(const doctest::detail::Subcase &
DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
doctest::detail::Subcase(name, __FILE__, __LINE__))
// for grouping tests in test suites by using code blocks
@@ -1995,53 +2092,56 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
namespace ns_name
#define DOCTEST_TEST_SUITE(decorators)
\
- DOCTEST_TEST_SUITE_IMPL(decorators,
DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUITE_))
+ DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))
// for starting a testsuite block
#define DOCTEST_TEST_SUITE_BEGIN(decorators)
\
- DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =
\
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_)) =
\
doctest::detail::setTestSuite(doctest::detail::TestSuite() *
decorators); \
DOCTEST_GLOBAL_NO_WARNINGS_END()
\
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
// for ending a testsuite block
#define DOCTEST_TEST_SUITE_END
\
- DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) =
\
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_)) =
\
doctest::detail::setTestSuite(doctest::detail::TestSuite() * "");
\
DOCTEST_GLOBAL_NO_WARNINGS_END()
\
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
// for registering exception translators
#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature)
\
inline doctest::String translatorName(signature);
\
- DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)) =
\
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)) =
\
doctest::registerExceptionTranslator(translatorName);
\
DOCTEST_GLOBAL_NO_WARNINGS_END()
\
doctest::String translatorName(signature)
#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
\
-
DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_),
\
+
DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_),
\
signature)
// for registering reporters
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
\
- DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) =
\
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_)) =
\
doctest::registerReporter<reporter>(name, priority, true);
\
- DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int
DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int
DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
// for registering listeners
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
\
- DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) =
\
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_)) =
\
doctest::registerReporter<reporter>(name, priority, false);
\
- DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int
DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int
DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
-// for logging
+// clang-format off
+// for logging - disabling formatting because it's important to have these on
2 separate lines - see PR #557
#define DOCTEST_INFO(...)
\
- DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_),
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
+ DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_),
\
+ DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_),
\
__VA_ARGS__)
+// clang-format on
#define DOCTEST_INFO_IMPL(mb_name, s_name, ...)
\
- auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) =
doctest::detail::MakeContextScope( \
+ auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) =
doctest::detail::MakeContextScope( \
[&](std::ostream* s_name) {
\
doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__,
doctest::assertType::is_warn); \
mb_name.m_stream = s_name;
\
@@ -2058,9 +2158,9 @@ int registerReporter(const char* name, int priority, bool
isReporter) {
} while(false)
// clang-format off
-#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn,
file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
-#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...)
DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_),
__VA_ARGS__)
-#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require,
file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
+#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn,
file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
+#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...)
DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_),
__VA_ARGS__)
+#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require,
file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
// clang-format on
#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__,
__VA_ARGS__)
@@ -2073,12 +2173,12 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...)
\
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses")
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #__VA_ARGS__);
\
- DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.setResult(
\
+ DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult(
\
doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type)
\
<< __VA_ARGS__))
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB)
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB)
\
DOCTEST_CLANG_SUPPRESS_WARNING_POP
#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...)
\
@@ -2119,39 +2219,39 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...)
\
do {
\
if(!doctest::getContextOptions()->no_throw) {
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #expr,
#__VA_ARGS__, message); \
try {
\
DOCTEST_CAST_TO_VOID(expr)
\
} catch(const typename doctest::detail::remove_const<
\
typename
doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
- _DOCTEST_RB.translateException();
\
- _DOCTEST_RB.m_threw_as = true;
\
- } catch(...) { _DOCTEST_RB.translateException(); }
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);
\
+ DOCTEST_RB.translateException();
\
+ DOCTEST_RB.m_threw_as = true;
\
+ } catch(...) { DOCTEST_RB.translateException(); }
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB);
\
}
\
} while(false)
#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...)
\
do {
\
if(!doctest::getContextOptions()->no_throw) {
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, expr_str, "",
__VA_ARGS__); \
try {
\
DOCTEST_CAST_TO_VOID(expr)
\
- } catch(...) { _DOCTEST_RB.translateException(); }
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);
\
+ } catch(...) { DOCTEST_RB.translateException(); }
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB);
\
}
\
} while(false)
#define DOCTEST_ASSERT_NOTHROW(assert_type, ...)
\
do {
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #__VA_ARGS__);
\
try {
\
DOCTEST_CAST_TO_VOID(__VA_ARGS__)
\
- } catch(...) { _DOCTEST_RB.translateException(); }
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);
\
+ } catch(...) { DOCTEST_RB.translateException(); }
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB);
\
} while(false)
// clang-format off
@@ -2196,20 +2296,20 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...)
\
do {
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #__VA_ARGS__);
\
DOCTEST_WRAP_IN_TRY(
\
-
_DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(
\
+
DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(
\
__VA_ARGS__))
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB);
\
} while(false)
#define DOCTEST_UNARY_ASSERT(assert_type, ...)
\
do {
\
- doctest::detail::ResultBuilder
_DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
+ doctest::detail::ResultBuilder
DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
__LINE__, #__VA_ARGS__);
\
- DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__))
\
- DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB);
\
+ DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__))
\
+ DOCTEST_ASSERT_LOG_AND_REACT(DOCTEST_RB);
\
} while(false)
#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
@@ -2358,35 +2458,35 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
// for registering tests
#define DOCTEST_TEST_CASE(name)
\
-
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),
name)
+
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),
name)
// for registering tests in classes
#define DOCTEST_TEST_CASE_CLASS(name)
\
-
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_),
name)
+
DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),
name)
// for registering tests with a fixture
#define DOCTEST_TEST_CASE_FIXTURE(x, name)
\
- DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x,
\
- DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name)
+ DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x,
\
+ DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
// for converting types to strings without the <typeinfo> header and demangling
-#define DOCTEST_TYPE_TO_STRING(...) typedef int
DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+#define DOCTEST_TYPE_TO_STRING(...) typedef int
DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_TYPE_TO_STRING_IMPL(...)
// for typed tests
#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...)
\
template <typename type>
\
- inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)()
+ inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id)
\
template <typename type>
\
- inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)()
+ inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...)
\
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...)
\
- typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+ typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
// for subcases
#define DOCTEST_SUBCASE(name)
@@ -2395,14 +2495,14 @@ int registerReporter(const char* name, int priority,
bool isReporter) {
#define DOCTEST_TEST_SUITE(name) namespace
// for starting a testsuite block
-#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int
DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int
DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
// for ending a testsuite block
-#define DOCTEST_TEST_SUITE_END typedef int
DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
+#define DOCTEST_TEST_SUITE_END typedef int
DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
\
template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>
\
- static inline doctest::String
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)(signature)
+ static inline doctest::String
DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
@@ -2792,6 +2892,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment
operator was implicitly d
DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined
as deleted
DOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined
as deleted
DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false'
(performance warning)
+DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal
linkage has been removed
// static analysis
DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw.
Declare it 'noexcept'
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
@@ -2885,8 +2986,12 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
#endif
#ifndef DOCTEST_THREAD_LOCAL
+#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
+#define DOCTEST_THREAD_LOCAL
+#else // DOCTEST_MSVC
#define DOCTEST_THREAD_LOCAL thread_local
-#endif
+#endif // DOCTEST_MSVC
+#endif // DOCTEST_THREAD_LOCAL
#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
@@ -2906,6 +3011,10 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
#endif
+#ifndef DOCTEST_CDECL
+#define DOCTEST_CDECL __cdecl
+#endif
+
namespace doctest {
bool is_running_in_test = false;
@@ -2975,10 +3084,13 @@ namespace detail {
DOCTEST_THREAD_LOCAL std::ostringstream g_oss; // NOLINT(cert-err58-cpp)
- std::ostream* getTlsOss() {
- g_oss.clear(); // there shouldn't be anything worth clearing in the
flags
- g_oss.str(""); // the slow way of resetting a string stream
- //g_oss.seekp(0); // optimal reset - as seen here:
https://stackoverflow.com/a/624291/3162383
+ //reset default value is true. getTlsOss(bool reset=true);
+ std::ostream* getTlsOss(bool reset) {
+ if(reset) {
+ g_oss.clear(); // there shouldn't be anything worth clearing in the
flags
+ g_oss.str(""); // the slow way of resetting a string stream
+ //g_oss.seekp(0); // optimal reset - as seen here:
https://stackoverflow.com/a/624291/3162383
+ }
return &g_oss;
}
@@ -3088,7 +3200,7 @@ typedef timer_large_integer::type ticks_t;
return result;
}
- T operator=(T desired) DOCTEST_NOEXCEPT {
+ T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm
[cpp/assignment-does-not-return-this]
store(desired);
return desired;
}
@@ -3103,7 +3215,7 @@ typedef timer_large_integer::type ticks_t;
private:
// Each thread has a different atomic that it operates on. If more
than NumLanes threads
- // use this, some will use the same atomic. So performance will
degrate a bit, but still
+ // use this, some will use the same atomic. So performance will
degrade a bit, but still
// everything will work.
//
// The logic here is a bit tricky. The call should be as fast as
possible, so that there
@@ -3198,7 +3310,8 @@ typedef timer_large_integer::type ticks_t;
(TestCaseFailureReason::FailedExactlyNumTimes &
failure_flags);
// if any subcase has failed - the whole test case has failed
- if(failure_flags && !ok_to_fail)
+ testCaseSuccess = !(failure_flags && !ok_to_fail);
+ if(!testCaseSuccess)
numTestCasesFailed++;
}
};
@@ -3323,9 +3436,6 @@ String& String::operator+=(const String& other) {
return *this;
}
-// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
-String String::operator+(const String& other) const { return String(*this) +=
other; }
-
String::String(String&& other) {
using namespace std;
memcpy(buf, other.buf, len);
@@ -3379,6 +3489,9 @@ int String::compare(const String& other, bool no_case)
const {
return compare(other.c_str(), no_case);
}
+// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
+String operator+(const String& lhs, const String& rhs) { return String(lhs)
+= rhs; }
+
// clang-format off
bool operator==(const String& lhs, const String& rhs) { return
lhs.compare(rhs) == 0; }
bool operator!=(const String& lhs, const String& rhs) { return
lhs.compare(rhs) != 0; }
@@ -3581,7 +3694,7 @@ bool operator>(const Approx& lhs, double rhs) { return
lhs.m_value > rhs && lhs
String toString(const Approx& in) {
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
- return String("Approx( ") + doctest::toString(in.m_value) + " )";
+ return "Approx( " + doctest::toString(in.m_value) + " )";
}
const ContextOptions* getContextOptions() { return
DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
@@ -3594,11 +3707,13 @@ Context::~Context() = default;
void Context::applyCommandLine(int, const char* const*) {}
void Context::addFilter(const char*, const char*) {}
void Context::clearFilters() {}
+void Context::setOption(const char*, bool) {}
void Context::setOption(const char*, int) {}
void Context::setOption(const char*, const char*) {}
bool Context::shouldExit() { return false; }
void Context::setAsDefaultForAssertsOutOfTestCases() {}
void Context::setAssertHandler(detail::assert_handler) {}
+void Context::setCout(std::ostream* out) {}
int Context::run() { return 0; }
IReporter::~IReporter() = default;
@@ -3812,15 +3927,6 @@ namespace detail {
TestSuite& TestSuite::operator*(const char* in) {
m_test_suite = in;
- // clear state
- m_description = nullptr;
- m_skip = false;
- m_no_breaks = false;
- m_no_output = false;
- m_may_fail = false;
- m_should_fail = false;
- m_expected_failures = 0;
- m_timeout = 0;
return *this;
}
@@ -3929,12 +4035,12 @@ namespace {
HANDLE g_stdoutHandle;
WORD g_origFgAttrs;
WORD g_origBgAttrs;
- bool g_attrsInitted = false;
+ bool g_attrsInited = false;
int colors_init() {
- if(!g_attrsInitted) {
+ if(!g_attrsInited) {
g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
- g_attrsInitted = true;
+ g_attrsInited = true;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo(g_stdoutHandle, &csbiInfo);
g_origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN |
BACKGROUND_RED |
@@ -3945,7 +4051,7 @@ namespace {
return 0;
}
- int dumy_init_console_colors = colors_init();
+ int dummy_init_console_colors = colors_init();
#endif // DOCTEST_CONFIG_COLORS_WINDOWS
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
@@ -3981,7 +4087,7 @@ namespace {
#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
if(g_no_colors ||
- (isatty(fileno(stdout)) == false &&
getContextOptions()->force_colors == false))
+ (_isatty(_fileno(stdout)) == false &&
getContextOptions()->force_colors == false))
return;
#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(g_stdoutHandle, x |
g_origBgAttrs)
@@ -4145,6 +4251,14 @@ namespace detail {
g_infoContexts.push_back(this);
}
+ ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) {
+ if (other.need_to_destroy) {
+ other.destroy();
+ }
+ other.need_to_destroy = false;
+ g_infoContexts.push_back(this);
+ }
+
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception
is deprecated in C++17
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
@@ -4313,7 +4427,7 @@ namespace {
static unsigned int prev_abort_behavior;
static int prev_report_mode;
static _HFILE prev_report_file;
- static void (*prev_sigabrt_handler)(int);
+ static void (DOCTEST_CDECL *prev_sigabrt_handler)(int);
static std::terminate_handler original_terminate_handler;
static bool isSet;
static ULONG guaranteeSize;
@@ -4325,7 +4439,7 @@ namespace {
unsigned int FatalConditionHandler::prev_abort_behavior;
int FatalConditionHandler::prev_report_mode;
_HFILE FatalConditionHandler::prev_report_file;
- void (*FatalConditionHandler::prev_sigabrt_handler)(int);
+ void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int);
std::terminate_handler FatalConditionHandler::original_terminate_handler;
bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
@@ -4498,7 +4612,7 @@ namespace detail {
}
if(m_exception.size())
- m_exception = String("\"") + m_exception + "\"";
+ m_exception = "\"" + m_exception + "\"";
if(is_running_in_test) {
addAssert(m_at);
@@ -5054,7 +5168,8 @@ namespace {
xml.scopedElement("TestCase").writeAttribute("name",
in.data[i]->m_name)
.writeAttribute("testsuite", in.data[i]->m_test_suite)
.writeAttribute("filename",
skipPathFromFilename(in.data[i]->m_file.c_str()))
- .writeAttribute("line", line(in.data[i]->m_line));
+ .writeAttribute("line", line(in.data[i]->m_line))
+ .writeAttribute("skipped", in.data[i]->m_skip);
}
xml.scopedElement("OverallResultsTestCases")
.writeAttribute("unskipped",
in.run_stats->numTestCasesPassingFilters);
@@ -5124,7 +5239,8 @@ namespace {
xml.startElement("OverallResultsAsserts")
.writeAttribute("successes",
st.numAssertsCurrentTest -
st.numAssertsFailedCurrentTest)
- .writeAttribute("failures",
st.numAssertsFailedCurrentTest);
+ .writeAttribute("failures", st.numAssertsFailedCurrentTest)
+ .writeAttribute("test_case_success", st.testCaseSuccess);
if(opt.duration)
xml.writeAttribute("duration", st.seconds);
if(tc->m_expected_failures)
@@ -5143,8 +5259,6 @@ namespace {
}
void subcase_start(const SubcaseSignature& in) override {
- std::lock_guard<std::mutex> lock(mutex);
-
xml.startElement("SubCase")
.writeAttribute("name", in.m_name)
.writeAttribute("filename",
skipPathFromFilename(in.m_file))
@@ -5440,7 +5554,6 @@ namespace {
}
void subcase_start(const SubcaseSignature& in) override {
- std::lock_guard<std::mutex> lock(mutex);
deepestSubcaseStackNames.push_back(in.m_name);
}
@@ -5606,9 +5719,11 @@ namespace {
}
void printIntro() {
- printVersion();
- s << Color::Cyan << "[doctest] " << Color::None
- << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for
options\n";
+ if(opt.no_intro == false) {
+ printVersion();
+ s << Color::Cyan << "[doctest] " << Color::None
+ << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\"
for options\n";
+ }
}
void printHelp() {
@@ -5693,12 +5808,18 @@ namespace {
<< Whitespace(sizePrefixDisplay*1) << "exits after the tests
finish\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "duration=<bool> "
<< Whitespace(sizePrefixDisplay*1) << "prints the time duration
of each test\n";
+ s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal=<bool> "
+ << Whitespace(sizePrefixDisplay*1) << "minimal console output
(only failures)\n";
+ s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet=<bool> "
+ << Whitespace(sizePrefixDisplay*1) << "no console output\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw=<bool> "
<< Whitespace(sizePrefixDisplay*1) << "skips exceptions-related
assert checks\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode=<bool> "
<< Whitespace(sizePrefixDisplay*1) << "returns (or exits) always
with success\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run=<bool> "
<< Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest
operations\n";
+ s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro=<bool> "
+ << Whitespace(sizePrefixDisplay*1) << "omit the framework intro
in the output\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version=<bool> "
<< Whitespace(sizePrefixDisplay*1) << "omit the framework
version in the output\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors=<bool> "
@@ -5736,22 +5857,6 @@ namespace {
printReporters(getReporters(), "reporters");
}
- void list_query_results() {
- separator_to_stream();
- if(opt.count || opt.list_test_cases) {
- s << Color::Cyan << "[doctest] " << Color::None
- << "unskipped test cases passing the current filters: "
- << g_cs->numTestCasesPassingFilters << "\n";
- } else if(opt.list_test_suites) {
- s << Color::Cyan << "[doctest] " << Color::None
- << "unskipped test cases passing the current filters: "
- << g_cs->numTestCasesPassingFilters << "\n";
- s << Color::Cyan << "[doctest] " << Color::None
- << "test suites with unskipped test cases passing the
current filters: "
- << g_cs->numTestSuitesPassingFilters << "\n";
- }
- }
-
//
=========================================================================================
// WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER
INTERFACE
//
=========================================================================================
@@ -5797,9 +5902,15 @@ namespace {
}
}
- void test_run_start() override { printIntro(); }
+ void test_run_start() override {
+ if(!opt.minimal)
+ printIntro();
+ }
void test_run_end(const TestRunStats& p) override {
+ if(opt.minimal && p.numTestCasesFailed == 0)
+ return;
+
separator_to_stream();
s << std::dec;
@@ -5880,6 +5991,7 @@ namespace {
}
void test_case_exception(const TestCaseException& e) override {
+ std::lock_guard<std::mutex> lock(mutex);
if(tc->m_no_output)
return;
@@ -5904,14 +6016,12 @@ namespace {
}
void subcase_start(const SubcaseSignature& subc) override {
- std::lock_guard<std::mutex> lock(mutex);
subcasesStack.push_back(subc);
++currentSubcaseLevel;
hasLoggedCurrentTestStart = false;
}
void subcase_end() override {
- std::lock_guard<std::mutex> lock(mutex);
--currentSubcaseLevel;
hasLoggedCurrentTestStart = false;
}
@@ -6047,18 +6157,42 @@ namespace {
std::vector<String>& res) {
String filtersString;
if(parseOption(argc, argv, pattern, &filtersString)) {
- // tokenize with "," as a separator
- // cppcheck-suppress strtokCalled
-
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
- auto pch = std::strtok(filtersString.c_str(), ","); // modifies
the string
- while(pch != nullptr) {
- if(strlen(pch))
- res.push_back(pch);
- // uses the strtok() internal state to go to the next token
- // cppcheck-suppress strtokCalled
- pch = std::strtok(nullptr, ",");
+ // tokenize with "," as a separator, unless escaped with backslash
+ std::ostringstream s;
+ auto flush = [&s, &res]() {
+ auto string = s.str();
+ if(string.size() > 0) {
+ res.push_back(string.c_str());
+ }
+ s.str("");
+ };
+
+ bool seenBackslash = false;
+ const char* current = filtersString.c_str();
+ const char* end = current + strlen(current);
+ while(current != end) {
+ char character = *current++;
+ if(seenBackslash) {
+ seenBackslash = false;
+ if(character == ',') {
+ s.put(',');
+ continue;
+ }
+ s.put('\\');
+ }
+ if(character == '\\') {
+ seenBackslash = true;
+ } else if(character == ',') {
+ flush();
+ } else {
+ s.put(character);
+ }
+ }
+
+ if(seenBackslash) {
+ s.put('\\');
}
- DOCTEST_CLANG_SUPPRESS_WARNING_POP
+ flush();
return true;
}
return false;
@@ -6191,9 +6325,12 @@ void Context::parseArgs(int argc, const char* const*
argv, bool withDefaults) {
DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive,
false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false);
@@ -6257,7 +6394,12 @@ void Context::clearFilters() {
curr.clear();
}
-// allows the user to override procedurally the int/bool options from the
command line
+// allows the user to override procedurally the bool options from the command
line
+void Context::setOption(const char* option, bool value) {
+ setOption(option, value ? "true" : "false");
+}
+
+// allows the user to override procedurally the int options from the command
line
void Context::setOption(const char* option, int value) {
setOption(option, toString(value).c_str());
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
@@ -6277,6 +6419,31 @@ void Context::setAsDefaultForAssertsOutOfTestCases() {
g_cs = p; }
void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; }
+void Context::setCout(std::ostream* out) { p->cout = out; }
+
+static class DiscardOStream : public std::ostream
+{
+private:
+ class : public std::streambuf
+ {
+ private:
+ // allowing some buffering decreases the amount of calls to overflow
+ char buf[1024];
+
+ protected:
+ std::streamsize xsputn(const char_type*, std::streamsize count)
override { return count; }
+
+ int_type overflow(int_type ch) override {
+ setp(std::begin(buf), std::end(buf));
+ return traits_type::not_eof(ch);
+ }
+ } discardBuf;
+
+public:
+ DiscardOStream()
+ : std::ostream(&discardBuf) {}
+} discardOut;
+
// the main function that does all the filtering and test running
int Context::run() {
using namespace detail;
@@ -6290,15 +6457,18 @@ int Context::run() {
g_no_colors = p->no_colors;
p->resetRunData();
- // stdout by default
- p->cout = &std::cout;
- p->cerr = &std::cerr;
-
- // or to a file if specified
std::fstream fstr;
- if(p->out.size()) {
- fstr.open(p->out.c_str(), std::fstream::out);
- p->cout = &fstr;
+ if(p->cout == nullptr) {
+ if(p->quiet) {
+ p->cout = &discardOut;
+ } else if(p->out.size()) {
+ // to a file if specified
+ fstr.open(p->out.c_str(), std::fstream::out);
+ p->cout = &fstr;
+ } else {
+ // stdout by default
+ p->cout = &std::cout;
+ }
}
FatalConditionHandler::allocateAltStackMem();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]