From b025a007b924cc16da84c07a5d35118695cb9bcc Mon Sep 17 00:00:00 2001 From: Scott Hutchinson Date: Sat, 23 Jan 2021 12:58:20 -0800 Subject: [PATCH 01/42] Wrap all std::min and std::max calls in parentheses --- include/internal/benchmark/detail/catch_estimate_clock.hpp | 4 +++- include/internal/benchmark/detail/catch_stats.cpp | 4 ++-- include/internal/benchmark/detail/catch_stats.hpp | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/internal/benchmark/detail/catch_estimate_clock.hpp b/include/internal/benchmark/detail/catch_estimate_clock.hpp index 055c5825..391f5d24 100644 --- a/include/internal/benchmark/detail/catch_estimate_clock.hpp +++ b/include/internal/benchmark/detail/catch_estimate_clock.hpp @@ -68,7 +68,9 @@ namespace Catch { } template EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) { - auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit)); + auto time_limit = (std::min)( + resolution * clock_cost_estimation_tick_limit, + FloatDuration(clock_cost_estimation_time_limit)); auto time_clock = [](int k) { return Detail::measure([k] { for (int i = 0; i < k; ++i) { diff --git a/include/internal/benchmark/detail/catch_stats.cpp b/include/internal/benchmark/detail/catch_stats.cpp index b85b740e..dcb51b15 100644 --- a/include/internal/benchmark/detail/catch_stats.cpp +++ b/include/internal/benchmark/detail/catch_stats.cpp @@ -152,7 +152,7 @@ namespace Catch { double sb = stddev.point; double mn = mean.point / n; double mg_min = mn / 2.; - double sg = std::min(mg_min / 4., sb / std::sqrt(n)); + double sg = (std::min)(mg_min / 4., sb / std::sqrt(n)); double sg2 = sg * sg; double sb2 = sb * sb; @@ -171,7 +171,7 @@ namespace Catch { return (nc / n) * (sb2 - nc * sg2); }; - return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2; + return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2; } diff --git a/include/internal/benchmark/detail/catch_stats.hpp b/include/internal/benchmark/detail/catch_stats.hpp index 71a460d9..1bcbc259 100644 --- a/include/internal/benchmark/detail/catch_stats.hpp +++ b/include/internal/benchmark/detail/catch_stats.hpp @@ -138,8 +138,8 @@ namespace Catch { double b2 = bias - z1; double a1 = a(b1); double a2 = a(b2); - auto lo = std::max(cumn(a1), 0); - auto hi = std::min(cumn(a2), n - 1); + auto lo = (std::max)(cumn(a1), 0); + auto hi = (std::min)(cumn(a2), n - 1); return { point, resample[lo], resample[hi], confidence_level }; } From 4cb3220a8a648eb5af5c250c939ed49c648cfc04 Mon Sep 17 00:00:00 2001 From: Pavel Kamenov Date: Tue, 30 Mar 2021 09:25:38 +0300 Subject: [PATCH 02/42] Add lcc to the list of unwanted compilers that mimic gcc --- include/internal/catch_compiler_capabilities.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index 93e191c2..9efda561 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -39,9 +39,9 @@ #endif -// We have to avoid both ICC and Clang, because they try to mask themselves -// as gcc, and we want only GCC in this block -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) From 8f277a54c0b9c1d1024dedcb2dec1d206971e745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 27 Mar 2021 17:54:22 +0100 Subject: [PATCH 03/42] Significantly refactor fatal error handling Because new glibc has changed `MINSIGSTKSZ` to be a syscall instead of being constant, the signal posix handling needed changes, as it used the value in constexpr context, for deciding size of an array. It would be simple to fix it by having the handler determine the signal handling stack size and allocate the memory every time the handler is being installed, but that would add another allocation and a syscall every time a test case is entered. Instead, I split apart the idea of preparing fatal error handlers, and engaging them, so that the memory can be allocated only once and still be guarded by RAII. Also turns out that Catch2's use of `MINSIGSTKSZ` was wrong, and we should've been using `SIGSTKSZ` the whole time, which we use now. Closes #2178 --- include/internal/catch_fatal_condition.cpp | 218 ++++++++++++++------- include/internal/catch_fatal_condition.h | 87 ++++---- include/internal/catch_run_context.cpp | 3 +- include/internal/catch_run_context.h | 1 + 4 files changed, 189 insertions(+), 120 deletions(-) diff --git a/include/internal/catch_fatal_condition.cpp b/include/internal/catch_fatal_condition.cpp index 1eb6bb87..ac601f67 100644 --- a/include/internal/catch_fatal_condition.cpp +++ b/include/internal/catch_fatal_condition.cpp @@ -7,30 +7,72 @@ * */ +/** \file + * This file provides platform specific implementations of FatalConditionHandler + * + * This means that there is a lot of conditional compilation, and platform + * specific code. Currently, Catch2 supports a dummy handler (if no + * handler is desired), and 2 platform specific handlers: + * * Windows' SEH + * * POSIX signals + * + * Consequently, various pieces of code below are compiled if either of + * the platform specific handlers is enabled, or if none of them are + * enabled. It is assumed that both cannot be enabled at the same time, + * and doing so should cause a compilation error. + * + * If another platform specific handler is added, the compile guards + * below will need to be updated taking these assumptions into account. + */ + #include "catch_fatal_condition.h" #include "catch_context.h" -#include "catch_interfaces_capture.h" +#include "catch_enforce.h" +#include "catch_run_context.h" +#include "catch_windows_h_proxy.h" -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif +#include + +#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace Catch { + + // If neither SEH nor signal handling is required, the handler impls + // do not have to do anything, and can be empty. + FatalConditionHandler::engage_platform() {} + FatalConditionHandler::disengage_platform() {} + FatalConditionHandler::FatalConditionHandler() = default; + FatalConditionHandler::~FatalConditionHandler() = default; + +} // end namespace Catch + +#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS ) +#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time" +#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) namespace { - // Report the error condition + //! Signals fatal error message to the run context void reportFatal( char const * const message ) { Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); } -} -#endif // signals/SEH handling + //! Minimal size Catch2 needs for its own fatal error handling. + //! Picked anecdotally, so it might not be sufficient on all + //! platforms, and for all configurations. + constexpr std::size_t minStackSizeForErrors = 32 * 1024; +} // end unnamed namespace + +#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS #if defined( CATCH_CONFIG_WINDOWS_SEH ) namespace Catch { + struct SignalDefs { DWORD id; const char* name; }; // There is no 1-1 mapping between signals and windows exceptions. @@ -43,7 +85,7 @@ namespace Catch { { static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, }; - LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { for (auto const& def : signalDefs) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { reportFatal(def.name); @@ -54,39 +96,52 @@ namespace Catch { return EXCEPTION_CONTINUE_SEARCH; } - FatalConditionHandler::FatalConditionHandler() { - isSet = true; - // 32k seems enough for Catch 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); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } + // Since we do not support multiple instantiations, we put these + // into global variables and rely on cleaning them up in outlined + // constructors/destructors + static PVOID exceptionHandlerHandle = nullptr; - void FatalConditionHandler::reset() { - if (isSet) { - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = nullptr; - isSet = false; + + // For MSVC, we reserve part of the stack memory for handling + // memory overflow structured exception. + FatalConditionHandler::FatalConditionHandler() { + ULONG guaranteeSize = static_cast(minStackSizeForErrors); + if (!SetThreadStackGuarantee(&guaranteeSize)) { + // We do not want to fully error out, because needing + // the stack reserve should be rare enough anyway. + Catch::cerr() + << "Failed to reserve piece of stack." + << " Stack overflows will not be reported successfully."; } } - FatalConditionHandler::~FatalConditionHandler() { - reset(); + // We do not attempt to unset the stack guarantee, because + // Windows does not support lowering the stack size guarantee. + FatalConditionHandler::~FatalConditionHandler() = default; + + + void FatalConditionHandler::engage_platform() { + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + if (!exceptionHandlerHandle) { + CATCH_RUNTIME_ERROR("Could not register vectored exception handler"); + } } -bool FatalConditionHandler::isSet = false; -ULONG FatalConditionHandler::guaranteeSize = 0; -PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + void FatalConditionHandler::disengage_platform() { + if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) { + CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler"); + } + exceptionHandlerHandle = nullptr; + } +} // end namespace Catch -} // namespace Catch +#endif // CATCH_CONFIG_WINDOWS_SEH -#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) +#if defined( CATCH_CONFIG_POSIX_SIGNALS ) + +#include namespace Catch { @@ -94,10 +149,6 @@ namespace Catch { int id; const char* name; }; - - // 32kb for the alternate stack seems to be sufficient. However, this value - // is experimentally determined, so that's not guaranteed. - static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; static SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, @@ -108,8 +159,32 @@ namespace Catch { { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } }; +// Older GCCs trigger -Wmissing-field-initializers for T foo = {} +// which is zero initialization, but not explicit. We want to avoid +// that. +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif - void FatalConditionHandler::handleSignal( int sig ) { + static char* altStackMem = nullptr; + static std::size_t altStackSize = 0; + static stack_t oldSigStack{}; + static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{}; + + static void restorePreviousSignalHandlers() { + // We set signal handlers back to the previous ones. Hopefully + // nobody overwrote them in the meantime, and doesn't expect + // their signal handlers to live past ours given that they + // installed them after ours.. + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + } + + static void handleSignal( int sig ) { char const * name = ""; for (auto const& def : signalDefs) { if (sig == def.id) { @@ -117,16 +192,33 @@ namespace Catch { break; } } - reset(); - reportFatal(name); + // We need to restore previous signal handlers and let them do + // their thing, so that the users can have the debugger break + // when a signal is raised, and so on. + restorePreviousSignalHandlers(); + reportFatal( name ); raise( sig ); } FatalConditionHandler::FatalConditionHandler() { - isSet = true; + assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists"); + if (altStackSize == 0) { + altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors); + } + altStackMem = new char[altStackSize](); + } + + FatalConditionHandler::~FatalConditionHandler() { + delete[] altStackMem; + // We signal that another instance can be constructed by zeroing + // out the pointer. + altStackMem = nullptr; + } + + void FatalConditionHandler::engage_platform() { stack_t sigStack; sigStack.ss_sp = altStackMem; - sigStack.ss_size = sigStackSize; + sigStack.ss_size = altStackSize; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { }; @@ -138,39 +230,15 @@ namespace Catch { } } - - FatalConditionHandler::~FatalConditionHandler() { - reset(); - } - - void FatalConditionHandler::reset() { - if( isSet ) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[sigStackSize] = {}; - - -} // namespace Catch - -#else - -namespace Catch { - void FatalConditionHandler::reset() {} -} - -#endif // signals/SEH handling - #if defined(__GNUC__) # pragma GCC diagnostic pop #endif + + + void FatalConditionHandler::disengage_platform() { + restorePreviousSignalHandlers(); + } + +} // end namespace Catch + +#endif // CATCH_CONFIG_POSIX_SIGNALS diff --git a/include/internal/catch_fatal_condition.h b/include/internal/catch_fatal_condition.h index a64fa628..6b5f8f91 100644 --- a/include/internal/catch_fatal_condition.h +++ b/include/internal/catch_fatal_condition.h @@ -11,59 +11,60 @@ #include "catch_platform.h" #include "catch_compiler_capabilities.h" -#include "catch_windows_h_proxy.h" - -#if defined( CATCH_CONFIG_WINDOWS_SEH ) +#include namespace Catch { - struct FatalConditionHandler { - - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); - FatalConditionHandler(); - static void reset(); - ~FatalConditionHandler(); - - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - -} // namespace Catch - -#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) - -#include - -namespace Catch { - - struct FatalConditionHandler { - - static bool isSet; - static struct sigaction oldSigActions[]; - static stack_t oldSigStack; - static char altStackMem[]; - - static void handleSignal( int sig ); + /** + * Wrapper for platform-specific fatal error (signals/SEH) handlers + * + * Tries to be cooperative with other handlers, and not step over + * other handlers. This means that unknown structured exceptions + * are passed on, previous signal handlers are called, and so on. + * + * Can only be instantiated once, and assumes that once a signal + * is caught, the binary will end up terminating. Thus, there + */ + class FatalConditionHandler { + bool m_started = false; + // Install/disengage implementation for specific platform. + // Should be if-defed to work on current platform, can assume + // engage-disengage 1:1 pairing. + void engage_platform(); + void disengage_platform(); + public: + // Should also have platform-specific implementations as needed FatalConditionHandler(); ~FatalConditionHandler(); - static void reset(); + + void engage() { + assert(!m_started && "Handler cannot be installed twice."); + m_started = true; + engage_platform(); + } + + void disengage() { + assert(m_started && "Handler cannot be uninstalled without being installed first"); + m_started = false; + disengage_platform(); + } }; -} // namespace Catch - - -#else - -namespace Catch { - struct FatalConditionHandler { - void reset(); + //! Simple RAII guard for (dis)engaging the FatalConditionHandler + class FatalConditionHandlerGuard { + FatalConditionHandler* m_handler; + public: + FatalConditionHandlerGuard(FatalConditionHandler* handler): + m_handler(handler) { + m_handler->engage(); + } + ~FatalConditionHandlerGuard() { + m_handler->disengage(); + } }; -} -#endif +} // end namespace Catch #endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED diff --git a/include/internal/catch_run_context.cpp b/include/internal/catch_run_context.cpp index fa1b2f6f..de38e285 100644 --- a/include/internal/catch_run_context.cpp +++ b/include/internal/catch_run_context.cpp @@ -452,9 +452,8 @@ namespace Catch { } void RunContext::invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals + FatalConditionHandlerGuard _(&m_fatalConditionhandler); m_activeTestCase->invoke(); - fatalConditionHandler.reset(); } void RunContext::handleUnfinishedSections() { diff --git a/include/internal/catch_run_context.h b/include/internal/catch_run_context.h index 044bdd81..2f3adbda 100644 --- a/include/internal/catch_run_context.h +++ b/include/internal/catch_run_context.h @@ -146,6 +146,7 @@ namespace Catch { std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; + FatalConditionHandler m_fatalConditionhandler; bool m_lastAssertionPassed = false; bool m_shouldReportUnexpected = true; bool m_includeSuccessfulResults; From b8b03da534ef6245c90698eff3123576b93162b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 4 Apr 2021 13:35:38 +0200 Subject: [PATCH 04/42] Mangle doccoments to avoid breaking single include stitching --- include/internal/catch_fatal_condition.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/include/internal/catch_fatal_condition.h b/include/internal/catch_fatal_condition.h index 6b5f8f91..b5744f8f 100644 --- a/include/internal/catch_fatal_condition.h +++ b/include/internal/catch_fatal_condition.h @@ -16,16 +16,14 @@ namespace Catch { - /** - * Wrapper for platform-specific fatal error (signals/SEH) handlers - * - * Tries to be cooperative with other handlers, and not step over - * other handlers. This means that unknown structured exceptions - * are passed on, previous signal handlers are called, and so on. - * - * Can only be instantiated once, and assumes that once a signal - * is caught, the binary will end up terminating. Thus, there - */ + // Wrapper for platform-specific fatal error (signals/SEH) handlers + // + // Tries to be cooperative with other handlers, and not step over + // other handlers. This means that unknown structured exceptions + // are passed on, previous signal handlers are called, and so on. + // + // Can only be instantiated once, and assumes that once a signal + // is caught, the binary will end up terminating. Thus, there class FatalConditionHandler { bool m_started = false; From cec35630fb08ce9631a92e7a06c9b655a850caa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 5 Apr 2021 15:17:28 +0200 Subject: [PATCH 05/42] Don't build Catch2WithMain target by default for v2 The `Catch2WithMain` target was added experimentally for v2.13.4 to provide potentially better compilation (and link) times to users. However, having it compiled by default causes worse experience for people who do not use it, and for the v2 versions the single include distribution is still the main one. Closes #2142 --- CMakeLists.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05acead3..727aa186 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,12 +25,12 @@ option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF) option(CATCH_BUILD_TESTING "Build SelfTest project" ON) option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF) option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF) +option(CATCH_BUILD_STATIC_LIBRARY "Builds static library from the main implementation. EXPERIMENTAL" OFF) option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF) option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON) option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON) option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON) - # define some folders set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest) @@ -104,15 +104,17 @@ endif() add_library(Catch2::Catch2 ALIAS Catch2) # Hacky support for compiling the impl into a static lib -add_library(Catch2WithMain ${CMAKE_CURRENT_LIST_DIR}/src/catch_with_main.cpp) -target_link_libraries(Catch2WithMain PUBLIC Catch2) -add_library(Catch2::Catch2WithMain ALIAS Catch2WithMain) +if (CATCH_BUILD_STATIC_LIBRARY) + add_library(Catch2WithMain ${CMAKE_CURRENT_LIST_DIR}/src/catch_with_main.cpp) + target_link_libraries(Catch2WithMain PUBLIC Catch2) + add_library(Catch2::Catch2WithMain ALIAS Catch2WithMain) -# Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map -if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8) OR - ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10)) - target_compile_options(Catch2WithMain PRIVATE "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.") -endif() + # Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map + if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8) OR + ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10)) + target_compile_options(Catch2WithMain PRIVATE "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.") + endif() +endif(CATCH_BUILD_STATIC_LIBRARY) # Only perform the installation steps when Catch is not being used as # a subproject via `add_subdirectory`, or the destinations will break, @@ -128,11 +130,17 @@ if (NOT_SUBPROJECT) ${CATCH_CMAKE_CONFIG_DESTINATION} ) + # Workaround lack of generator expressions in install(TARGETS + set(InstallationTargets Catch2) + if (TARGET Catch2WithMain) + list(APPEND InstallationTargets Catch2WithMain) + endif() + # create and install an export set for catch target as Catch2::Catch install( TARGETS - Catch2 Catch2WithMain + ${InstallationTargets} EXPORT Catch2Targets DESTINATION From 269f96e2bc0fca840846fd3dc199c0540558e345 Mon Sep 17 00:00:00 2001 From: Julien Brianceau Date: Wed, 7 Apr 2021 23:02:12 +0200 Subject: [PATCH 06/42] Fix typos in the code base Note that only documentation and comments are impacted by this change. --- contrib/ParseAndAddCatchTests.cmake | 2 +- docs/contributing.md | 2 +- examples/302-Gen-Table.cpp | 2 +- include/internal/catch_enum_values_registry.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/ParseAndAddCatchTests.cmake b/contrib/ParseAndAddCatchTests.cmake index 42c68055..4771e029 100644 --- a/contrib/ParseAndAddCatchTests.cmake +++ b/contrib/ParseAndAddCatchTests.cmake @@ -200,7 +200,7 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget) # Escape commas in the test spec string(REPLACE "," "\\," Name ${Name}) - # Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were neccessary, + # Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were necessary, # only with CMake 3.18.0 the escaped double quotes confuse the call. This change is reverted in 3.18.1 # And properly introduced in 3.19 with the CMP0110 policy if(_cmp0110_value STREQUAL "NEW" OR ${CMAKE_VERSION} VERSION_EQUAL "3.18") diff --git a/docs/contributing.md b/docs/contributing.md index ca050bf4..f23e3a11 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -26,7 +26,7 @@ Ongoing development happens in the `v2.x` branch for Catch2 v2, and in Commits should be small and atomic. A commit is atomic when, after it is applied, the codebase, tests and all, still works as expected. Small -commits are also prefered, as they make later operations with git history, +commits are also preferred, as they make later operations with git history, whether it is bisecting, reverting, or something else, easier. _When submitting a pull request please do not include changes to the diff --git a/examples/302-Gen-Table.cpp b/examples/302-Gen-Table.cpp index fe226dc1..14a0405e 100644 --- a/examples/302-Gen-Table.cpp +++ b/examples/302-Gen-Table.cpp @@ -43,7 +43,7 @@ TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][genera /* Possible simplifications where less legacy toolchain support is needed: * - * - With libstdc++6 or newer, the make_tuple() calls can be ommitted + * - With libstdc++6 or newer, the make_tuple() calls can be omitted * (technically C++17 but does not require -std in GCC/Clang). See * https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list * diff --git a/include/internal/catch_enum_values_registry.cpp b/include/internal/catch_enum_values_registry.cpp index 063f9d62..a119d152 100644 --- a/include/internal/catch_enum_values_registry.cpp +++ b/include/internal/catch_enum_values_registry.cpp @@ -22,7 +22,7 @@ namespace Catch { // Extracts the actual name part of an enum instance // In other words, it returns the Blue part of Bikeshed::Colour::Blue StringRef extractInstanceName(StringRef enumInstance) { - // Find last occurence of ":" + // Find last occurrence of ":" size_t name_start = enumInstance.size(); while (name_start > 0 && enumInstance[name_start - 1] != ':') { --name_start; From 1ff1f2741d5e24686172d4681617ea6b89ea6654 Mon Sep 17 00:00:00 2001 From: Clare Macrae Date: Mon, 5 Apr 2021 14:10:10 +0100 Subject: [PATCH 07/42] Prevent Catch2 v2 tests running if loaded as a sub-project See #2202 --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 727aa186..2c6c8694 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.5) # disable testsuite in that case if(NOT DEFINED PROJECT_NAME) set(NOT_SUBPROJECT ON) +else() + set(NOT_SUBPROJECT OFF) endif() # Catch2's build breaks if done in-tree. You probably should not build From 42e368dd0aedc122798008d8c4f583fea3296a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 10 Apr 2021 23:48:32 +0200 Subject: [PATCH 08/42] v2.13.5 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 22 ++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 388 +++++++++++++++++------------ 6 files changed, 248 insertions(+), 170 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c6c8694..ff0ca8e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.4) +project(Catch2 LANGUAGES CXX VERSION 2.13.5) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index 0e9cf5b4..8ec18ae2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index 48f75bd0..3fd6588b 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.5](#2135)
[2.13.4](#2134)
[2.13.3](#2133)
[2.13.2](#2132)
@@ -45,6 +46,27 @@ [Even Older versions](#even-older-versions)
+## 2.13.5 + +### Improvements +* Detection of MAC and IPHONE platforms has been improved (#2140, #2157) +* Added workaround for bug in XLC 16.1.0.1 (#2155) +* Add detection for LCC when it is masquerading as GCC (#2199) +* Modified posix signal handling so it supports newer libcs (#2178) + * `MINSIGSTKSZ` was no longer usable in constexpr context. + +### Fixes +* Fixed compilation of benchmarking when `min` and `max` macros are defined (#2159) + * Including `windows.h` without `NOMINMAX` remains a really bad idea, don't do it + +### Miscellaneous +* `Catch2WithMain` target (static library) is no longer built by default (#2142) + * Building it by default was at best unnecessary overhead for people not using it, and at worst it caused trouble with install paths + * To have it built, set CMake option `CATCH_BUILD_STATIC_LIBRARY` to `ON` +* The check whether Catch2 is being built as a subproject is now more reliable (#2202, #2204) + * The problem was that if the variable name used internally was defined the project including Catch2 as subproject, it would not be properly overwritten for Catch2's CMake. + + ## 2.13.4 ### Improvements diff --git a/include/catch.hpp b/include/catch.hpp index f588eaa1..da126ce5 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 4 +#define CATCH_VERSION_PATCH 5 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index c9864434..d407218a 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 4, "", 0 ); + static Version version( 2, 13, 5, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index 0384171a..9c1c854f 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,9 +1,9 @@ /* - * Catch v2.13.4 - * Generated: 2020-12-29 14:48:00.116107 + * Catch v2.13.5 + * Generated: 2021-04-10 23:43:17.560525 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 4 +#define CATCH_VERSION_PATCH 5 #ifdef __clang__ # pragma clang system_header @@ -66,13 +66,16 @@ #if !defined(CATCH_CONFIG_IMPL_ONLY) // start catch_platform.h +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ -# include -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif TARGET_OS_IPHONE == 1 -# define CATCH_PLATFORM_IPHONE -# endif +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX @@ -132,9 +135,9 @@ namespace Catch { #endif -// We have to avoid both ICC and Clang, because they try to mask themselves -// as gcc, and we want only GCC in this block -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) @@ -7054,8 +7057,8 @@ namespace Catch { double b2 = bias - z1; double a1 = a(b1); double a2 = a(b2); - auto lo = std::max(cumn(a1), 0); - auto hi = std::min(cumn(a2), n - 1); + auto lo = (std::max)(cumn(a1), 0); + auto hi = (std::min)(cumn(a2), n - 1); return { point, resample[lo], resample[hi], confidence_level }; } @@ -7124,7 +7127,9 @@ namespace Catch { } template EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) { - auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit)); + auto time_limit = (std::min)( + resolution * clock_cost_estimation_tick_limit, + FloatDuration(clock_cost_estimation_time_limit)); auto time_clock = [](int k) { return Detail::measure([k] { for (int i = 0; i < k; ++i) { @@ -7771,7 +7776,7 @@ namespace Catch { double sb = stddev.point; double mn = mean.point / n; double mg_min = mn / 2.; - double sg = std::min(mg_min / 4., sb / std::sqrt(n)); + double sg = (std::min)(mg_min / 4., sb / std::sqrt(n)); double sg2 = sg * sg; double sb2 = sb * sb; @@ -7790,7 +7795,7 @@ namespace Catch { return (nc / n) * (sb2 - nc * sg2); }; - return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2; + return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2; } bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector::iterator first, std::vector::iterator last) { @@ -7980,86 +7985,58 @@ namespace Catch { // start catch_fatal_condition.h -// start catch_windows_h_proxy.h - - -#if defined(CATCH_PLATFORM_WINDOWS) - -#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) -# define CATCH_DEFINED_NOMINMAX -# define NOMINMAX -#endif -#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) -# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif - -#ifdef __AFXDLL -#include -#else -#include -#endif - -#ifdef CATCH_DEFINED_NOMINMAX -# undef NOMINMAX -#endif -#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN -# undef WIN32_LEAN_AND_MEAN -#endif - -#endif // defined(CATCH_PLATFORM_WINDOWS) - -// end catch_windows_h_proxy.h -#if defined( CATCH_CONFIG_WINDOWS_SEH ) +#include namespace Catch { - struct FatalConditionHandler { - - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); - FatalConditionHandler(); - static void reset(); - ~FatalConditionHandler(); - - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - -} // namespace Catch - -#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) - -#include - -namespace Catch { - - struct FatalConditionHandler { - - static bool isSet; - static struct sigaction oldSigActions[]; - static stack_t oldSigStack; - static char altStackMem[]; - - static void handleSignal( int sig ); + // Wrapper for platform-specific fatal error (signals/SEH) handlers + // + // Tries to be cooperative with other handlers, and not step over + // other handlers. This means that unknown structured exceptions + // are passed on, previous signal handlers are called, and so on. + // + // Can only be instantiated once, and assumes that once a signal + // is caught, the binary will end up terminating. Thus, there + class FatalConditionHandler { + bool m_started = false; + // Install/disengage implementation for specific platform. + // Should be if-defed to work on current platform, can assume + // engage-disengage 1:1 pairing. + void engage_platform(); + void disengage_platform(); + public: + // Should also have platform-specific implementations as needed FatalConditionHandler(); ~FatalConditionHandler(); - static void reset(); + + void engage() { + assert(!m_started && "Handler cannot be installed twice."); + m_started = true; + engage_platform(); + } + + void disengage() { + assert(m_started && "Handler cannot be uninstalled without being installed first"); + m_started = false; + disengage_platform(); + } }; -} // namespace Catch - -#else - -namespace Catch { - struct FatalConditionHandler { - void reset(); + //! Simple RAII guard for (dis)engaging the FatalConditionHandler + class FatalConditionHandlerGuard { + FatalConditionHandler* m_handler; + public: + FatalConditionHandlerGuard(FatalConditionHandler* handler): + m_handler(handler) { + m_handler->engage(); + } + ~FatalConditionHandlerGuard() { + m_handler->disengage(); + } }; -} -#endif +} // end namespace Catch // end catch_fatal_condition.h #include @@ -8185,6 +8162,7 @@ namespace Catch { std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; + FatalConditionHandler m_fatalConditionhandler; bool m_lastAssertionPassed = false; bool m_shouldReportUnexpected = true; bool m_includeSuccessfulResults; @@ -10057,6 +10035,36 @@ namespace Catch { } // end catch_errno_guard.h +// start catch_windows_h_proxy.h + + +#if defined(CATCH_PLATFORM_WINDOWS) + +#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINED_NOMINMAX +# define NOMINMAX +#endif +#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINED_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + +#endif // defined(CATCH_PLATFORM_WINDOWS) + +// end catch_windows_h_proxy.h #include namespace Catch { @@ -10573,7 +10581,7 @@ namespace Catch { // Extracts the actual name part of an enum instance // In other words, it returns the Blue part of Bikeshed::Colour::Blue StringRef extractInstanceName(StringRef enumInstance) { - // Find last occurence of ":" + // Find last occurrence of ":" size_t name_start = enumInstance.size(); while (name_start > 0 && enumInstance[name_start - 1] != ':') { --name_start; @@ -10735,25 +10743,47 @@ namespace Catch { // end catch_exception_translator_registry.cpp // start catch_fatal_condition.cpp -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif +#include + +#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace Catch { + + // If neither SEH nor signal handling is required, the handler impls + // do not have to do anything, and can be empty. + FatalConditionHandler::engage_platform() {} + FatalConditionHandler::disengage_platform() {} + FatalConditionHandler::FatalConditionHandler() = default; + FatalConditionHandler::~FatalConditionHandler() = default; + +} // end namespace Catch + +#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS ) +#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time" +#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) namespace { - // Report the error condition + //! Signals fatal error message to the run context void reportFatal( char const * const message ) { Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); } -} -#endif // signals/SEH handling + //! Minimal size Catch2 needs for its own fatal error handling. + //! Picked anecdotally, so it might not be sufficient on all + //! platforms, and for all configurations. + constexpr std::size_t minStackSizeForErrors = 32 * 1024; +} // end unnamed namespace + +#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS #if defined( CATCH_CONFIG_WINDOWS_SEH ) namespace Catch { + struct SignalDefs { DWORD id; const char* name; }; // There is no 1-1 mapping between signals and windows exceptions. @@ -10766,7 +10796,7 @@ namespace Catch { { static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, }; - LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { for (auto const& def : signalDefs) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { reportFatal(def.name); @@ -10777,38 +10807,50 @@ namespace Catch { return EXCEPTION_CONTINUE_SEARCH; } - FatalConditionHandler::FatalConditionHandler() { - isSet = true; - // 32k seems enough for Catch 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); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } + // Since we do not support multiple instantiations, we put these + // into global variables and rely on cleaning them up in outlined + // constructors/destructors + static PVOID exceptionHandlerHandle = nullptr; - void FatalConditionHandler::reset() { - if (isSet) { - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = nullptr; - isSet = false; + // For MSVC, we reserve part of the stack memory for handling + // memory overflow structured exception. + FatalConditionHandler::FatalConditionHandler() { + ULONG guaranteeSize = static_cast(minStackSizeForErrors); + if (!SetThreadStackGuarantee(&guaranteeSize)) { + // We do not want to fully error out, because needing + // the stack reserve should be rare enough anyway. + Catch::cerr() + << "Failed to reserve piece of stack." + << " Stack overflows will not be reported successfully."; } } - FatalConditionHandler::~FatalConditionHandler() { - reset(); + // We do not attempt to unset the stack guarantee, because + // Windows does not support lowering the stack size guarantee. + FatalConditionHandler::~FatalConditionHandler() = default; + + void FatalConditionHandler::engage_platform() { + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + if (!exceptionHandlerHandle) { + CATCH_RUNTIME_ERROR("Could not register vectored exception handler"); + } } -bool FatalConditionHandler::isSet = false; -ULONG FatalConditionHandler::guaranteeSize = 0; -PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + void FatalConditionHandler::disengage_platform() { + if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) { + CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler"); + } + exceptionHandlerHandle = nullptr; + } -} // namespace Catch +} // end namespace Catch -#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) +#endif // CATCH_CONFIG_WINDOWS_SEH + +#if defined( CATCH_CONFIG_POSIX_SIGNALS ) + +#include namespace Catch { @@ -10817,10 +10859,6 @@ namespace Catch { const char* name; }; - // 32kb for the alternate stack seems to be sufficient. However, this value - // is experimentally determined, so that's not guaranteed. - static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; - static SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, @@ -10830,7 +10868,32 @@ namespace Catch { { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } }; - void FatalConditionHandler::handleSignal( int sig ) { +// Older GCCs trigger -Wmissing-field-initializers for T foo = {} +// which is zero initialization, but not explicit. We want to avoid +// that. +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + + static char* altStackMem = nullptr; + static std::size_t altStackSize = 0; + static stack_t oldSigStack{}; + static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{}; + + static void restorePreviousSignalHandlers() { + // We set signal handlers back to the previous ones. Hopefully + // nobody overwrote them in the meantime, and doesn't expect + // their signal handlers to live past ours given that they + // installed them after ours.. + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + } + + static void handleSignal( int sig ) { char const * name = ""; for (auto const& def : signalDefs) { if (sig == def.id) { @@ -10838,16 +10901,33 @@ namespace Catch { break; } } - reset(); - reportFatal(name); + // We need to restore previous signal handlers and let them do + // their thing, so that the users can have the debugger break + // when a signal is raised, and so on. + restorePreviousSignalHandlers(); + reportFatal( name ); raise( sig ); } FatalConditionHandler::FatalConditionHandler() { - isSet = true; + assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists"); + if (altStackSize == 0) { + altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors); + } + altStackMem = new char[altStackSize](); + } + + FatalConditionHandler::~FatalConditionHandler() { + delete[] altStackMem; + // We signal that another instance can be constructed by zeroing + // out the pointer. + altStackMem = nullptr; + } + + void FatalConditionHandler::engage_platform() { stack_t sigStack; sigStack.ss_sp = altStackMem; - sigStack.ss_size = sigStackSize; + sigStack.ss_size = altStackSize; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { }; @@ -10859,40 +10939,17 @@ namespace Catch { } } - FatalConditionHandler::~FatalConditionHandler() { - reset(); - } - - void FatalConditionHandler::reset() { - if( isSet ) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[sigStackSize] = {}; - -} // namespace Catch - -#else - -namespace Catch { - void FatalConditionHandler::reset() {} -} - -#endif // signals/SEH handling - #if defined(__GNUC__) # pragma GCC diagnostic pop #endif + + void FatalConditionHandler::disengage_platform() { + restorePreviousSignalHandlers(); + } + +} // end namespace Catch + +#endif // CATCH_CONFIG_POSIX_SIGNALS // end catch_fatal_condition.cpp // start catch_generators.cpp @@ -11447,7 +11504,8 @@ namespace { return lhs == rhs; } - auto ulpDiff = std::abs(lc - rc); + // static cast as a workaround for IBM XLC + auto ulpDiff = std::abs(static_cast(lc - rc)); return static_cast(ulpDiff) <= maxUlpDiff; } @@ -11621,7 +11679,6 @@ Floating::WithinRelMatcher WithinRel(float target) { } // namespace Matchers } // namespace Catch - // end catch_matchers_floating.cpp // start catch_matchers_generic.cpp @@ -12955,9 +13012,8 @@ namespace Catch { } void RunContext::invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals + FatalConditionHandlerGuard _(&m_fatalConditionhandler); m_activeTestCase->invoke(); - fatalConditionHandler.reset(); } void RunContext::handleUnfinishedSections() { @@ -15320,7 +15376,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 4, "", 0 ); + static Version version( 2, 13, 5, "", 0 ); return version; } From 469a7173951eb490c933bef1b214a0e4492b4686 Mon Sep 17 00:00:00 2001 From: Matteo Beniamino Date: Tue, 13 Apr 2021 10:46:59 +0200 Subject: [PATCH 09/42] Fixed [dis]engage_platform declarations mismatch --- include/internal/catch_fatal_condition.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/internal/catch_fatal_condition.cpp b/include/internal/catch_fatal_condition.cpp index ac601f67..873e2ed5 100644 --- a/include/internal/catch_fatal_condition.cpp +++ b/include/internal/catch_fatal_condition.cpp @@ -40,8 +40,8 @@ namespace Catch { // If neither SEH nor signal handling is required, the handler impls // do not have to do anything, and can be empty. - FatalConditionHandler::engage_platform() {} - FatalConditionHandler::disengage_platform() {} + void FatalConditionHandler::engage_platform() {} + void FatalConditionHandler::disengage_platform() {} FatalConditionHandler::FatalConditionHandler() = default; FatalConditionHandler::~FatalConditionHandler() = default; From 86a4d704bcf1003f1726957c22f9eb9905f021aa Mon Sep 17 00:00:00 2001 From: Georg Schwab Date: Wed, 14 Apr 2021 08:35:59 +0200 Subject: [PATCH 10/42] fixed inconsistent semicolon expansion in catch_discover_tests (Bug #2214) --- contrib/CatchAddTests.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/CatchAddTests.cmake b/contrib/CatchAddTests.cmake index 18286b71..184e506e 100644 --- a/contrib/CatchAddTests.cmake +++ b/contrib/CatchAddTests.cmake @@ -16,7 +16,10 @@ set(tests) function(add_command NAME) set(_args "") - foreach(_arg ${ARGN}) + # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments + math(EXPR _last_arg ${ARGC}-1) + foreach(_n RANGE 1 ${_last_arg}) + set(_arg "${ARGV${_n}}") if(_arg MATCHES "[^-./:a-zA-Z0-9_]") set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument else() From 5c88067bd339465513af4aec606bd2292f1b594a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Fri, 16 Apr 2021 20:14:58 +0200 Subject: [PATCH 11/42] v2.13.6 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 10 ++++++++++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 12 ++++++------ 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff0ca8e8..0370ea3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.5) +project(Catch2 LANGUAGES CXX VERSION 2.13.6) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index 8ec18ae2..6d4776da 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index 3fd6588b..4d173dc1 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.6](#2136)
[2.13.5](#2135)
[2.13.4](#2134)
[2.13.3](#2133)
@@ -46,6 +47,15 @@ [Even Older versions](#even-older-versions)
+## 2.13.6 + +### Fixes +* Disabling all signal handlers no longer breaks compilation (#2212, #2213) + +### Miscellaneous +* `catch_discover_tests` should handle escaped semicolon (`;`) better (#2214, #2215) + + ## 2.13.5 ### Improvements diff --git a/include/catch.hpp b/include/catch.hpp index da126ce5..d178c778 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 5 +#define CATCH_VERSION_PATCH 6 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index d407218a..58f1123c 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 5, "", 0 ); + static Version version( 2, 13, 6, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index 9c1c854f..36eaeb27 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.5 - * Generated: 2021-04-10 23:43:17.560525 + * Catch v2.13.6 + * Generated: 2021-04-16 18:23:38.044268 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 5 +#define CATCH_VERSION_PATCH 6 #ifdef __clang__ # pragma clang system_header @@ -10751,8 +10751,8 @@ namespace Catch { // If neither SEH nor signal handling is required, the handler impls // do not have to do anything, and can be empty. - FatalConditionHandler::engage_platform() {} - FatalConditionHandler::disengage_platform() {} + void FatalConditionHandler::engage_platform() {} + void FatalConditionHandler::disengage_platform() {} FatalConditionHandler::FatalConditionHandler() = default; FatalConditionHandler::~FatalConditionHandler() = default; @@ -15376,7 +15376,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 5, "", 0 ); + static Version version( 2, 13, 6, "", 0 ); return version; } From 6971476563e09813b7f18d2146054b97dbd73858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Fri, 21 May 2021 20:02:22 +0200 Subject: [PATCH 12/42] Ensure that is included before back_inserter is used Closes #2231 --- include/internal/benchmark/catch_execution_plan.hpp | 1 + include/internal/catch_interfaces_reporter.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/internal/benchmark/catch_execution_plan.hpp b/include/internal/benchmark/catch_execution_plan.hpp index e56c83aa..4edfa60c 100644 --- a/include/internal/benchmark/catch_execution_plan.hpp +++ b/include/internal/benchmark/catch_execution_plan.hpp @@ -19,6 +19,7 @@ #include "detail/catch_run_for_at_least.hpp" #include +#include namespace Catch { namespace Benchmark { diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index 751ef2c2..eea0df10 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -21,6 +21,8 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #include "benchmark/catch_estimate.hpp" #include "benchmark/catch_outlier_classification.hpp" + +#include #endif // CATCH_CONFIG_ENABLE_BENCHMARKING From b15b862d864a2d9dab634d49491b9b14ad7180f3 Mon Sep 17 00:00:00 2001 From: Evgeny Proydakov Date: Thu, 20 May 2021 19:30:45 +0300 Subject: [PATCH 13/42] Fixed noexcept benchmark build for gcc. --- include/internal/benchmark/detail/catch_run_for_at_least.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/internal/benchmark/detail/catch_run_for_at_least.hpp b/include/internal/benchmark/detail/catch_run_for_at_least.hpp index 339507ba..f63d2b1f 100644 --- a/include/internal/benchmark/detail/catch_run_for_at_least.hpp +++ b/include/internal/benchmark/detail/catch_run_for_at_least.hpp @@ -56,7 +56,7 @@ namespace Catch { } iters *= 2; } - throw optimized_away_error{}; + Catch::throw_exception(optimized_away_error{}); } } // namespace Detail } // namespace Benchmark From 581c46249acf8389e90b37f2d920ba522038a190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 22 May 2021 23:41:58 +0200 Subject: [PATCH 14/42] JUnit reporter uses only 3 decimal places when reporting durations We used to use whatever precision we ended up having from C++'s stdlib. However, some relatively popular tools, like Jenkins, use Maven SureFire XML schema to validate JUnit test reports, and Maven SureFire schema requires the duration to have at most 3 decimal places. For compatibility, the JUnit reporter will now respect this limitation. Closes #2221 --- include/reporters/catch_reporter_junit.cpp | 16 ++++++++++++++-- scripts/approvalTests.py | 7 +++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/reporters/catch_reporter_junit.cpp b/include/reporters/catch_reporter_junit.cpp index 31f0802f..e793fbc2 100644 --- a/include/reporters/catch_reporter_junit.cpp +++ b/include/reporters/catch_reporter_junit.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace Catch { @@ -56,6 +57,17 @@ namespace Catch { return it->substr(1); return std::string(); } + + // Formats the duration in seconds to 3 decimal places. + // This is done because some genius defined Maven Surefire schema + // in a way that only accepts 3 decimal places, and tools like + // Jenkins use that schema for validation JUnit reporter output. + std::string formatDuration( double seconds ) { + ReusableStringStream rss; + rss << std::fixed << std::setprecision( 3 ) << seconds; + return rss.str(); + } + } // anonymous namespace JunitReporter::JunitReporter( ReporterConfig const& _config ) @@ -125,7 +137,7 @@ namespace Catch { if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else - xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "time", formatDuration( suiteTime ) ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write properties if there are any @@ -192,7 +204,7 @@ namespace Catch { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } - xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) ); // This is not ideal, but it should be enough to mimic gtest's // junit output. // Ideally the JUnit reporter would also handle `skipTest` diff --git a/scripts/approvalTests.py b/scripts/approvalTests.py index 838a1a78..9b781911 100755 --- a/scripts/approvalTests.py +++ b/scripts/approvalTests.py @@ -28,7 +28,10 @@ filelocParser = re.compile(r''' ''', re.VERBOSE) lineNumberParser = re.compile(r' line="[0-9]*"') hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b') -durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"') +# Note: junit must serialize time with 3 (or or less) decimal places +# before generalizing this parser, make sure that this is checked +# in other places too. +junitDurationsParser = re.compile(r' time="[0-9]*\.[0-9]{3}"') sonarqubeDurationParser = re.compile(r' duration="[0-9]+"') timestampsParser = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z') versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?') @@ -138,7 +141,7 @@ def filterLine(line, isCompact): line = hexParser.sub("0x", line) # strip durations and timestamps - line = durationsParser.sub(' time="{duration}"', line) + line = junitDurationsParser.sub(' time="{duration}"', line) line = sonarqubeDurationParser.sub(' duration="{duration}"', line) line = timestampsParser.sub('{iso8601-timestamp}', line) line = specialCaseParser.sub('file:\g<1>', line) From 9683570be7a552557f495f66379226628fafe5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 23 May 2021 11:31:33 +0200 Subject: [PATCH 15/42] Tiny optimization in JUnit reporter --- include/reporters/catch_reporter_junit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/reporters/catch_reporter_junit.cpp b/include/reporters/catch_reporter_junit.cpp index e793fbc2..a50ead5f 100644 --- a/include/reporters/catch_reporter_junit.cpp +++ b/include/reporters/catch_reporter_junit.cpp @@ -46,7 +46,7 @@ namespace Catch { #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif - return std::string(timeStamp); + return std::string(timeStamp, timeStampSize-1); } std::string fileNameTag(const std::vector &tags) { From 531a149ae70dd4143ba1ac28e33d40ab612d3897 Mon Sep 17 00:00:00 2001 From: Dimitrij Mijoski Date: Fri, 26 Mar 2021 13:04:53 +0100 Subject: [PATCH 16/42] Fix compiling v2.x with C++17 + Clang 5 + libstdc++ v5 This basically tests the combination where the compiler supports most of C++17 but the library does not. --- .travis.yml | 9 +++++++++ .../internal/catch_compiler_capabilities.h | 2 +- .../SelfTest/UsageTests/Generators.tests.cpp | 20 +++++++++---------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0fe2abb1..239ab0cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -258,6 +258,15 @@ matrix: addons: *gcc7 env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1 + - os: linux + dist: xenial + compiler: clang + addons: + apt: + sources: *all_sources + packages: ['clang-5.0'] + env: COMPILER='clang++-5.0' CPP17=1 + - os: linux dist: xenial compiler: clang diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index 9efda561..b6ef9fe2 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -234,7 +234,7 @@ // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include - # if __cpp_lib_byte > 0 + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) diff --git a/projects/SelfTest/UsageTests/Generators.tests.cpp b/projects/SelfTest/UsageTests/Generators.tests.cpp index f2906dbf..10c87707 100644 --- a/projects/SelfTest/UsageTests/Generators.tests.cpp +++ b/projects/SelfTest/UsageTests/Generators.tests.cpp @@ -58,12 +58,12 @@ TEST_CASE("tables", "[generators]") { // Structured bindings make the table utility much nicer to use TEST_CASE( "strlen2", "[approvals][generators]" ) { - auto [test_input, expected] = GENERATE( table({ - {"one", 3}, - {"two", 3}, - {"three", 5}, - {"four", 4} - })); + using tuple_type = std::tuple; // see above workaround + auto [test_input, expected] = + GENERATE( table( { tuple_type{ "one", 3 }, + tuple_type{ "two", 3 }, + tuple_type{ "three", 5 }, + tuple_type{ "four", 4 } } ) ); REQUIRE( test_input.size() == expected ); } @@ -99,11 +99,9 @@ TEST_CASE( "strlen3", "[generators]" ) { static auto eatCucumbers( int start, int eat ) -> int { return start-eat; } SCENARIO("Eating cucumbers", "[generators][approvals]") { - - auto [start, eat, left] = GENERATE( table ({ - { 12, 5, 7 }, - { 20, 5, 15 } - })); + using tuple_type = std::tuple; + auto [start, eat, left] = GENERATE( table( + { tuple_type{ 12, 5, 7 }, tuple_type{ 20, 5, 15 } } ) ); GIVEN( "there are " << start << " cucumbers" ) WHEN( "I eat " << eat << " cucumbers" ) From 7727c15290ce2d289c1809d0eab3cceb88384ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 7 Jun 2021 20:02:30 +0200 Subject: [PATCH 17/42] Remove Conan builds from travis-CI --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 239ab0cb..fa40bc3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -285,19 +285,6 @@ matrix: packages: ['clang-6.0', 'libstdc++-8-dev'] env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1 - # 8/ Conan - - language: python - python: - - "3.7" - dist: xenial - install: - - pip install conan-package-tools - env: - - CONAN_GCC_VERSIONS=8 - - CONAN_DOCKER_IMAGE=conanio/gcc8 - script: - - python .conan/build.py - install: - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} From eea3e9a5b5b0a405369961eb6601a56512a87ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 7 Jun 2021 19:53:34 +0200 Subject: [PATCH 18/42] Mark !mayfail tests as skipped in the JUnit reporter Should fix #2116 --- include/reporters/catch_reporter_junit.cpp | 19 +++++--- include/reporters/catch_reporter_junit.h | 7 +-- .../Baselines/compact.sw.approved.txt | 4 ++ .../Baselines/console.std.approved.txt | 44 +++++++++++++++++- .../Baselines/console.sw.approved.txt | 44 +++++++++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 35 ++++++++++++++- .../Baselines/sonarqube.sw.approved.txt | 24 ++++++++++ .../SelfTest/Baselines/xml.sw.approved.txt | 45 +++++++++++++++++-- .../SelfTest/UsageTests/Condition.tests.cpp | 15 ++++++- 9 files changed, 218 insertions(+), 19 deletions(-) diff --git a/include/reporters/catch_reporter_junit.cpp b/include/reporters/catch_reporter_junit.cpp index a50ead5f..ceb941be 100644 --- a/include/reporters/catch_reporter_junit.cpp +++ b/include/reporters/catch_reporter_junit.cpp @@ -182,12 +182,13 @@ namespace Catch { if ( !m_config->name().empty() ) className = m_config->name() + "." + className; - writeSection( className, "", rootSection ); + writeSection( className, "", rootSection, stats.testInfo.okToFail() ); } - void JunitReporter::writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; @@ -211,8 +212,14 @@ namespace Catch { // events and write those out appropriately. xml.writeAttribute( "status", "run" ); + if (sectionNode.stats.assertions.failedButOk) { + xml.scopedElement("skipped") + .writeAttribute("message", "TEST_CASE tagged with !mayfail"); + } + writeAssertions( sectionNode ); + if( !sectionNode.stdOut.empty() ) xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline ); if( !sectionNode.stdErr.empty() ) @@ -220,9 +227,9 @@ namespace Catch { } for( auto const& childNode : sectionNode.childSections ) if( className.empty() ) - writeSection( name, "", *childNode ); + writeSection( name, "", *childNode, testOkToFail ); else - writeSection( className, name, *childNode ); + writeSection( className, name, *childNode, testOkToFail ); } void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { diff --git a/include/reporters/catch_reporter_junit.h b/include/reporters/catch_reporter_junit.h index 5ee3a570..da5b5721 100644 --- a/include/reporters/catch_reporter_junit.h +++ b/include/reporters/catch_reporter_junit.h @@ -41,9 +41,10 @@ namespace Catch { void writeTestCase(TestCaseNode const& testCaseNode); - void writeSection(std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode); + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail ); void writeAssertions(SectionNode const& sectionNode); void writeAssertion(AssertionStats const& stats); diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt index efefa833..0d12ebb9 100644 --- a/projects/SelfTest/Baselines/compact.sw.approved.txt +++ b/projects/SelfTest/Baselines/compact.sw.approved.txt @@ -846,6 +846,10 @@ Matchers.tests.cpp:: passed: testStringForMatching(), (Contains("st Matchers.tests.cpp:: failed: testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random") for: "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" ) Matchers.tests.cpp:: passed: testStringForMatching(), !Contains("different") for: "this string contains 'abc' as a substring" not contains: "different" Matchers.tests.cpp:: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring" +Condition.tests.cpp:: failed: explicitly +Condition.tests.cpp:: failed: explicitly +Condition.tests.cpp:: failed: explicitly +Condition.tests.cpp:: failed: explicitly Exception.tests.cpp:: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception" Exception.tests.cpp:: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail" Generators.tests.cpp:: passed: values > -6 for: 3 > -6 diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index cfcdc72e..9de49d9a 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -694,6 +694,46 @@ Matchers.tests.cpp:: FAILED: with expansion: "this string contains 'abc' as a substring" not contains: "substring" +------------------------------------------------------------------------------- +Mayfail test case with nested sections + A + 1 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + A + 2 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + B + 1 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + B + 2 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + ------------------------------------------------------------------------------- Mismatching exception messages failing the test ------------------------------------------------------------------------------- @@ -1380,6 +1420,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 322 | 248 passed | 70 failed | 4 failed as expected -assertions: 1759 | 1607 passed | 131 failed | 21 failed as expected +test cases: 323 | 248 passed | 70 failed | 5 failed as expected +assertions: 1763 | 1607 passed | 131 failed | 25 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 3c09bf31..7f663129 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -6492,6 +6492,46 @@ Matchers.tests.cpp:: FAILED: with expansion: "this string contains 'abc' as a substring" not contains: "substring" +------------------------------------------------------------------------------- +Mayfail test case with nested sections + A + 1 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + A + 2 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + B + 1 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + +------------------------------------------------------------------------------- +Mayfail test case with nested sections + B + 2 +------------------------------------------------------------------------------- +Condition.tests.cpp: +............................................................................... + +Condition.tests.cpp:: FAILED: + ------------------------------------------------------------------------------- Mismatching exception messages failing the test ------------------------------------------------------------------------------- @@ -14138,6 +14178,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 322 | 232 passed | 86 failed | 4 failed as expected -assertions: 1776 | 1607 passed | 148 failed | 21 failed as expected +test cases: 323 | 232 passed | 86 failed | 5 failed as expected +assertions: 1780 | 1607 passed | 148 failed | 25 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index 89a0b438..b7e55e04 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -48,6 +48,7 @@ Nor would this + FAILED: expected exception @@ -56,6 +57,7 @@ Exception.tests.cpp: + FAILED: REQUIRE_NOTHROW( thisThrows() ) @@ -68,6 +70,7 @@ Exception.tests.cpp: + FAILED: CHECK( f() == 0 ) @@ -443,6 +446,7 @@ Matchers.tests.cpp: + FAILED: CHECK( data.int_seven == 6 ) @@ -736,6 +740,7 @@ Message.tests.cpp: + FAILED: CHECK( data.int_seven != 7 ) @@ -799,6 +804,34 @@ with expansion: Matchers.tests.cpp: + + + +FAILED: +Condition.tests.cpp: + + + + + +FAILED: +Condition.tests.cpp: + + + + + +FAILED: +Condition.tests.cpp: + + + + + +FAILED: +Condition.tests.cpp: + + FAILED: diff --git a/projects/SelfTest/Baselines/sonarqube.sw.approved.txt b/projects/SelfTest/Baselines/sonarqube.sw.approved.txt index 12a4e5be..1b4248d3 100644 --- a/projects/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/projects/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -575,6 +575,30 @@ Condition.tests.cpp: + + +FAILED: +Condition.tests.cpp: + + + + +FAILED: +Condition.tests.cpp: + + + + +FAILED: +Condition.tests.cpp: + + + + +FAILED: +Condition.tests.cpp: + + FAILED: diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index 2b5da8d3..0a2d3377 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -7956,6 +7956,43 @@ Nor would this + +
+
+ + +
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+ +
+ +
@@ -16722,9 +16759,9 @@ loose text artifact - - + + - - + + diff --git a/projects/SelfTest/UsageTests/Condition.tests.cpp b/projects/SelfTest/UsageTests/Condition.tests.cpp index 9aed5e2c..fa533095 100644 --- a/projects/SelfTest/UsageTests/Condition.tests.cpp +++ b/projects/SelfTest/UsageTests/Condition.tests.cpp @@ -11,7 +11,7 @@ // Wdouble-promotion is not supported until 3.8 # if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7) # pragma clang diagnostic ignored "-Wdouble-promotion" -# endif +# endif #endif #include "catch.hpp" @@ -89,6 +89,19 @@ TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" ) CHECK( x == Approx( 1.301 ) ); } +// Needed to test junit reporter's handling of mayfail test cases and sections +TEST_CASE("Mayfail test case with nested sections", "[!mayfail]") { + SECTION("A") { + SECTION("1") { FAIL(); } + SECTION("2") { FAIL(); } + } + SECTION("B") { + SECTION("1") { FAIL(); } + SECTION("2") { FAIL(); } + } +} + + TEST_CASE( "Inequality checks that should succeed" ) { TestData data; From c4e3767e265808590986d5db6ca1b5532a7f3d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Wed, 28 Jul 2021 20:30:51 +0200 Subject: [PATCH 19/42] v2.13.7 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 11 ++++++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 58 ++++++++++++++++++++---------- 6 files changed, 55 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0370ea3c..9765aa04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.6) +project(Catch2 LANGUAGES CXX VERSION 2.13.7) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index 6d4776da..b38863a5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index 4d173dc1..32f75257 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.7](#2137)
[2.13.6](#2136)
[2.13.5](#2135)
[2.13.4](#2134)
@@ -47,6 +48,16 @@ [Even Older versions](#even-older-versions)
+## 2.13.7 + +### Fixes +* Added missing `` include in benchmarking. (#2231) +* Fixed noexcept build with benchmarking enabled (#2235) +* Fixed build for compilers with C++17 support but without C++17 library support (#2195) +* JUnit only uses 3 decimal places when reporting durations (#2221) +* `!mayfail` tagged tests are now marked as `skipped` in JUnit reporter output (#2116) + + ## 2.13.6 ### Fixes diff --git a/include/catch.hpp b/include/catch.hpp index d178c778..902619bf 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 6 +#define CATCH_VERSION_PATCH 7 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index 58f1123c..1fcf1e40 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 6, "", 0 ); + static Version version( 2, 13, 7, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index 36eaeb27..7e706f94 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.6 - * Generated: 2021-04-16 18:23:38.044268 + * Catch v2.13.7 + * Generated: 2021-07-28 20:29:27.753164 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 6 +#define CATCH_VERSION_PATCH 7 #ifdef __clang__ # pragma clang system_header @@ -326,7 +326,7 @@ namespace Catch { // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include - # if __cpp_lib_byte > 0 + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) @@ -5458,6 +5458,8 @@ namespace Catch { } // namespace Catch // end catch_outlier_classification.hpp + +#include #endif // CATCH_CONFIG_ENABLE_BENCHMARKING #include @@ -6342,9 +6344,10 @@ namespace Catch { void writeTestCase(TestCaseNode const& testCaseNode); - void writeSection(std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode); + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail ); void writeAssertions(SectionNode const& sectionNode); void writeAssertion(AssertionStats const& stats); @@ -6879,7 +6882,7 @@ namespace Catch { } iters *= 2; } - throw optimized_away_error{}; + Catch::throw_exception(optimized_away_error{}); } } // namespace Detail } // namespace Benchmark @@ -6887,6 +6890,7 @@ namespace Catch { // end catch_run_for_at_least.hpp #include +#include namespace Catch { namespace Benchmark { @@ -15376,7 +15380,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 6, "", 0 ); + static Version version( 2, 13, 7, "", 0 ); return version; } @@ -16789,6 +16793,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter) #include #include #include +#include namespace Catch { @@ -16816,7 +16821,7 @@ namespace Catch { #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif - return std::string(timeStamp); + return std::string(timeStamp, timeStampSize-1); } std::string fileNameTag(const std::vector &tags) { @@ -16827,6 +16832,17 @@ namespace Catch { return it->substr(1); return std::string(); } + + // Formats the duration in seconds to 3 decimal places. + // This is done because some genius defined Maven Surefire schema + // in a way that only accepts 3 decimal places, and tools like + // Jenkins use that schema for validation JUnit reporter output. + std::string formatDuration( double seconds ) { + ReusableStringStream rss; + rss << std::fixed << std::setprecision( 3 ) << seconds; + return rss.str(); + } + } // anonymous namespace JunitReporter::JunitReporter( ReporterConfig const& _config ) @@ -16896,7 +16912,7 @@ namespace Catch { if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else - xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "time", formatDuration( suiteTime ) ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write properties if there are any @@ -16941,12 +16957,13 @@ namespace Catch { if ( !m_config->name().empty() ) className = m_config->name() + "." + className; - writeSection( className, "", rootSection ); + writeSection( className, "", rootSection, stats.testInfo.okToFail() ); } - void JunitReporter::writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; @@ -16963,13 +16980,18 @@ namespace Catch { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } - xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) ); // This is not ideal, but it should be enough to mimic gtest's // junit output. // Ideally the JUnit reporter would also handle `skipTest` // events and write those out appropriately. xml.writeAttribute( "status", "run" ); + if (sectionNode.stats.assertions.failedButOk) { + xml.scopedElement("skipped") + .writeAttribute("message", "TEST_CASE tagged with !mayfail"); + } + writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) @@ -16979,9 +17001,9 @@ namespace Catch { } for( auto const& childNode : sectionNode.childSections ) if( className.empty() ) - writeSection( name, "", *childNode ); + writeSection( name, "", *childNode, testOkToFail ); else - writeSection( className, name, *childNode ); + writeSection( className, name, *childNode, testOkToFail ); } void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { From 4b9780201bbebdd8468d74cf028c53da3c83a187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Fri, 27 Aug 2021 16:59:35 -0700 Subject: [PATCH 20/42] Fix warning suppressions leaking under clang.exe When running clang.exe under Windows, catch.hpp leaks warning suppressions because it uses `#pragma warning(push)` & `#pragma warning(pop)` around warning suppressions like `#pragma clang diagnostic ignore "-Wunused-variable"`, instead of using `#pragma clang diagnostic push` and `#pragma clang diagnostic pop`. This fixes that by only defining `CATCH_INTERNAL_START_WARNINGS_SUPPRESSION` and `CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION` to be the cl.exe variants if `defined(_MSC_VER) && !defined(__clang__)`. --- include/internal/catch_compiler_capabilities.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index b6ef9fe2..533e3c08 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -146,10 +146,6 @@ // Visual C++ #if defined(_MSC_VER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - - // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) @@ -158,13 +154,18 @@ # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +# if !defined(__clang__) // Handle Clang masquerading for msvc + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER From 85c9544fa4c9625b9656d9bd765e54f8e639287f Mon Sep 17 00:00:00 2001 From: Biswapriyo Nath Date: Wed, 8 Sep 2021 19:07:09 +0530 Subject: [PATCH 21/42] pkgconfig: Add missing entries This adds prefix, exec_prefix and libdir fields --- CMake/catch2.pc.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMake/catch2.pc.in b/CMake/catch2.pc.in index 3ac9fbd1..2ad128ed 100644 --- a/CMake/catch2.pc.in +++ b/CMake/catch2.pc.in @@ -1,4 +1,7 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ Name: Catch2 Description: A modern, C++-native, header-only, test framework for C++11 From 3d01f3ae3279b806739936f0ffd44598bf20245c Mon Sep 17 00:00:00 2001 From: Rupert Nash Date: Fri, 17 Sep 2021 11:03:25 +0100 Subject: [PATCH 22/42] Backport changes from 7bea1e2ac36ac54b648ae5c9d381a59bc69db912 to fix #2273 for 2.x --- include/internal/catch_approx.h | 2 +- projects/SelfTest/UsageTests/Approx.tests.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/internal/catch_approx.h b/include/internal/catch_approx.h index 4522e5ad..2d12efe4 100644 --- a/include/internal/catch_approx.h +++ b/include/internal/catch_approx.h @@ -33,7 +33,7 @@ namespace Detail { Approx operator-() const; template ::value>::type> - Approx operator()( T const& value ) { + Approx operator()( T const& value ) const { Approx approx( static_cast(value) ); approx.m_epsilon = m_epsilon; approx.m_margin = m_margin; diff --git a/projects/SelfTest/UsageTests/Approx.tests.cpp b/projects/SelfTest/UsageTests/Approx.tests.cpp index 4029223a..6280599e 100644 --- a/projects/SelfTest/UsageTests/Approx.tests.cpp +++ b/projects/SelfTest/UsageTests/Approx.tests.cpp @@ -212,4 +212,11 @@ TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" ) } +TEST_CASE("Approx::operator() is const correct", "[Approx][.approvals]") { + const Approx ap = Approx(0.0).margin(0.01); + + // As long as this compiles, the test should be considered passing + REQUIRE(1.0 == ap(1.0)); +} + }} // namespace ApproxTests From dba29b60d639bf8d206a9a12c223e6ed4284fb13 Mon Sep 17 00:00:00 2001 From: Alecto Irene Perez Date: Mon, 4 Oct 2021 13:11:03 -0600 Subject: [PATCH 23/42] Fixed #2272: Compilation failure with C++20 (#2297) * Suppressed warning for comma-in-indexing-operator in tests that check that specific behaviour. * Made deprecated (and removed) allocator usings conditional on the tests being compiled with old version of MSVC that still requires them. Fixes #2272 --- projects/SelfTest/UsageTests/Matchers.tests.cpp | 6 ++++-- projects/SelfTest/UsageTests/Message.tests.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/projects/SelfTest/UsageTests/Matchers.tests.cpp b/projects/SelfTest/UsageTests/Matchers.tests.cpp index 1797d4a1..3fc64b96 100644 --- a/projects/SelfTest/UsageTests/Matchers.tests.cpp +++ b/projects/SelfTest/UsageTests/Matchers.tests.cpp @@ -242,12 +242,14 @@ namespace { namespace MatchersTests { ~CustomAllocator() = default; +#if defined(_MSC_VER) && _MSVC_LANG < 201703L using std::allocator::address; - using std::allocator::allocate; using std::allocator::construct; - using std::allocator::deallocate; using std::allocator::max_size; using std::allocator::destroy; +#endif + using std::allocator::allocate; + using std::allocator::deallocate; }; TEST_CASE("Vector matchers", "[matchers][vector]") { diff --git a/projects/SelfTest/UsageTests/Message.tests.cpp b/projects/SelfTest/UsageTests/Message.tests.cpp index 93347084..d151b2ba 100644 --- a/projects/SelfTest/UsageTests/Message.tests.cpp +++ b/projects/SelfTest/UsageTests/Message.tests.cpp @@ -241,6 +241,17 @@ std::ostream& operator<<(std::ostream& out, helper_1436 const& helper) { return out; } +// Clang and gcc have different names for this warning, and clang also +// warns about an unused value +#if defined(__GNUG__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcomma-subscript" +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-comma-subscript" +#pragma clang diagnostic ignored "-Wunused-value" +#endif + TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") { CAPTURE(std::vector{1, 2, 3}[0, 1, 2], std::vector{1, 2, 3}[(0, 1)], @@ -251,6 +262,10 @@ TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messag SUCCEED(); } +#ifdef __GNUG__ +#pragma GCC diagnostic pop +#endif + TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") { CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\"); CAPTURE("some, ), unmatched, } prenheses {[<"); From f2f0dcc5113fe3f262e5b81c6b6d9846ebe665a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 15 Nov 2021 23:27:17 +0100 Subject: [PATCH 24/42] Add VS2015 + char literals in GENERATE issue to known-limitations Closes #2207 --- docs/limitations.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/limitations.md b/docs/limitations.md index 65483b87..b17369b3 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -104,6 +104,20 @@ Both of these solutions have their problems, but should let you wring parallelis ## 3rd party bugs This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes). +### Visual Studio 2015 -- `GENERATE` does not compile if it would deduce char array + +VS 2015 refuses to compile `GENERATE` statements that would deduce to a +char array with known size, e.g. this: +```cpp +TEST_CASE("Deducing string lit") { + auto param = GENERATE("start", "stop"); +} +``` + +A workaround for this is to use the `as` helper and force deduction of +either a `char const*` or a `std::string`. + + ### Visual Studio 2017 -- raw string literal in assert fails to compile There is a known bug in Visual Studio 2017 (VC 15), that causes compilation error when preprocessor attempts to stringize a raw string literal (`#` preprocessor is applied to it). This snippet is sufficient to trigger the compilation error: ```cpp From f45dac8fc1827f3566079c2728f9fcd7f86e0716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Thu, 28 Oct 2021 11:20:00 +0200 Subject: [PATCH 25/42] Add broken test --- projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp index 549f3559..1ff3c2fa 100644 --- a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp +++ b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp @@ -53,6 +53,9 @@ TEST_CASE("Generators internals", "[generators][internals]") { // Completely filtered-out generator should throw on construction REQUIRE_THROWS_AS(filter([] (int) { return false; }, value(1)), Catch::GeneratorException); + REQUIRE_THROWS_AS( + filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), + Catch::GeneratorException ); } SECTION("Take generator") { SECTION("Take less") { From 33794a204c00158b15eeda38bd2e30a5a57533fc Mon Sep 17 00:00:00 2001 From: Xo Wang Date: Wed, 27 Oct 2021 12:10:38 -0700 Subject: [PATCH 26/42] Fix clang analyzer warning about FilterGenerator Refactor FilterGenerator to remove ctor call to overridden method next() in order to address clang static analyzer diagnostic: catch2-src/single_include/catch2/catch.hpp:4166:42: note: Call to virtual method 'FilterGenerator::next' during construction bypasses virtual dispatch auto has_initial_value = next(); ^~~~~~ --- include/internal/catch_generators_generic.hpp | 7 ++++++- .../SelfTest/Baselines/compact.sw.approved.txt | 1 + .../SelfTest/Baselines/console.std.approved.txt | 2 +- .../SelfTest/Baselines/console.sw.approved.txt | 5 ++++- projects/SelfTest/Baselines/junit.sw.approved.txt | 2 +- projects/SelfTest/Baselines/xml.sw.approved.txt | 14 +++++++++++--- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/include/internal/catch_generators_generic.hpp b/include/internal/catch_generators_generic.hpp index c3410147..b2a0af5e 100644 --- a/include/internal/catch_generators_generic.hpp +++ b/include/internal/catch_generators_generic.hpp @@ -63,7 +63,7 @@ namespace Generators { if (!m_predicate(m_generator.get())) { // It might happen that there are no values that pass the // filter. In that case we throw an exception. - auto has_initial_value = next(); + auto has_initial_value = nextImpl(); if (!has_initial_value) { Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); } @@ -75,6 +75,11 @@ namespace Generators { } bool next() override { + return nextImpl(); + } + + private: + bool nextImpl() { bool success = m_generator.next(); if (!success) { return false; diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt index 0d12ebb9..d66cb98e 100644 --- a/projects/SelfTest/Baselines/compact.sw.approved.txt +++ b/projects/SelfTest/Baselines/compact.sw.approved.txt @@ -628,6 +628,7 @@ GeneratorsImpl.tests.cpp:: passed: gen.next() for: true GeneratorsImpl.tests.cpp:: passed: gen.get() == 3 for: 3 == 3 GeneratorsImpl.tests.cpp:: passed: !(gen.next()) for: !false GeneratorsImpl.tests.cpp:: passed: filter([] (int) { return false; }, value(1)), Catch::GeneratorException +GeneratorsImpl.tests.cpp:: passed: filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException GeneratorsImpl.tests.cpp:: passed: gen.get() == 1 for: 1 == 1 GeneratorsImpl.tests.cpp:: passed: gen.next() for: true GeneratorsImpl.tests.cpp:: passed: gen.get() == 2 for: 2 == 2 diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index 9de49d9a..c29715f0 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -1421,5 +1421,5 @@ due to unexpected exception with message: =============================================================================== test cases: 323 | 248 passed | 70 failed | 5 failed as expected -assertions: 1763 | 1607 passed | 131 failed | 25 failed as expected +assertions: 1764 | 1608 passed | 131 failed | 25 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 7f663129..2318ebea 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -4968,6 +4968,9 @@ with expansion: GeneratorsImpl.tests.cpp:: PASSED: REQUIRE_THROWS_AS( filter([] (int) { return false; }, value(1)), Catch::GeneratorException ) +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE_THROWS_AS( filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException ) + ------------------------------------------------------------------------------- Generators internals Take generator @@ -14179,5 +14182,5 @@ Misc.tests.cpp:: PASSED: =============================================================================== test cases: 323 | 232 passed | 86 failed | 5 failed as expected -assertions: 1780 | 1607 passed | 148 failed | 25 failed as expected +assertions: 1781 | 1608 passed | 148 failed | 25 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index b7e55e04..e2a504f5 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index 0a2d3377..30856484 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -5720,7 +5720,15 @@ Nor would this filter([] (int) { return false; }, value(1)), Catch::GeneratorException - + + + filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException + + + filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException + + +
@@ -16759,9 +16767,9 @@ loose text artifact
- + - + From 8a06a6dce8d9b38884d1d7f79aee59dab9018535 Mon Sep 17 00:00:00 2001 From: Dan Raviv Date: Wed, 8 Dec 2021 11:51:37 +0200 Subject: [PATCH 27/42] Fix typo --- docs/other-macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/other-macros.md b/docs/other-macros.md index 994115f1..a27f132d 100644 --- a/docs/other-macros.md +++ b/docs/other-macros.md @@ -121,7 +121,7 @@ constructor, or before Catch2's session is created in user's own main._ `ANON_TEST_CASE` is a `TEST_CASE` replacement that will autogenerate unique name. The advantage of this is that you do not have to think -of a name for the test case,`the disadvantage is that the name doesn't +of a name for the test case, the disadvantage is that the name doesn't necessarily remain stable across different links, and thus it might be hard to run directly. From e9e4117016b1c6a47efbdf53b9e95ed8239885c7 Mon Sep 17 00:00:00 2001 From: Bernhard Manfred Gruber Date: Thu, 16 Dec 2021 09:21:51 +0100 Subject: [PATCH 28/42] Remove double-underscores in macros Such identifiers are reserved by the C++ standard. Fixes part of #578. --- include/catch.hpp | 28 ++++++------- include/internal/catch_test_registry.h | 56 +++++++++++++------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/include/catch.hpp b/include/catch.hpp index 902619bf..f8f9de93 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -195,9 +195,9 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required @@ -301,9 +301,9 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING using Catch::Detail::Approx; @@ -350,8 +350,8 @@ using Catch::Detail::Approx; #define CATCH_WARN( msg ) (void)(0) #define CATCH_CAPTURE( msg ) (void)(0) -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_SECTION( ... ) @@ -360,7 +360,7 @@ using Catch::Detail::Approx; #define CATCH_FAIL_CHECK( ... ) (void)(0) #define CATCH_SUCCEED( ... ) (void)(0) -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -383,8 +383,8 @@ using Catch::Detail::Approx; #endif // "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define CATCH_GIVEN( desc ) #define CATCH_AND_GIVEN( desc ) #define CATCH_WHEN( desc ) @@ -435,8 +435,8 @@ using Catch::Detail::Approx; #define WARN( msg ) (void)(0) #define CAPTURE( msg ) (void)(0) -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define METHOD_AS_TEST_CASE( method, ... ) #define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define SECTION( ... ) @@ -444,7 +444,7 @@ using Catch::Detail::Approx; #define FAIL( ... ) (void)(0) #define FAIL_CHECK( ... ) (void)(0) #define SUCCEED( ... ) (void)(0) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -474,8 +474,8 @@ using Catch::Detail::Approx; #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // "BDD-style" convenience wrappers -#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define GIVEN( desc ) #define AND_GIVEN( desc ) diff --git a/include/internal/catch_test_registry.h b/include/internal/catch_test_registry.h index d28309e2..55b49e4c 100644 --- a/include/internal/catch_test_registry.h +++ b/include/internal/catch_test_registry.h @@ -71,34 +71,34 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #endif @@ -111,7 +111,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ @@ -133,7 +133,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ @@ -174,18 +174,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ @@ -223,18 +223,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ @@ -265,7 +265,7 @@ struct AutoReg : NonCopyable { static void TestFunc() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList ) #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ @@ -299,18 +299,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ @@ -351,18 +351,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ @@ -396,7 +396,7 @@ struct AutoReg : NonCopyable { void TestName::test() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList ) #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED From 216713a4066b79d9803d374f261ccb30c0fb451f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 3 Jan 2022 21:21:39 +0100 Subject: [PATCH 29/42] v2.13.8 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 13 ++++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 113 +++++++++++++++-------------- 6 files changed, 77 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9765aa04..3db32a53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.7) +project(Catch2 LANGUAGES CXX VERSION 2.13.8) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index b38863a5..7dd9213f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index 32f75257..5a4fe27d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.8](#2138)
[2.13.7](#2137)
[2.13.6](#2136)
[2.13.5](#2135)
@@ -48,6 +49,18 @@ [Even Older versions](#even-older-versions)
+## 2.13.8 + +### Fixes +* Made `Approx::operator()` const (#2288) +* Improved pkg-config files (#2284) +* Fixed warning suppression leaking out of Catch2 when compiled with clang.exe (#2280) +* The macro-generated names for things like `TEST_CASE` no longer create reserved identifiers (#2336) + +### Improvements +* Clang-tidy should no longer warn about missing virtual dispatch in `FilterGenerator`'s constructor (#2314) + + ## 2.13.7 ### Fixes diff --git a/include/catch.hpp b/include/catch.hpp index f8f9de93..dbcb9495 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 7 +#define CATCH_VERSION_PATCH 8 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index 1fcf1e40..8e587984 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 7, "", 0 ); + static Version version( 2, 13, 8, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index 7e706f94..db1fed3b 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,9 +1,9 @@ /* - * Catch v2.13.7 - * Generated: 2021-07-28 20:29:27.753164 + * Catch v2.13.8 + * Generated: 2022-01-03 21:20:09.589503 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 7 +#define CATCH_VERSION_PATCH 8 #ifdef __clang__ # pragma clang system_header @@ -240,9 +240,6 @@ namespace Catch { // Visual C++ #if defined(_MSC_VER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) @@ -251,13 +248,18 @@ namespace Catch { # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +# if !defined(__clang__) // Handle Clang masquerading for msvc + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER @@ -1010,34 +1012,34 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #endif @@ -1050,7 +1052,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ @@ -1072,7 +1074,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ @@ -1113,18 +1115,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ @@ -1162,18 +1164,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ @@ -1204,7 +1206,7 @@ struct AutoReg : NonCopyable { static void TestFunc() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList ) #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ @@ -1237,18 +1239,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ @@ -1289,18 +1291,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ @@ -1334,7 +1336,7 @@ struct AutoReg : NonCopyable { void TestName::test() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList ) // end catch_test_registry.h // start catch_capture.hpp @@ -3091,7 +3093,7 @@ namespace Detail { Approx operator-() const; template ::value>::type> - Approx operator()( T const& value ) { + Approx operator()( T const& value ) const { Approx approx( static_cast(value) ); approx.m_epsilon = m_epsilon; approx.m_margin = m_margin; @@ -4163,7 +4165,7 @@ namespace Generators { if (!m_predicate(m_generator.get())) { // It might happen that there are no values that pass the // filter. In that case we throw an exception. - auto has_initial_value = next(); + auto has_initial_value = nextImpl(); if (!has_initial_value) { Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); } @@ -4175,6 +4177,11 @@ namespace Generators { } bool next() override { + return nextImpl(); + } + + private: + bool nextImpl() { bool success = m_generator.next(); if (!success) { return false; @@ -15380,7 +15387,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 7, "", 0 ); + static Version version( 2, 13, 8, "", 0 ); return version; } @@ -17648,9 +17655,9 @@ int main (int argc, char * const argv[]) { #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required @@ -17752,9 +17759,9 @@ int main (int argc, char * const argv[]) { #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING using Catch::Detail::Approx; @@ -17801,8 +17808,8 @@ using Catch::Detail::Approx; #define CATCH_WARN( msg ) (void)(0) #define CATCH_CAPTURE( msg ) (void)(0) -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_SECTION( ... ) @@ -17811,7 +17818,7 @@ using Catch::Detail::Approx; #define CATCH_FAIL_CHECK( ... ) (void)(0) #define CATCH_SUCCEED( ... ) (void)(0) -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17834,8 +17841,8 @@ using Catch::Detail::Approx; #endif // "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define CATCH_GIVEN( desc ) #define CATCH_AND_GIVEN( desc ) #define CATCH_WHEN( desc ) @@ -17885,8 +17892,8 @@ using Catch::Detail::Approx; #define WARN( msg ) (void)(0) #define CAPTURE( msg ) (void)(0) -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define METHOD_AS_TEST_CASE( method, ... ) #define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define SECTION( ... ) @@ -17894,7 +17901,7 @@ using Catch::Detail::Approx; #define FAIL( ... ) (void)(0) #define FAIL_CHECK( ... ) (void)(0) #define SUCCEED( ... ) (void)(0) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17924,8 +17931,8 @@ using Catch::Detail::Approx; #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // "BDD-style" convenience wrappers -#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define GIVEN( desc ) #define AND_GIVEN( desc ) From 958944d27a2d2fb82aa008377bf4f8752f6b848e Mon Sep 17 00:00:00 2001 From: Mikhail Matrosov Date: Tue, 25 Jan 2022 23:54:19 +0300 Subject: [PATCH 30/42] Allow to specify CATCH_CONFIG_DEFAULT_REPORTER for static library with main() (#2346) --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3db32a53..c0dfb09b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,6 +116,10 @@ if (CATCH_BUILD_STATIC_LIBRARY) ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10)) target_compile_options(Catch2WithMain PRIVATE "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.") endif() + + if (CATCH_CONFIG_DEFAULT_REPORTER) + target_compile_definitions(Catch2WithMain PRIVATE CATCH_CONFIG_DEFAULT_REPORTER=${CATCH_CONFIG_DEFAULT_REPORTER}) + endif() endif(CATCH_BUILD_STATIC_LIBRARY) # Only perform the installation steps when Catch is not being used as From ff151d2833d48aa630564859cd1401a93a2bb333 Mon Sep 17 00:00:00 2001 From: John Beard Date: Fri, 4 Mar 2022 14:29:22 +0000 Subject: [PATCH 31/42] Fix: CAPTURE not variadic when disabled (#2378) Closes: #2316 --- include/catch.hpp | 2 +- projects/ExtraTests/X01-PrefixedMacros.cpp | 1 + projects/ExtraTests/X02-DisabledMacros.cpp | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/catch.hpp b/include/catch.hpp index dbcb9495..e027712b 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -433,7 +433,7 @@ using Catch::Detail::Approx; #define INFO( msg ) (void)(0) #define UNSCOPED_INFO( msg ) (void)(0) #define WARN( msg ) (void)(0) -#define CAPTURE( msg ) (void)(0) +#define CAPTURE( ... ) (void)(0) #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) diff --git a/projects/ExtraTests/X01-PrefixedMacros.cpp b/projects/ExtraTests/X01-PrefixedMacros.cpp index 3d2ab9c1..4a4d4293 100644 --- a/projects/ExtraTests/X01-PrefixedMacros.cpp +++ b/projects/ExtraTests/X01-PrefixedMacros.cpp @@ -53,6 +53,7 @@ CATCH_TEST_CASE("PrefixedMacros") { CATCH_SECTION("some section") { int i = 1; CATCH_CAPTURE( i ); + CATCH_CAPTURE( i, i + 1 ); CATCH_DYNAMIC_SECTION("Dynamic section: " << i) { CATCH_FAIL_CHECK( "failure" ); } diff --git a/projects/ExtraTests/X02-DisabledMacros.cpp b/projects/ExtraTests/X02-DisabledMacros.cpp index 3a969d76..2669145d 100644 --- a/projects/ExtraTests/X02-DisabledMacros.cpp +++ b/projects/ExtraTests/X02-DisabledMacros.cpp @@ -26,6 +26,10 @@ foo f; // This test should not be run, because it won't be registered TEST_CASE( "Disabled Macros" ) { + + CAPTURE( 1 ); + CAPTURE( 1, "captured" ); + std::cout << "This should not happen\n"; FAIL(); } From 0aa4dbae2e5d0b86fc6602354fdcea6d186752b2 Mon Sep 17 00:00:00 2001 From: Martin Mekota Date: Thu, 17 Mar 2022 20:56:11 +0100 Subject: [PATCH 32/42] Fix filename as tag bug When a test file isn't provided with "/" in the path, the filename isn't registered as a tag. Fixing by providing a conditon for this edge case. Closes #2328 --- include/internal/catch_session.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp index 24ebe4de..6254c584 100644 --- a/include/internal/catch_session.cpp +++ b/include/internal/catch_session.cpp @@ -127,6 +127,10 @@ namespace Catch { filename.erase(0, lastSlash); filename[0] = '#'; } + else + { + filename.insert(0, "#"); + } auto lastDot = filename.find_last_of('.'); if (lastDot != std::string::npos) { From 62fd660583d3ae7a7886930b413c3c570e89786c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 12 Apr 2022 22:38:17 +0200 Subject: [PATCH 33/42] v2.13.9 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 8 ++++++++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 14 +++++++++----- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0dfb09b..a6f1d463 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.8) +project(Catch2 LANGUAGES CXX VERSION 2.13.9) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index 7dd9213f..26ac2bb3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index 5a4fe27d..b88acc89 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.9](#2139)
[2.13.8](#2138)
[2.13.7](#2137)
[2.13.6](#2136)
@@ -49,6 +50,13 @@ [Even Older versions](#even-older-versions)
+## 2.13.9 + +### Fixes +* Fixed issue with `-#` (filename-as-tag) flag when `__FILE__` expands into filename without directories (#2328, #2393) +* Fixed `CAPTURE` macro not being variadic when disabled through `CATCH_CONFIG_DISABLE` (#2316, #2378) + + ## 2.13.8 ### Fixes diff --git a/include/catch.hpp b/include/catch.hpp index e027712b..cfa894ac 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 8 +#define CATCH_VERSION_PATCH 9 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index 8e587984..bc9aaf9f 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 8, "", 0 ); + static Version version( 2, 13, 9, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index db1fed3b..d2a12427 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.8 - * Generated: 2022-01-03 21:20:09.589503 + * Catch v2.13.9 + * Generated: 2022-04-12 22:37:23.260201 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 8 +#define CATCH_VERSION_PATCH 9 #ifdef __clang__ # pragma clang system_header @@ -13392,6 +13392,10 @@ namespace Catch { filename.erase(0, lastSlash); filename[0] = '#'; } + else + { + filename.insert(0, "#"); + } auto lastDot = filename.find_last_of('.'); if (lastDot != std::string::npos) { @@ -15387,7 +15391,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 8, "", 0 ); + static Version version( 2, 13, 9, "", 0 ); return version; } @@ -17890,7 +17894,7 @@ using Catch::Detail::Approx; #define INFO( msg ) (void)(0) #define UNSCOPED_INFO( msg ) (void)(0) #define WARN( msg ) (void)(0) -#define CAPTURE( msg ) (void)(0) +#define CAPTURE( ... ) (void)(0) #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) From d71b4617e9935f8589870af211f5b7552d743654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 17 Apr 2022 21:11:36 +0200 Subject: [PATCH 34/42] Disable Werror for unknown pragmas in tests Closes #2375 --- projects/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index aee85974..5de0713c 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -354,7 +354,7 @@ endif() if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations ) if (CATCH_ENABLE_WERROR) - target_compile_options( SelfTest PRIVATE -Werror ) + target_compile_options( SelfTest PRIVATE -Werror -Wno-error=pragmas ) endif() endif() # Clang specific options go here From ca455815fdbe7774ef81fed497f0026cd5bc3965 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 7 May 2022 11:41:38 +0200 Subject: [PATCH 35/42] ObjectStorage: port away from std::aligned_storage It's deprecated in C++23. Just use alignas on a char array, wrapped in a struct to avoid decaying to char*, which is the canonical implementation of aligned_storage: https://en.cppreference.com/w/cpp/types/aligned_storage#Possible_implementation Fixes #2419 Catch3 is not affected. --- include/internal/benchmark/catch_constructor.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/internal/benchmark/catch_constructor.hpp b/include/internal/benchmark/catch_constructor.hpp index 4fc04042..976a1eeb 100644 --- a/include/internal/benchmark/catch_constructor.hpp +++ b/include/internal/benchmark/catch_constructor.hpp @@ -19,8 +19,6 @@ namespace Catch { template struct ObjectStorage { - using TStorage = typename std::aligned_storage::value>::type; - ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) @@ -64,7 +62,7 @@ namespace Catch { } - TStorage data; + struct { alignas(T) unsigned char data[sizeof(T)]; } data; }; } From 1127d847a1b52402b7a224caaabe647883287115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 15 May 2022 23:15:07 +0200 Subject: [PATCH 36/42] Use better instruction for CATCH_TRAP on ARM Macs The old instruction would cause the debugger to be stuck at the triggering source line forever, while the new one should have the expected semantics, where the debugger can then single-step, continue. or generally do things, afterwards. Closes #2422 --- include/internal/catch_debugger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/internal/catch_debugger.h b/include/internal/catch_debugger.h index a0148aa8..a5a59b3b 100644 --- a/include/internal/catch_debugger.h +++ b/include/internal/catch_debugger.h @@ -20,7 +20,7 @@ namespace Catch { #if defined(__i386__) || defined(__x86_64__) #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #define CATCH_TRAP() __asm__(".inst 0xd43e0000") #endif #elif defined(CATCH_PLATFORM_IPHONE) From e33de8fc05ca80923a8216a8aecd6a1afc5e00af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 31 May 2022 12:31:02 +0200 Subject: [PATCH 37/42] Update FetchContent docs to use 2.13.9 --- docs/cmake-integration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/cmake-integration.md b/docs/cmake-integration.md index 1cab907a..075d8faa 100644 --- a/docs/cmake-integration.md +++ b/docs/cmake-integration.md @@ -43,7 +43,8 @@ Include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v2.13.1) + GIT_TAG v2.13.9 # or a later release +) FetchContent_MakeAvailable(Catch2) From 20d413b8b6803c6d456874935d7014fe684e9426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 6 Jun 2022 01:04:07 +0200 Subject: [PATCH 38/42] Fix comma-subscript warning suppression to only target GCC 10.1+ Fixes #2416 --- projects/SelfTest/UsageTests/Message.tests.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/projects/SelfTest/UsageTests/Message.tests.cpp b/projects/SelfTest/UsageTests/Message.tests.cpp index d151b2ba..e2bd486f 100644 --- a/projects/SelfTest/UsageTests/Message.tests.cpp +++ b/projects/SelfTest/UsageTests/Message.tests.cpp @@ -241,17 +241,19 @@ std::ostream& operator<<(std::ostream& out, helper_1436 const& helper) { return out; } +// clang can handle GCC's diagnostic pragma +#if defined( __GNUG__ ) || defined(__clang__) +# pragma GCC diagnostic push +#endif // Clang and gcc have different names for this warning, and clang also // warns about an unused value -#if defined(__GNUG__) && !defined(__clang__) -#pragma GCC diagnostic push +#if defined( __GNUG__ ) && !defined( __clang__ ) && \ + ( __GNUG__ > 10 || ( __GNUG__ == 10 && __GNUC_MINOR__ >= 1 ) ) #pragma GCC diagnostic ignored "-Wcomma-subscript" #elif defined(__clang__) -#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-comma-subscript" #pragma clang diagnostic ignored "-Wunused-value" #endif - TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") { CAPTURE(std::vector{1, 2, 3}[0, 1, 2], std::vector{1, 2, 3}[(0, 1)], @@ -261,9 +263,8 @@ TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messag CAPTURE( (1, 2), (2, 3) ); SUCCEED(); } - -#ifdef __GNUG__ -#pragma GCC diagnostic pop +#if defined( __GNUG__ ) || defined(__clang__) +# pragma GCC diagnostic pop #endif TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") { From 14bc25be00881a0f85229d62dfeb32ce1e9cbe03 Mon Sep 17 00:00:00 2001 From: David Matson Date: Sat, 6 Aug 2022 12:15:53 -0700 Subject: [PATCH 39/42] Explicitly specify __cdecl on main/wmain for MSVC (#2487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2486 Co-authored-by: Martin Hořeňovský --- include/internal/catch_default_main.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/internal/catch_default_main.hpp b/include/internal/catch_default_main.hpp index aab5cba3..4d113d02 100644 --- a/include/internal/catch_default_main.hpp +++ b/include/internal/catch_default_main.hpp @@ -13,12 +13,20 @@ #ifndef __OBJC__ +#ifndef CATCH_INTERNAL_CDECL +#ifdef _MSC_VER +#define CATCH_INTERNAL_CDECL __cdecl +#else +#define CATCH_INTERNAL_CDECL +#endif +#endif + #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point -int main (int argc, char * argv[]) { +int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) { #endif return Catch::Session().run( argc, argv ); From 02123776f208502aecd374a324472720e5e3352f Mon Sep 17 00:00:00 2001 From: Thomas Gamper Date: Sun, 21 Aug 2022 17:44:03 +0200 Subject: [PATCH 40/42] fixes catchorg/Catch2#2401 --- include/internal/catch_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp index 6254c584..6247fa7d 100644 --- a/include/internal/catch_session.cpp +++ b/include/internal/catch_session.cpp @@ -293,7 +293,7 @@ namespace Catch { // Handle list request if( Option listed = list( m_config ) ) - return static_cast( *listed ); + return (std::min) (MaxExitCode, static_cast(*listed)); TestGroup tests { m_config }; auto const totals = tests.execute(); From 182c910b4b63ff587a3440e08f84f70497e49a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 16 Oct 2022 11:02:17 +0200 Subject: [PATCH 41/42] v2.13.10 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/release-notes.md | 10 ++++++++++ include/catch.hpp | 2 +- include/internal/catch_version.cpp | 2 +- single_include/catch2/catch.hpp | 28 +++++++++++++++++----------- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6f1d463..56ab7a44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() -project(Catch2 LANGUAGES CXX VERSION 2.13.9) +project(Catch2 LANGUAGES CXX VERSION 2.13.10) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff --git a/README.md b/README.md index 26ac2bb3..3754d3c2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff --git a/docs/release-notes.md b/docs/release-notes.md index b88acc89..9c4a1d2d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[2.13.10](#21310)
[2.13.9](#2139)
[2.13.8](#2138)
[2.13.7](#2137)
@@ -50,6 +51,15 @@ [Even Older versions](#even-older-versions)
+## 2.13.10 + +### Fixes +* Fixed issue with `catch_discover_tests` when there is multiple of 256 tests (#2401, #2503) +* Catch2-provided `main` and `wmain` are explicitly marked as `__cdecl` when compiled with MSVC (#2486, #2487) +* Improved break-into-debugger behaviour for ARM Macs. It should now be possible to step execution after the break (#2422) +* Replaced deprecated `std::aligned_storage` (#2419, #2420) + + ## 2.13.9 ### Fixes diff --git a/include/catch.hpp b/include/catch.hpp index cfa894ac..39a30171 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 9 +#define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp index bc9aaf9f..e1744727 100644 --- a/include/internal/catch_version.cpp +++ b/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 9, "", 0 ); + static Version version( 2, 13, 10, "", 0 ); return version; } diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index d2a12427..9b309bdd 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.9 - * Generated: 2022-04-12 22:37:23.260201 + * Catch v2.13.10 + * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 9 +#define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header @@ -7395,8 +7395,6 @@ namespace Catch { template struct ObjectStorage { - using TStorage = typename std::aligned_storage::value>::type; - ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) @@ -7439,7 +7437,7 @@ namespace Catch { return *static_cast(static_cast(&data)); } - TStorage data; + struct { alignas(T) unsigned char data[sizeof(T)]; } data; }; } @@ -7949,7 +7947,7 @@ namespace Catch { #if defined(__i386__) || defined(__x86_64__) #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #define CATCH_TRAP() __asm__(".inst 0xd43e0000") #endif #elif defined(CATCH_PLATFORM_IPHONE) @@ -13558,7 +13556,7 @@ namespace Catch { // Handle list request if( Option listed = list( m_config ) ) - return static_cast( *listed ); + return (std::min) (MaxExitCode, static_cast(*listed)); TestGroup tests { m_config }; auto const totals = tests.execute(); @@ -15391,7 +15389,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 9, "", 0 ); + static Version version( 2, 13, 10, "", 0 ); return version; } @@ -17526,12 +17524,20 @@ namespace Catch { #ifndef __OBJC__ +#ifndef CATCH_INTERNAL_CDECL +#ifdef _MSC_VER +#define CATCH_INTERNAL_CDECL __cdecl +#else +#define CATCH_INTERNAL_CDECL +#endif +#endif + #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point -int main (int argc, char * argv[]) { +int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) { #endif return Catch::Session().run( argc, argv ); From 20ace5503422a8511036aa9d486435041127e0cf Mon Sep 17 00:00:00 2001 From: alvinhochun Date: Wed, 19 Oct 2022 00:07:18 +0800 Subject: [PATCH 42/42] Allow ANSI colour to be compiled on Windows This enables building with `CATCH_CONFIG_COLOUR_ANSI` on Windows. The changes are taken from v3 commit 0e176c318bf309aaa4acd8686a82517fda7b859a. --- include/internal/catch_console_colour.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/internal/catch_console_colour.cpp b/include/internal/catch_console_colour.cpp index de0fff43..0d2fde0e 100644 --- a/include/internal/catch_console_colour.cpp +++ b/include/internal/catch_console_colour.cpp @@ -121,7 +121,10 @@ namespace { #elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// -#include +#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC ) +# define CATCH_INTERNAL_HAS_ISATTY +# include +#endif namespace Catch { namespace { @@ -170,7 +173,8 @@ namespace { #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE) !isDebuggerActive() && #endif -#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) +#if defined( CATCH_INTERNAL_HAS_ISATTY ) && \ + !( defined( __DJGPP__ ) && defined( __STRICT_ANSI__ ) ) isatty(STDOUT_FILENO) #else false