Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
json
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
json
Commits
ef826b6f
Commit
ef826b6f
authored
4 years ago
by
Benjamin A. Beasley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update doctest from 2.4.4 to 2.4.6 (fixes #2686)
parent
82380187
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
393 additions
and
197 deletions
+393
-197
test/thirdparty/doctest/LICENSE.txt
test/thirdparty/doctest/LICENSE.txt
+2
-2
test/thirdparty/doctest/doctest.h
test/thirdparty/doctest/doctest.h
+391
-195
No files found.
test/thirdparty/doctest/LICENSE.txt
100755 → 100644
View file @
ef826b6f
The MIT License (MIT)
Copyright (c) 2016-202
0
Viktor Kirilov
Copyright (c) 2016-202
1
Viktor Kirilov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
...
...
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
SOFTWARE.
This diff is collapsed.
Click to expand it.
test/thirdparty/doctest/doctest.h
View file @
ef826b6f
...
...
@@ -4,7 +4,7 @@
//
// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
//
// Copyright (c) 2016-202
0
Viktor Kirilov
// Copyright (c) 2016-202
1
Viktor Kirilov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
...
...
@@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH
4
#define DOCTEST_VERSION_STR "2.4.
4
"
#define DOCTEST_VERSION_PATCH
6
#define DOCTEST_VERSION_STR "2.4.
6
"
#define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
...
...
@@ -354,7 +354,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_GLOBAL_NO_WARNINGS(var) \
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-variable") \
static int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp)
static
const
int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp)
#define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP
#ifndef DOCTEST_BREAK_INTO_DEBUGGER
...
...
@@ -362,16 +362,16 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#ifdef DOCTEST_PLATFORM_LINUX
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
// Break at the location of the failing check if possible
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
// NOLINT (hicpp-no-assembler)
#else
#include <signal.h>
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
// NOLINT (hicpp-no-assembler)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
// NOLINT (hicpp-no-assembler)
#endif
#elif DOCTEST_MSVC
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
...
...
@@ -656,12 +656,14 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
struct DOCTEST_INTERFACE TestCaseData
{
String
m_file
;
// the file in which the test was registered
String m_file; // the file in which the test was registered
(using String - see #350)
unsigned m_line; // the line where the test was registered
const char* m_name; // name of the test case
const char* m_test_suite; // the test suite in which the test was added
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;
...
...
@@ -715,12 +717,18 @@ struct DOCTEST_INTERFACE IContextScope
virtual void stringify(std::ostream*) const = 0;
};
namespace detail {
struct DOCTEST_INTERFACE TestCase;
} // 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
const detail::TestCase* currentTest = nullptr;
// == parameters from the command line
String out; // output filename
String order_by; // how tests should be ordered
...
...
@@ -773,6 +781,29 @@ namespace detail {
template<class T> struct remove_reference<T&> { typedef T type; };
template<class T> struct remove_reference<T&&> { typedef T type; };
template<typename T, typename U = T&&> U declval(int);
template<typename T> T declval(long);
template<typename T> auto declval() DOCTEST_NOEXCEPT -> decltype(declval<T>(0)) ;
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>
inline T&& forward(typename remove_reference<T>::type& t) DOCTEST_NOEXCEPT
{
return static_cast<T&&>(t);
}
template <class T>
inline T&& forward(typename remove_reference<T>::type&& t) DOCTEST_NOEXCEPT
{
static_assert(!is_lvalue_reference<T>::value,
"Can not forward an rvalue as an lvalue.");
return static_cast<T&&>(t);
}
template<class T> struct remove_const { typedef T type; };
template<class T> struct remove_const<const T> { typedef T type; };
#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
...
...
@@ -1040,10 +1071,20 @@ namespace detail {
return toString(lhs) + op + toString(rhs);
}
#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
#endif
// This will check if there is any way it could find a operator like member or friend and uses it.
// 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 DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
template <typename R> \
DOCTEST_NOINLINE
Result operator op(const DOCTEST_REF_WRAP(R) rhs) {
\
bool res = op_macro(lhs, rhs
); \
DOCTEST_NOINLINE
SFINAE_OP(Result,op) operator op(R&& rhs) {
\
bool res = op_macro(doctest::detail::forward<L>(lhs), doctest::detail::forward<R>(rhs)
); \
if(m_at & assertType::is_false) \
res = !res; \
if(!res || doctest::getContextOptions()->success) \
...
...
@@ -1171,12 +1212,16 @@ namespace detail {
L lhs;
assertType::Enum m_at;
explicit
Expression_lhs
(
L
in
,
assertType
::
Enum
at
)
:
lhs
(
in
)
explicit Expression_lhs(L
&&
in, assertType::Enum at)
: lhs(
doctest::detail::forward<L>(in)
)
, m_at(at) {}
DOCTEST_NOINLINE operator Result() {
bool
res
=
!!
lhs
;
// this is needed only foc 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);
DOCTEST_MSVC_SUPPRESS_WARNING_POP
if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional
res = !res;
...
...
@@ -1185,6 +1230,10 @@ namespace detail {
return Result(res);
}
/* This is required for user-defined conversions from Expression_lhs to L */
//operator L() const { return lhs; }
operator L() const { return lhs; }
// clang-format off
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional
...
...
@@ -1225,6 +1274,10 @@ namespace detail {
#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_POP
#endif
struct DOCTEST_INTERFACE ExpressionDecomposer
{
assertType::Enum m_at;
...
...
@@ -1236,8 +1289,8 @@ namespace detail {
// https://github.com/catchorg/Catch2/issues/870
// https://github.com/catchorg/Catch2/issues/565
template <typename L>
Expression_lhs
<
const
DOCTEST_REF_WRAP
(
L
)
>
operator
<<
(
const
DOCTEST_REF_WRAP
(
L
)
operand
)
{
return
Expression_lhs
<
const
DOCTEST_REF_WRAP
(
L
)
>
(
operand
,
m_at
);
Expression_lhs<L> operator<<(L &&
operand) {
return Expression_lhs<
L>(doctest::detail::forward<L>(operand)
, m_at);
}
};
...
...
@@ -1246,6 +1299,8 @@ namespace detail {
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;
...
...
@@ -1524,7 +1579,7 @@ namespace detail {
template <typename L> class ContextScope : public ContextScopeBase
{
const
L
&
lambda_
;
const L lambda_;
public:
explicit ContextScope(const L &lambda) : lambda_(lambda) {}
...
...
@@ -1585,6 +1640,8 @@ namespace detail {
DOCTEST_DEFINE_DECORATOR(test_suite, const char*, "");
DOCTEST_DEFINE_DECORATOR(description, const char*, "");
DOCTEST_DEFINE_DECORATOR(skip, bool, true);
DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true);
DOCTEST_DEFINE_DECORATOR(no_output, bool, true);
DOCTEST_DEFINE_DECORATOR(timeout, double, 0);
DOCTEST_DEFINE_DECORATOR(may_fail, bool, true);
DOCTEST_DEFINE_DECORATOR(should_fail, bool, true);
...
...
@@ -1921,10 +1978,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
static doctest::detail::TestSuite data; \
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
static doctest::detail::TestSuite data{}; \
static bool inited = false; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
DOCTEST_CLANG_SUPPRESS_WARNING_POP \
DOCTEST_GCC_SUPPRESS_WARNING_POP \
if(!inited) { \
data* decorators; \
inited = true; \
...
...
@@ -1979,17 +2038,15 @@ int registerReporter(const char* name, int priority, bool isReporter) {
// for logging
#define DOCTEST_INFO(...) \
DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_),
__VA_ARGS__)
__VA_ARGS__)
#define DOCTEST_INFO_IMPL(
lambda_name,
mb_name, s_name, ...) \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626)
\
auto lambda_name = [&](std::ostream* s_name) {
\
#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
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; \
mb_name * __VA_ARGS__; \
}; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name)
})
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
...
...
@@ -2461,7 +2518,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
DOCTEST_TEST_CASE_TEMPLATE_INVOKE
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
// clang-format on
// BDD style macros
...
...
@@ -2481,138 +2538,138 @@ int registerReporter(const char* name, int priority, bool isReporter) {
// == SHORT VERSIONS OF THE MACROS
#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)
#define TEST_CASE
DOCTEST_TEST_CASE
#define TEST_CASE_CLASS
DOCTEST_TEST_CASE_CLASS
#define TEST_CASE_FIXTURE
DOCTEST_TEST_CASE_FIXTURE
#define TYPE_TO_STRING
DOCTEST_TYPE_TO_STRING
#define TEST_CASE_TEMPLATE
DOCTEST_TEST_CASE_TEMPLATE
#define TEST_CASE_TEMPLATE_DEFINE
DOCTEST_TEST_CASE_TEMPLATE_DEFINE
#define TEST_CASE_TEMPLATE_INVOKE
DOCTEST_TEST_CASE_TEMPLATE_INVOKE
#define TEST_CASE_TEMPLATE_APPLY
DOCTEST_TEST_CASE_TEMPLATE_APPLY
#define SUBCASE
DOCTEST_SUBCASE
#define TEST_SUITE
DOCTEST_TEST_SUITE
#define TEST_SUITE_BEGIN
DOCTEST_TEST_SUITE_BEGIN
#define TEST_CASE
(name) DOCTEST_TEST_CASE(name)
#define TEST_CASE_CLASS
(name) DOCTEST_TEST_CASE_CLASS(name)
#define TEST_CASE_FIXTURE
(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
#define TYPE_TO_STRING
(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
#define TEST_CASE_TEMPLATE
(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_DEFINE
(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
#define TEST_CASE_TEMPLATE_INVOKE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_APPLY
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
#define SUBCASE
(name) DOCTEST_SUBCASE(name)
#define TEST_SUITE
(decorators) DOCTEST_TEST_SUITE(decorators)
#define TEST_SUITE_BEGIN
(name) DOCTEST_TEST_SUITE_BEGIN(name)
#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
#define REGISTER_EXCEPTION_TRANSLATOR
DOCTEST_REGISTER_EXCEPTION_TRANSLATOR
#define REGISTER_REPORTER
DOCTEST_REGISTER_REPORTER
#define REGISTER_LISTENER
DOCTEST_REGISTER_LISTENER
#define INFO
DOCTEST_INFO
#define CAPTURE
DOCTEST_CAPTURE
#define ADD_MESSAGE_AT
DOCTEST_ADD_MESSAGE_AT
#define ADD_FAIL_CHECK_AT
DOCTEST_ADD_FAIL_CHECK_AT
#define ADD_FAIL_AT
DOCTEST_ADD_FAIL_AT
#define MESSAGE
DOCTEST_MESSAGE
#define FAIL_CHECK
DOCTEST_FAIL_CHECK
#define FAIL
DOCTEST_FAIL
#define TO_LVALUE
DOCTEST_TO_LVALUE
#define WARN
DOCTEST_WARN
#define WARN_FALSE
DOCTEST_WARN_FALSE
#define WARN_THROWS
DOCTEST_WARN_THROWS
#define WARN_THROWS_AS
DOCTEST_WARN_THROWS_AS
#define WARN_THROWS_WITH
DOCTEST_WARN_THROWS_WITH
#define WARN_THROWS_WITH_AS
DOCTEST_WARN_THROWS_WITH_AS
#define WARN_NOTHROW
DOCTEST_WARN_NOTHROW
#define CHECK
DOCTEST_CHECK
#define CHECK_FALSE
DOCTEST_CHECK_FALSE
#define CHECK_THROWS
DOCTEST_CHECK_THROWS
#define CHECK_THROWS_AS
DOCTEST_CHECK_THROWS_AS
#define CHECK_THROWS_WITH
DOCTEST_CHECK_THROWS_WITH
#define CHECK_THROWS_WITH_AS
DOCTEST_CHECK_THROWS_WITH_AS
#define CHECK_NOTHROW
DOCTEST_CHECK_NOTHROW
#define REQUIRE
DOCTEST_REQUIRE
#define REQUIRE_FALSE
DOCTEST_REQUIRE_FALSE
#define REQUIRE_THROWS
DOCTEST_REQUIRE_THROWS
#define REQUIRE_THROWS_AS
DOCTEST_REQUIRE_THROWS_AS
#define REQUIRE_THROWS_WITH
DOCTEST_REQUIRE_THROWS_WITH
#define REQUIRE_THROWS_WITH_AS
DOCTEST_REQUIRE_THROWS_WITH_AS
#define REQUIRE_NOTHROW
DOCTEST_REQUIRE_NOTHROW
#define WARN_MESSAGE
DOCTEST_WARN_MESSAGE
#define WARN_FALSE_MESSAGE
DOCTEST_WARN_FALSE_MESSAGE
#define WARN_THROWS_MESSAGE
DOCTEST_WARN_THROWS_MESSAGE
#define WARN_THROWS_AS_MESSAGE
DOCTEST_WARN_THROWS_AS_MESSAGE
#define WARN_THROWS_WITH_MESSAGE
DOCTEST_WARN_THROWS_WITH_MESSAGE
#define WARN_THROWS_WITH_AS_MESSAGE
DOCTEST_WARN_THROWS_WITH_AS_MESSAGE
#define WARN_NOTHROW_MESSAGE
DOCTEST_WARN_NOTHROW_MESSAGE
#define CHECK_MESSAGE
DOCTEST_CHECK_MESSAGE
#define CHECK_FALSE_MESSAGE
DOCTEST_CHECK_FALSE_MESSAGE
#define CHECK_THROWS_MESSAGE
DOCTEST_CHECK_THROWS_MESSAGE
#define CHECK_THROWS_AS_MESSAGE
DOCTEST_CHECK_THROWS_AS_MESSAGE
#define CHECK_THROWS_WITH_MESSAGE
DOCTEST_CHECK_THROWS_WITH_MESSAGE
#define CHECK_THROWS_WITH_AS_MESSAGE
DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE
#define CHECK_NOTHROW_MESSAGE
DOCTEST_CHECK_NOTHROW_MESSAGE
#define REQUIRE_MESSAGE
DOCTEST_REQUIRE_MESSAGE
#define REQUIRE_FALSE_MESSAGE
DOCTEST_REQUIRE_FALSE_MESSAGE
#define REQUIRE_THROWS_MESSAGE
DOCTEST_REQUIRE_THROWS_MESSAGE
#define REQUIRE_THROWS_AS_MESSAGE
DOCTEST_REQUIRE_THROWS_AS_MESSAGE
#define REQUIRE_THROWS_WITH_MESSAGE
DOCTEST_REQUIRE_THROWS_WITH_MESSAGE
#define REQUIRE_THROWS_WITH_AS_MESSAGE
DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE
#define REQUIRE_NOTHROW_MESSAGE
DOCTEST_REQUIRE_NOTHROW_MESSAGE
#define SCENARIO
DOCTEST_SCENARIO
#define SCENARIO_CLASS
DOCTEST_SCENARIO_CLASS
#define SCENARIO_TEMPLATE
DOCTEST_SCENARIO_TEMPLATE
#define SCENARIO_TEMPLATE_DEFINE
DOCTEST_SCENARIO_TEMPLATE_DEFINE
#define GIVEN
DOCTEST_GIVEN
#define WHEN
DOCTEST_WHEN
#define AND_WHEN
DOCTEST_AND_WHEN
#define THEN
DOCTEST_THEN
#define AND_THEN
DOCTEST_AND_THEN
#define WARN_EQ
DOCTEST_WARN_EQ
#define CHECK_EQ
DOCTEST_CHECK_EQ
#define REQUIRE_EQ
DOCTEST_REQUIRE_EQ
#define WARN_NE
DOCTEST_WARN_NE
#define CHECK_NE
DOCTEST_CHECK_NE
#define REQUIRE_NE
DOCTEST_REQUIRE_NE
#define WARN_GT
DOCTEST_WARN_GT
#define CHECK_GT
DOCTEST_CHECK_GT
#define REQUIRE_GT
DOCTEST_REQUIRE_GT
#define WARN_LT
DOCTEST_WARN_LT
#define CHECK_LT
DOCTEST_CHECK_LT
#define REQUIRE_LT
DOCTEST_REQUIRE_LT
#define WARN_GE
DOCTEST_WARN_GE
#define CHECK_GE
DOCTEST_CHECK_GE
#define REQUIRE_GE
DOCTEST_REQUIRE_GE
#define WARN_LE
DOCTEST_WARN_LE
#define CHECK_LE
DOCTEST_CHECK_LE
#define REQUIRE_LE
DOCTEST_REQUIRE_LE
#define WARN_UNARY
DOCTEST_WARN_UNARY
#define CHECK_UNARY
DOCTEST_CHECK_UNARY
#define REQUIRE_UNARY
DOCTEST_REQUIRE_UNARY
#define WARN_UNARY_FALSE
DOCTEST_WARN_UNARY_FALSE
#define CHECK_UNARY_FALSE
DOCTEST_CHECK_UNARY_FALSE
#define REQUIRE_UNARY_FALSE
DOCTEST_REQUIRE_UNARY_FALSE
#define REGISTER_EXCEPTION_TRANSLATOR
(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
#define REGISTER_REPORTER
(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define REGISTER_LISTENER
(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
#define INFO
(...) DOCTEST_INFO(__VA_ARGS__)
#define CAPTURE
(x) DOCTEST_CAPTURE(x)
#define ADD_MESSAGE_AT
(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_CHECK_AT
(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_AT
(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
#define MESSAGE
(...) DOCTEST_MESSAGE(__VA_ARGS__)
#define FAIL_CHECK
(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
#define FAIL
(...) DOCTEST_FAIL(__VA_ARGS__)
#define TO_LVALUE
(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
#define WARN
(...) DOCTEST_WARN(__VA_ARGS__)
#define WARN_FALSE
(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
#define WARN_THROWS
(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
#define WARN_THROWS_AS
(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
#define WARN_THROWS_WITH
(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
#define WARN_THROWS_WITH_AS
(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define WARN_NOTHROW
(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
#define CHECK
(...) DOCTEST_CHECK(__VA_ARGS__)
#define CHECK_FALSE
(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
#define CHECK_THROWS
(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
#define CHECK_THROWS_AS
(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH
(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS
(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define CHECK_NOTHROW
(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
#define REQUIRE
(...) DOCTEST_REQUIRE(__VA_ARGS__)
#define REQUIRE_FALSE
(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
#define REQUIRE_THROWS
(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
#define REQUIRE_THROWS_AS
(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH
(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS
(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define REQUIRE_NOTHROW
(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
#define WARN_MESSAGE
(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
#define WARN_FALSE_MESSAGE
(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
#define WARN_THROWS_MESSAGE
(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
#define WARN_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define WARN_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define WARN_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define WARN_NOTHROW_MESSAGE
(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define CHECK_MESSAGE
(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
#define CHECK_FALSE_MESSAGE
(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
#define CHECK_THROWS_MESSAGE
(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
#define CHECK_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define CHECK_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define CHECK_NOTHROW_MESSAGE
(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_MESSAGE
(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_FALSE_MESSAGE
(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_THROWS_MESSAGE
(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define REQUIRE_NOTHROW_MESSAGE
(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define SCENARIO
(name) DOCTEST_SCENARIO(name)
#define SCENARIO_CLASS
(name) DOCTEST_SCENARIO_CLASS(name)
#define SCENARIO_TEMPLATE
(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
#define SCENARIO_TEMPLATE_DEFINE
(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
#define GIVEN
(name) DOCTEST_GIVEN(name)
#define WHEN
(name) DOCTEST_WHEN(name)
#define AND_WHEN
(name) DOCTEST_AND_WHEN(name)
#define THEN
(name) DOCTEST_THEN(name)
#define AND_THEN
(name) DOCTEST_AND_THEN(name)
#define WARN_EQ
(...) DOCTEST_WARN_EQ(__VA_ARGS__)
#define CHECK_EQ
(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
#define REQUIRE_EQ
(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
#define WARN_NE
(...) DOCTEST_WARN_NE(__VA_ARGS__)
#define CHECK_NE
(...) DOCTEST_CHECK_NE(__VA_ARGS__)
#define REQUIRE_NE
(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
#define WARN_GT
(...) DOCTEST_WARN_GT(__VA_ARGS__)
#define CHECK_GT
(...) DOCTEST_CHECK_GT(__VA_ARGS__)
#define REQUIRE_GT
(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
#define WARN_LT
(...) DOCTEST_WARN_LT(__VA_ARGS__)
#define CHECK_LT
(...) DOCTEST_CHECK_LT(__VA_ARGS__)
#define REQUIRE_LT
(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
#define WARN_GE
(...) DOCTEST_WARN_GE(__VA_ARGS__)
#define CHECK_GE
(...) DOCTEST_CHECK_GE(__VA_ARGS__)
#define REQUIRE_GE
(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
#define WARN_LE
(...) DOCTEST_WARN_LE(__VA_ARGS__)
#define CHECK_LE
(...) DOCTEST_CHECK_LE(__VA_ARGS__)
#define REQUIRE_LE
(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
#define WARN_UNARY
(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
#define CHECK_UNARY
(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
#define REQUIRE_UNARY
(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
#define WARN_UNARY_FALSE
(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
#define CHECK_UNARY_FALSE
(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define REQUIRE_UNARY_FALSE
(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
// KEPT FOR BACKWARDS COMPATIBILITY
#define FAST_WARN_EQ
DOCTEST_FAST_WARN_EQ
#define FAST_CHECK_EQ
DOCTEST_FAST_CHECK_EQ
#define FAST_REQUIRE_EQ
DOCTEST_FAST_REQUIRE_EQ
#define FAST_WARN_NE
DOCTEST_FAST_WARN_NE
#define FAST_CHECK_NE
DOCTEST_FAST_CHECK_NE
#define FAST_REQUIRE_NE
DOCTEST_FAST_REQUIRE_NE
#define FAST_WARN_GT
DOCTEST_FAST_WARN_GT
#define FAST_CHECK_GT
DOCTEST_FAST_CHECK_GT
#define FAST_REQUIRE_GT
DOCTEST_FAST_REQUIRE_GT
#define FAST_WARN_LT
DOCTEST_FAST_WARN_LT
#define FAST_CHECK_LT
DOCTEST_FAST_CHECK_LT
#define FAST_REQUIRE_LT
DOCTEST_FAST_REQUIRE_LT
#define FAST_WARN_GE
DOCTEST_FAST_WARN_GE
#define FAST_CHECK_GE
DOCTEST_FAST_CHECK_GE
#define FAST_REQUIRE_GE
DOCTEST_FAST_REQUIRE_GE
#define FAST_WARN_LE
DOCTEST_FAST_WARN_LE
#define FAST_CHECK_LE
DOCTEST_FAST_CHECK_LE
#define FAST_REQUIRE_LE
DOCTEST_FAST_REQUIRE_LE
#define FAST_WARN_UNARY
DOCTEST_FAST_WARN_UNARY
#define FAST_CHECK_UNARY
DOCTEST_FAST_CHECK_UNARY
#define FAST_REQUIRE_UNARY
DOCTEST_FAST_REQUIRE_UNARY
#define FAST_WARN_UNARY_FALSE
DOCTEST_FAST_WARN_UNARY_FALSE
#define FAST_CHECK_UNARY_FALSE
DOCTEST_FAST_CHECK_UNARY_FALSE
#define FAST_REQUIRE_UNARY_FALSE
DOCTEST_FAST_REQUIRE_UNARY_FALSE
#define TEST_CASE_TEMPLATE_INSTANTIATE
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
#define FAST_WARN_EQ
(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
#define FAST_CHECK_EQ
(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
#define FAST_REQUIRE_EQ
(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
#define FAST_WARN_NE
(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
#define FAST_CHECK_NE
(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
#define FAST_REQUIRE_NE
(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
#define FAST_WARN_GT
(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
#define FAST_CHECK_GT
(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
#define FAST_REQUIRE_GT
(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
#define FAST_WARN_LT
(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
#define FAST_CHECK_LT
(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
#define FAST_REQUIRE_LT
(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
#define FAST_WARN_GE
(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
#define FAST_CHECK_GE
(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
#define FAST_REQUIRE_GE
(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
#define FAST_WARN_LE
(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
#define FAST_CHECK_LE
(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
#define FAST_REQUIRE_LE
(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
#define FAST_WARN_UNARY
(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
#define FAST_CHECK_UNARY
(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
#define FAST_REQUIRE_UNARY
(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
#define FAST_WARN_UNARY_FALSE
(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
#define FAST_CHECK_UNARY_FALSE
(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define FAST_REQUIRE_UNARY_FALSE
(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
#define TEST_CASE_TEMPLATE_INSTANTIATE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
...
...
@@ -2689,6 +2746,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path")
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas")
...
...
@@ -2794,11 +2852,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <windows.h>
#else // MINGW
#include <Windows.h>
#endif // MINGW
#endif
#include <io.h>
...
...
@@ -2834,12 +2888,24 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
#define DOCTEST_THREAD_LOCAL thread_local
#endif
#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
#endif
#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
#endif
#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
#else
#define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
#endif
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
#endif
namespace doctest {
bool is_running_in_test = false;
...
...
@@ -2972,18 +3038,105 @@ typedef timer_large_integer::type ticks_t;
ticks_t m_ticks = 0;
};
#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
template <typename T>
using AtomicOrMultiLaneAtomic = std::atomic<T>;
#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
// Provides a multilane implementation of an atomic variable that supports add, sub, load,
// store. Instead of using a single atomic variable, this splits up into multiple ones,
// each sitting on a separate cache line. The goal is to provide a speedup when most
// operations are modifying. It achieves this with two properties:
//
// * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
// * Each atomic sits on a separate cache line, so false sharing is reduced.
//
// The disadvantage is that there is a small overhead due to the use of TLS, and load/store
// is slower because all atomics have to be accessed.
template <typename T>
class MultiLaneAtomic
{
struct CacheLineAlignedAtomic
{
std::atomic<T> atomic{};
char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic<T>)];
};
CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];
static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
"guarantee one atomic takes exactly one cache line");
public:
T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }
T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }
T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
return myAtomic().fetch_add(arg, order);
}
T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
return myAtomic().fetch_sub(arg, order);
}
operator T() const DOCTEST_NOEXCEPT { return load(); }
T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {
auto result = T();
for(auto const& c : m_atomics) {
result += c.atomic.load(order);
}
return result;
}
T operator=(T desired) DOCTEST_NOEXCEPT {
store(desired);
return desired;
}
void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
// first value becomes desired", all others become 0.
for(auto& c : m_atomics) {
c.atomic.store(desired, order);
desired = {};
}
}
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
// everything will work.
//
// The logic here is a bit tricky. The call should be as fast as possible, so that there
// is minimal to no overhead in determining the correct atomic for the current thread.
//
// 1. A global static counter laneCounter counts continuously up.
// 2. Each successive thread will use modulo operation of that counter so it gets an atomic
// assigned in a round-robin fashion.
// 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
// little overhead.
std::atomic<T>& myAtomic() DOCTEST_NOEXCEPT {
static std::atomic<size_t> laneCounter;
DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =
laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;
return m_atomics[tlsLaneIdx].atomic;
}
};
template <typename T>
using AtomicOrMultiLaneAtomic = MultiLaneAtomic<T>;
#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
// this holds both parameters from the command line and runtime data for tests
struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
{
std
::
a
tomic
<
int
>
numAssertsCurrentTest_atomic
;
std
::
a
tomic
<
int
>
numAssertsFailedCurrentTest_atomic
;
AtomicOrMultiLaneA
tomic<int> numAssertsCurrentTest_atomic;
AtomicOrMultiLaneA
tomic<int> numAssertsFailedCurrentTest_atomic;
std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters
std::vector<IReporter*> reporters_currently_used;
const
TestCase
*
currentTest
=
nullptr
;
assert_handler ah = nullptr;
Timer timer;
...
...
@@ -3093,14 +3246,16 @@ String::String(const char* in)
String::String(const char* in, unsigned in_size) {
using namespace std;
if(in_size <= last) {
memcpy
(
buf
,
in
,
in_size
+
1
);
memcpy(buf, in, in_size);
buf[in_size] = '\0';
setLast(last - in_size);
} else {
setOnHeap();
data.size = in_size;
data.capacity = data.size + 1;
data.ptr = new char[data.capacity];
memcpy
(
data
.
ptr
,
in
,
in_size
+
1
);
memcpy(data.ptr, in, in_size);
data.ptr[in_size] = '\0';
}
}
...
...
@@ -3471,7 +3626,7 @@ int registerReporter(const char*, int, IReporter*) { return 0; }
namespace doctest_detail_test_suite_ns {
// holds the current test suite
doctest::detail::TestSuite& getCurrentTestSuite() {
static
doctest
::
detail
::
TestSuite
data
;
static doctest::detail::TestSuite data
{}
;
return data;
}
} // namespace doctest_detail_test_suite_ns
...
...
@@ -3583,7 +3738,7 @@ namespace detail {
Subcase::Subcase(const String& name, const char* file, int line)
: m_signature({name, file, line}) {
ContextState
*
s
=
g_cs
;
auto
* s = g_cs;
// check subcase filters
if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {
...
...
@@ -3625,7 +3780,7 @@ namespace detail {
g_cs->subcasesPassed.insert(g_cs->subcasesStack);
g_cs->subcasesStack.pop_back();
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
#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)
if(std::uncaught_exceptions() > 0
#else
if(std::uncaught_exception()
...
...
@@ -3660,6 +3815,8 @@ namespace detail {
// 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;
...
...
@@ -3675,6 +3832,8 @@ namespace detail {
m_test_suite = test_suite.m_test_suite;
m_description = test_suite.m_description;
m_skip = test_suite.m_skip;
m_no_breaks = test_suite.m_no_breaks;
m_no_output = test_suite.m_no_output;
m_may_fail = test_suite.m_may_fail;
m_should_fail = test_suite.m_should_fail;
m_expected_failures = test_suite.m_expected_failures;
...
...
@@ -3721,14 +3880,20 @@ namespace detail {
// this will be used only to differentiate between test cases - not relevant for sorting
if(m_line != other.m_line)
return m_line < other.m_line;
const
int
file_cmp
=
m_file
.
compare
(
other
.
m_file
);
if
(
file_cmp
!=
0
)
return
file_cmp
<
0
;
const int name_cmp = strcmp(m_name, other.m_name);
if(name_cmp != 0)
return name_cmp < 0;
const int file_cmp = m_file.compare(other.m_file);
if(file_cmp != 0)
return file_cmp < 0;
return m_template_id < other.m_template_id;
}
// all the registered tests
std::set<TestCase>& getRegisteredTests() {
static std::set<TestCase> data;
return data;
}
} // namespace detail
namespace {
using namespace detail;
...
...
@@ -3760,12 +3925,6 @@ namespace {
return suiteOrderComparator(lhs, rhs);
}
// all the registered tests
std
::
set
<
TestCase
>&
getRegisteredTests
()
{
static
std
::
set
<
TestCase
>
data
;
return
data
;
}
#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
HANDLE g_stdoutHandle;
WORD g_origFgAttrs;
...
...
@@ -3994,7 +4153,7 @@ namespace detail {
// ContextScope has been destroyed (base class destructors run after derived class destructors).
// Instead, ContextScope calls this method directly from its destructor.
void ContextScopeBase::destroy() {
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
#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)
if(std::uncaught_exceptions() > 0) {
#else
if(std::uncaught_exception()) {
...
...
@@ -4016,7 +4175,9 @@ namespace {
#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
struct FatalConditionHandler
{
void
reset
()
{}
static void reset() {}
static void allocateAltStackMem() {}
static void freeAltStackMem() {}
};
#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
...
...
@@ -4069,6 +4230,9 @@ namespace {
std::exit(EXIT_FAILURE);
}
static void allocateAltStackMem() {}
static void freeAltStackMem() {}
FatalConditionHandler() {
isSet = true;
// 32k seems enough for doctest to handle stack overflow,
...
...
@@ -4086,7 +4250,7 @@ namespace {
// - std::terminate is called FROM THE TEST RUNNER THREAD
// - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
original_terminate_handler = std::get_terminate();
std
::
set_terminate
([]()
noexcept
{
std::set_terminate([]()
DOCTEST_NOEXCEPT
{
reportFatal("Terminate handler called");
if(isDebuggerActive() && !g_cs->no_breaks)
DOCTEST_BREAK_INTO_DEBUGGER();
...
...
@@ -4097,7 +4261,7 @@ namespace {
// - std::terminate is called FROM A DIFFERENT THREAD
// - an exception is thrown from a destructor FROM A DIFFERENT THREAD
// - an uncaught exception is thrown FROM A DIFFERENT THREAD
prev_sigabrt_handler
=
std
::
signal
(
SIGABRT
,
[](
int
signal
)
noexcept
{
prev_sigabrt_handler = std::signal(SIGABRT, [](int signal)
DOCTEST_NOEXCEPT
{
if(signal == SIGABRT) {
reportFatal("SIGABRT - Abort (abnormal termination) signal");
if(isDebuggerActive() && !g_cs->no_breaks)
...
...
@@ -4135,8 +4299,8 @@ namespace {
SetErrorMode(prev_error_mode_1);
_set_error_mode(prev_error_mode_2);
_set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
_CrtSetReportMode
(
_CRT_ASSERT
,
prev_report_mode
);
_CrtSetReportFile
(
_CRT_ASSERT
,
prev_report_file
);
static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode)
);
static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file)
);
isSet = false;
}
}
...
...
@@ -4186,7 +4350,8 @@ namespace {
static bool isSet;
static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];
static stack_t oldSigStack;
static
char
altStackMem
[
4
*
SIGSTKSZ
];
static size_t altStackSize;
static char* altStackMem;
static void handleSignal(int sig) {
const char* name = "<unknown signal>";
...
...
@@ -4202,11 +4367,19 @@ namespace {
raise(sig);
}
static void allocateAltStackMem() {
altStackMem = new char[altStackSize];
}
static void freeAltStackMem() {
delete[] altStackMem;
}
FatalConditionHandler() {
isSet = true;
stack_t sigStack;
sigStack.ss_sp = altStackMem;
sigStack
.
ss_size
=
sizeof
(
altStackMem
)
;
sigStack.ss_size =
altStackSize
;
sigStack.ss_flags = 0;
sigaltstack(&sigStack, &oldSigStack);
struct sigaction sa = {};
...
...
@@ -4231,10 +4404,11 @@ namespace {
}
};
bool
FatalConditionHandler
::
isSet
=
false
;
bool FatalConditionHandler::isSet = false;
struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};
stack_t
FatalConditionHandler
::
oldSigStack
=
{};
char
FatalConditionHandler
::
altStackMem
[]
=
{};
stack_t FatalConditionHandler::oldSigStack = {};
size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;
char* FatalConditionHandler::altStackMem = nullptr;
#endif // DOCTEST_PLATFORM_WINDOWS
#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
...
...
@@ -4336,8 +4510,8 @@ namespace detail {
failed_out_of_a_testing_context(*this);
}
return
m_failed
&&
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
;
// break into debugger
return m_failed && isDebuggerActive() &&
!getContextOptions()->no_breaks &&
(g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks)
; // break into debugger
}
void ResultBuilder::react() const {
...
...
@@ -4387,7 +4561,8 @@ namespace detail {
addFailedAssert(m_severity);
}
return
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
&&
!
isWarn
;
// break
return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn &&
(g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
}
void MessageBuilder::react() {
...
...
@@ -5495,7 +5670,7 @@ namespace {
<< Whitespace(sizePrefixDisplay*1) << "output filename\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by=<string> "
<< Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n";
s
<<
Whitespace
(
sizePrefixDisplay
*
3
)
<<
" <string> -
by [file/suite/name/rand
]
\n
"
;
s << Whitespace(sizePrefixDisplay*3) << " <string> -
[file/suite/name/rand/none
]\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed=<int> "
<< Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n";
s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first=<int> "
...
...
@@ -5668,6 +5843,9 @@ namespace {
}
void test_case_end(const CurrentTestCaseStats& st) override {
if(tc->m_no_output)
return;
// log the preamble of the test case only if there is something
// else to print - something other than that an assert has failed
if(opt.duration ||
...
...
@@ -5702,6 +5880,9 @@ namespace {
}
void test_case_exception(const TestCaseException& e) override {
if(tc->m_no_output)
return;
logTestStart();
file_line_to_stream(tc->m_file.c_str(), tc->m_line, " ");
...
...
@@ -5736,7 +5917,7 @@ namespace {
}
void log_assert(const AssertData& rb) override {
if
(
!
rb
.
m_failed
&&
!
opt
.
success
)
if(
(!rb.m_failed && !opt.success) || tc->m_no_output
)
return;
std::lock_guard<std::mutex> lock(mutex);
...
...
@@ -5752,6 +5933,9 @@ namespace {
}
void log_message(const MessageData& mb) override {
if(tc->m_no_output)
return;
std::lock_guard<std::mutex> lock(mutex);
logTestStart();
...
...
@@ -5782,8 +5966,10 @@ namespace {
bool with_col = g_no_colors; \
g_no_colors = false; \
ConsoleReporter::func(arg); \
DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
oss.str(""); \
if(oss.tellp() != std::streampos{}) { \
DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
oss.str(""); \
} \
g_no_colors = with_col; \
}
...
...
@@ -5970,7 +6156,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
p->var =
!!intRes;
\
p->var =
static_cast<bool>(intRes);
\
else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
p->var = true; \
...
...
@@ -6115,7 +6301,11 @@ int Context::run() {
p->cout = &fstr;
}
FatalConditionHandler::allocateAltStackMem();
auto cleanup_and_return = [&]() {
FatalConditionHandler::freeAltStackMem();
if(fstr.is_open())
fstr.close();
...
...
@@ -6187,6 +6377,9 @@ int Context::run() {
first[i] = first[idxToSwap];
first[idxToSwap] = temp;
}
} else if(p->order_by.compare("none", true) == 0) {
// means no sorting - beneficial for death tests which call into the executable
// with a specific test case in mind - we don't want to slow down the startup times
}
}
...
...
@@ -6286,10 +6479,13 @@ int Context::run() {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
try {
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable
FatalConditionHandler fatalConditionHandler; // Handle signals
// execute the test
tc.m_test();
fatalConditionHandler.reset();
DOCTEST_MSVC_SUPPRESS_WARNING_POP
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
} catch(const TestFailureException&) {
p->failure_flags |= TestCaseFailureReason::AssertFailure;
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment