diff --git a/packages/Catch2/.gitrepo b/packages/Catch2/.gitrepo index 0accbeb85c8bd6751e1860c856f04f29d9f53db7..f0489ed62b2408124ccd6dc479c66fa99de2417b 100644 --- a/packages/Catch2/.gitrepo +++ b/packages/Catch2/.gitrepo @@ -6,6 +6,6 @@ [subrepo] remote = git@github.com:catchorg/Catch2.git branch = master - commit = 8d5d49299be5b8c62ec90be7d6ee4f71cbe89ea0 - parent = 6d44c5b577be5d55320b4a7f4e2668dec2293f5c + commit = 1dce91d78eb6764a474badee7559650502f1d2fc + parent = 5515dc5466f2c351639c28fdc16cce10cb067e12 cmdver = 0.3.1 diff --git a/packages/Catch2/CMakeLists.txt b/packages/Catch2/CMakeLists.txt index c877a3ca8305c7d547b2ac952afa999458dc82e8..9fdb50866c35cbb2a5f83ae8f878d298dceb03b3 100644 --- a/packages/Catch2/CMakeLists.txt +++ b/packages/Catch2/CMakeLists.txt @@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME) set(NOT_SUBPROJECT ON) endif() -project(Catch2 LANGUAGES CXX VERSION 2.2.2) +project(Catch2 LANGUAGES CXX VERSION 2.2.3) include(GNUInstallDirs) @@ -187,6 +187,7 @@ set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_test_spec_parser.h ${HEADER_DIR}/internal/catch_text.h ${HEADER_DIR}/internal/catch_timer.h + ${HEADER_DIR}/internal/catch_to_string.hpp ${HEADER_DIR}/internal/catch_tostring.h ${HEADER_DIR}/internal/catch_totals.h ${HEADER_DIR}/internal/catch_uncaught_exceptions.h diff --git a/packages/Catch2/README.md b/packages/Catch2/README.md index 5d7f4ff8dc51687aee5126ef903fc1b1fd2b98e7..7defcd5567594ea24f21c65812ac3268ee2b44f6 100644 --- a/packages/Catch2/README.md +++ b/packages/Catch2/README.md @@ -5,9 +5,9 @@ [](https://travis-ci.org/catchorg/Catch2) [](https://ci.appveyor.com/project/catchorg/catch2) [](https://codecov.io/gh/catchorg/Catch2) -[](https://wandbox.org/permlink/fRDMfYjUnrbOFwLn) +[](https://wandbox.org/permlink/u7qF77qgv9YqOr55) -<a href="https://github.com/catchorg/Catch2/releases/download/v2.2.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a> +<a href="https://github.com/catchorg/Catch2/releases/download/v2.2.3/catch.hpp">The latest version of the single header can be downloaded directly using this link</a> ## Catch2 is released! diff --git a/packages/Catch2/codecov.yml b/packages/Catch2/codecov.yml index d81582d7ec44d0814d79ecdf777abf7e8605a625..94d88d8331eec87994d49c0802a08a794617c8f8 100644 --- a/packages/Catch2/codecov.yml +++ b/packages/Catch2/codecov.yml @@ -9,6 +9,12 @@ coverage: patch: default: target: 80% + ignore: + - "projects/SelfTest" + - "**/catch_reporter_tap.hpp" + - "**/catch_reporter_automake.hpp" + - "**/catch_reporter_teamcity.hpp" + - "**/external/clara.hpp" codecov: @@ -16,11 +22,3 @@ codecov: comment: layout: "diff" - -coverage: - ignore: - - "projects/SelfTest" - - "**/catch_reporter_tap.hpp" - - "**/catch_reporter_automake.hpp" - - "**/catch_reporter_teamcity.hpp" - - "**/external/clara.hpp" diff --git a/packages/Catch2/conanfile.py b/packages/Catch2/conanfile.py index a3949588548875d8e3c6a813d1f48876c9f91976..716ca420ecb8f088ba82b509888bc6ef78f0a819 100644 --- a/packages/Catch2/conanfile.py +++ b/packages/Catch2/conanfile.py @@ -4,7 +4,7 @@ from conans import ConanFile class CatchConan(ConanFile): name = "Catch" - version = "2.2.2" + version = "2.2.3" description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD" author = "philsquared" generators = "cmake" diff --git a/packages/Catch2/contrib/CatchAddTests.cmake b/packages/Catch2/contrib/CatchAddTests.cmake index c68921e4f83b0c7eb5038cf6744a437c7060d880..07856130663918ddf6c6bfa9154c87f20046c6a1 100644 --- a/packages/Catch2/contrib/CatchAddTests.cmake +++ b/packages/Catch2/contrib/CatchAddTests.cmake @@ -50,8 +50,7 @@ string(REPLACE "\n" ";" output "${output}") # Parse output foreach(line ${output}) - # Test name; strip spaces to get just the name... - string(REGEX REPLACE " +" "" test "${line}") + set(test ${line}) # ...and add to script add_command(add_test "${prefix}${test}${suffix}" diff --git a/packages/Catch2/contrib/gdbinit b/packages/Catch2/contrib/gdbinit new file mode 100644 index 0000000000000000000000000000000000000000..fb3608aebafc2e07cea24510cf00eb8c8fb611f2 --- /dev/null +++ b/packages/Catch2/contrib/gdbinit @@ -0,0 +1,16 @@ +# +# This file provides a way to skip stepping into Catch code when debugging with gdb. +# +# With the gdb "skip" command you can tell gdb to skip files or functions during debugging. +# see https://xaizek.github.io/2016-05-26/skipping-standard-library-in-gdb/ for an example +# +# Basically the following line tells gdb to skip all functions containing the +# regexp "Catch", which matches the complete Catch namespace. +# If you want to skip just some parts of the Catch code you can modify the +# regexp accordingly. +# +# If you want to permanently skip stepping into Catch code copy the following +# line into your ~/.gdbinit file +# + +skip -rfu Catch diff --git a/packages/Catch2/contrib/lldbinit b/packages/Catch2/contrib/lldbinit new file mode 100644 index 0000000000000000000000000000000000000000..4f13634d0b483e69df9fcd6a35ba166aca971c80 --- /dev/null +++ b/packages/Catch2/contrib/lldbinit @@ -0,0 +1,16 @@ +# +# This file provides a way to skip stepping into Catch code when debugging with lldb. +# +# With the setting "target.process.thread.step-avoid-regexp" you can tell lldb +# to skip functions matching the regexp +# +# Basically the following line tells lldb to skip all functions containing the +# regexp "Catch", which matches the complete Catch namespace. +# If you want to skip just some parts of the Catch code you can modify the +# regexp accordingly. +# +# If you want to permanently skip stepping into Catch code copy the following +# line into your ~/.lldbinit file +# + +settings set target.process.thread.step-avoid-regexp Catch \ No newline at end of file diff --git a/packages/Catch2/docs/assertions.md b/packages/Catch2/docs/assertions.md index 187b7ea8cc1d50ea17b246eafc553f0920e7d4aa..90c0856cb3ea63aad9af63f4909b29de23af0070 100644 --- a/packages/Catch2/docs/assertions.md +++ b/packages/Catch2/docs/assertions.md @@ -162,7 +162,7 @@ Because the preprocessor parses code using different rules than the compiler, multiple-argument assertions (e.g. `REQUIRE_THROWS_AS`) have problems with commas inside the provided expressions. As an example `REQUIRE_THROWS_AS(std::pair<int, int>(1, 2), std::invalid_argument);` -will fails to compile, because the preprocessor sees 3 arguments provided, +will fail to compile, because the preprocessor sees 3 arguments provided, but the macro accepts only 2. There are two possible workarounds. 1) Use typedef: diff --git a/packages/Catch2/docs/configuration.md b/packages/Catch2/docs/configuration.md index 00d012df82878dda891e68bf37ae2ecb7e71c739..81bf292aa7b998075c7ccef9178155c0244cb6f2 100644 --- a/packages/Catch2/docs/configuration.md +++ b/packages/Catch2/docs/configuration.md @@ -77,13 +77,16 @@ This can be useful on certain platforms that do not provide the standard iostrea ## Fallback stringifier -By default Catch's stringification machinery falls back to a "{?}". To -let projects reuse their own existing stringification machinery, this -fallback can be overridden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` -to a name of a function that should perform the stringification instead. +By default, when Catch's stringification machinery has to stringify +a type that does not specialize `StringMaker`, does not overload `operator<<`, +is not an enumeration and is not a range, it uses `"{?}"`. This can be +overriden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` to name of a +function that should perform the stringification instead. -The provided function must return std::string and must accept any type -(e.g. via overloading). +All types that do not provide `StringMaker` specialization or `operator<<` +overload will be sent to this function (this includes enums and ranges). +The provided function must return `std::string` and must accept any type, +e.g. via overloading. _Note that if the provided function does not handle a type and this type requires to be stringified, the compilation will fail._ @@ -99,6 +102,19 @@ This means that defining `CATCH_CONFIG_DEFAULT_REPORTER` to `"console"` is equivalent with the out-of-the-box experience. +## C++11 toggles + + CATCH_CONFIG_CPP11_TO_STRING // Use `std::to_string` + +Because we support platforms whose standard library does not contain +`std::to_string`, it is possible to force Catch to use a workaround +based on `std::stringstream`. On platforms other than Android, +the default is to use `std::to_string`. On Android, the default is to +use the `stringstream` workaround. As always, it is possible to override +Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or +`CATCH_CONFIG_NO_CPP11_TO_STRING`. + + ## C++17 toggles CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception diff --git a/packages/Catch2/docs/list-of-examples.md b/packages/Catch2/docs/list-of-examples.md index 6517d5d367bfa5e5c2b00cd7d034832fc3aa951e..81f5a903f067dbc5a18e24bcef39ff7d43a02388 100644 --- a/packages/Catch2/docs/list-of-examples.md +++ b/packages/Catch2/docs/list-of-examples.md @@ -1,18 +1,25 @@ <a id="top"></a> # List of examples +## Already available + - Test Case: [Single-file](../examples/010-TestCase.cpp) - Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-1.cpp) - Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp) +- Fixture: [Sections](../examples/100-Fix-Section.cpp) +- Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp) +- BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp) +- Listener: [Listeners](../examples/210-Evt-EventListeners.cpp) + + +## Planned + - Assertion: [REQUIRE_THAT and Matchers](../examples/040-Asn-RequireThat.cpp) - Assertion: [REQUIRE_NO_THROW](../examples/050-Asn-RequireNoThrow.cpp) - Assertion: [REQUIRE_THROWS](../examples/050-Asn-RequireThrows.cpp) - Assertion: [REQUIRE_THROWS_AS](../examples/070-Asn-RequireThrowsAs.cpp) - Assertion: [REQUIRE_THROWS_WITH](../examples/080-Asn-RequireThrowsWith.cpp) - Assertion: [REQUIRE_THROWS_MATCHES](../examples/090-Asn-RequireThrowsMatches.cpp) -- Fixture: [Sections](../examples/100-Fix-Section.cpp) -- Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp) -- BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp) - Floating point: [Approx - Comparisons](../examples/130-Fpt-Approx.cpp) - Logging: [CAPTURE - Capture expression](../examples/140-Log-Capture.cpp) - Logging: [INFO - Provide information with failure](../examples/150-Log-Info.cpp) @@ -21,7 +28,6 @@ - Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp) - Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp) - Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp) -- Listener: [Listeners](../examples/210-Evt-EventListeners.cpp) - Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp) - Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp) - Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp) diff --git a/packages/Catch2/docs/release-notes.md b/packages/Catch2/docs/release-notes.md index 37849affcab30ccf1b6e5a478ed02200eb8dbe24..6ebe4d03d0d85138a720383676b6373c9fc6c22c 100644 --- a/packages/Catch2/docs/release-notes.md +++ b/packages/Catch2/docs/release-notes.md @@ -1,5 +1,43 @@ <a id="top"></a> +# 2.2.3 + +**To fix some of the bugs, some behavior had to change in potentially breaking manner.** +**This means that even though this is a patch release, it might not be a drop-in replacement.** + +## Fixes +* Listeners are now called before reporter + * This was always documented to be the case, now it actually works that way +* Catch's commandline will no longer accept multiple reporters + * This was done because multiple reporters never worked properly and broke things in non-obvious ways + * **This has potential to be a breaking change** +* MinGW is now detected as Windows platform w/o SEH support (#1257) + * This means that Catch2 no longer tries to use POSIX signal handling when compiled with MinGW +* Fixed potential UB in parsing tags using non-ASCII characters (#1266) + * Note that Catch2 still supports only ASCII test names/tags/etc +* `TEST_CASE_METHOD` can now be used on classnames containing commas (#1245) + * You have to enclose the classname in extra set of parentheses +* Fixed insufficient alt stack size for POSIX signal handling (#1225) +* Fixed compilation error on Android due to missing `std::to_string` in C++11 mode (#1280) +* Fixed the order of user-provided `FALLBACK_STRINGIFIER` in stringification machinery (#1024) + * It was intended to be replacement for built-in fallbacks, but it was used _after_ them. + * **This has potential to be a breaking change** +* Fixed compilation error when a type has an `operator<<` with templated lhs (#1285, #1306) + +## Improvements +* Added a new, experimental, output capture (#1243) + * This capture can also redirect output written via C apis, e.g. `printf` + * To opt-in, define `CATCH_CONFIG_EXPERIMENTAL_REDIRECT` in the implementation file +* Added a new fallback stringifier for classes derived from `std::exception` + * Both `StringMaker` specialization and `operator<<` overload are given priority + +## Miscellaneous +* `contrib/` now contains dbg scripts that skip over Catch's internals (#904, #1283) + * `gdbinit` for gdb `lldbinit` for lldb +* `CatchAddTests.cmake` no longer strips whitespace from tests (#1265, #1281) +* Online documentation now describes `--use-colour` option (#1263) + + # 2.2.2 ## Fixes diff --git a/packages/Catch2/docs/release-process.md b/packages/Catch2/docs/release-process.md index 9990bab2b6da281059ebed13ce368bca76a8f704..b556c3990cd980cbbf61ac20c2dd8648cc21e696 100644 --- a/packages/Catch2/docs/release-process.md +++ b/packages/Catch2/docs/release-process.md @@ -49,17 +49,5 @@ on a specific version of the single-include header. ## Optional steps -The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they *should* happen, but they can happen the next day without losing anything significant. - - -### vcpkg update - -Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of necessary work for you, it creates a branch and commits necessary changes. You should review these changes, push and open a PR against vcpkg's upstream. - -Note that the script assumes you have your fork of vcpkg checked out in a directory next to the directory where you have checked out Catch, like so: -``` -GitHub - Catch - vcpkg -``` - +Because Catch's [vcpkg](https://github.com/Microsoft/vcpkg) port updates +itself automagically, there are no optional steps at this time. diff --git a/packages/Catch2/include/catch.hpp b/packages/Catch2/include/catch.hpp index 10388cece2e1262cb0a9bca47fdbbc72033644a3..0c92ed3af153a90a51f9def57dcfa45c13b38617 100644 --- a/packages/Catch2/include/catch.hpp +++ b/packages/Catch2/include/catch.hpp @@ -11,7 +11,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 2 -#define CATCH_VERSION_PATCH 2 +#define CATCH_VERSION_PATCH 3 #ifdef __clang__ # pragma clang system_header diff --git a/packages/Catch2/include/internal/catch_assertionhandler.cpp b/packages/Catch2/include/internal/catch_assertionhandler.cpp index c6818c14d3bc78d4c6346da2dbbcc1c5bfe73e77..28768077ab50eabb4a8d78beba651893a44e0188 100644 --- a/packages/Catch2/include/internal/catch_assertionhandler.cpp +++ b/packages/Catch2/include/internal/catch_assertionhandler.cpp @@ -18,9 +18,11 @@ namespace Catch { - auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { - expr.streamReconstructedExpression( os ); - return os; + namespace { + auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { + expr.streamReconstructedExpression( os ); + return os; + } } LazyExpression::LazyExpression( bool isNegated ) diff --git a/packages/Catch2/include/internal/catch_compiler_capabilities.h b/packages/Catch2/include/internal/catch_compiler_capabilities.h index c78c9d6d796650230fae393e50815f3b33c3d50a..37f625b2827c43b040dcd39802e5d1686a56626d 100644 --- a/packages/Catch2/include/internal/catch_compiler_capabilities.h +++ b/packages/Catch2/include/internal/catch_compiler_capabilities.h @@ -24,6 +24,7 @@ // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. +#include "catch_platform.h" #ifdef __cplusplus @@ -76,7 +77,11 @@ # define CATCH_CONFIG_COLOUR_NONE #endif - +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#endif //////////////////////////////////////////////////////////////////////////////// // Not all Windows environments support SEH properly @@ -146,6 +151,10 @@ # define CATCH_CONFIG_WCHAR #endif +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS #endif diff --git a/packages/Catch2/include/internal/catch_fatal_condition.cpp b/packages/Catch2/include/internal/catch_fatal_condition.cpp index ca72d980db15ac0e93bf7a5846b7a7b10652e00a..24e16d3c611e4f7d5dc6a86d56361b8955ad8e24 100644 --- a/packages/Catch2/include/internal/catch_fatal_condition.cpp +++ b/packages/Catch2/include/internal/catch_fatal_condition.cpp @@ -94,6 +94,11 @@ 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. + constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; + static SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, @@ -121,7 +126,7 @@ namespace Catch { isSet = true; stack_t sigStack; sigStack.ss_sp = altStackMem; - sigStack.ss_size = SIGSTKSZ; + sigStack.ss_size = sigStackSize; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { }; @@ -153,7 +158,7 @@ namespace Catch { bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + char FatalConditionHandler::altStackMem[sigStackSize] = {}; } // namespace Catch diff --git a/packages/Catch2/include/internal/catch_matchers_floating.cpp b/packages/Catch2/include/internal/catch_matchers_floating.cpp index b758bcf9e8ecb28a5026f2e53de4148f2cfe495f..72728a83d2d5f7786317d43d1d274b863cdadfbb 100644 --- a/packages/Catch2/include/internal/catch_matchers_floating.cpp +++ b/packages/Catch2/include/internal/catch_matchers_floating.cpp @@ -6,6 +6,7 @@ */ #include "catch_matchers_floating.h" +#include "catch_to_string.hpp" #include "catch_tostring.h" #include <cstdlib> @@ -115,7 +116,7 @@ namespace Floating { } std::string WithinUlpsMatcher::describe() const { - return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); + return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); } }// namespace Floating diff --git a/packages/Catch2/include/internal/catch_objc.hpp b/packages/Catch2/include/internal/catch_objc.hpp index b43f3352f8d08633508775ca8bed88ff81ca09db..39cbb1fa8965d40dfc98704a569154d3fd5f9418 100644 --- a/packages/Catch2/include/internal/catch_objc.hpp +++ b/packages/Catch2/include/internal/catch_objc.hpp @@ -93,7 +93,7 @@ namespace Catch { std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); const char* className = class_getName( cls ); - getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) ); + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) ); noTestMethods++; } } diff --git a/packages/Catch2/include/internal/catch_output_redirect.cpp b/packages/Catch2/include/internal/catch_output_redirect.cpp index 07d4a33c816496cfd27b2fd44ab2b5fce948df96..c43dca04870026d742dceeb0a18fef89b1fc4e1d 100644 --- a/packages/Catch2/include/internal/catch_output_redirect.cpp +++ b/packages/Catch2/include/internal/catch_output_redirect.cpp @@ -49,7 +49,7 @@ namespace Catch { -#if defined(CATCH_PLATFORM_WINDOWS) +#if defined(_MSC_VER) TempFile::TempFile() { if (tmpnam_s(m_buffer)) { throw std::runtime_error("Could not get a temp filename"); @@ -77,7 +77,7 @@ namespace Catch { std::fclose(m_file); // We manually create the file on Windows only, on Linux // it will be autodeleted -#if defined(CATCH_PLATFORM_WINDOWS) +#if defined(_MSC_VER) std::remove(m_buffer); #endif } @@ -125,7 +125,7 @@ namespace Catch { } // namespace Catch -#if defined(CATCH_PLATFORM_WINDOWS) +#if defined(_MSC_VER) #undef dup #undef dup2 #undef fileno diff --git a/packages/Catch2/include/internal/catch_string_manip.cpp b/packages/Catch2/include/internal/catch_string_manip.cpp index 8476204495a84a6107f69d9d022ed854a26924aa..904d10138ffe10ea6cd38ca1f6c1ea1331e6425d 100644 --- a/packages/Catch2/include/internal/catch_string_manip.cpp +++ b/packages/Catch2/include/internal/catch_string_manip.cpp @@ -14,6 +14,12 @@ namespace Catch { + namespace { + char toLowerCh(char c) { + return static_cast<char>( std::tolower( c ) ); + } + } + bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); } @@ -29,9 +35,6 @@ namespace Catch { bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } - char toLowerCh(char c) { - return static_cast<char>( std::tolower( c ) ); - } void toLowerInPlace( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); } diff --git a/packages/Catch2/include/internal/catch_test_case_info.cpp b/packages/Catch2/include/internal/catch_test_case_info.cpp index 461642212514addf10ebab538e2abf259abf68d3..536462d114b2ac76e2bd3be78c82390aafb225fb 100644 --- a/packages/Catch2/include/internal/catch_test_case_info.cpp +++ b/packages/Catch2/include/internal/catch_test_case_info.cpp @@ -19,31 +19,33 @@ namespace Catch { - TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, '.' ) || - tag == "!hide" ) - return TestCaseInfo::IsHidden; - else if( tag == "!throws" ) - return TestCaseInfo::Throws; - else if( tag == "!shouldfail" ) - return TestCaseInfo::ShouldFail; - else if( tag == "!mayfail" ) - return TestCaseInfo::MayFail; - else if( tag == "!nonportable" ) - return TestCaseInfo::NonPortable; - else if( tag == "!benchmark" ) - return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); - else - return TestCaseInfo::None; - } - bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) ); - } - void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { - CATCH_ENFORCE( !isReservedTag(tag), - "Tag name: [" << tag << "] is not allowed.\n" - << "Tag names starting with non alpha-numeric characters are reserved\n" - << _lineInfo ); + namespace { + TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else if( tag == "!benchmark" ) + return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); + else + return TestCaseInfo::None; + } + bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) ); + } + void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + CATCH_ENFORCE( !isReservedTag(tag), + "Tag name: [" << tag << "] is not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n" + << _lineInfo ); + } } TestCase makeTestCase( ITestInvoker* _testCase, diff --git a/packages/Catch2/include/internal/catch_timer.cpp b/packages/Catch2/include/internal/catch_timer.cpp index 6786efb04a2cfe1304440f7075a9a945ccd03c00..d52c0085c049bd09244306e09be7fe601a1b113f 100644 --- a/packages/Catch2/include/internal/catch_timer.cpp +++ b/packages/Catch2/include/internal/catch_timer.cpp @@ -18,34 +18,36 @@ namespace Catch { return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); } - auto estimateClockResolution() -> uint64_t { - uint64_t sum = 0; - static const uint64_t iterations = 1000000; + namespace { + auto estimateClockResolution() -> uint64_t { + uint64_t sum = 0; + static const uint64_t iterations = 1000000; - auto startTime = getCurrentNanosecondsSinceEpoch(); + auto startTime = getCurrentNanosecondsSinceEpoch(); - for( std::size_t i = 0; i < iterations; ++i ) { + for( std::size_t i = 0; i < iterations; ++i ) { - uint64_t ticks; - uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); - do { - ticks = getCurrentNanosecondsSinceEpoch(); - } while( ticks == baseTicks ); + uint64_t ticks; + uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); + do { + ticks = getCurrentNanosecondsSinceEpoch(); + } while( ticks == baseTicks ); - auto delta = ticks - baseTicks; - sum += delta; + auto delta = ticks - baseTicks; + sum += delta; - // If we have been calibrating for over 3 seconds -- the clock - // is terrible and we should move on. - // TBD: How to signal that the measured resolution is probably wrong? - if (ticks > startTime + 3 * nanosecondsInSecond) { - return sum / i; + // If we have been calibrating for over 3 seconds -- the clock + // is terrible and we should move on. + // TBD: How to signal that the measured resolution is probably wrong? + if (ticks > startTime + 3 * nanosecondsInSecond) { + return sum / i; + } } - } - // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers - // - and potentially do more iterations if there's a high variance. - return sum/iterations; + // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers + // - and potentially do more iterations if there's a high variance. + return sum/iterations; + } } auto getEstimatedClockResolution() -> uint64_t { static auto s_resolution = estimateClockResolution(); diff --git a/packages/Catch2/include/internal/catch_to_string.hpp b/packages/Catch2/include/internal/catch_to_string.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3e2b5879061a7fa53fe3f684b37832df888ec626 --- /dev/null +++ b/packages/Catch2/include/internal/catch_to_string.hpp @@ -0,0 +1,28 @@ +/* + * Created by Martin on 9/5/2018. + * + * 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) + */ +#ifndef TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED +#define TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED + +#include <string> + +#include "catch_compiler_capabilities.h" +#include "catch_stream.h" + +namespace Catch { + template <typename T> + std::string to_string(T const& t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif + } +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED diff --git a/packages/Catch2/include/internal/catch_tostring.cpp b/packages/Catch2/include/internal/catch_tostring.cpp index 0d0158fa677fed45366417bfe819b2079ee85cb5..ee6a815f9aa76196ed3949305fffdbb3fa965000 100644 --- a/packages/Catch2/include/internal/catch_tostring.cpp +++ b/packages/Catch2/include/internal/catch_tostring.cpp @@ -236,7 +236,6 @@ std::string ratio_string<std::nano>::symbol() { return "n"; } std::string ratio_string<std::micro>::symbol() { return "u"; } std::string ratio_string<std::milli>::symbol() { return "m"; } - } // end namespace Catch #if defined(__clang__) diff --git a/packages/Catch2/include/internal/catch_tostring.h b/packages/Catch2/include/internal/catch_tostring.h index 79e1001f63db64b0b50e4f5e1e6bd86aeeafc855..2aa06f442752e891ec651c8281f648393a3cb580 100644 --- a/packages/Catch2/include/internal/catch_tostring.h +++ b/packages/Catch2/include/internal/catch_tostring.h @@ -62,20 +62,26 @@ namespace Catch { std::string convertUnknownEnumToString( E e ); template<typename T> - typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { -#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) - (void)value; + typename std::enable_if< + !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable( T const& ) { return Detail::unprintableString; -#else - return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); -#endif } template<typename T> - typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { - return convertUnknownEnumToString( value ); + typename std::enable_if< + !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable(T const& ex) { + return ex.what(); } + template<typename T> + typename std::enable_if< + std::is_enum<T>::value + , std::string>::type convertUnstreamable( T const& value ) { + return convertUnknownEnumToString( value ); + } + #if defined(_MANAGED) //! Convert a CLR string to a utf8 std::string template<typename T> @@ -99,7 +105,9 @@ namespace Catch { typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert(const Fake& value) { ReusableStringStream rss; - rss << value; + // NB: call using the function-like syntax to avoid ambiguity with + // user-defined templated operator<< under clang. + rss.operator<<(value); return rss.str(); } @@ -107,7 +115,11 @@ namespace Catch { static typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert( const Fake& value ) { - return Detail::convertUnstreamable( value ); +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + return Detail::convertUnstreamable(value); +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif } }; diff --git a/packages/Catch2/include/internal/catch_version.cpp b/packages/Catch2/include/internal/catch_version.cpp index 561117cfb3c0fd64bebaa5518fdefa77b1d77cae..94e11e0851ec6ef6a68db8cb03cb6c86bb897017 100644 --- a/packages/Catch2/include/internal/catch_version.cpp +++ b/packages/Catch2/include/internal/catch_version.cpp @@ -37,7 +37,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 2, 2, "", 0 ); + static Version version( 2, 2, 3, "", 0 ); return version; } diff --git a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt index 6247761c153177d47bb3dfc7071883f62a73f3ac..24d9b1b792a14c184280dd16514ef6868f22f301 100644 --- a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt +++ b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt @@ -211,14 +211,21 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" (case insensitive) Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("this string contains 'ABC' as a substring") for: "this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring" Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "something else" (case insensitive) +ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" for: "This exception has overriden what() method" +== +"This exception has overriden what() method" +ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" for: "OperatorException" == "OperatorException" +ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException" for: "StringMakerException" +== +"StringMakerException" Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1} Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1} Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1} Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1} -Matchers.tests.cpp:<line number>: failed: throws(3), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1 -Matchers.tests.cpp:<line number>: failed: throws(4), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1 -Matchers.tests.cpp:<line number>: passed: throws(1), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1 -Matchers.tests.cpp:<line number>: passed: throws(2), SpecialException, ExceptionMatcher{2} for: {?} special exception has value of 2 +Matchers.tests.cpp:<line number>: failed: throws(3), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1 +Matchers.tests.cpp:<line number>: failed: throws(4), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1 +Matchers.tests.cpp:<line number>: passed: throws(1), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1 +Matchers.tests.cpp:<line number>: passed: throws(2), SpecialException, ExceptionMatcher{2} for: SpecialException::what special exception has value of 2 Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception" Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive) Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected" @@ -1058,6 +1065,9 @@ ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(item) ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( item ) == "operator<<( has_operator )" for: "operator<<( has_operator )" == "operator<<( has_operator )" +ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( item ) == "operator<<( has_template_operator )" for: "operator<<( has_template_operator )" +== +"operator<<( has_template_operator )" ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }" for: "{ StringMaker<has_maker> }" == "{ StringMaker<has_maker> }" diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt index 79e1bf89052738eb64e1e638575ccab931f6f964..1992fb9fc2ca43773f4e551132aec016ef1b0ad3 100644 --- a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt +++ b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt @@ -335,12 +335,12 @@ Matchers.tests.cpp:<line number> Matchers.tests.cpp:<line number>: FAILED: CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} ) with expansion: - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 Matchers.tests.cpp:<line number>: FAILED: REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} ) with expansion: - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 ------------------------------------------------------------------------------- Expected exceptions that don't throw or unexpected exceptions fail the test @@ -1084,6 +1084,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 206 | 153 passed | 49 failed | 4 failed as expected -assertions: 1061 | 933 passed | 107 failed | 21 failed as expected +test cases: 208 | 155 passed | 49 failed | 4 failed as expected +assertions: 1065 | 937 passed | 107 failed | 21 failed as expected diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt index 5a62613daf6b81b4892bad61a1e2e79b7c3fb702..047c7163754c18b2da9eebdea8f0b12e95674fdc 100644 --- a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt @@ -1680,6 +1680,34 @@ with expansion: "this string contains 'abc' as a substring" equals: "something else" (case insensitive) +------------------------------------------------------------------------------- +Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified +------------------------------------------------------------------------------- +ToStringGeneral.tests.cpp:<line number> +............................................................................... + +ToStringGeneral.tests.cpp:<line number>: +PASSED: + REQUIRE( ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" ) +with expansion: + "This exception has overriden what() method" + == + "This exception has overriden what() method" + +ToStringGeneral.tests.cpp:<line number>: +PASSED: + REQUIRE( ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" ) +with expansion: + "OperatorException" == "OperatorException" + +ToStringGeneral.tests.cpp:<line number>: +PASSED: + REQUIRE( ::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException" ) +with expansion: + "StringMakerException" + == + "StringMakerException" + ------------------------------------------------------------------------------- Exception matchers that fail No exception @@ -1722,12 +1750,12 @@ Matchers.tests.cpp:<line number> Matchers.tests.cpp:<line number>: FAILED: CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} ) with expansion: - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 Matchers.tests.cpp:<line number>: FAILED: REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} ) with expansion: - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 ------------------------------------------------------------------------------- Exception matchers that succeed @@ -1739,13 +1767,13 @@ Matchers.tests.cpp:<line number>: PASSED: CHECK_THROWS_MATCHES( throws(1), SpecialException, ExceptionMatcher{1} ) with expansion: - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 Matchers.tests.cpp:<line number>: PASSED: REQUIRE_THROWS_MATCHES( throws(2), SpecialException, ExceptionMatcher{2} ) with expansion: - {?} special exception has value of 2 + SpecialException::what special exception has value of 2 ------------------------------------------------------------------------------- Exception messages can be tested for @@ -8379,6 +8407,20 @@ with expansion: == "operator<<( has_operator )" +------------------------------------------------------------------------------- +stringify( has_template_operator ) +------------------------------------------------------------------------------- +ToStringWhich.tests.cpp:<line number> +............................................................................... + +ToStringWhich.tests.cpp:<line number>: +PASSED: + REQUIRE( ::Catch::Detail::stringify( item ) == "operator<<( has_template_operator )" ) +with expansion: + "operator<<( has_template_operator )" + == + "operator<<( has_template_operator )" + ------------------------------------------------------------------------------- stringify( vectors<has_maker> ) ------------------------------------------------------------------------------- @@ -8950,6 +8992,6 @@ Misc.tests.cpp:<line number>: PASSED: =============================================================================== -test cases: 206 | 140 passed | 62 failed | 4 failed as expected -assertions: 1075 | 933 passed | 121 failed | 21 failed as expected +test cases: 208 | 142 passed | 62 failed | 4 failed as expected +assertions: 1079 | 937 passed | 121 failed | 21 failed as expected diff --git a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt index 02579344e87901dd00d8e3d7c1bc967f78fdd35c..62ca9094090e9e63f1578f64beb88a31f4d7173f 100644 --- a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <testsuitesloose text artifact > - <testsuite name="<exe-name>" errors="17" failures="105" tests="1076" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> + <testsuite name="<exe-name>" errors="17" failures="105" tests="1080" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/> @@ -218,6 +218,7 @@ Matchers.tests.cpp:<line number> Matchers.tests.cpp:<line number> </failure> </testcase> + <testcase classname="<exe-name>.global" name="Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified" time="{duration}"/> <testcase classname="<exe-name>.global" name="Exception matchers that fail/No exception" time="{duration}"> <failure message="doesNotThrow(), SpecialException, ExceptionMatcher{1}" type="CHECK_THROWS_MATCHES"> Matchers.tests.cpp:<line number> @@ -237,10 +238,10 @@ Matchers.tests.cpp:<line number> </error> </testcase> <testcase classname="<exe-name>.global" name="Exception matchers that fail/Contents are wrong" time="{duration}"> - <failure message="{?} special exception has value of 1" type="CHECK_THROWS_MATCHES"> + <failure message="SpecialException::what special exception has value of 1" type="CHECK_THROWS_MATCHES"> Matchers.tests.cpp:<line number> </failure> - <failure message="{?} special exception has value of 1" type="REQUIRE_THROWS_MATCHES"> + <failure message="SpecialException::what special exception has value of 1" type="REQUIRE_THROWS_MATCHES"> Matchers.tests.cpp:<line number> </failure> </testcase> @@ -837,6 +838,7 @@ Tricky.tests.cpp:<line number> <testcase classname="<exe-name>.global" name="stringify( has_maker_and_operator )" time="{duration}"/> <testcase classname="<exe-name>.global" name="stringify( has_neither )" time="{duration}"/> <testcase classname="<exe-name>.global" name="stringify( has_operator )" time="{duration}"/> + <testcase classname="<exe-name>.global" name="stringify( has_template_operator )" time="{duration}"/> <testcase classname="<exe-name>.global" name="stringify( vectors<has_maker> )" time="{duration}"/> <testcase classname="<exe-name>.global" name="stringify( vectors<has_maker_and_operator> )" time="{duration}"/> <testcase classname="<exe-name>.global" name="stringify( vectors<has_operator> )" time="{duration}"/> diff --git a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt index 001cb0e1d18ac868eb5645194467c1574d1e7d86..5452f2fa36c8a3d3b3fc992f60531413233d6828 100644 --- a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -1901,6 +1901,37 @@ </Expression> <OverallResult success="false"/> </TestCase> + <TestCase name="Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified" tags="[exception][toString]" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" > + <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" > + <Original> + ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" + </Original> + <Expanded> + "This exception has overriden what() method" +== +"This exception has overriden what() method" + </Expanded> + </Expression> + <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" > + <Original> + ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" + </Original> + <Expanded> + "OperatorException" == "OperatorException" + </Expanded> + </Expression> + <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" > + <Original> + ::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException" + </Original> + <Expanded> + "StringMakerException" +== +"StringMakerException" + </Expanded> + </Expression> + <OverallResult success="true"/> + </TestCase> <TestCase name="Exception matchers that fail" tags="[!throws][.][.failing][exceptions][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Section name="No exception" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="false" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > @@ -1952,7 +1983,7 @@ throws(3), SpecialException, ExceptionMatcher{1} </Original> <Expanded> - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 </Expanded> </Expression> <Expression success="false" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > @@ -1960,7 +1991,7 @@ throws(4), SpecialException, ExceptionMatcher{1} </Original> <Expanded> - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 </Expanded> </Expression> <OverallResults successes="0" failures="2" expectedFailures="0"/> @@ -1973,7 +2004,7 @@ throws(1), SpecialException, ExceptionMatcher{1} </Original> <Expanded> - {?} special exception has value of 1 + SpecialException::what special exception has value of 1 </Expanded> </Expression> <Expression success="true" type="REQUIRE_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > @@ -1981,7 +2012,7 @@ throws(2), SpecialException, ExceptionMatcher{2} </Original> <Expanded> - {?} special exception has value of 2 + SpecialException::what special exception has value of 2 </Expanded> </Expression> <OverallResult success="true"/> @@ -9335,6 +9366,19 @@ loose text artifact </Expression> <OverallResult success="true"/> </TestCase> + <TestCase name="stringify( has_template_operator )" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" > + <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" > + <Original> + ::Catch::Detail::stringify( item ) == "operator<<( has_template_operator )" + </Original> + <Expanded> + "operator<<( has_template_operator )" +== +"operator<<( has_template_operator )" + </Expanded> + </Expression> + <OverallResult success="true"/> + </TestCase> <TestCase name="stringify( vectors<has_maker> )" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" > <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" > <Original> @@ -9892,7 +9936,7 @@ loose text artifact </Section> <OverallResult success="true"/> </TestCase> - <OverallResults successes="933" failures="122" expectedFailures="21"/> + <OverallResults successes="937" failures="122" expectedFailures="21"/> </Group> - <OverallResults successes="933" failures="121" expectedFailures="21"/> + <OverallResults successes="937" failures="121" expectedFailures="21"/> </Catch> diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp index 7bdc466ba08bb787b2132ce3ce2fa1b6c751f9cc..71abb8688dbeb3400e3710b621c6f3ee98d0bc97 100644 --- a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp +++ b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp @@ -45,6 +45,10 @@ namespace { namespace MatchersTests { struct SpecialException : std::exception { SpecialException(int i_) : i(i_) {} + char const* what() const noexcept override { + return "SpecialException::what"; + } + int i; }; diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp index 8ab33249e99f7c4499eb51ec2e1e2d4493b34e59..a1f8c233a25e3d386410470ed08ffff7ba05c844 100644 --- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp +++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp @@ -115,3 +115,46 @@ TEST_CASE("Static arrays are convertible to string", "[toString]") { REQUIRE(Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })"); } } + +struct WhatException : std::exception { + char const* what() const noexcept override { + return "This exception has overriden what() method"; + } + ~WhatException() override; +}; + +struct OperatorException : std::exception { + ~OperatorException() override; +}; + +std::ostream& operator<<(std::ostream& out, OperatorException const&) { + out << "OperatorException"; + return out; +} + +struct StringMakerException : std::exception { + ~StringMakerException() override; +}; + +namespace Catch { +template <> +struct StringMaker<StringMakerException> { + static std::string convert(StringMakerException const&) { + return "StringMakerException"; + } +}; +} + +// Avoid -Wweak-tables +WhatException::~WhatException() = default; +OperatorException::~OperatorException() = default; +StringMakerException::~StringMakerException() = default; + + + + +TEST_CASE("Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified", "[toString][exception]") { + REQUIRE(::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method"); + REQUIRE(::Catch::Detail::stringify(OperatorException{}) == "OperatorException"); + REQUIRE(::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException"); +} diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp index 7be99dcd42249f6ce18ee39f8a75aca0ab38c9ca..26afa3b12fcea142a72f92b217564dec21962b22 100644 --- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp +++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp @@ -20,6 +20,7 @@ struct has_operator { }; struct has_maker {}; struct has_maker_and_operator {}; struct has_neither {}; +struct has_template_operator {}; std::ostream& operator<<(std::ostream& os, const has_operator&) { os << "operator<<( has_operator )"; @@ -31,6 +32,12 @@ std::ostream& operator<<(std::ostream& os, const has_maker_and_operator&) { return os; } +template <typename StreamT> +StreamT& operator<<(StreamT& os, const has_template_operator&) { + os << "operator<<( has_template_operator )"; + return os; +} + namespace Catch { template<> struct StringMaker<has_maker> { @@ -69,6 +76,12 @@ TEST_CASE("stringify( has_neither )", "[toString]") { REQUIRE( ::Catch::Detail::stringify(item) == "{ !!! }" ); } +// Call the templated operator +TEST_CASE( "stringify( has_template_operator )", "[toString]" ) { + has_template_operator item; + REQUIRE( ::Catch::Detail::stringify( item ) == "operator<<( has_template_operator )" ); +} + // Vectors... diff --git a/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj b/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj index 91e2cd9a6836057b271c3a4683c41e2aa9598442..71532036046603eff7f7289626a164e5009a5e9b 100644 --- a/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj +++ b/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj @@ -120,7 +120,7 @@ 4A63D29C14E3C1A900F615CB /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 0940; }; buildConfigurationList = 4A63D29F14E3C1A900F615CB /* Build configuration list for PBXProject "OCTest" */; compatibilityVersion = "Xcode 3.2"; @@ -159,16 +159,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -194,16 +208,29 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; diff --git a/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /dev/null +++ b/packages/Catch2/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IDEDidComputeMac32BitWarning</key> + <true/> +</dict> +</plist> diff --git a/packages/Catch2/projects/XCode/OCTest/catch_objc_impl.mm b/packages/Catch2/projects/XCode/OCTest/catch_objc_impl.mm index 01443cc93487d80756392529fcfe1ac44d080977..e439a3ab7c50b312f9f054b9179b41cec43cf10b 100644 --- a/packages/Catch2/projects/XCode/OCTest/catch_objc_impl.mm +++ b/packages/Catch2/projects/XCode/OCTest/catch_objc_impl.mm @@ -1,6 +1,7 @@ // This file #includes all the .cpp files into a single .mm // - so they get compiled as ObjectiveC++ +#include "../../../include/internal/catch_tostring.cpp" #include "../../../include/internal/catch_approx.cpp" #include "../../../include/internal/catch_assertionhandler.cpp" #include "../../../include/internal/catch_assertionresult.cpp" @@ -29,6 +30,7 @@ #include "../../../include/internal/catch_matchers.cpp" #include "../../../include/internal/catch_matchers_string.cpp" #include "../../../include/internal/catch_message.cpp" +#include "../../../include/internal/catch_output_redirect.cpp" #include "../../../include/internal/catch_random_number_generator.cpp" #include "../../../include/internal/catch_registry_hub.cpp" #include "../../../include/internal/catch_reporter_registry.cpp" @@ -51,8 +53,8 @@ #include "../../../include/internal/catch_test_spec.cpp" #include "../../../include/internal/catch_test_spec_parser.cpp" #include "../../../include/internal/catch_timer.cpp" -#include "../../../include/internal/catch_tostring.cpp" #include "../../../include/internal/catch_totals.cpp" +#include "../../../include/internal/catch_uncaught_exceptions.cpp" #include "../../../include/internal/catch_version.cpp" #include "../../../include/internal/catch_wildcard_pattern.cpp" #include "../../../include/internal/catch_xmlwriter.cpp" @@ -63,5 +65,5 @@ #include "../../../include/reporters/catch_reporter_compact.cpp" #include "../../../include/reporters/catch_reporter_console.cpp" #include "../../../include/reporters/catch_reporter_junit.cpp" -#include "../../../include/reporters/catch_reporter_multi.cpp" +#include "../../../include/reporters/catch_reporter_listening.cpp" #include "../../../include/reporters/catch_reporter_xml.cpp" diff --git a/packages/Catch2/scripts/approvalTests.py b/packages/Catch2/scripts/approvalTests.py index ee6a8f15378545f5100725867f91e4c727053c7e..3293c938885036f7723dd95dd12a3dc2d402c931 100755 --- a/packages/Catch2/scripts/approvalTests.py +++ b/packages/Catch2/scripts/approvalTests.py @@ -12,6 +12,10 @@ import difflib import scriptCommon from scriptCommon import catchPath +if os.name == 'nt': + # Enable console colours on windows + os.system('') + rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines') @@ -87,7 +91,7 @@ def diffFiles(fileA, fileB): return [line for line in diff if line[0] in ('+', '-')] -def filterLine(line): +def filterLine(line, isCompact): if catchPath in line: # make paths relative to Catch root line = line.replace(catchPath + os.sep, '') @@ -105,6 +109,10 @@ def filterLine(line): else: line = lineNumberParser.sub(" ", line) + if isCompact: + line = line.replace(': FAILED', ': failed') + line = line.replace(': PASSED', ': passed') + # strip Catch version number line = versionParser.sub("<version>", line) @@ -144,7 +152,7 @@ def approve(baseName, args): rawFile = io.open(rawResultsPath, 'r', encoding='utf-8', errors='surrogateescape') filteredFile = io.open(filteredResultsPath, 'w', encoding='utf-8', errors='surrogateescape') for line in rawFile: - filteredFile.write(filterLine(line).rstrip() + "\n") + filteredFile.write(filterLine(line, 'compact' in baseName).rstrip() + "\n") filteredFile.close() rawFile.close() diff --git a/packages/Catch2/scripts/updateVcpkgPackage.py b/packages/Catch2/scripts/updateVcpkgPackage.py deleted file mode 100644 index c1f40b59e3abe85d41cb1bed60a5e141d421805e..0000000000000000000000000000000000000000 --- a/packages/Catch2/scripts/updateVcpkgPackage.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python - -import io, os, re, sys, subprocess -import hashlib - -from scriptCommon import catchPath -from releaseCommon import Version - -print(catchPath) - -default_path = '../vcpkg/ports/catch2/' - -def adjusted_path(path): - return os.path.join(catchPath, path) - -def get_hash(path): - BUFF_SIZE = 65536 - sha512 = hashlib.sha512() - # The newlines should be normalized into \n, which is what we want - # If reused use 'rb' with a file written with io.open(newline='\n') - with open(path, 'r') as f: - while True: - data = f.read(BUFF_SIZE) - if not data: - break - if sys.version_info[0] < 3: - sha512.update(data) - else: - sha512.update(data.encode('utf-8')) - return sha512.hexdigest() - -def update_control(path): - v = Version() - - # Update control - lines = [] - control_path = os.path.join(path, 'CONTROL') - with open(control_path, 'r') as f: - for line in f: - lines.append(line) - with open(control_path, 'w') as f: - for line in lines: - if 'Version: ' in line: - line = 'Version: {}\n'.format(v.getVersionString()) - f.write(line) - -def update_portfile(path, header_hash, licence_hash): - print('Updating portfile') - v = Version() - - # Update portfile - lines = [] - portfile_path = os.path.join(path, 'portfile.cmake') - with open(portfile_path, 'r') as f: - for line in f: - lines.append(line) - with open(portfile_path, 'w') as f: - # There are three things we need to change/update - # 1) CATCH_VERSION cmake variable - # 2) Hash of header - # 3) Hash of licence - # We could assume licence never changes, but where is the fun in that? - for line in lines: - # Update the version - if 'set(CATCH_VERSION' in line: - line = 'set(CATCH_VERSION v{})\n'.format(v.getVersionString()) - - # Determine which file we are updating - if 'vcpkg_download_distfile' in line: - kind = line.split('(')[-1].strip() - - # Update the hashes - if 'SHA512' in line and kind == 'HEADER': - line = ' SHA512 {}\n'.format(header_hash) - if 'SHA512' in line and kind == 'LICENSE': - line = ' SHA512 {}\n'.format(licence_hash) - f.write(line) - - -def git_push(path_to_repo): - v = Version() - ver_string = v.getVersionString() - - os.chdir(path_to_repo) - - # Work with git - # Make sure we branch off master - subprocess.call('git checkout master', shell=True) - - # Update repo to current master, so we don't work off old version of the portfile - subprocess.call('git pull Microsoft master', shell=True) - subprocess.call('git push', shell=True) - - # Create a new branch for the update - subprocess.call('git checkout -b catch-{}'.format(ver_string), shell=True) - # Add changed files (should be only our files) - subprocess.call('git add -u .', shell=True) - # Create a commit with these changes - subprocess.call('git commit -m "Update Catch to {}"'.format(ver_string), shell=True) - # Don't push, so author can review - print('Changes were commited to the vcpkg fork. Please check, push and open PR.') - -header_hash = get_hash(adjusted_path('single_include/catch.hpp')) -licence_hash = get_hash(adjusted_path('LICENSE.txt')) -update_control(adjusted_path(default_path)) -update_portfile(adjusted_path(default_path), header_hash, licence_hash) - -git_push(adjusted_path('../vcpkg')) diff --git a/packages/Catch2/single_include/catch.hpp b/packages/Catch2/single_include/catch.hpp index ecd8907ea30f1f2a2e0d184e7161c60a1aba80a0..28448ddb22e17f7f6a536fa8a932489447c2cfd7 100644 --- a/packages/Catch2/single_include/catch.hpp +++ b/packages/Catch2/single_include/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.2.2 - * Generated: 2018-04-06 12:05:03.186665 + * Catch v2.2.3 + * Generated: 2018-06-06 23:11:57.601416 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 2 -#define CATCH_VERSION_PATCH 2 +#define CATCH_VERSION_PATCH 3 #ifdef __clang__ # pragma clang system_header @@ -72,7 +72,7 @@ #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) # define CATCH_PLATFORM_WINDOWS #endif @@ -164,6 +164,18 @@ namespace Catch { # define CATCH_CONFIG_COLOUR_NONE #endif +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ @@ -213,7 +225,7 @@ namespace Catch { #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. @@ -225,6 +237,10 @@ namespace Catch { # define CATCH_CONFIG_WCHAR #endif +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS #endif @@ -513,12 +529,17 @@ struct AutoReg : NonCopyable { } // end namespace Catch +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF + #if defined(CATCH_CONFIG_DISABLE) #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ static void TestName() #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ namespace{ \ - struct TestName : ClassName { \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ void test(); \ }; \ } \ @@ -546,7 +567,7 @@ struct AutoReg : NonCopyable { #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ \ - struct TestName : ClassName{ \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ @@ -770,16 +791,22 @@ namespace Catch { std::string convertUnknownEnumToString( E e ); template<typename T> - typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { -#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) - (void)value; + typename std::enable_if< + !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable( T const& ) { return Detail::unprintableString; -#else - return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); -#endif } template<typename T> - typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) { + typename std::enable_if< + !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable(T const& ex) { + return ex.what(); + } + + template<typename T> + typename std::enable_if< + std::is_enum<T>::value + , std::string>::type convertUnstreamable( T const& value ) { return convertUnknownEnumToString( value ); } @@ -805,7 +832,9 @@ namespace Catch { typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert(const Fake& value) { ReusableStringStream rss; - rss << value; + // NB: call using the function-like syntax to avoid ambiguity with + // user-defined templated operator<< under clang. + rss.operator<<(value); return rss.str(); } @@ -813,7 +842,11 @@ namespace Catch { static typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert( const Fake& value ) { - return Detail::convertUnstreamable( value ); +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + return Detail::convertUnstreamable(value); +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif } }; @@ -3354,8 +3387,12 @@ namespace Catch { std::string outputFilename; std::string name; std::string processName; +#ifndef CATCH_CONFIG_DEFAULT_REPORTER +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER; +#undef CATCH_CONFIG_DEFAULT_REPORTER - std::vector<std::string> reporterNames; std::vector<std::string> testsOrTags; std::vector<std::string> sectionsToRun; }; @@ -3375,8 +3412,8 @@ namespace Catch { bool listReporters() const; std::string getProcessName() const; + std::string const& getReporterName() const; - std::vector<std::string> const& getReporterNames() const; std::vector<std::string> const& getTestsOrTags() const; std::vector<std::string> const& getSectionsToRun() const override; @@ -3733,8 +3770,6 @@ namespace Catch { virtual Listeners const& getListeners() const = 0; }; - void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ); - } // end namespace Catch // end catch_interfaces_reporter.h @@ -3742,7 +3777,7 @@ namespace Catch { #include <cstring> #include <cfloat> #include <cstdio> -#include <assert.h> +#include <cassert> #include <memory> #include <ostream> @@ -6592,7 +6627,7 @@ namespace Catch { | Opt( config.outputFilename, "filename" ) ["-o"]["--out"] ( "output filename" ) - | Opt( config.reporterNames, "name" ) + | Opt( config.reporterName, "name" ) ["-r"]["--reporter"] ( "reporter to use (defaults to console)" ) | Opt( config.name, "name" ) @@ -6734,8 +6769,8 @@ namespace Catch { bool Config::listReporters() const { return m_data.listReporters; } std::string Config::getProcessName() const { return m_data.processName; } + std::string const& Config::getReporterName() const { return m_data.reporterName; } - std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; } std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; } std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } @@ -7381,6 +7416,11 @@ 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. + constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; + static SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, @@ -7407,7 +7447,7 @@ namespace Catch { isSet = true; stack_t sigStack; sigStack.ss_sp = altStackMem; - sigStack.ss_size = SIGSTKSZ; + sigStack.ss_size = sigStackSize; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = { }; @@ -7438,7 +7478,7 @@ namespace Catch { bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + char FatalConditionHandler::altStackMem[sigStackSize] = {}; } // namespace Catch @@ -7482,16 +7522,18 @@ namespace Catch { // end catch_interfaces_registry_hub.cpp // start catch_interfaces_reporter.cpp -// start catch_reporter_multi.h +// start catch_reporter_listening.h namespace Catch { - class MultipleReporters : public IStreamingReporter { + class ListeningReporter : public IStreamingReporter { using Reporters = std::vector<IStreamingReporterPtr>; - Reporters m_reporters; + Reporters m_listeners; + IStreamingReporterPtr m_reporter = nullptr; public: - void add( IStreamingReporterPtr&& reporter ); + void addListener( IStreamingReporterPtr&& listener ); + void addReporter( IStreamingReporterPtr&& reporter ); public: // IStreamingReporter @@ -7524,7 +7566,7 @@ namespace Catch { } // end namespace Catch -// end catch_reporter_multi.h +// end catch_reporter_listening.h namespace Catch { ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) @@ -7625,27 +7667,6 @@ namespace Catch { IReporterFactory::~IReporterFactory() = default; IReporterRegistry::~IReporterRegistry() = default; - void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) { - - if( !existingReporter ) { - existingReporter = std::move( additionalReporter ); - return; - } - - MultipleReporters* multi = nullptr; - - if( existingReporter->isMulti() ) { - multi = static_cast<MultipleReporters*>( existingReporter.get() ); - } - else { - auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters ); - newMulti->add( std::move( existingReporter ) ); - multi = newMulti.get(); - existingReporter = std::move( newMulti ); - } - multi->add( std::move( additionalReporter ) ); - } - } // end namespace Catch // end catch_interfaces_reporter.cpp // start catch_interfaces_runner.cpp @@ -7887,6 +7908,24 @@ using Matchers::Impl::MatcherBase; // end catch_matchers.cpp // start catch_matchers_floating.cpp +// start catch_to_string.hpp + +#include <string> + +namespace Catch { + template <typename T> + std::string to_string(T const& t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif + } +} // end namespace Catch + +// end catch_to_string.hpp #include <cstdlib> #include <cstdint> #include <cstring> @@ -7992,7 +8031,7 @@ namespace Floating { } std::string WithinUlpsMatcher::describe() const { - return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); + return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); } }// namespace Floating @@ -8179,6 +8218,213 @@ namespace Catch { } } // end namespace Catch // end catch_message.cpp +// start catch_output_redirect.cpp + +// start catch_output_redirect.h +#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H + +#include <cstdio> +#include <iosfwd> +#include <string> + +namespace Catch { + + class RedirectedStream { + std::ostream& m_originalStream; + std::ostream& m_redirectionStream; + std::streambuf* m_prevBuf; + + public: + RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ); + ~RedirectedStream(); + }; + + class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + public: + RedirectedStdOut(); + auto str() const -> std::string; + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes + class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + public: + RedirectedStdErr(); + auto str() const -> std::string; + }; + + // Windows's implementation of std::tmpfile is terrible (it tries + // to create a file inside system folder, thus requiring elevated + // privileges for the binary), so we have to use tmpnam(_s) and + // create the file ourselves there. + class TempFile { + public: + TempFile(TempFile const&) = delete; + TempFile& operator=(TempFile const&) = delete; + TempFile(TempFile&&) = delete; + TempFile& operator=(TempFile&&) = delete; + + TempFile(); + ~TempFile(); + + std::FILE* getFile(); + std::string getContents(); + + private: + std::FILE* m_file = nullptr; + #if defined(_MSC_VER) + char m_buffer[L_tmpnam] = { 0 }; + #endif + }; + + class OutputRedirect { + public: + OutputRedirect(OutputRedirect const&) = delete; + OutputRedirect& operator=(OutputRedirect const&) = delete; + OutputRedirect(OutputRedirect&&) = delete; + OutputRedirect& operator=(OutputRedirect&&) = delete; + + OutputRedirect(std::string& stdout_dest, std::string& stderr_dest); + ~OutputRedirect(); + + private: + int m_originalStdout = -1; + int m_originalStderr = -1; + TempFile m_stdoutFile; + TempFile m_stderrFile; + std::string& m_stdoutDest; + std::string& m_stderrDest; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +// end catch_output_redirect.h +#include <cstdio> +#include <cstring> +#include <fstream> +#include <sstream> +#include <stdexcept> + +#if defined(_MSC_VER) +#include <io.h> //_dup and _dup2 +#define dup _dup +#define dup2 _dup2 +#define fileno _fileno +#else +#include <unistd.h> // dup and dup2 +#endif + +namespace Catch { + + RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) + : m_originalStream( originalStream ), + m_redirectionStream( redirectionStream ), + m_prevBuf( m_originalStream.rdbuf() ) + { + m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); + } + + RedirectedStream::~RedirectedStream() { + m_originalStream.rdbuf( m_prevBuf ); + } + + RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} + auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); } + + RedirectedStdErr::RedirectedStdErr() + : m_cerr( Catch::cerr(), m_rss.get() ), + m_clog( Catch::clog(), m_rss.get() ) + {} + auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } + +#if defined(_MSC_VER) + TempFile::TempFile() { + if (tmpnam_s(m_buffer)) { + throw std::runtime_error("Could not get a temp filename"); + } + if (fopen_s(&m_file, m_buffer, "w")) { + char buffer[100]; + if (strerror_s(buffer, errno)) { + throw std::runtime_error("Could not translate errno to string"); + } + throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer); + } + } +#else + TempFile::TempFile() { + m_file = std::tmpfile(); + if (!m_file) { + throw std::runtime_error("Could not create a temp file."); + } + } + +#endif + + TempFile::~TempFile() { + // TBD: What to do about errors here? + std::fclose(m_file); + // We manually create the file on Windows only, on Linux + // it will be autodeleted +#if defined(_MSC_VER) + std::remove(m_buffer); +#endif + } + + FILE* TempFile::getFile() { + return m_file; + } + + std::string TempFile::getContents() { + std::stringstream sstr; + char buffer[100] = {}; + std::rewind(m_file); + while (std::fgets(buffer, sizeof(buffer), m_file)) { + sstr << buffer; + } + return sstr.str(); + } + + OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) : + m_originalStdout(dup(1)), + m_originalStderr(dup(2)), + m_stdoutDest(stdout_dest), + m_stderrDest(stderr_dest) { + dup2(fileno(m_stdoutFile.getFile()), 1); + dup2(fileno(m_stderrFile.getFile()), 2); + } + + OutputRedirect::~OutputRedirect() { + Catch::cout() << std::flush; + fflush(stdout); + // Since we support overriding these streams, we flush cerr + // even though std::cerr is unbuffered + Catch::cerr() << std::flush; + Catch::clog() << std::flush; + fflush(stderr); + + dup2(m_originalStdout, 1); + dup2(m_originalStderr, 2); + + m_stdoutDest += m_stdoutFile.getContents(); + m_stderrDest += m_stderrFile.getContents(); + } + +} // namespace Catch + +#if defined(_MSC_VER) +#undef dup +#undef dup2 +#undef fileno +#endif +// end catch_output_redirect.cpp // start catch_random_number_generator.cpp // start catch_random_number_generator.h @@ -8507,47 +8753,6 @@ namespace Catch { namespace Catch { - class RedirectedStream { - std::ostream& m_originalStream; - std::ostream& m_redirectionStream; - std::streambuf* m_prevBuf; - - public: - RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) - : m_originalStream( originalStream ), - m_redirectionStream( redirectionStream ), - m_prevBuf( m_originalStream.rdbuf() ) - { - m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); - } - ~RedirectedStream() { - m_originalStream.rdbuf( m_prevBuf ); - } - }; - - class RedirectedStdOut { - ReusableStringStream m_rss; - RedirectedStream m_cout; - public: - RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} - auto str() const -> std::string { return m_rss.str(); } - }; - - // StdErr has two constituent streams in C++, std::cerr and std::clog - // This means that we need to redirect 2 streams into 1 to keep proper - // order of writes - class RedirectedStdErr { - ReusableStringStream m_rss; - RedirectedStream m_cerr; - RedirectedStream m_clog; - public: - RedirectedStdErr() - : m_cerr( Catch::cerr(), m_rss.get() ), - m_clog( Catch::clog(), m_rss.get() ) - {} - auto str() const -> std::string { return m_rss.str(); } - }; - RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) : m_runInfo(_config->name()), m_context(getCurrentMutableContext()), @@ -8794,13 +8999,19 @@ namespace Catch { Timer timer; try { if (m_reporter->getPreferences().shouldRedirectStdOut) { +#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) RedirectedStdOut redirectedStdOut; RedirectedStdErr redirectedStdErr; + timer.start(); invokeActiveTestCase(); redirectedCout += redirectedStdOut.str(); redirectedCerr += redirectedStdErr.str(); - +#else + OutputRedirect r(redirectedCout, redirectedCerr); + timer.start(); + invokeActiveTestCase(); +#endif } else { timer.start(); invokeActiveTestCase(); @@ -9094,32 +9305,25 @@ namespace Catch { return reporter; } -#ifndef CATCH_CONFIG_DEFAULT_REPORTER -#define CATCH_CONFIG_DEFAULT_REPORTER "console" -#endif - IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) { - auto const& reporterNames = config->getReporterNames(); - if (reporterNames.empty()) - return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config); - - IStreamingReporterPtr reporter; - for (auto const& name : reporterNames) - addReporter(reporter, createReporter(name, config)); - return reporter; - } + if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) { + return createReporter(config->getReporterName(), config); + } -#undef CATCH_CONFIG_DEFAULT_REPORTER + auto multi = std::unique_ptr<ListeningReporter>(new ListeningReporter); - void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) { auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); - for (auto const& listener : listeners) - addReporter(reporters, listener->create(Catch::ReporterConfig(config))); + for (auto const& listener : listeners) { + multi->addListener(listener->create(Catch::ReporterConfig(config))); + } + multi->addReporter(createReporter(config->getReporterName(), config)); + return std::move(multi); } Catch::Totals runTests(std::shared_ptr<Config> const& config) { - IStreamingReporterPtr reporter = makeReporter(config); - addListeners(reporter, config); + // FixMe: Add listeners in order first, then add reporters. + + auto reporter = makeReporter(config); RunContext context(config, std::move(reporter)); @@ -9847,7 +10051,7 @@ namespace Catch { return TestCaseInfo::None; } bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) ); } void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { CATCH_ENFORCE( !isReservedTag(tag), @@ -10085,7 +10289,7 @@ namespace Catch { // start catch_test_case_tracker.cpp #include <algorithm> -#include <assert.h> +#include <cassert> #include <stdexcept> #include <memory> #include <sstream> @@ -10913,7 +11117,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 2, 2, "", 0 ); + static Version version( 2, 2, 3, "", 0 ); return version; } @@ -11240,7 +11444,7 @@ namespace { #include <cstring> #include <cfloat> #include <cstdio> -#include <assert.h> +#include <cassert> #include <memory> namespace Catch { @@ -12183,7 +12387,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter) // end catch_reporter_console.cpp // start catch_reporter_junit.cpp -#include <assert.h> +#include <cassert> #include <sstream> #include <ctime> #include <algorithm> @@ -12416,100 +12620,133 @@ namespace Catch { } // end namespace Catch // end catch_reporter_junit.cpp -// start catch_reporter_multi.cpp +// start catch_reporter_listening.cpp + +#include <cassert> namespace Catch { - void MultipleReporters::add( IStreamingReporterPtr&& reporter ) { - m_reporters.push_back( std::move( reporter ) ); + void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { + m_listeners.push_back( std::move( listener ) ); } - ReporterPreferences MultipleReporters::getPreferences() const { - return m_reporters[0]->getPreferences(); + void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) { + assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); + m_reporter = std::move( reporter ); } - std::set<Verbosity> MultipleReporters::getSupportedVerbosities() { + ReporterPreferences ListeningReporter::getPreferences() const { + return m_reporter->getPreferences(); + } + + std::set<Verbosity> ListeningReporter::getSupportedVerbosities() { return std::set<Verbosity>{ }; } - void MultipleReporters::noMatchingTestCases( std::string const& spec ) { - for( auto const& reporter : m_reporters ) - reporter->noMatchingTestCases( spec ); + void ListeningReporter::noMatchingTestCases( std::string const& spec ) { + for ( auto const& listener : m_listeners ) { + listener->noMatchingTestCases( spec ); + } + m_reporter->noMatchingTestCases( spec ); } - void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { - for( auto const& reporter : m_reporters ) - reporter->benchmarkStarting( benchmarkInfo ); + void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkStarting( benchmarkInfo ); + } + m_reporter->benchmarkStarting( benchmarkInfo ); } - void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) { - for( auto const& reporter : m_reporters ) - reporter->benchmarkEnded( benchmarkStats ); + void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkEnded( benchmarkStats ); + } + m_reporter->benchmarkEnded( benchmarkStats ); } - void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) { - for( auto const& reporter : m_reporters ) - reporter->testRunStarting( testRunInfo ); + void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testRunStarting( testRunInfo ); + } + m_reporter->testRunStarting( testRunInfo ); } - void MultipleReporters::testGroupStarting( GroupInfo const& groupInfo ) { - for( auto const& reporter : m_reporters ) - reporter->testGroupStarting( groupInfo ); + void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupStarting( groupInfo ); + } + m_reporter->testGroupStarting( groupInfo ); } - void MultipleReporters::testCaseStarting( TestCaseInfo const& testInfo ) { - for( auto const& reporter : m_reporters ) - reporter->testCaseStarting( testInfo ); + void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseStarting( testInfo ); + } + m_reporter->testCaseStarting( testInfo ); } - void MultipleReporters::sectionStarting( SectionInfo const& sectionInfo ) { - for( auto const& reporter : m_reporters ) - reporter->sectionStarting( sectionInfo ); + void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->sectionStarting( sectionInfo ); + } + m_reporter->sectionStarting( sectionInfo ); } - void MultipleReporters::assertionStarting( AssertionInfo const& assertionInfo ) { - for( auto const& reporter : m_reporters ) - reporter->assertionStarting( assertionInfo ); + void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->assertionStarting( assertionInfo ); + } + m_reporter->assertionStarting( assertionInfo ); } // The return value indicates if the messages buffer should be cleared: - bool MultipleReporters::assertionEnded( AssertionStats const& assertionStats ) { - bool clearBuffer = false; - for( auto const& reporter : m_reporters ) - clearBuffer |= reporter->assertionEnded( assertionStats ); - return clearBuffer; + bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) { + for( auto const& listener : m_listeners ) { + static_cast<void>( listener->assertionEnded( assertionStats ) ); + } + return m_reporter->assertionEnded( assertionStats ); } - void MultipleReporters::sectionEnded( SectionStats const& sectionStats ) { - for( auto const& reporter : m_reporters ) - reporter->sectionEnded( sectionStats ); + void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) { + for ( auto const& listener : m_listeners ) { + listener->sectionEnded( sectionStats ); + } + m_reporter->sectionEnded( sectionStats ); } - void MultipleReporters::testCaseEnded( TestCaseStats const& testCaseStats ) { - for( auto const& reporter : m_reporters ) - reporter->testCaseEnded( testCaseStats ); + void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseEnded( testCaseStats ); + } + m_reporter->testCaseEnded( testCaseStats ); } - void MultipleReporters::testGroupEnded( TestGroupStats const& testGroupStats ) { - for( auto const& reporter : m_reporters ) - reporter->testGroupEnded( testGroupStats ); + void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupEnded( testGroupStats ); + } + m_reporter->testGroupEnded( testGroupStats ); } - void MultipleReporters::testRunEnded( TestRunStats const& testRunStats ) { - for( auto const& reporter : m_reporters ) - reporter->testRunEnded( testRunStats ); + void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) { + for ( auto const& listener : m_listeners ) { + listener->testRunEnded( testRunStats ); + } + m_reporter->testRunEnded( testRunStats ); } - void MultipleReporters::skipTest( TestCaseInfo const& testInfo ) { - for( auto const& reporter : m_reporters ) - reporter->skipTest( testInfo ); + void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->skipTest( testInfo ); + } + m_reporter->skipTest( testInfo ); } - bool MultipleReporters::isMulti() const { + bool ListeningReporter::isMulti() const { return true; } } // end namespace Catch -// end catch_reporter_multi.cpp +// end catch_reporter_listening.cpp // start catch_reporter_xml.cpp #if defined(_MSC_VER) diff --git a/packages/Catch2/test_package/conanfile.py b/packages/Catch2/test_package/conanfile.py index f95bfbdb45895254f638cdff691e90087af56481..7ed77b5cafa1477f80778ccff43b8ae1dcf9a010 100644 --- a/packages/Catch2/test_package/conanfile.py +++ b/packages/Catch2/test_package/conanfile.py @@ -10,7 +10,7 @@ class CatchConanTest(ConanFile): settings = "os", "compiler", "arch", "build_type" username = getenv("CONAN_USERNAME", "philsquared") channel = getenv("CONAN_CHANNEL", "testing") - requires = "Catch/2.2.2@%s/%s" % (username, channel) + requires = "Catch/2.2.3@%s/%s" % (username, channel) def build(self): cmake = CMake(self)