⬆️ doctest 2.3.7 #2048
This commit is contained in:
parent
be137609df
commit
45d5b09425
2 changed files with 87 additions and 72 deletions
2
test/thirdparty/doctest/LICENSE.txt
vendored
Normal file → Executable file
2
test/thirdparty/doctest/LICENSE.txt
vendored
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016-2018 Viktor Kirilov
|
Copyright (c) 2016-2019 Viktor Kirilov
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
151
test/thirdparty/doctest/doctest.h
vendored
151
test/thirdparty/doctest/doctest.h
vendored
|
@ -48,8 +48,8 @@
|
||||||
|
|
||||||
#define DOCTEST_VERSION_MAJOR 2
|
#define DOCTEST_VERSION_MAJOR 2
|
||||||
#define DOCTEST_VERSION_MINOR 3
|
#define DOCTEST_VERSION_MINOR 3
|
||||||
#define DOCTEST_VERSION_PATCH 5
|
#define DOCTEST_VERSION_PATCH 7
|
||||||
#define DOCTEST_VERSION_STR "2.3.5"
|
#define DOCTEST_VERSION_STR "2.3.7"
|
||||||
|
|
||||||
#define DOCTEST_VERSION \
|
#define DOCTEST_VERSION \
|
||||||
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
|
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
|
||||||
|
@ -157,7 +157,6 @@ DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Winline")
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept")
|
||||||
|
@ -182,6 +181,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Dec
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
|
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...
|
DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtr...
|
DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtr...
|
||||||
|
DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
|
||||||
|
|
||||||
// 4548 - expression before comma has no effect; expected expression with side - effect
|
// 4548 - expression before comma has no effect; expected expression with side - effect
|
||||||
// 4265 - class has virtual functions, but destructor is not virtual
|
// 4265 - class has virtual functions, but destructor is not virtual
|
||||||
|
@ -369,10 +369,7 @@ DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||||
#ifdef DOCTEST_CONFIG_USE_STD_HEADERS
|
#ifdef DOCTEST_CONFIG_USE_STD_HEADERS
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
|
|
||||||
// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#endif // VS 2019
|
|
||||||
#else // DOCTEST_CONFIG_USE_STD_HEADERS
|
#else // DOCTEST_CONFIG_USE_STD_HEADERS
|
||||||
|
|
||||||
#if DOCTEST_CLANG
|
#if DOCTEST_CLANG
|
||||||
|
@ -677,7 +674,7 @@ struct DOCTEST_INTERFACE MessageData
|
||||||
|
|
||||||
struct DOCTEST_INTERFACE SubcaseSignature
|
struct DOCTEST_INTERFACE SubcaseSignature
|
||||||
{
|
{
|
||||||
const char* m_name;
|
String m_name;
|
||||||
const char* m_file;
|
const char* m_file;
|
||||||
int m_line;
|
int m_line;
|
||||||
|
|
||||||
|
@ -999,7 +996,7 @@ namespace detail {
|
||||||
SubcaseSignature m_signature;
|
SubcaseSignature m_signature;
|
||||||
bool m_entered = false;
|
bool m_entered = false;
|
||||||
|
|
||||||
Subcase(const char* name, const char* file, int line);
|
Subcase(const String& name, const char* file, int line);
|
||||||
~Subcase();
|
~Subcase();
|
||||||
|
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
|
@ -1040,7 +1037,7 @@ namespace detail {
|
||||||
|
|
||||||
Result(bool passed, const String& decomposition = String());
|
Result(bool passed, const String& decomposition = String());
|
||||||
|
|
||||||
// forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence
|
// forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
|
||||||
DOCTEST_FORBIT_EXPRESSION(Result, &)
|
DOCTEST_FORBIT_EXPRESSION(Result, &)
|
||||||
DOCTEST_FORBIT_EXPRESSION(Result, ^)
|
DOCTEST_FORBIT_EXPRESSION(Result, ^)
|
||||||
DOCTEST_FORBIT_EXPRESSION(Result, |)
|
DOCTEST_FORBIT_EXPRESSION(Result, |)
|
||||||
|
@ -1082,7 +1079,7 @@ namespace detail {
|
||||||
//DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
|
//DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
|
||||||
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
|
DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
|
||||||
// http://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
|
// https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
|
DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
|
DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
|
DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
|
||||||
|
@ -1164,7 +1161,7 @@ namespace detail {
|
||||||
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional
|
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence
|
// forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
|
||||||
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)
|
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)
|
||||||
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)
|
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)
|
||||||
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)
|
DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)
|
||||||
|
@ -1492,7 +1489,7 @@ namespace detail {
|
||||||
void destroy();
|
void destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L> class DOCTEST_INTERFACE ContextScope : public ContextScopeBase
|
template <typename L> class ContextScope : public ContextScopeBase
|
||||||
{
|
{
|
||||||
const L &lambda_;
|
const L &lambda_;
|
||||||
|
|
||||||
|
@ -1649,7 +1646,7 @@ struct DOCTEST_INTERFACE TestRunStats
|
||||||
struct QueryData
|
struct QueryData
|
||||||
{
|
{
|
||||||
const TestRunStats* run_stats = nullptr;
|
const TestRunStats* run_stats = nullptr;
|
||||||
String* data = nullptr;
|
const TestCaseData** data = nullptr;
|
||||||
unsigned num_data = 0;
|
unsigned num_data = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2659,7 +2656,6 @@ DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Winline")
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
|
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
|
||||||
|
@ -2698,6 +2694,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Dec
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
|
DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...
|
DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ...
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtor...
|
DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtor...
|
||||||
|
DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
|
||||||
|
|
||||||
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
|
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
|
||||||
|
|
||||||
|
@ -2873,26 +2870,37 @@ namespace detail {
|
||||||
|
|
||||||
#ifndef DOCTEST_CONFIG_DISABLE
|
#ifndef DOCTEST_CONFIG_DISABLE
|
||||||
|
|
||||||
typedef uint64_t UInt64;
|
namespace timer_large_integer
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(DOCTEST_PLATFORM_WINDOWS)
|
||||||
|
typedef ULONGLONG type;
|
||||||
|
#else // DOCTEST_PLATFORM_WINDOWS
|
||||||
|
using namespace std;
|
||||||
|
typedef uint64_t type;
|
||||||
|
#endif // DOCTEST_PLATFORM_WINDOWS
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef timer_large_integer::type ticks_t;
|
||||||
|
|
||||||
#ifdef DOCTEST_CONFIG_GETCURRENTTICKS
|
#ifdef DOCTEST_CONFIG_GETCURRENTTICKS
|
||||||
UInt64 getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
|
ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
|
||||||
#elif defined(DOCTEST_PLATFORM_WINDOWS)
|
#elif defined(DOCTEST_PLATFORM_WINDOWS)
|
||||||
UInt64 getCurrentTicks() {
|
ticks_t getCurrentTicks() {
|
||||||
static UInt64 hz = 0, hzo = 0;
|
static LARGE_INTEGER hz = {0}, hzo = {0};
|
||||||
if(!hz) {
|
if(!hz.QuadPart) {
|
||||||
QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&hz));
|
QueryPerformanceFrequency(&hz);
|
||||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&hzo));
|
QueryPerformanceCounter(&hzo);
|
||||||
}
|
}
|
||||||
UInt64 t;
|
LARGE_INTEGER t;
|
||||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&t));
|
QueryPerformanceCounter(&t);
|
||||||
return ((t - hzo) * 1000000) / hz;
|
return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
|
||||||
}
|
}
|
||||||
#else // DOCTEST_PLATFORM_WINDOWS
|
#else // DOCTEST_PLATFORM_WINDOWS
|
||||||
UInt64 getCurrentTicks() {
|
ticks_t getCurrentTicks() {
|
||||||
timeval t;
|
timeval t;
|
||||||
gettimeofday(&t, nullptr);
|
gettimeofday(&t, nullptr);
|
||||||
return static_cast<UInt64>(t.tv_sec) * 1000000 + static_cast<UInt64>(t.tv_usec);
|
return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);
|
||||||
}
|
}
|
||||||
#endif // DOCTEST_PLATFORM_WINDOWS
|
#endif // DOCTEST_PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
@ -2905,10 +2913,10 @@ namespace detail {
|
||||||
//unsigned int getElapsedMilliseconds() const {
|
//unsigned int getElapsedMilliseconds() const {
|
||||||
// return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
|
// return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
|
||||||
//}
|
//}
|
||||||
double getElapsedSeconds() const { return getElapsedMicroseconds() / 1000000.0; }
|
double getElapsedSeconds() const { return (getCurrentTicks() - m_ticks) / 1000000.0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UInt64 m_ticks = 0;
|
ticks_t m_ticks = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this holds both parameters from the command line and runtime data for tests
|
// this holds both parameters from the command line and runtime data for tests
|
||||||
|
@ -3003,6 +3011,7 @@ void String::setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last]) = 128;
|
||||||
void String::setLast(unsigned in) { buf[last] = char(in); }
|
void String::setLast(unsigned in) { buf[last] = char(in); }
|
||||||
|
|
||||||
void String::copy(const String& other) {
|
void String::copy(const String& other) {
|
||||||
|
using namespace std;
|
||||||
if(other.isOnStack()) {
|
if(other.isOnStack()) {
|
||||||
memcpy(buf, other.buf, len);
|
memcpy(buf, other.buf, len);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3028,6 +3037,7 @@ String::String(const char* in)
|
||||||
: String(in, strlen(in)) {}
|
: String(in, strlen(in)) {}
|
||||||
|
|
||||||
String::String(const char* in, unsigned in_size) {
|
String::String(const char* in, unsigned in_size) {
|
||||||
|
using namespace std;
|
||||||
if(in_size <= last) {
|
if(in_size <= last) {
|
||||||
memcpy(buf, in, in_size + 1);
|
memcpy(buf, in, in_size + 1);
|
||||||
setLast(last - in_size);
|
setLast(last - in_size);
|
||||||
|
@ -3057,6 +3067,7 @@ String& String::operator+=(const String& other) {
|
||||||
const unsigned my_old_size = size();
|
const unsigned my_old_size = size();
|
||||||
const unsigned other_size = other.size();
|
const unsigned other_size = other.size();
|
||||||
const unsigned total_size = my_old_size + other_size;
|
const unsigned total_size = my_old_size + other_size;
|
||||||
|
using namespace std;
|
||||||
if(isOnStack()) {
|
if(isOnStack()) {
|
||||||
if(total_size < len) {
|
if(total_size < len) {
|
||||||
// append to the current stack space
|
// append to the current stack space
|
||||||
|
@ -3105,12 +3116,14 @@ String& String::operator+=(const String& other) {
|
||||||
String String::operator+(const String& other) const { return String(*this) += other; }
|
String String::operator+(const String& other) const { return String(*this) += other; }
|
||||||
|
|
||||||
String::String(String&& other) {
|
String::String(String&& other) {
|
||||||
|
using namespace std;
|
||||||
memcpy(buf, other.buf, len);
|
memcpy(buf, other.buf, len);
|
||||||
other.buf[0] = '\0';
|
other.buf[0] = '\0';
|
||||||
other.setLast();
|
other.setLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
String& String::operator=(String&& other) {
|
String& String::operator=(String&& other) {
|
||||||
|
using namespace std;
|
||||||
if(this != &other) {
|
if(this != &other) {
|
||||||
if(!isOnStack())
|
if(!isOnStack())
|
||||||
delete[] data.ptr;
|
delete[] data.ptr;
|
||||||
|
@ -3147,7 +3160,7 @@ unsigned String::capacity() const {
|
||||||
|
|
||||||
int String::compare(const char* other, bool no_case) const {
|
int String::compare(const char* other, bool no_case) const {
|
||||||
if(no_case)
|
if(no_case)
|
||||||
return stricmp(c_str(), other);
|
return doctest::stricmp(c_str(), other);
|
||||||
return std::strcmp(c_str(), other);
|
return std::strcmp(c_str(), other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3273,7 +3286,7 @@ bool SubcaseSignature::operator<(const SubcaseSignature& other) const {
|
||||||
return m_line < other.m_line;
|
return m_line < other.m_line;
|
||||||
if(std::strcmp(m_file, other.m_file) != 0)
|
if(std::strcmp(m_file, other.m_file) != 0)
|
||||||
return std::strcmp(m_file, other.m_file) < 0;
|
return std::strcmp(m_file, other.m_file) < 0;
|
||||||
return std::strcmp(m_name, other.m_name) < 0;
|
return m_name.compare(other.m_name) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IContextScope::IContextScope() = default;
|
IContextScope::IContextScope() = default;
|
||||||
|
@ -3508,15 +3521,15 @@ namespace {
|
||||||
} // namespace
|
} // namespace
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
Subcase::Subcase(const char* name, const char* file, int line)
|
Subcase::Subcase(const String& name, const char* file, int line)
|
||||||
: m_signature({name, file, line}) {
|
: m_signature({name, file, line}) {
|
||||||
ContextState* s = g_cs;
|
ContextState* s = g_cs;
|
||||||
|
|
||||||
// check subcase filters
|
// check subcase filters
|
||||||
if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {
|
if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {
|
||||||
if(!matchesAny(m_signature.m_name, s->filters[6], true, s->case_sensitive))
|
if(!matchesAny(m_signature.m_name.c_str(), s->filters[6], true, s->case_sensitive))
|
||||||
return;
|
return;
|
||||||
if(matchesAny(m_signature.m_name, s->filters[7], false, s->case_sensitive))
|
if(matchesAny(m_signature.m_name.c_str(), s->filters[7], false, s->case_sensitive))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3541,9 +3554,6 @@ namespace detail {
|
||||||
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
|
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
|
||||||
Subcase::~Subcase() {
|
Subcase::~Subcase() {
|
||||||
if(m_entered) {
|
if(m_entered) {
|
||||||
// only mark the subcase stack as passed if no subcases have been skipped
|
// only mark the subcase stack as passed if no subcases have been skipped
|
||||||
|
@ -3551,7 +3561,12 @@ namespace detail {
|
||||||
g_cs->subcasesPassed.insert(g_cs->subcasesStack);
|
g_cs->subcasesPassed.insert(g_cs->subcasesStack);
|
||||||
g_cs->subcasesStack.pop_back();
|
g_cs->subcasesStack.pop_back();
|
||||||
|
|
||||||
if(std::uncaught_exception() && g_cs->shouldLogCurrentException) {
|
#if __cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411
|
||||||
|
if(std::uncaught_exceptions() > 0
|
||||||
|
#else
|
||||||
|
if(std::uncaught_exception()
|
||||||
|
#endif
|
||||||
|
&& g_cs->shouldLogCurrentException) {
|
||||||
DOCTEST_ITERATE_THROUGH_REPORTERS(
|
DOCTEST_ITERATE_THROUGH_REPORTERS(
|
||||||
test_case_exception, {"exception thrown in subcase - will translate later "
|
test_case_exception, {"exception thrown in subcase - will translate later "
|
||||||
"when the whole test case has been exited (cannot "
|
"when the whole test case has been exited (cannot "
|
||||||
|
@ -3562,9 +3577,6 @@ namespace detail {
|
||||||
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
|
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
|
||||||
|
|
||||||
Subcase::operator bool() const { return m_entered; }
|
Subcase::operator bool() const { return m_entered; }
|
||||||
|
|
||||||
|
@ -3653,7 +3665,7 @@ namespace {
|
||||||
#if DOCTEST_MSVC
|
#if DOCTEST_MSVC
|
||||||
// this is needed because MSVC gives different case for drive letters
|
// this is needed because MSVC gives different case for drive letters
|
||||||
// for __FILE__ when evaluated in a header and a source file
|
// for __FILE__ when evaluated in a header and a source file
|
||||||
const int res = stricmp(lhs->m_file, rhs->m_file);
|
const int res = doctest::stricmp(lhs->m_file, rhs->m_file);
|
||||||
#else // MSVC
|
#else // MSVC
|
||||||
const int res = std::strcmp(lhs->m_file, rhs->m_file);
|
const int res = std::strcmp(lhs->m_file, rhs->m_file);
|
||||||
#endif // MSVC
|
#endif // MSVC
|
||||||
|
@ -3820,7 +3832,7 @@ namespace detail {
|
||||||
#else // DOCTEST_IS_DEBUGGER_ACTIVE
|
#else // DOCTEST_IS_DEBUGGER_ACTIVE
|
||||||
#ifdef DOCTEST_PLATFORM_MAC
|
#ifdef DOCTEST_PLATFORM_MAC
|
||||||
// The following function is taken directly from the following technical note:
|
// The following function is taken directly from the following technical note:
|
||||||
// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
|
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
|
||||||
// Returns true if the current process is being debugged (either
|
// Returns true if the current process is being debugged (either
|
||||||
// running under the debugger or has a debugger attached post facto).
|
// running under the debugger or has a debugger attached post facto).
|
||||||
bool isDebuggerActive() {
|
bool isDebuggerActive() {
|
||||||
|
@ -3885,23 +3897,21 @@ namespace detail {
|
||||||
g_infoContexts.push_back(this);
|
g_infoContexts.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
|
||||||
// destroy cannot be inlined into the destructor because that would mean calling stringify after
|
// destroy cannot be inlined into the destructor because that would mean calling stringify after
|
||||||
// ContextScope has been destroyed (base class destructors run after derived class destructors).
|
// ContextScope has been destroyed (base class destructors run after derived class destructors).
|
||||||
// Instead, ContextScope calls this method directly from its destructor.
|
// Instead, ContextScope calls this method directly from its destructor.
|
||||||
void ContextScopeBase::destroy() {
|
void ContextScopeBase::destroy() {
|
||||||
|
#if __cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411
|
||||||
|
if(std::uncaught_exceptions() > 0) {
|
||||||
|
#else
|
||||||
if(std::uncaught_exception()) {
|
if(std::uncaught_exception()) {
|
||||||
|
#endif
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
this->stringify(&s);
|
this->stringify(&s);
|
||||||
g_cs->stringifiedContexts.push_back(s.str().c_str());
|
g_cs->stringifiedContexts.push_back(s.str().c_str());
|
||||||
}
|
}
|
||||||
g_infoContexts.pop_back();
|
g_infoContexts.pop_back();
|
||||||
}
|
}
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
|
||||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
|
||||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -3944,10 +3954,11 @@ namespace {
|
||||||
|
|
||||||
struct FatalConditionHandler
|
struct FatalConditionHandler
|
||||||
{
|
{
|
||||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||||
for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
|
for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
|
||||||
if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||||
reportFatal(signalDefs[i].name);
|
reportFatal(signalDefs[i].name);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If its not an exception we care about, pass it along.
|
// If its not an exception we care about, pass it along.
|
||||||
|
@ -3960,9 +3971,8 @@ namespace {
|
||||||
// 32k seems enough for doctest to handle stack overflow,
|
// 32k seems enough for doctest to handle stack overflow,
|
||||||
// but the value was found experimentally, so there is no strong guarantee
|
// but the value was found experimentally, so there is no strong guarantee
|
||||||
guaranteeSize = 32 * 1024;
|
guaranteeSize = 32 * 1024;
|
||||||
exceptionHandlerHandle = nullptr;
|
// Register an unhandled exception filter
|
||||||
// Register as first handler in current chain
|
previousTop = SetUnhandledExceptionFilter(handleException);
|
||||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
|
||||||
// Pass in guarantee size to be filled
|
// Pass in guarantee size to be filled
|
||||||
SetThreadStackGuarantee(&guaranteeSize);
|
SetThreadStackGuarantee(&guaranteeSize);
|
||||||
}
|
}
|
||||||
|
@ -3970,9 +3980,9 @@ namespace {
|
||||||
static void reset() {
|
static void reset() {
|
||||||
if(isSet) {
|
if(isSet) {
|
||||||
// Unregister handler and restore the old guarantee
|
// Unregister handler and restore the old guarantee
|
||||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
SetUnhandledExceptionFilter(previousTop);
|
||||||
SetThreadStackGuarantee(&guaranteeSize);
|
SetThreadStackGuarantee(&guaranteeSize);
|
||||||
exceptionHandlerHandle = nullptr;
|
previousTop = nullptr;
|
||||||
isSet = false;
|
isSet = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3982,12 +3992,12 @@ namespace {
|
||||||
private:
|
private:
|
||||||
static bool isSet;
|
static bool isSet;
|
||||||
static ULONG guaranteeSize;
|
static ULONG guaranteeSize;
|
||||||
static PVOID exceptionHandlerHandle;
|
static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool FatalConditionHandler::isSet = false;
|
bool FatalConditionHandler::isSet = false;
|
||||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||||
PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
|
LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
|
||||||
|
|
||||||
#else // DOCTEST_PLATFORM_WINDOWS
|
#else // DOCTEST_PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
@ -4382,7 +4392,7 @@ namespace {
|
||||||
|
|
||||||
void XmlEncode::encodeTo( std::ostream& os ) const {
|
void XmlEncode::encodeTo( std::ostream& os ) const {
|
||||||
// Apostrophe escaping not necessary if we always use " to write attributes
|
// Apostrophe escaping not necessary if we always use " to write attributes
|
||||||
// (see: http://www.w3.org/TR/xml/#syntax)
|
// (see: https://www.w3.org/TR/xml/#syntax)
|
||||||
|
|
||||||
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
|
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
|
||||||
uchar c = m_str[idx];
|
uchar c = m_str[idx];
|
||||||
|
@ -4391,7 +4401,7 @@ namespace {
|
||||||
case '&': os << "&"; break;
|
case '&': os << "&"; break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
// See: http://www.w3.org/TR/xml/#syntax
|
// See: https://www.w3.org/TR/xml/#syntax
|
||||||
if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
|
if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
|
||||||
os << ">";
|
os << ">";
|
||||||
else
|
else
|
||||||
|
@ -4409,7 +4419,7 @@ namespace {
|
||||||
// Check for control characters and invalid utf-8
|
// Check for control characters and invalid utf-8
|
||||||
|
|
||||||
// Escape control characters in standard ascii
|
// Escape control characters in standard ascii
|
||||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
// see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||||
if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
|
if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
|
||||||
hexEscapeChar(os, c);
|
hexEscapeChar(os, c);
|
||||||
break;
|
break;
|
||||||
|
@ -4649,7 +4659,7 @@ namespace {
|
||||||
void test_case_start_impl(const TestCaseData& in) {
|
void test_case_start_impl(const TestCaseData& in) {
|
||||||
bool open_ts_tag = false;
|
bool open_ts_tag = false;
|
||||||
if(tc != nullptr) { // we have already opened a test suite
|
if(tc != nullptr) { // we have already opened a test suite
|
||||||
if(strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
|
if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
|
||||||
xml.endElement();
|
xml.endElement();
|
||||||
open_ts_tag = true;
|
open_ts_tag = true;
|
||||||
}
|
}
|
||||||
|
@ -4694,13 +4704,17 @@ namespace {
|
||||||
.writeAttribute("priority", curr.first.first)
|
.writeAttribute("priority", curr.first.first)
|
||||||
.writeAttribute("name", curr.first.second);
|
.writeAttribute("name", curr.first.second);
|
||||||
} else if(opt.count || opt.list_test_cases) {
|
} else if(opt.count || opt.list_test_cases) {
|
||||||
for(unsigned i = 0; i < in.num_data; ++i)
|
for(unsigned i = 0; i < in.num_data; ++i) {
|
||||||
xml.scopedElement("TestCase").writeAttribute("name", in.data[i]);
|
xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
|
||||||
|
.writeAttribute("testsuite", in.data[i]->m_test_suite)
|
||||||
|
.writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file))
|
||||||
|
.writeAttribute("line", line(in.data[i]->m_line));
|
||||||
|
}
|
||||||
xml.scopedElement("OverallResultsTestCases")
|
xml.scopedElement("OverallResultsTestCases")
|
||||||
.writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
|
.writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
|
||||||
} else if(opt.list_test_suites) {
|
} else if(opt.list_test_suites) {
|
||||||
for(unsigned i = 0; i < in.num_data; ++i)
|
for(unsigned i = 0; i < in.num_data; ++i)
|
||||||
xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]);
|
xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite);
|
||||||
xml.scopedElement("OverallResultsTestCases")
|
xml.scopedElement("OverallResultsTestCases")
|
||||||
.writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
|
.writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
|
||||||
xml.scopedElement("OverallResultsTestSuites")
|
xml.scopedElement("OverallResultsTestSuites")
|
||||||
|
@ -5120,7 +5134,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned i = 0; i < in.num_data; ++i)
|
for(unsigned i = 0; i < in.num_data; ++i)
|
||||||
s << Color::None << in.data[i] << "\n";
|
s << Color::None << in.data[i]->m_name << "\n";
|
||||||
|
|
||||||
separator_to_stream();
|
separator_to_stream();
|
||||||
|
|
||||||
|
@ -5133,7 +5147,7 @@ namespace {
|
||||||
separator_to_stream();
|
separator_to_stream();
|
||||||
|
|
||||||
for(unsigned i = 0; i < in.num_data; ++i)
|
for(unsigned i = 0; i < in.num_data; ++i)
|
||||||
s << Color::None << in.data[i] << "\n";
|
s << Color::None << in.data[i]->m_test_suite << "\n";
|
||||||
|
|
||||||
separator_to_stream();
|
separator_to_stream();
|
||||||
|
|
||||||
|
@ -5150,6 +5164,7 @@ namespace {
|
||||||
|
|
||||||
void test_run_end(const TestRunStats& p) override {
|
void test_run_end(const TestRunStats& p) override {
|
||||||
separator_to_stream();
|
separator_to_stream();
|
||||||
|
s << std::dec;
|
||||||
|
|
||||||
const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
|
const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
|
||||||
s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6)
|
s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6)
|
||||||
|
@ -5750,7 +5765,7 @@ int Context::run() {
|
||||||
std::set<String> testSuitesPassingFilt;
|
std::set<String> testSuitesPassingFilt;
|
||||||
|
|
||||||
bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
|
bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
|
||||||
std::vector<String> queryResults;
|
std::vector<const TestCaseData*> queryResults;
|
||||||
|
|
||||||
if(!query_mode)
|
if(!query_mode)
|
||||||
DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);
|
DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);
|
||||||
|
@ -5796,14 +5811,14 @@ int Context::run() {
|
||||||
|
|
||||||
// print the name of the test and don't execute it
|
// print the name of the test and don't execute it
|
||||||
if(p->list_test_cases) {
|
if(p->list_test_cases) {
|
||||||
queryResults.push_back(tc.m_name);
|
queryResults.push_back(&tc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the name of the test suite if not done already and don't execute it
|
// print the name of the test suite if not done already and don't execute it
|
||||||
if(p->list_test_suites) {
|
if(p->list_test_suites) {
|
||||||
if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') {
|
if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') {
|
||||||
queryResults.push_back(tc.m_test_suite);
|
queryResults.push_back(&tc);
|
||||||
testSuitesPassingFilt.insert(tc.m_test_suite);
|
testSuitesPassingFilt.insert(tc.m_test_suite);
|
||||||
p->numTestSuitesPassingFilters++;
|
p->numTestSuitesPassingFilters++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue