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
f65ade0f
Unverified
Commit
f65ade0f
authored
Dec 29, 2021
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
⬆
Doctest 2.4.7
parent
e6bf789f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
339 additions
and
169 deletions
+339
-169
test/thirdparty/doctest/doctest.h
test/thirdparty/doctest/doctest.h
+339
-169
No files found.
test/thirdparty/doctest/doctest.h
View file @
f65ade0f
...
...
@@ -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 fo
c
MSVC 2015:
// this is needed only fo
r
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 degra
t
e a bit, but still
// use this, some will use the same atomic. So performance will degra
d
e 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_attrsInit
t
ed
=
false
;
bool
g_attrsInited
=
false
;
int
colors_init
()
{
if
(
!
g_attrsInit
t
ed
)
{
if
(
!
g_attrsInited
)
{
g_stdoutHandle
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
g_attrsInit
t
ed
=
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
dum
m
y_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
();
...
...
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