From 45d5b094258a96a394107e5e9c76eec1768b53de Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 19 Apr 2020 12:33:42 +0200 Subject: [PATCH] :arrow_up: doctest 2.3.7 #2048 --- test/thirdparty/doctest/LICENSE.txt | 2 +- test/thirdparty/doctest/doctest.h | 157 +++++++++++++++------------- 2 files changed, 87 insertions(+), 72 deletions(-) mode change 100644 => 100755 test/thirdparty/doctest/LICENSE.txt diff --git a/test/thirdparty/doctest/LICENSE.txt b/test/thirdparty/doctest/LICENSE.txt old mode 100644 new mode 100755 index 62cdd948..a2047214 --- a/test/thirdparty/doctest/LICENSE.txt +++ b/test/thirdparty/doctest/LICENSE.txt @@ -1,6 +1,6 @@ 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 of this software and associated documentation files (the "Software"), to deal diff --git a/test/thirdparty/doctest/doctest.h b/test/thirdparty/doctest/doctest.h index 8b76419a..4f3a0e33 100755 --- a/test/thirdparty/doctest/doctest.h +++ b/test/thirdparty/doctest/doctest.h @@ -48,8 +48,8 @@ #define DOCTEST_VERSION_MAJOR 2 #define DOCTEST_VERSION_MINOR 3 -#define DOCTEST_VERSION_PATCH 5 -#define DOCTEST_VERSION_STR "2.3.5" +#define DOCTEST_VERSION_PATCH 7 +#define DOCTEST_VERSION_STR "2.3.7" #define DOCTEST_VERSION \ (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("-Wmissing-declarations") DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_GCC_SUPPRESS_WARNING("-Winline") DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") 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(26451) // Arithmetic overflow ... 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 // 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 #include #include -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183 #include -#endif // VS 2019 #else // DOCTEST_CONFIG_USE_STD_HEADERS #if DOCTEST_CLANG @@ -677,7 +674,7 @@ struct DOCTEST_INTERFACE MessageData struct DOCTEST_INTERFACE SubcaseSignature { - const char* m_name; + String m_name; const char* m_file; int m_line; @@ -999,7 +996,7 @@ namespace detail { SubcaseSignature m_signature; bool m_entered = false; - Subcase(const char* name, const char* file, int line); + Subcase(const String& name, const char* file, int line); ~Subcase(); operator bool() const; @@ -1040,7 +1037,7 @@ namespace detail { 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, |) @@ -1082,7 +1079,7 @@ namespace detail { //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal") 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(4389) // 'operator' : 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 // 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, |) @@ -1492,7 +1489,7 @@ namespace detail { void destroy(); }; - template class DOCTEST_INTERFACE ContextScope : public ContextScopeBase + template class ContextScope : public ContextScopeBase { const L &lambda_; @@ -1648,9 +1645,9 @@ struct DOCTEST_INTERFACE TestRunStats struct QueryData { - const TestRunStats* run_stats = nullptr; - String* data = nullptr; - unsigned num_data = 0; + const TestRunStats* run_stats = nullptr; + const TestCaseData** data = nullptr; + unsigned num_data = 0; }; struct DOCTEST_INTERFACE IReporter @@ -2659,7 +2656,6 @@ DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers") DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces") DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") -DOCTEST_GCC_SUPPRESS_WARNING("-Winline") DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch") DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum") 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(26451) // Arithmetic overflow ... 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 @@ -2873,26 +2870,37 @@ namespace detail { #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 - UInt64 getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); } + ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); } #elif defined(DOCTEST_PLATFORM_WINDOWS) - UInt64 getCurrentTicks() { - static UInt64 hz = 0, hzo = 0; - if(!hz) { - QueryPerformanceFrequency(reinterpret_cast(&hz)); - QueryPerformanceCounter(reinterpret_cast(&hzo)); + ticks_t getCurrentTicks() { + static LARGE_INTEGER hz = {0}, hzo = {0}; + if(!hz.QuadPart) { + QueryPerformanceFrequency(&hz); + QueryPerformanceCounter(&hzo); } - UInt64 t; - QueryPerformanceCounter(reinterpret_cast(&t)); - return ((t - hzo) * 1000000) / hz; + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart; } #else // DOCTEST_PLATFORM_WINDOWS - UInt64 getCurrentTicks() { + ticks_t getCurrentTicks() { timeval t; gettimeofday(&t, nullptr); - return static_cast(t.tv_sec) * 1000000 + static_cast(t.tv_usec); + return static_cast(t.tv_sec) * 1000000 + static_cast(t.tv_usec); } #endif // DOCTEST_PLATFORM_WINDOWS @@ -2905,10 +2913,10 @@ namespace detail { //unsigned int getElapsedMilliseconds() const { // return static_cast(getElapsedMicroseconds() / 1000); //} - double getElapsedSeconds() const { return getElapsedMicroseconds() / 1000000.0; } + double getElapsedSeconds() const { return (getCurrentTicks() - m_ticks) / 1000000.0; } private: - UInt64 m_ticks = 0; + ticks_t m_ticks = 0; }; // this holds both parameters from the command line and runtime data for tests @@ -3003,6 +3011,7 @@ void String::setOnHeap() { *reinterpret_cast(&buf[last]) = 128; void String::setLast(unsigned in) { buf[last] = char(in); } void String::copy(const String& other) { + using namespace std; if(other.isOnStack()) { memcpy(buf, other.buf, len); } else { @@ -3028,6 +3037,7 @@ String::String(const char* in) : String(in, strlen(in)) {} String::String(const char* in, unsigned in_size) { + using namespace std; if(in_size <= last) { memcpy(buf, in, in_size + 1); setLast(last - in_size); @@ -3057,6 +3067,7 @@ String& String::operator+=(const String& other) { const unsigned my_old_size = size(); const unsigned other_size = other.size(); const unsigned total_size = my_old_size + other_size; + using namespace std; if(isOnStack()) { if(total_size < len) { // 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(String&& other) { + using namespace std; memcpy(buf, other.buf, len); other.buf[0] = '\0'; other.setLast(); } String& String::operator=(String&& other) { + using namespace std; if(this != &other) { if(!isOnStack()) delete[] data.ptr; @@ -3147,7 +3160,7 @@ unsigned String::capacity() const { int String::compare(const char* other, bool no_case) const { if(no_case) - return stricmp(c_str(), other); + return doctest::stricmp(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; if(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; @@ -3508,15 +3521,15 @@ namespace { } // namespace 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}) { ContextState* s = g_cs; // check subcase filters 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; - 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; } @@ -3541,9 +3554,6 @@ namespace detail { 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() { if(m_entered) { // 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->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( test_case_exception, {"exception thrown in subcase - will translate later " "when the whole test case has been exited (cannot " @@ -3562,9 +3577,6 @@ namespace detail { 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; } @@ -3653,7 +3665,7 @@ namespace { #if DOCTEST_MSVC // this is needed because MSVC gives different case for drive letters // 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 const int res = std::strcmp(lhs->m_file, rhs->m_file); #endif // MSVC @@ -3820,7 +3832,7 @@ namespace detail { #else // DOCTEST_IS_DEBUGGER_ACTIVE #ifdef DOCTEST_PLATFORM_MAC // 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 // running under the debugger or has a debugger attached post facto). bool isDebuggerActive() { @@ -3885,23 +3897,21 @@ namespace detail { 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 // 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 __cplusplus >= 201703L && defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411 + if(std::uncaught_exceptions() > 0) { +#else if(std::uncaught_exception()) { +#endif std::ostringstream s; this->stringify(&s); g_cs->stringifiedContexts.push_back(s.str().c_str()); } g_infoContexts.pop_back(); } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP } // namespace detail namespace { @@ -3944,10 +3954,11 @@ namespace { 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) { if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { reportFatal(signalDefs[i].name); + break; } } // 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, // but the value was found experimentally, so there is no strong guarantee guaranteeSize = 32 * 1024; - exceptionHandlerHandle = nullptr; - // Register as first handler in current chain - exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Register an unhandled exception filter + previousTop = SetUnhandledExceptionFilter(handleException); // Pass in guarantee size to be filled SetThreadStackGuarantee(&guaranteeSize); } @@ -3970,9 +3980,9 @@ namespace { static void reset() { if(isSet) { // Unregister handler and restore the old guarantee - RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetUnhandledExceptionFilter(previousTop); SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = nullptr; + previousTop = nullptr; isSet = false; } } @@ -3982,12 +3992,12 @@ namespace { private: static bool isSet; static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; + static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; }; bool FatalConditionHandler::isSet = false; ULONG FatalConditionHandler::guaranteeSize = 0; - PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; #else // DOCTEST_PLATFORM_WINDOWS @@ -4382,7 +4392,7 @@ namespace { void XmlEncode::encodeTo( std::ostream& os ) const { // 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 ) { uchar c = m_str[idx]; @@ -4391,7 +4401,7 @@ namespace { case '&': os << "&"; break; 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] == ']') os << ">"; else @@ -4409,7 +4419,7 @@ namespace { // Check for control characters and invalid utf-8 // 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) { hexEscapeChar(os, c); break; @@ -4649,7 +4659,7 @@ namespace { void test_case_start_impl(const TestCaseData& in) { bool open_ts_tag = false; 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(); open_ts_tag = true; } @@ -4694,13 +4704,17 @@ namespace { .writeAttribute("priority", curr.first.first) .writeAttribute("name", curr.first.second); } else if(opt.count || opt.list_test_cases) { - for(unsigned i = 0; i < in.num_data; ++i) - xml.scopedElement("TestCase").writeAttribute("name", in.data[i]); + for(unsigned i = 0; i < in.num_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") .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); } else if(opt.list_test_suites) { 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") .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); xml.scopedElement("OverallResultsTestSuites") @@ -5120,7 +5134,7 @@ namespace { } 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(); @@ -5133,7 +5147,7 @@ namespace { separator_to_stream(); 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(); @@ -5150,6 +5164,7 @@ namespace { void test_run_end(const TestRunStats& p) override { separator_to_stream(); + s << std::dec; const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6) @@ -5749,8 +5764,8 @@ int Context::run() { std::set testSuitesPassingFilt; - bool query_mode = p->count || p->list_test_cases || p->list_test_suites; - std::vector queryResults; + bool query_mode = p->count || p->list_test_cases || p->list_test_suites; + std::vector queryResults; if(!query_mode) 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 if(p->list_test_cases) { - queryResults.push_back(tc.m_name); + queryResults.push_back(&tc); continue; } // print the name of the test suite if not done already and don't execute it if(p->list_test_suites) { 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); p->numTestSuitesPassingFilters++; }