diff --git a/.travis.yml b/.travis.yml
index 0fe2abb1..fa40bc3e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -258,6 +258,15 @@ matrix:
addons: *gcc7
env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1
+ - os: linux
+ dist: xenial
+ compiler: clang
+ addons:
+ apt:
+ sources: *all_sources
+ packages: ['clang-5.0']
+ env: COMPILER='clang++-5.0' CPP17=1
+
- os: linux
dist: xenial
compiler: clang
@@ -276,19 +285,6 @@ matrix:
packages: ['clang-6.0', 'libstdc++-8-dev']
env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
- # 8/ Conan
- - language: python
- python:
- - "3.7"
- dist: xenial
- install:
- - pip install conan-package-tools
- env:
- - CONAN_GCC_VERSIONS=8
- - CONAN_DOCKER_IMAGE=conanio/gcc8
- script:
- - python .conan/build.py
-
install:
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
diff --git a/CMake/catch2.pc.in b/CMake/catch2.pc.in
index 3ac9fbd1..2ad128ed 100644
--- a/CMake/catch2.pc.in
+++ b/CMake/catch2.pc.in
@@ -1,4 +1,7 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+libdir=@CMAKE_INSTALL_FULL_LIBDIR@
Name: Catch2
Description: A modern, C++-native, header-only, test framework for C++11
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 05acead3..56ab7a44 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.5)
# disable testsuite in that case
if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
+else()
+ set(NOT_SUBPROJECT OFF)
endif()
# Catch2's build breaks if done in-tree. You probably should not build
@@ -14,7 +16,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.13.4)
+project(Catch2 LANGUAGES CXX VERSION 2.13.10)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
@@ -25,12 +27,12 @@ option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
option(CATCH_BUILD_TESTING "Build SelfTest project" ON)
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF)
+option(CATCH_BUILD_STATIC_LIBRARY "Builds static library from the main implementation. EXPERIMENTAL" OFF)
option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON)
-
# define some folders
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
@@ -104,15 +106,21 @@ endif()
add_library(Catch2::Catch2 ALIAS Catch2)
# Hacky support for compiling the impl into a static lib
-add_library(Catch2WithMain ${CMAKE_CURRENT_LIST_DIR}/src/catch_with_main.cpp)
-target_link_libraries(Catch2WithMain PUBLIC Catch2)
-add_library(Catch2::Catch2WithMain ALIAS Catch2WithMain)
+if (CATCH_BUILD_STATIC_LIBRARY)
+ add_library(Catch2WithMain ${CMAKE_CURRENT_LIST_DIR}/src/catch_with_main.cpp)
+ target_link_libraries(Catch2WithMain PUBLIC Catch2)
+ add_library(Catch2::Catch2WithMain ALIAS Catch2WithMain)
-# Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map
-if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8) OR
- ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10))
- target_compile_options(Catch2WithMain PRIVATE "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
-endif()
+ # Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map
+ if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8) OR
+ ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10))
+ target_compile_options(Catch2WithMain PRIVATE "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
+ endif()
+
+ if (CATCH_CONFIG_DEFAULT_REPORTER)
+ target_compile_definitions(Catch2WithMain PRIVATE CATCH_CONFIG_DEFAULT_REPORTER=${CATCH_CONFIG_DEFAULT_REPORTER})
+ endif()
+endif(CATCH_BUILD_STATIC_LIBRARY)
# Only perform the installation steps when Catch is not being used as
# a subproject via `add_subdirectory`, or the destinations will break,
@@ -128,11 +136,17 @@ if (NOT_SUBPROJECT)
${CATCH_CMAKE_CONFIG_DESTINATION}
)
+ # Workaround lack of generator expressions in install(TARGETS
+ set(InstallationTargets Catch2)
+ if (TARGET Catch2WithMain)
+ list(APPEND InstallationTargets Catch2WithMain)
+ endif()
+
# create and install an export set for catch target as Catch2::Catch
install(
TARGETS
- Catch2 Catch2WithMain
+ ${InstallationTargets}
EXPORT
Catch2Targets
DESTINATION
diff --git a/README.md b/README.md
index 0e9cf5b4..3754d3c2 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
-The latest version of the single header can be downloaded directly using this link
+The latest version of the single header can be downloaded directly using this link
## Catch2 is released!
diff --git a/contrib/CatchAddTests.cmake b/contrib/CatchAddTests.cmake
index 18286b71..184e506e 100644
--- a/contrib/CatchAddTests.cmake
+++ b/contrib/CatchAddTests.cmake
@@ -16,7 +16,10 @@ set(tests)
function(add_command NAME)
set(_args "")
- foreach(_arg ${ARGN})
+ # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments
+ math(EXPR _last_arg ${ARGC}-1)
+ foreach(_n RANGE 1 ${_last_arg})
+ set(_arg "${ARGV${_n}}")
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
else()
diff --git a/contrib/ParseAndAddCatchTests.cmake b/contrib/ParseAndAddCatchTests.cmake
index 42c68055..4771e029 100644
--- a/contrib/ParseAndAddCatchTests.cmake
+++ b/contrib/ParseAndAddCatchTests.cmake
@@ -200,7 +200,7 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
# Escape commas in the test spec
string(REPLACE "," "\\," Name ${Name})
- # Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were neccessary,
+ # Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were necessary,
# only with CMake 3.18.0 the escaped double quotes confuse the call. This change is reverted in 3.18.1
# And properly introduced in 3.19 with the CMP0110 policy
if(_cmp0110_value STREQUAL "NEW" OR ${CMAKE_VERSION} VERSION_EQUAL "3.18")
diff --git a/docs/cmake-integration.md b/docs/cmake-integration.md
index 1cab907a..075d8faa 100644
--- a/docs/cmake-integration.md
+++ b/docs/cmake-integration.md
@@ -43,7 +43,8 @@ Include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
- GIT_TAG v2.13.1)
+ GIT_TAG v2.13.9 # or a later release
+)
FetchContent_MakeAvailable(Catch2)
diff --git a/docs/contributing.md b/docs/contributing.md
index ca050bf4..f23e3a11 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -26,7 +26,7 @@ Ongoing development happens in the `v2.x` branch for Catch2 v2, and in
Commits should be small and atomic. A commit is atomic when, after it is
applied, the codebase, tests and all, still works as expected. Small
-commits are also prefered, as they make later operations with git history,
+commits are also preferred, as they make later operations with git history,
whether it is bisecting, reverting, or something else, easier.
_When submitting a pull request please do not include changes to the
diff --git a/docs/limitations.md b/docs/limitations.md
index 65483b87..b17369b3 100644
--- a/docs/limitations.md
+++ b/docs/limitations.md
@@ -104,6 +104,20 @@ Both of these solutions have their problems, but should let you wring parallelis
## 3rd party bugs
This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes).
+### Visual Studio 2015 -- `GENERATE` does not compile if it would deduce char array
+
+VS 2015 refuses to compile `GENERATE` statements that would deduce to a
+char array with known size, e.g. this:
+```cpp
+TEST_CASE("Deducing string lit") {
+ auto param = GENERATE("start", "stop");
+}
+```
+
+A workaround for this is to use the `as` helper and force deduction of
+either a `char const*` or a `std::string`.
+
+
### Visual Studio 2017 -- raw string literal in assert fails to compile
There is a known bug in Visual Studio 2017 (VC 15), that causes compilation error when preprocessor attempts to stringize a raw string literal (`#` preprocessor is applied to it). This snippet is sufficient to trigger the compilation error:
```cpp
diff --git a/docs/other-macros.md b/docs/other-macros.md
index 994115f1..a27f132d 100644
--- a/docs/other-macros.md
+++ b/docs/other-macros.md
@@ -121,7 +121,7 @@ constructor, or before Catch2's session is created in user's own main._
`ANON_TEST_CASE` is a `TEST_CASE` replacement that will autogenerate
unique name. The advantage of this is that you do not have to think
-of a name for the test case,`the disadvantage is that the name doesn't
+of a name for the test case, the disadvantage is that the name doesn't
necessarily remain stable across different links, and thus it might be
hard to run directly.
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 48f75bd0..9c4a1d2d 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,12 @@
# Release notes
**Contents**
+[2.13.10](#21310)
+[2.13.9](#2139)
+[2.13.8](#2138)
+[2.13.7](#2137)
+[2.13.6](#2136)
+[2.13.5](#2135)
[2.13.4](#2134)
[2.13.3](#2133)
[2.13.2](#2132)
@@ -45,6 +51,74 @@
[Even Older versions](#even-older-versions)
+## 2.13.10
+
+### Fixes
+* Fixed issue with `catch_discover_tests` when there is multiple of 256 tests (#2401, #2503)
+* Catch2-provided `main` and `wmain` are explicitly marked as `__cdecl` when compiled with MSVC (#2486, #2487)
+* Improved break-into-debugger behaviour for ARM Macs. It should now be possible to step execution after the break (#2422)
+* Replaced deprecated `std::aligned_storage` (#2419, #2420)
+
+
+## 2.13.9
+
+### Fixes
+* Fixed issue with `-#` (filename-as-tag) flag when `__FILE__` expands into filename without directories (#2328, #2393)
+* Fixed `CAPTURE` macro not being variadic when disabled through `CATCH_CONFIG_DISABLE` (#2316, #2378)
+
+
+## 2.13.8
+
+### Fixes
+* Made `Approx::operator()` const (#2288)
+* Improved pkg-config files (#2284)
+* Fixed warning suppression leaking out of Catch2 when compiled with clang.exe (#2280)
+* The macro-generated names for things like `TEST_CASE` no longer create reserved identifiers (#2336)
+
+### Improvements
+* Clang-tidy should no longer warn about missing virtual dispatch in `FilterGenerator`'s constructor (#2314)
+
+
+## 2.13.7
+
+### Fixes
+* Added missing `` include in benchmarking. (#2231)
+* Fixed noexcept build with benchmarking enabled (#2235)
+* Fixed build for compilers with C++17 support but without C++17 library support (#2195)
+* JUnit only uses 3 decimal places when reporting durations (#2221)
+* `!mayfail` tagged tests are now marked as `skipped` in JUnit reporter output (#2116)
+
+
+## 2.13.6
+
+### Fixes
+* Disabling all signal handlers no longer breaks compilation (#2212, #2213)
+
+### Miscellaneous
+* `catch_discover_tests` should handle escaped semicolon (`;`) better (#2214, #2215)
+
+
+## 2.13.5
+
+### Improvements
+* Detection of MAC and IPHONE platforms has been improved (#2140, #2157)
+* Added workaround for bug in XLC 16.1.0.1 (#2155)
+* Add detection for LCC when it is masquerading as GCC (#2199)
+* Modified posix signal handling so it supports newer libcs (#2178)
+ * `MINSIGSTKSZ` was no longer usable in constexpr context.
+
+### Fixes
+* Fixed compilation of benchmarking when `min` and `max` macros are defined (#2159)
+ * Including `windows.h` without `NOMINMAX` remains a really bad idea, don't do it
+
+### Miscellaneous
+* `Catch2WithMain` target (static library) is no longer built by default (#2142)
+ * Building it by default was at best unnecessary overhead for people not using it, and at worst it caused trouble with install paths
+ * To have it built, set CMake option `CATCH_BUILD_STATIC_LIBRARY` to `ON`
+* The check whether Catch2 is being built as a subproject is now more reliable (#2202, #2204)
+ * The problem was that if the variable name used internally was defined the project including Catch2 as subproject, it would not be properly overwritten for Catch2's CMake.
+
+
## 2.13.4
### Improvements
diff --git a/examples/302-Gen-Table.cpp b/examples/302-Gen-Table.cpp
index fe226dc1..14a0405e 100644
--- a/examples/302-Gen-Table.cpp
+++ b/examples/302-Gen-Table.cpp
@@ -43,7 +43,7 @@ TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][genera
/* Possible simplifications where less legacy toolchain support is needed:
*
- * - With libstdc++6 or newer, the make_tuple() calls can be ommitted
+ * - With libstdc++6 or newer, the make_tuple() calls can be omitted
* (technically C++17 but does not require -std in GCC/Clang). See
* https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list
*
diff --git a/include/catch.hpp b/include/catch.hpp
index f588eaa1..39a30171 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -11,7 +11,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 13
-#define CATCH_VERSION_PATCH 4
+#define CATCH_VERSION_PATCH 10
#ifdef __clang__
# pragma clang system_header
@@ -195,9 +195,9 @@
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#define CATCH_BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+ INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
#define CATCH_BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+ INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
@@ -301,9 +301,9 @@
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#define BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+ INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
#define BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+ INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
using Catch::Detail::Approx;
@@ -350,8 +350,8 @@ using Catch::Detail::Approx;
#define CATCH_WARN( msg ) (void)(0)
#define CATCH_CAPTURE( msg ) (void)(0)
-#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
@@ -360,7 +360,7 @@ using Catch::Detail::Approx;
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
@@ -383,8 +383,8 @@ using Catch::Detail::Approx;
#endif
// "BDD-style" convenience wrappers
-#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
#define CATCH_GIVEN( desc )
#define CATCH_AND_GIVEN( desc )
#define CATCH_WHEN( desc )
@@ -433,10 +433,10 @@ using Catch::Detail::Approx;
#define INFO( msg ) (void)(0)
#define UNSCOPED_INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
-#define CAPTURE( msg ) (void)(0)
+#define CAPTURE( ... ) (void)(0)
-#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
@@ -444,7 +444,7 @@ using Catch::Detail::Approx;
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
@@ -474,8 +474,8 @@ using Catch::Detail::Approx;
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
// "BDD-style" convenience wrappers
-#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
#define GIVEN( desc )
#define AND_GIVEN( desc )
diff --git a/include/internal/benchmark/catch_constructor.hpp b/include/internal/benchmark/catch_constructor.hpp
index 4fc04042..976a1eeb 100644
--- a/include/internal/benchmark/catch_constructor.hpp
+++ b/include/internal/benchmark/catch_constructor.hpp
@@ -19,8 +19,6 @@ namespace Catch {
template
struct ObjectStorage
{
- using TStorage = typename std::aligned_storage::value>::type;
-
ObjectStorage() : data() {}
ObjectStorage(const ObjectStorage& other)
@@ -64,7 +62,7 @@ namespace Catch {
}
- TStorage data;
+ struct { alignas(T) unsigned char data[sizeof(T)]; } data;
};
}
diff --git a/include/internal/benchmark/catch_execution_plan.hpp b/include/internal/benchmark/catch_execution_plan.hpp
index e56c83aa..4edfa60c 100644
--- a/include/internal/benchmark/catch_execution_plan.hpp
+++ b/include/internal/benchmark/catch_execution_plan.hpp
@@ -19,6 +19,7 @@
#include "detail/catch_run_for_at_least.hpp"
#include
+#include
namespace Catch {
namespace Benchmark {
diff --git a/include/internal/benchmark/detail/catch_run_for_at_least.hpp b/include/internal/benchmark/detail/catch_run_for_at_least.hpp
index 339507ba..f63d2b1f 100644
--- a/include/internal/benchmark/detail/catch_run_for_at_least.hpp
+++ b/include/internal/benchmark/detail/catch_run_for_at_least.hpp
@@ -56,7 +56,7 @@ namespace Catch {
}
iters *= 2;
}
- throw optimized_away_error{};
+ Catch::throw_exception(optimized_away_error{});
}
} // namespace Detail
} // namespace Benchmark
diff --git a/include/internal/catch_approx.h b/include/internal/catch_approx.h
index 4522e5ad..2d12efe4 100644
--- a/include/internal/catch_approx.h
+++ b/include/internal/catch_approx.h
@@ -33,7 +33,7 @@ namespace Detail {
Approx operator-() const;
template ::value>::type>
- Approx operator()( T const& value ) {
+ Approx operator()( T const& value ) const {
Approx approx( static_cast(value) );
approx.m_epsilon = m_epsilon;
approx.m_margin = m_margin;
diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h
index 93e191c2..533e3c08 100644
--- a/include/internal/catch_compiler_capabilities.h
+++ b/include/internal/catch_compiler_capabilities.h
@@ -39,9 +39,9 @@
#endif
-// We have to avoid both ICC and Clang, because they try to mask themselves
-// as gcc, and we want only GCC in this block
-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__)
+// Only GCC compiler should be used in this block, so other compilers trying to
+// mask themselves as GCC should be ignored.
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
@@ -146,10 +146,6 @@
// Visual C++
#if defined(_MSC_VER)
-# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
-# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
-
-
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
@@ -158,13 +154,18 @@
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
# endif
+# if !defined(__clang__) // Handle Clang masquerading for msvc
+
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
-# if !defined(__clang__) // Handle Clang masquerading for msvc
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
# endif // MSVC_TRADITIONAL
+
+// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
# endif // __clang__
#endif // _MSC_VER
@@ -234,7 +235,7 @@
// Check if byte is available and usable
# if __has_include() && defined(CATCH_CPP17_OR_GREATER)
# include
- # if __cpp_lib_byte > 0
+ # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
# endif
# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER)
diff --git a/include/internal/catch_console_colour.cpp b/include/internal/catch_console_colour.cpp
index de0fff43..0d2fde0e 100644
--- a/include/internal/catch_console_colour.cpp
+++ b/include/internal/catch_console_colour.cpp
@@ -121,7 +121,10 @@ namespace {
#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
-#include
+#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC )
+# define CATCH_INTERNAL_HAS_ISATTY
+# include
+#endif
namespace Catch {
namespace {
@@ -170,7 +173,8 @@ namespace {
#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
!isDebuggerActive() &&
#endif
-#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
+#if defined( CATCH_INTERNAL_HAS_ISATTY ) && \
+ !( defined( __DJGPP__ ) && defined( __STRICT_ANSI__ ) )
isatty(STDOUT_FILENO)
#else
false
diff --git a/include/internal/catch_debugger.h b/include/internal/catch_debugger.h
index a0148aa8..a5a59b3b 100644
--- a/include/internal/catch_debugger.h
+++ b/include/internal/catch_debugger.h
@@ -20,7 +20,7 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
- #define CATCH_TRAP() __asm__(".inst 0xd4200000")
+ #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
#endif
#elif defined(CATCH_PLATFORM_IPHONE)
diff --git a/include/internal/catch_default_main.hpp b/include/internal/catch_default_main.hpp
index aab5cba3..4d113d02 100644
--- a/include/internal/catch_default_main.hpp
+++ b/include/internal/catch_default_main.hpp
@@ -13,12 +13,20 @@
#ifndef __OBJC__
+#ifndef CATCH_INTERNAL_CDECL
+#ifdef _MSC_VER
+#define CATCH_INTERNAL_CDECL __cdecl
+#else
+#define CATCH_INTERNAL_CDECL
+#endif
+#endif
+
#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
-extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
+extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
// Standard C/C++ main entry point
-int main (int argc, char * argv[]) {
+int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) {
#endif
return Catch::Session().run( argc, argv );
diff --git a/include/internal/catch_enum_values_registry.cpp b/include/internal/catch_enum_values_registry.cpp
index 063f9d62..a119d152 100644
--- a/include/internal/catch_enum_values_registry.cpp
+++ b/include/internal/catch_enum_values_registry.cpp
@@ -22,7 +22,7 @@ namespace Catch {
// Extracts the actual name part of an enum instance
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
StringRef extractInstanceName(StringRef enumInstance) {
- // Find last occurence of ":"
+ // Find last occurrence of ":"
size_t name_start = enumInstance.size();
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
--name_start;
diff --git a/include/internal/catch_fatal_condition.cpp b/include/internal/catch_fatal_condition.cpp
index 1eb6bb87..873e2ed5 100644
--- a/include/internal/catch_fatal_condition.cpp
+++ b/include/internal/catch_fatal_condition.cpp
@@ -7,30 +7,72 @@
*
*/
+/** \file
+ * This file provides platform specific implementations of FatalConditionHandler
+ *
+ * This means that there is a lot of conditional compilation, and platform
+ * specific code. Currently, Catch2 supports a dummy handler (if no
+ * handler is desired), and 2 platform specific handlers:
+ * * Windows' SEH
+ * * POSIX signals
+ *
+ * Consequently, various pieces of code below are compiled if either of
+ * the platform specific handlers is enabled, or if none of them are
+ * enabled. It is assumed that both cannot be enabled at the same time,
+ * and doing so should cause a compilation error.
+ *
+ * If another platform specific handler is added, the compile guards
+ * below will need to be updated taking these assumptions into account.
+ */
+
#include "catch_fatal_condition.h"
#include "catch_context.h"
-#include "catch_interfaces_capture.h"
+#include "catch_enforce.h"
+#include "catch_run_context.h"
+#include "catch_windows_h_proxy.h"
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
+#include
+
+#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace Catch {
+
+ // If neither SEH nor signal handling is required, the handler impls
+ // do not have to do anything, and can be empty.
+ void FatalConditionHandler::engage_platform() {}
+ void FatalConditionHandler::disengage_platform() {}
+ FatalConditionHandler::FatalConditionHandler() = default;
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+} // end namespace Catch
+
+#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
+#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
+#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
namespace {
- // Report the error condition
+ //! Signals fatal error message to the run context
void reportFatal( char const * const message ) {
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
}
-}
-#endif // signals/SEH handling
+ //! Minimal size Catch2 needs for its own fatal error handling.
+ //! Picked anecdotally, so it might not be sufficient on all
+ //! platforms, and for all configurations.
+ constexpr std::size_t minStackSizeForErrors = 32 * 1024;
+} // end unnamed namespace
+
+#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
+
struct SignalDefs { DWORD id; const char* name; };
// There is no 1-1 mapping between signals and windows exceptions.
@@ -43,7 +85,7 @@ namespace Catch {
{ static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
};
- LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (auto const& def : signalDefs) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
reportFatal(def.name);
@@ -54,39 +96,52 @@ namespace Catch {
return EXCEPTION_CONTINUE_SEARCH;
}
- FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
- // 32k seems enough for Catch to handle stack overflow,
- // but the value was found experimentally, so there is no strong guarantee
- guaranteeSize = 32 * 1024;
- exceptionHandlerHandle = nullptr;
- // Register as first handler in current chain
- exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
- // Pass in guarantee size to be filled
- SetThreadStackGuarantee(&guaranteeSize);
- }
+ // Since we do not support multiple instantiations, we put these
+ // into global variables and rely on cleaning them up in outlined
+ // constructors/destructors
+ static PVOID exceptionHandlerHandle = nullptr;
- void FatalConditionHandler::reset() {
- if (isSet) {
- RemoveVectoredExceptionHandler(exceptionHandlerHandle);
- SetThreadStackGuarantee(&guaranteeSize);
- exceptionHandlerHandle = nullptr;
- isSet = false;
+
+ // For MSVC, we reserve part of the stack memory for handling
+ // memory overflow structured exception.
+ FatalConditionHandler::FatalConditionHandler() {
+ ULONG guaranteeSize = static_cast(minStackSizeForErrors);
+ if (!SetThreadStackGuarantee(&guaranteeSize)) {
+ // We do not want to fully error out, because needing
+ // the stack reserve should be rare enough anyway.
+ Catch::cerr()
+ << "Failed to reserve piece of stack."
+ << " Stack overflows will not be reported successfully.";
}
}
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
+ // We do not attempt to unset the stack guarantee, because
+ // Windows does not support lowering the stack size guarantee.
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+
+ void FatalConditionHandler::engage_platform() {
+ // Register as first handler in current chain
+ exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+ if (!exceptionHandlerHandle) {
+ CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
+ }
}
-bool FatalConditionHandler::isSet = false;
-ULONG FatalConditionHandler::guaranteeSize = 0;
-PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
+ void FatalConditionHandler::disengage_platform() {
+ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
+ CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
+ }
+ exceptionHandlerHandle = nullptr;
+ }
+} // end namespace Catch
-} // namespace Catch
+#endif // CATCH_CONFIG_WINDOWS_SEH
-#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+#if defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+#include
namespace Catch {
@@ -94,10 +149,6 @@ namespace Catch {
int id;
const char* name;
};
-
- // 32kb for the alternate stack seems to be sufficient. However, this value
- // is experimentally determined, so that's not guaranteed.
- static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
static SignalDefs signalDefs[] = {
{ SIGINT, "SIGINT - Terminal interrupt signal" },
@@ -108,8 +159,32 @@ namespace Catch {
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};
+// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
+// which is zero initialization, but not explicit. We want to avoid
+// that.
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
- void FatalConditionHandler::handleSignal( int sig ) {
+ static char* altStackMem = nullptr;
+ static std::size_t altStackSize = 0;
+ static stack_t oldSigStack{};
+ static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
+
+ static void restorePreviousSignalHandlers() {
+ // We set signal handlers back to the previous ones. Hopefully
+ // nobody overwrote them in the meantime, and doesn't expect
+ // their signal handlers to live past ours given that they
+ // installed them after ours..
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+ sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+ }
+ // Return the old stack
+ sigaltstack(&oldSigStack, nullptr);
+ }
+
+ static void handleSignal( int sig ) {
char const * name = "";
for (auto const& def : signalDefs) {
if (sig == def.id) {
@@ -117,16 +192,33 @@ namespace Catch {
break;
}
}
- reset();
- reportFatal(name);
+ // We need to restore previous signal handlers and let them do
+ // their thing, so that the users can have the debugger break
+ // when a signal is raised, and so on.
+ restorePreviousSignalHandlers();
+ reportFatal( name );
raise( sig );
}
FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
+ assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
+ if (altStackSize == 0) {
+ altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors);
+ }
+ altStackMem = new char[altStackSize]();
+ }
+
+ FatalConditionHandler::~FatalConditionHandler() {
+ delete[] altStackMem;
+ // We signal that another instance can be constructed by zeroing
+ // out the pointer.
+ altStackMem = nullptr;
+ }
+
+ void FatalConditionHandler::engage_platform() {
stack_t sigStack;
sigStack.ss_sp = altStackMem;
- sigStack.ss_size = sigStackSize;
+ sigStack.ss_size = altStackSize;
sigStack.ss_flags = 0;
sigaltstack(&sigStack, &oldSigStack);
struct sigaction sa = { };
@@ -138,39 +230,15 @@ namespace Catch {
}
}
-
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
-
- void FatalConditionHandler::reset() {
- if( isSet ) {
- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
- sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
- }
- // Return the old stack
- sigaltstack(&oldSigStack, nullptr);
- isSet = false;
- }
- }
-
- bool FatalConditionHandler::isSet = false;
- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
- stack_t FatalConditionHandler::oldSigStack = {};
- char FatalConditionHandler::altStackMem[sigStackSize] = {};
-
-
-} // namespace Catch
-
-#else
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-#endif // signals/SEH handling
-
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
+
+
+ void FatalConditionHandler::disengage_platform() {
+ restorePreviousSignalHandlers();
+ }
+
+} // end namespace Catch
+
+#endif // CATCH_CONFIG_POSIX_SIGNALS
diff --git a/include/internal/catch_fatal_condition.h b/include/internal/catch_fatal_condition.h
index a64fa628..b5744f8f 100644
--- a/include/internal/catch_fatal_condition.h
+++ b/include/internal/catch_fatal_condition.h
@@ -11,59 +11,58 @@
#include "catch_platform.h"
#include "catch_compiler_capabilities.h"
-#include "catch_windows_h_proxy.h"
-
-#if defined( CATCH_CONFIG_WINDOWS_SEH )
+#include
namespace Catch {
- struct FatalConditionHandler {
-
- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
- FatalConditionHandler();
- static void reset();
- ~FatalConditionHandler();
-
- private:
- static bool isSet;
- static ULONG guaranteeSize;
- static PVOID exceptionHandlerHandle;
- };
-
-} // namespace Catch
-
-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
-
-#include
-
-namespace Catch {
-
- struct FatalConditionHandler {
-
- static bool isSet;
- static struct sigaction oldSigActions[];
- static stack_t oldSigStack;
- static char altStackMem[];
-
- static void handleSignal( int sig );
+ // Wrapper for platform-specific fatal error (signals/SEH) handlers
+ //
+ // Tries to be cooperative with other handlers, and not step over
+ // other handlers. This means that unknown structured exceptions
+ // are passed on, previous signal handlers are called, and so on.
+ //
+ // Can only be instantiated once, and assumes that once a signal
+ // is caught, the binary will end up terminating. Thus, there
+ class FatalConditionHandler {
+ bool m_started = false;
+ // Install/disengage implementation for specific platform.
+ // Should be if-defed to work on current platform, can assume
+ // engage-disengage 1:1 pairing.
+ void engage_platform();
+ void disengage_platform();
+ public:
+ // Should also have platform-specific implementations as needed
FatalConditionHandler();
~FatalConditionHandler();
- static void reset();
+
+ void engage() {
+ assert(!m_started && "Handler cannot be installed twice.");
+ m_started = true;
+ engage_platform();
+ }
+
+ void disengage() {
+ assert(m_started && "Handler cannot be uninstalled without being installed first");
+ m_started = false;
+ disengage_platform();
+ }
};
-} // namespace Catch
-
-
-#else
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
+ //! Simple RAII guard for (dis)engaging the FatalConditionHandler
+ class FatalConditionHandlerGuard {
+ FatalConditionHandler* m_handler;
+ public:
+ FatalConditionHandlerGuard(FatalConditionHandler* handler):
+ m_handler(handler) {
+ m_handler->engage();
+ }
+ ~FatalConditionHandlerGuard() {
+ m_handler->disengage();
+ }
};
-}
-#endif
+} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
diff --git a/include/internal/catch_generators_generic.hpp b/include/internal/catch_generators_generic.hpp
index c3410147..b2a0af5e 100644
--- a/include/internal/catch_generators_generic.hpp
+++ b/include/internal/catch_generators_generic.hpp
@@ -63,7 +63,7 @@ namespace Generators {
if (!m_predicate(m_generator.get())) {
// It might happen that there are no values that pass the
// filter. In that case we throw an exception.
- auto has_initial_value = next();
+ auto has_initial_value = nextImpl();
if (!has_initial_value) {
Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
}
@@ -75,6 +75,11 @@ namespace Generators {
}
bool next() override {
+ return nextImpl();
+ }
+
+ private:
+ bool nextImpl() {
bool success = m_generator.next();
if (!success) {
return false;
diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h
index 751ef2c2..eea0df10 100644
--- a/include/internal/catch_interfaces_reporter.h
+++ b/include/internal/catch_interfaces_reporter.h
@@ -21,6 +21,8 @@
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#include "benchmark/catch_estimate.hpp"
#include "benchmark/catch_outlier_classification.hpp"
+
+#include
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
diff --git a/include/internal/catch_run_context.cpp b/include/internal/catch_run_context.cpp
index fa1b2f6f..de38e285 100644
--- a/include/internal/catch_run_context.cpp
+++ b/include/internal/catch_run_context.cpp
@@ -452,9 +452,8 @@ namespace Catch {
}
void RunContext::invokeActiveTestCase() {
- FatalConditionHandler fatalConditionHandler; // Handle signals
+ FatalConditionHandlerGuard _(&m_fatalConditionhandler);
m_activeTestCase->invoke();
- fatalConditionHandler.reset();
}
void RunContext::handleUnfinishedSections() {
diff --git a/include/internal/catch_run_context.h b/include/internal/catch_run_context.h
index 044bdd81..2f3adbda 100644
--- a/include/internal/catch_run_context.h
+++ b/include/internal/catch_run_context.h
@@ -146,6 +146,7 @@ namespace Catch {
std::vector m_unfinishedSections;
std::vector m_activeSections;
TrackerContext m_trackerContext;
+ FatalConditionHandler m_fatalConditionhandler;
bool m_lastAssertionPassed = false;
bool m_shouldReportUnexpected = true;
bool m_includeSuccessfulResults;
diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp
index 24ebe4de..6247fa7d 100644
--- a/include/internal/catch_session.cpp
+++ b/include/internal/catch_session.cpp
@@ -127,6 +127,10 @@ namespace Catch {
filename.erase(0, lastSlash);
filename[0] = '#';
}
+ else
+ {
+ filename.insert(0, "#");
+ }
auto lastDot = filename.find_last_of('.');
if (lastDot != std::string::npos) {
@@ -289,7 +293,7 @@ namespace Catch {
// Handle list request
if( Option listed = list( m_config ) )
- return static_cast( *listed );
+ return (std::min) (MaxExitCode, static_cast(*listed));
TestGroup tests { m_config };
auto const totals = tests.execute();
diff --git a/include/internal/catch_test_registry.h b/include/internal/catch_test_registry.h
index d28309e2..55b49e4c 100644
--- a/include/internal/catch_test_registry.h
+++ b/include/internal/catch_test_registry.h
@@ -71,34 +71,34 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#endif
@@ -111,7 +111,7 @@ struct AutoReg : NonCopyable {
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
@@ -133,7 +133,7 @@ struct AutoReg : NonCopyable {
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
@@ -174,18 +174,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
@@ -223,18 +223,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
@@ -265,7 +265,7 @@ struct AutoReg : NonCopyable {
static void TestFunc()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
@@ -299,18 +299,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
@@ -351,18 +351,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
@@ -396,7 +396,7 @@ struct AutoReg : NonCopyable {
void TestName::test()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index c9864434..e1744727 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 13, 4, "", 0 );
+ static Version version( 2, 13, 10, "", 0 );
return version;
}
diff --git a/include/reporters/catch_reporter_junit.cpp b/include/reporters/catch_reporter_junit.cpp
index 31f0802f..ceb941be 100644
--- a/include/reporters/catch_reporter_junit.cpp
+++ b/include/reporters/catch_reporter_junit.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
namespace Catch {
@@ -45,7 +46,7 @@ namespace Catch {
#else
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
- return std::string(timeStamp);
+ return std::string(timeStamp, timeStampSize-1);
}
std::string fileNameTag(const std::vector &tags) {
@@ -56,6 +57,17 @@ namespace Catch {
return it->substr(1);
return std::string();
}
+
+ // Formats the duration in seconds to 3 decimal places.
+ // This is done because some genius defined Maven Surefire schema
+ // in a way that only accepts 3 decimal places, and tools like
+ // Jenkins use that schema for validation JUnit reporter output.
+ std::string formatDuration( double seconds ) {
+ ReusableStringStream rss;
+ rss << std::fixed << std::setprecision( 3 ) << seconds;
+ return rss.str();
+ }
+
} // anonymous namespace
JunitReporter::JunitReporter( ReporterConfig const& _config )
@@ -125,7 +137,7 @@ namespace Catch {
if( m_config->showDurations() == ShowDurations::Never )
xml.writeAttribute( "time", "" );
else
- xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "time", formatDuration( suiteTime ) );
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
// Write properties if there are any
@@ -170,12 +182,13 @@ namespace Catch {
if ( !m_config->name().empty() )
className = m_config->name() + "." + className;
- writeSection( className, "", rootSection );
+ writeSection( className, "", rootSection, stats.testInfo.okToFail() );
}
- void JunitReporter::writeSection( std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode ) {
+ void JunitReporter::writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode,
+ bool testOkToFail) {
std::string name = trim( sectionNode.stats.sectionInfo.name );
if( !rootName.empty() )
name = rootName + '/' + name;
@@ -192,15 +205,21 @@ namespace Catch {
xml.writeAttribute( "classname", className );
xml.writeAttribute( "name", name );
}
- xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
+ xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) );
// This is not ideal, but it should be enough to mimic gtest's
// junit output.
// Ideally the JUnit reporter would also handle `skipTest`
// events and write those out appropriately.
xml.writeAttribute( "status", "run" );
+ if (sectionNode.stats.assertions.failedButOk) {
+ xml.scopedElement("skipped")
+ .writeAttribute("message", "TEST_CASE tagged with !mayfail");
+ }
+
writeAssertions( sectionNode );
+
if( !sectionNode.stdOut.empty() )
xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
if( !sectionNode.stdErr.empty() )
@@ -208,9 +227,9 @@ namespace Catch {
}
for( auto const& childNode : sectionNode.childSections )
if( className.empty() )
- writeSection( name, "", *childNode );
+ writeSection( name, "", *childNode, testOkToFail );
else
- writeSection( className, name, *childNode );
+ writeSection( className, name, *childNode, testOkToFail );
}
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
diff --git a/include/reporters/catch_reporter_junit.h b/include/reporters/catch_reporter_junit.h
index 5ee3a570..da5b5721 100644
--- a/include/reporters/catch_reporter_junit.h
+++ b/include/reporters/catch_reporter_junit.h
@@ -41,9 +41,10 @@ namespace Catch {
void writeTestCase(TestCaseNode const& testCaseNode);
- void writeSection(std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode);
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode,
+ bool testOkToFail );
void writeAssertions(SectionNode const& sectionNode);
void writeAssertion(AssertionStats const& stats);
diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt
index aee85974..5de0713c 100644
--- a/projects/CMakeLists.txt
+++ b/projects/CMakeLists.txt
@@ -354,7 +354,7 @@ endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
if (CATCH_ENABLE_WERROR)
- target_compile_options( SelfTest PRIVATE -Werror )
+ target_compile_options( SelfTest PRIVATE -Werror -Wno-error=pragmas )
endif()
endif()
# Clang specific options go here
diff --git a/projects/ExtraTests/X01-PrefixedMacros.cpp b/projects/ExtraTests/X01-PrefixedMacros.cpp
index 3d2ab9c1..4a4d4293 100644
--- a/projects/ExtraTests/X01-PrefixedMacros.cpp
+++ b/projects/ExtraTests/X01-PrefixedMacros.cpp
@@ -53,6 +53,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
CATCH_SECTION("some section") {
int i = 1;
CATCH_CAPTURE( i );
+ CATCH_CAPTURE( i, i + 1 );
CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
CATCH_FAIL_CHECK( "failure" );
}
diff --git a/projects/ExtraTests/X02-DisabledMacros.cpp b/projects/ExtraTests/X02-DisabledMacros.cpp
index 3a969d76..2669145d 100644
--- a/projects/ExtraTests/X02-DisabledMacros.cpp
+++ b/projects/ExtraTests/X02-DisabledMacros.cpp
@@ -26,6 +26,10 @@ foo f;
// This test should not be run, because it won't be registered
TEST_CASE( "Disabled Macros" ) {
+
+ CAPTURE( 1 );
+ CAPTURE( 1, "captured" );
+
std::cout << "This should not happen\n";
FAIL();
}
diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt
index efefa833..d66cb98e 100644
--- a/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -628,6 +628,7 @@ GeneratorsImpl.tests.cpp:: passed: gen.next() for: true
GeneratorsImpl.tests.cpp:: passed: gen.get() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:: passed: filter([] (int) { return false; }, value(1)), Catch::GeneratorException
+GeneratorsImpl.tests.cpp:: passed: filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
GeneratorsImpl.tests.cpp:: passed: gen.get() == 1 for: 1 == 1
GeneratorsImpl.tests.cpp:: passed: gen.next() for: true
GeneratorsImpl.tests.cpp:: passed: gen.get() == 2 for: 2 == 2
@@ -846,6 +847,10 @@ Matchers.tests.cpp:: passed: testStringForMatching(), (Contains("st
Matchers.tests.cpp:: failed: testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random") for: "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )
Matchers.tests.cpp:: passed: testStringForMatching(), !Contains("different") for: "this string contains 'abc' as a substring" not contains: "different"
Matchers.tests.cpp:: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring"
+Condition.tests.cpp:: failed: explicitly
+Condition.tests.cpp:: failed: explicitly
+Condition.tests.cpp:: failed: explicitly
+Condition.tests.cpp:: failed: explicitly
Exception.tests.cpp:: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
Exception.tests.cpp:: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail"
Generators.tests.cpp:: passed: values > -6 for: 3 > -6
diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt
index cfcdc72e..c29715f0 100644
--- a/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/projects/SelfTest/Baselines/console.std.approved.txt
@@ -694,6 +694,46 @@ Matchers.tests.cpp:: FAILED:
with expansion:
"this string contains 'abc' as a substring" not contains: "substring"
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ A
+ 1
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ A
+ 2
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ B
+ 1
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ B
+ 2
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
-------------------------------------------------------------------------------
Mismatching exception messages failing the test
-------------------------------------------------------------------------------
@@ -1380,6 +1420,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
-test cases: 322 | 248 passed | 70 failed | 4 failed as expected
-assertions: 1759 | 1607 passed | 131 failed | 21 failed as expected
+test cases: 323 | 248 passed | 70 failed | 5 failed as expected
+assertions: 1764 | 1608 passed | 131 failed | 25 failed as expected
diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt
index 3c09bf31..2318ebea 100644
--- a/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -4968,6 +4968,9 @@ with expansion:
GeneratorsImpl.tests.cpp:: PASSED:
REQUIRE_THROWS_AS( filter([] (int) { return false; }, value(1)), Catch::GeneratorException )
+GeneratorsImpl.tests.cpp:: PASSED:
+ REQUIRE_THROWS_AS( filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException )
+
-------------------------------------------------------------------------------
Generators internals
Take generator
@@ -6492,6 +6495,46 @@ Matchers.tests.cpp:: FAILED:
with expansion:
"this string contains 'abc' as a substring" not contains: "substring"
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ A
+ 1
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ A
+ 2
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ B
+ 1
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
+-------------------------------------------------------------------------------
+Mayfail test case with nested sections
+ B
+ 2
+-------------------------------------------------------------------------------
+Condition.tests.cpp:
+...............................................................................
+
+Condition.tests.cpp:: FAILED:
+
-------------------------------------------------------------------------------
Mismatching exception messages failing the test
-------------------------------------------------------------------------------
@@ -14138,6 +14181,6 @@ Misc.tests.cpp:
Misc.tests.cpp:: PASSED:
===============================================================================
-test cases: 322 | 232 passed | 86 failed | 4 failed as expected
-assertions: 1776 | 1607 passed | 148 failed | 21 failed as expected
+test cases: 323 | 232 passed | 86 failed | 5 failed as expected
+assertions: 1781 | 1608 passed | 148 failed | 25 failed as expected
diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt
index 89a0b438..e2a504f5 100644
--- a/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
-
+
@@ -48,6 +48,7 @@ Nor would this
+
FAILED:
expected exception
@@ -56,6 +57,7 @@ Exception.tests.cpp:
+
FAILED:
REQUIRE_NOTHROW( thisThrows() )
@@ -68,6 +70,7 @@ Exception.tests.cpp:
+
FAILED:
CHECK( f() == 0 )
@@ -443,6 +446,7 @@ Matchers.tests.cpp:
+
FAILED:
CHECK( data.int_seven == 6 )
@@ -736,6 +740,7 @@ Message.tests.cpp:
+
FAILED:
CHECK( data.int_seven != 7 )
@@ -799,6 +804,34 @@ with expansion:
Matchers.tests.cpp:
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
FAILED:
diff --git a/projects/SelfTest/Baselines/sonarqube.sw.approved.txt b/projects/SelfTest/Baselines/sonarqube.sw.approved.txt
index 12a4e5be..1b4248d3 100644
--- a/projects/SelfTest/Baselines/sonarqube.sw.approved.txt
+++ b/projects/SelfTest/Baselines/sonarqube.sw.approved.txt
@@ -575,6 +575,30 @@ Condition.tests.cpp:
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
+
+
+FAILED:
+Condition.tests.cpp:
+
+
FAILED:
diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt
index 2b5da8d3..30856484 100644
--- a/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -5720,7 +5720,15 @@ Nor would this
filter([] (int) { return false; }, value(1)), Catch::GeneratorException
-
+
+
+ filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
+
+
+ filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
+
+
+
@@ -7956,6 +7964,43 @@ Nor would this
+
+
+
+
+
+
+
+
+
@@ -16722,9 +16767,9 @@ loose text artifact
-
-
+
+
-
-
+
+
diff --git a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
index 549f3559..1ff3c2fa 100644
--- a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
+++ b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
@@ -53,6 +53,9 @@ TEST_CASE("Generators internals", "[generators][internals]") {
// Completely filtered-out generator should throw on construction
REQUIRE_THROWS_AS(filter([] (int) { return false; }, value(1)), Catch::GeneratorException);
+ REQUIRE_THROWS_AS(
+ filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ),
+ Catch::GeneratorException );
}
SECTION("Take generator") {
SECTION("Take less") {
diff --git a/projects/SelfTest/UsageTests/Approx.tests.cpp b/projects/SelfTest/UsageTests/Approx.tests.cpp
index 4029223a..6280599e 100644
--- a/projects/SelfTest/UsageTests/Approx.tests.cpp
+++ b/projects/SelfTest/UsageTests/Approx.tests.cpp
@@ -212,4 +212,11 @@ TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
}
+TEST_CASE("Approx::operator() is const correct", "[Approx][.approvals]") {
+ const Approx ap = Approx(0.0).margin(0.01);
+
+ // As long as this compiles, the test should be considered passing
+ REQUIRE(1.0 == ap(1.0));
+}
+
}} // namespace ApproxTests
diff --git a/projects/SelfTest/UsageTests/Condition.tests.cpp b/projects/SelfTest/UsageTests/Condition.tests.cpp
index 9aed5e2c..fa533095 100644
--- a/projects/SelfTest/UsageTests/Condition.tests.cpp
+++ b/projects/SelfTest/UsageTests/Condition.tests.cpp
@@ -11,7 +11,7 @@
// Wdouble-promotion is not supported until 3.8
# if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7)
# pragma clang diagnostic ignored "-Wdouble-promotion"
-# endif
+# endif
#endif
#include "catch.hpp"
@@ -89,6 +89,19 @@ TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
CHECK( x == Approx( 1.301 ) );
}
+// Needed to test junit reporter's handling of mayfail test cases and sections
+TEST_CASE("Mayfail test case with nested sections", "[!mayfail]") {
+ SECTION("A") {
+ SECTION("1") { FAIL(); }
+ SECTION("2") { FAIL(); }
+ }
+ SECTION("B") {
+ SECTION("1") { FAIL(); }
+ SECTION("2") { FAIL(); }
+ }
+}
+
+
TEST_CASE( "Inequality checks that should succeed" )
{
TestData data;
diff --git a/projects/SelfTest/UsageTests/Generators.tests.cpp b/projects/SelfTest/UsageTests/Generators.tests.cpp
index f2906dbf..10c87707 100644
--- a/projects/SelfTest/UsageTests/Generators.tests.cpp
+++ b/projects/SelfTest/UsageTests/Generators.tests.cpp
@@ -58,12 +58,12 @@ TEST_CASE("tables", "[generators]") {
// Structured bindings make the table utility much nicer to use
TEST_CASE( "strlen2", "[approvals][generators]" ) {
- auto [test_input, expected] = GENERATE( table({
- {"one", 3},
- {"two", 3},
- {"three", 5},
- {"four", 4}
- }));
+ using tuple_type = std::tuple; // see above workaround
+ auto [test_input, expected] =
+ GENERATE( table( { tuple_type{ "one", 3 },
+ tuple_type{ "two", 3 },
+ tuple_type{ "three", 5 },
+ tuple_type{ "four", 4 } } ) );
REQUIRE( test_input.size() == expected );
}
@@ -99,11 +99,9 @@ TEST_CASE( "strlen3", "[generators]" ) {
static auto eatCucumbers( int start, int eat ) -> int { return start-eat; }
SCENARIO("Eating cucumbers", "[generators][approvals]") {
-
- auto [start, eat, left] = GENERATE( table ({
- { 12, 5, 7 },
- { 20, 5, 15 }
- }));
+ using tuple_type = std::tuple;
+ auto [start, eat, left] = GENERATE( table(
+ { tuple_type{ 12, 5, 7 }, tuple_type{ 20, 5, 15 } } ) );
GIVEN( "there are " << start << " cucumbers" )
WHEN( "I eat " << eat << " cucumbers" )
diff --git a/projects/SelfTest/UsageTests/Matchers.tests.cpp b/projects/SelfTest/UsageTests/Matchers.tests.cpp
index 1797d4a1..3fc64b96 100644
--- a/projects/SelfTest/UsageTests/Matchers.tests.cpp
+++ b/projects/SelfTest/UsageTests/Matchers.tests.cpp
@@ -242,12 +242,14 @@ namespace { namespace MatchersTests {
~CustomAllocator() = default;
+#if defined(_MSC_VER) && _MSVC_LANG < 201703L
using std::allocator::address;
- using std::allocator::allocate;
using std::allocator::construct;
- using std::allocator::deallocate;
using std::allocator::max_size;
using std::allocator::destroy;
+#endif
+ using std::allocator::allocate;
+ using std::allocator::deallocate;
};
TEST_CASE("Vector matchers", "[matchers][vector]") {
diff --git a/projects/SelfTest/UsageTests/Message.tests.cpp b/projects/SelfTest/UsageTests/Message.tests.cpp
index 93347084..e2bd486f 100644
--- a/projects/SelfTest/UsageTests/Message.tests.cpp
+++ b/projects/SelfTest/UsageTests/Message.tests.cpp
@@ -241,6 +241,19 @@ std::ostream& operator<<(std::ostream& out, helper_1436 const& helper) {
return out;
}
+// clang can handle GCC's diagnostic pragma
+#if defined( __GNUG__ ) || defined(__clang__)
+# pragma GCC diagnostic push
+#endif
+// Clang and gcc have different names for this warning, and clang also
+// warns about an unused value
+#if defined( __GNUG__ ) && !defined( __clang__ ) && \
+ ( __GNUG__ > 10 || ( __GNUG__ == 10 && __GNUC_MINOR__ >= 1 ) )
+#pragma GCC diagnostic ignored "-Wcomma-subscript"
+#elif defined(__clang__)
+#pragma clang diagnostic ignored "-Wdeprecated-comma-subscript"
+#pragma clang diagnostic ignored "-Wunused-value"
+#endif
TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") {
CAPTURE(std::vector{1, 2, 3}[0, 1, 2],
std::vector{1, 2, 3}[(0, 1)],
@@ -250,6 +263,9 @@ TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messag
CAPTURE( (1, 2), (2, 3) );
SUCCEED();
}
+#if defined( __GNUG__ ) || defined(__clang__)
+# pragma GCC diagnostic pop
+#endif
TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
diff --git a/scripts/approvalTests.py b/scripts/approvalTests.py
index 838a1a78..9b781911 100755
--- a/scripts/approvalTests.py
+++ b/scripts/approvalTests.py
@@ -28,7 +28,10 @@ filelocParser = re.compile(r'''
''', re.VERBOSE)
lineNumberParser = re.compile(r' line="[0-9]*"')
hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b')
-durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"')
+# Note: junit must serialize time with 3 (or or less) decimal places
+# before generalizing this parser, make sure that this is checked
+# in other places too.
+junitDurationsParser = re.compile(r' time="[0-9]*\.[0-9]{3}"')
sonarqubeDurationParser = re.compile(r' duration="[0-9]+"')
timestampsParser = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z')
versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?')
@@ -138,7 +141,7 @@ def filterLine(line, isCompact):
line = hexParser.sub("0x", line)
# strip durations and timestamps
- line = durationsParser.sub(' time="{duration}"', line)
+ line = junitDurationsParser.sub(' time="{duration}"', line)
line = sonarqubeDurationParser.sub(' duration="{duration}"', line)
line = timestampsParser.sub('{iso8601-timestamp}', line)
line = specialCaseParser.sub('file:\g<1>', line)
diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp
index 0384171a..9b309bdd 100644
--- a/single_include/catch2/catch.hpp
+++ b/single_include/catch2/catch.hpp
@@ -1,9 +1,9 @@
/*
- * Catch v2.13.4
- * Generated: 2020-12-29 14:48:00.116107
+ * Catch v2.13.10
+ * Generated: 2022-10-16 11:01:23.452308
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
+ * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 13
-#define CATCH_VERSION_PATCH 4
+#define CATCH_VERSION_PATCH 10
#ifdef __clang__
# pragma clang system_header
@@ -66,13 +66,16 @@
#if !defined(CATCH_CONFIG_IMPL_ONLY)
// start catch_platform.h
+// See e.g.:
+// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
#ifdef __APPLE__
-# include
-# if TARGET_OS_OSX == 1
-# define CATCH_PLATFORM_MAC
-# elif TARGET_OS_IPHONE == 1
-# define CATCH_PLATFORM_IPHONE
-# endif
+# include
+# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
+ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
+# define CATCH_PLATFORM_MAC
+# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
+# define CATCH_PLATFORM_IPHONE
+# endif
#elif defined(linux) || defined(__linux) || defined(__linux__)
# define CATCH_PLATFORM_LINUX
@@ -132,9 +135,9 @@ namespace Catch {
#endif
-// We have to avoid both ICC and Clang, because they try to mask themselves
-// as gcc, and we want only GCC in this block
-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__)
+// Only GCC compiler should be used in this block, so other compilers trying to
+// mask themselves as GCC should be ignored.
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
@@ -237,9 +240,6 @@ namespace Catch {
// Visual C++
#if defined(_MSC_VER)
-# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
-# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
-
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
@@ -248,13 +248,18 @@ namespace Catch {
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
# endif
+# if !defined(__clang__) // Handle Clang masquerading for msvc
+
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
-# if !defined(__clang__) // Handle Clang masquerading for msvc
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
# endif // MSVC_TRADITIONAL
+
+// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
# endif // __clang__
#endif // _MSC_VER
@@ -323,7 +328,7 @@ namespace Catch {
// Check if byte is available and usable
# if __has_include() && defined(CATCH_CPP17_OR_GREATER)
# include
- # if __cpp_lib_byte > 0
+ # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
# endif
# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER)
@@ -1007,34 +1012,34 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#endif
@@ -1047,7 +1052,7 @@ struct AutoReg : NonCopyable {
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
@@ -1069,7 +1074,7 @@ struct AutoReg : NonCopyable {
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
@@ -1110,18 +1115,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
@@ -1159,18 +1164,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
@@ -1201,7 +1206,7 @@ struct AutoReg : NonCopyable {
static void TestFunc()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
@@ -1234,18 +1239,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
@@ -1286,18 +1291,18 @@ struct AutoReg : NonCopyable {
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+ INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
- INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
+ INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
@@ -1331,7 +1336,7 @@ struct AutoReg : NonCopyable {
void TestName::test()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
- INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
+ INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )
// end catch_test_registry.h
// start catch_capture.hpp
@@ -3088,7 +3093,7 @@ namespace Detail {
Approx operator-() const;
template ::value>::type>
- Approx operator()( T const& value ) {
+ Approx operator()( T const& value ) const {
Approx approx( static_cast(value) );
approx.m_epsilon = m_epsilon;
approx.m_margin = m_margin;
@@ -4160,7 +4165,7 @@ namespace Generators {
if (!m_predicate(m_generator.get())) {
// It might happen that there are no values that pass the
// filter. In that case we throw an exception.
- auto has_initial_value = next();
+ auto has_initial_value = nextImpl();
if (!has_initial_value) {
Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
}
@@ -4172,6 +4177,11 @@ namespace Generators {
}
bool next() override {
+ return nextImpl();
+ }
+
+ private:
+ bool nextImpl() {
bool success = m_generator.next();
if (!success) {
return false;
@@ -5455,6 +5465,8 @@ namespace Catch {
} // namespace Catch
// end catch_outlier_classification.hpp
+
+#include
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
#include
@@ -6339,9 +6351,10 @@ namespace Catch {
void writeTestCase(TestCaseNode const& testCaseNode);
- void writeSection(std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode);
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode,
+ bool testOkToFail );
void writeAssertions(SectionNode const& sectionNode);
void writeAssertion(AssertionStats const& stats);
@@ -6876,7 +6889,7 @@ namespace Catch {
}
iters *= 2;
}
- throw optimized_away_error{};
+ Catch::throw_exception(optimized_away_error{});
}
} // namespace Detail
} // namespace Benchmark
@@ -6884,6 +6897,7 @@ namespace Catch {
// end catch_run_for_at_least.hpp
#include
+#include
namespace Catch {
namespace Benchmark {
@@ -7054,8 +7068,8 @@ namespace Catch {
double b2 = bias - z1;
double a1 = a(b1);
double a2 = a(b2);
- auto lo = std::max(cumn(a1), 0);
- auto hi = std::min(cumn(a2), n - 1);
+ auto lo = (std::max)(cumn(a1), 0);
+ auto hi = (std::min)(cumn(a2), n - 1);
return { point, resample[lo], resample[hi], confidence_level };
}
@@ -7124,7 +7138,9 @@ namespace Catch {
}
template
EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) {
- auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit));
+ auto time_limit = (std::min)(
+ resolution * clock_cost_estimation_tick_limit,
+ FloatDuration(clock_cost_estimation_time_limit));
auto time_clock = [](int k) {
return Detail::measure([k] {
for (int i = 0; i < k; ++i) {
@@ -7379,8 +7395,6 @@ namespace Catch {
template
struct ObjectStorage
{
- using TStorage = typename std::aligned_storage::value>::type;
-
ObjectStorage() : data() {}
ObjectStorage(const ObjectStorage& other)
@@ -7423,7 +7437,7 @@ namespace Catch {
return *static_cast(static_cast(&data));
}
- TStorage data;
+ struct { alignas(T) unsigned char data[sizeof(T)]; } data;
};
}
@@ -7771,7 +7785,7 @@ namespace Catch {
double sb = stddev.point;
double mn = mean.point / n;
double mg_min = mn / 2.;
- double sg = std::min(mg_min / 4., sb / std::sqrt(n));
+ double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
double sg2 = sg * sg;
double sb2 = sb * sb;
@@ -7790,7 +7804,7 @@ namespace Catch {
return (nc / n) * (sb2 - nc * sg2);
};
- return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
+ return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
}
bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector::iterator first, std::vector::iterator last) {
@@ -7933,7 +7947,7 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
- #define CATCH_TRAP() __asm__(".inst 0xd4200000")
+ #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
#endif
#elif defined(CATCH_PLATFORM_IPHONE)
@@ -7980,86 +7994,58 @@ namespace Catch {
// start catch_fatal_condition.h
-// start catch_windows_h_proxy.h
-
-
-#if defined(CATCH_PLATFORM_WINDOWS)
-
-#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
-# define CATCH_DEFINED_NOMINMAX
-# define NOMINMAX
-#endif
-#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
-# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-
-#ifdef __AFXDLL
-#include
-#else
-#include
-#endif
-
-#ifdef CATCH_DEFINED_NOMINMAX
-# undef NOMINMAX
-#endif
-#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# undef WIN32_LEAN_AND_MEAN
-#endif
-
-#endif // defined(CATCH_PLATFORM_WINDOWS)
-
-// end catch_windows_h_proxy.h
-#if defined( CATCH_CONFIG_WINDOWS_SEH )
+#include
namespace Catch {
- struct FatalConditionHandler {
-
- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
- FatalConditionHandler();
- static void reset();
- ~FatalConditionHandler();
-
- private:
- static bool isSet;
- static ULONG guaranteeSize;
- static PVOID exceptionHandlerHandle;
- };
-
-} // namespace Catch
-
-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
-
-#include
-
-namespace Catch {
-
- struct FatalConditionHandler {
-
- static bool isSet;
- static struct sigaction oldSigActions[];
- static stack_t oldSigStack;
- static char altStackMem[];
-
- static void handleSignal( int sig );
+ // Wrapper for platform-specific fatal error (signals/SEH) handlers
+ //
+ // Tries to be cooperative with other handlers, and not step over
+ // other handlers. This means that unknown structured exceptions
+ // are passed on, previous signal handlers are called, and so on.
+ //
+ // Can only be instantiated once, and assumes that once a signal
+ // is caught, the binary will end up terminating. Thus, there
+ class FatalConditionHandler {
+ bool m_started = false;
+ // Install/disengage implementation for specific platform.
+ // Should be if-defed to work on current platform, can assume
+ // engage-disengage 1:1 pairing.
+ void engage_platform();
+ void disengage_platform();
+ public:
+ // Should also have platform-specific implementations as needed
FatalConditionHandler();
~FatalConditionHandler();
- static void reset();
+
+ void engage() {
+ assert(!m_started && "Handler cannot be installed twice.");
+ m_started = true;
+ engage_platform();
+ }
+
+ void disengage() {
+ assert(m_started && "Handler cannot be uninstalled without being installed first");
+ m_started = false;
+ disengage_platform();
+ }
};
-} // namespace Catch
-
-#else
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
+ //! Simple RAII guard for (dis)engaging the FatalConditionHandler
+ class FatalConditionHandlerGuard {
+ FatalConditionHandler* m_handler;
+ public:
+ FatalConditionHandlerGuard(FatalConditionHandler* handler):
+ m_handler(handler) {
+ m_handler->engage();
+ }
+ ~FatalConditionHandlerGuard() {
+ m_handler->disengage();
+ }
};
-}
-#endif
+} // end namespace Catch
// end catch_fatal_condition.h
#include
@@ -8185,6 +8171,7 @@ namespace Catch {
std::vector m_unfinishedSections;
std::vector m_activeSections;
TrackerContext m_trackerContext;
+ FatalConditionHandler m_fatalConditionhandler;
bool m_lastAssertionPassed = false;
bool m_shouldReportUnexpected = true;
bool m_includeSuccessfulResults;
@@ -10057,6 +10044,36 @@ namespace Catch {
}
// end catch_errno_guard.h
+// start catch_windows_h_proxy.h
+
+
+#if defined(CATCH_PLATFORM_WINDOWS)
+
+#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+# define CATCH_DEFINED_NOMINMAX
+# define NOMINMAX
+#endif
+#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include
+#else
+#include
+#endif
+
+#ifdef CATCH_DEFINED_NOMINMAX
+# undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // defined(CATCH_PLATFORM_WINDOWS)
+
+// end catch_windows_h_proxy.h
#include
namespace Catch {
@@ -10573,7 +10590,7 @@ namespace Catch {
// Extracts the actual name part of an enum instance
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
StringRef extractInstanceName(StringRef enumInstance) {
- // Find last occurence of ":"
+ // Find last occurrence of ":"
size_t name_start = enumInstance.size();
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
--name_start;
@@ -10735,25 +10752,47 @@ namespace Catch {
// end catch_exception_translator_registry.cpp
// start catch_fatal_condition.cpp
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
+#include
+
+#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace Catch {
+
+ // If neither SEH nor signal handling is required, the handler impls
+ // do not have to do anything, and can be empty.
+ void FatalConditionHandler::engage_platform() {}
+ void FatalConditionHandler::disengage_platform() {}
+ FatalConditionHandler::FatalConditionHandler() = default;
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+} // end namespace Catch
+
+#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
+#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
+#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
namespace {
- // Report the error condition
+ //! Signals fatal error message to the run context
void reportFatal( char const * const message ) {
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
}
-}
-#endif // signals/SEH handling
+ //! Minimal size Catch2 needs for its own fatal error handling.
+ //! Picked anecdotally, so it might not be sufficient on all
+ //! platforms, and for all configurations.
+ constexpr std::size_t minStackSizeForErrors = 32 * 1024;
+} // end unnamed namespace
+
+#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
#if defined( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
+
struct SignalDefs { DWORD id; const char* name; };
// There is no 1-1 mapping between signals and windows exceptions.
@@ -10766,7 +10805,7 @@ namespace Catch {
{ static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
};
- LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (auto const& def : signalDefs) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
reportFatal(def.name);
@@ -10777,38 +10816,50 @@ namespace Catch {
return EXCEPTION_CONTINUE_SEARCH;
}
- FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
- // 32k seems enough for Catch to handle stack overflow,
- // but the value was found experimentally, so there is no strong guarantee
- guaranteeSize = 32 * 1024;
- exceptionHandlerHandle = nullptr;
- // Register as first handler in current chain
- exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
- // Pass in guarantee size to be filled
- SetThreadStackGuarantee(&guaranteeSize);
- }
+ // Since we do not support multiple instantiations, we put these
+ // into global variables and rely on cleaning them up in outlined
+ // constructors/destructors
+ static PVOID exceptionHandlerHandle = nullptr;
- void FatalConditionHandler::reset() {
- if (isSet) {
- RemoveVectoredExceptionHandler(exceptionHandlerHandle);
- SetThreadStackGuarantee(&guaranteeSize);
- exceptionHandlerHandle = nullptr;
- isSet = false;
+ // For MSVC, we reserve part of the stack memory for handling
+ // memory overflow structured exception.
+ FatalConditionHandler::FatalConditionHandler() {
+ ULONG guaranteeSize = static_cast(minStackSizeForErrors);
+ if (!SetThreadStackGuarantee(&guaranteeSize)) {
+ // We do not want to fully error out, because needing
+ // the stack reserve should be rare enough anyway.
+ Catch::cerr()
+ << "Failed to reserve piece of stack."
+ << " Stack overflows will not be reported successfully.";
}
}
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
+ // We do not attempt to unset the stack guarantee, because
+ // Windows does not support lowering the stack size guarantee.
+ FatalConditionHandler::~FatalConditionHandler() = default;
+
+ void FatalConditionHandler::engage_platform() {
+ // Register as first handler in current chain
+ exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+ if (!exceptionHandlerHandle) {
+ CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
+ }
}
-bool FatalConditionHandler::isSet = false;
-ULONG FatalConditionHandler::guaranteeSize = 0;
-PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
+ void FatalConditionHandler::disengage_platform() {
+ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
+ CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
+ }
+ exceptionHandlerHandle = nullptr;
+ }
-} // namespace Catch
+} // end namespace Catch
-#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
+#endif // CATCH_CONFIG_WINDOWS_SEH
+
+#if defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+#include
namespace Catch {
@@ -10817,10 +10868,6 @@ namespace Catch {
const char* name;
};
- // 32kb for the alternate stack seems to be sufficient. However, this value
- // is experimentally determined, so that's not guaranteed.
- static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
-
static SignalDefs signalDefs[] = {
{ SIGINT, "SIGINT - Terminal interrupt signal" },
{ SIGILL, "SIGILL - Illegal instruction signal" },
@@ -10830,7 +10877,32 @@ namespace Catch {
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};
- void FatalConditionHandler::handleSignal( int sig ) {
+// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
+// which is zero initialization, but not explicit. We want to avoid
+// that.
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+ static char* altStackMem = nullptr;
+ static std::size_t altStackSize = 0;
+ static stack_t oldSigStack{};
+ static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
+
+ static void restorePreviousSignalHandlers() {
+ // We set signal handlers back to the previous ones. Hopefully
+ // nobody overwrote them in the meantime, and doesn't expect
+ // their signal handlers to live past ours given that they
+ // installed them after ours..
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+ sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+ }
+ // Return the old stack
+ sigaltstack(&oldSigStack, nullptr);
+ }
+
+ static void handleSignal( int sig ) {
char const * name = "";
for (auto const& def : signalDefs) {
if (sig == def.id) {
@@ -10838,16 +10910,33 @@ namespace Catch {
break;
}
}
- reset();
- reportFatal(name);
+ // We need to restore previous signal handlers and let them do
+ // their thing, so that the users can have the debugger break
+ // when a signal is raised, and so on.
+ restorePreviousSignalHandlers();
+ reportFatal( name );
raise( sig );
}
FatalConditionHandler::FatalConditionHandler() {
- isSet = true;
+ assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
+ if (altStackSize == 0) {
+ altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors);
+ }
+ altStackMem = new char[altStackSize]();
+ }
+
+ FatalConditionHandler::~FatalConditionHandler() {
+ delete[] altStackMem;
+ // We signal that another instance can be constructed by zeroing
+ // out the pointer.
+ altStackMem = nullptr;
+ }
+
+ void FatalConditionHandler::engage_platform() {
stack_t sigStack;
sigStack.ss_sp = altStackMem;
- sigStack.ss_size = sigStackSize;
+ sigStack.ss_size = altStackSize;
sigStack.ss_flags = 0;
sigaltstack(&sigStack, &oldSigStack);
struct sigaction sa = { };
@@ -10859,40 +10948,17 @@ namespace Catch {
}
}
- FatalConditionHandler::~FatalConditionHandler() {
- reset();
- }
-
- void FatalConditionHandler::reset() {
- if( isSet ) {
- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
- sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
- }
- // Return the old stack
- sigaltstack(&oldSigStack, nullptr);
- isSet = false;
- }
- }
-
- bool FatalConditionHandler::isSet = false;
- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
- stack_t FatalConditionHandler::oldSigStack = {};
- char FatalConditionHandler::altStackMem[sigStackSize] = {};
-
-} // namespace Catch
-
-#else
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-#endif // signals/SEH handling
-
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
+
+ void FatalConditionHandler::disengage_platform() {
+ restorePreviousSignalHandlers();
+ }
+
+} // end namespace Catch
+
+#endif // CATCH_CONFIG_POSIX_SIGNALS
// end catch_fatal_condition.cpp
// start catch_generators.cpp
@@ -11447,7 +11513,8 @@ namespace {
return lhs == rhs;
}
- auto ulpDiff = std::abs(lc - rc);
+ // static cast as a workaround for IBM XLC
+ auto ulpDiff = std::abs(static_cast(lc - rc));
return static_cast(ulpDiff) <= maxUlpDiff;
}
@@ -11621,7 +11688,6 @@ Floating::WithinRelMatcher WithinRel(float target) {
} // namespace Matchers
} // namespace Catch
-
// end catch_matchers_floating.cpp
// start catch_matchers_generic.cpp
@@ -12955,9 +13021,8 @@ namespace Catch {
}
void RunContext::invokeActiveTestCase() {
- FatalConditionHandler fatalConditionHandler; // Handle signals
+ FatalConditionHandlerGuard _(&m_fatalConditionhandler);
m_activeTestCase->invoke();
- fatalConditionHandler.reset();
}
void RunContext::handleUnfinishedSections() {
@@ -13325,6 +13390,10 @@ namespace Catch {
filename.erase(0, lastSlash);
filename[0] = '#';
}
+ else
+ {
+ filename.insert(0, "#");
+ }
auto lastDot = filename.find_last_of('.');
if (lastDot != std::string::npos) {
@@ -13487,7 +13556,7 @@ namespace Catch {
// Handle list request
if( Option listed = list( m_config ) )
- return static_cast( *listed );
+ return (std::min) (MaxExitCode, static_cast(*listed));
TestGroup tests { m_config };
auto const totals = tests.execute();
@@ -15320,7 +15389,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 13, 4, "", 0 );
+ static Version version( 2, 13, 10, "", 0 );
return version;
}
@@ -16733,6 +16802,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter)
#include
#include
#include
+#include
namespace Catch {
@@ -16760,7 +16830,7 @@ namespace Catch {
#else
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
- return std::string(timeStamp);
+ return std::string(timeStamp, timeStampSize-1);
}
std::string fileNameTag(const std::vector &tags) {
@@ -16771,6 +16841,17 @@ namespace Catch {
return it->substr(1);
return std::string();
}
+
+ // Formats the duration in seconds to 3 decimal places.
+ // This is done because some genius defined Maven Surefire schema
+ // in a way that only accepts 3 decimal places, and tools like
+ // Jenkins use that schema for validation JUnit reporter output.
+ std::string formatDuration( double seconds ) {
+ ReusableStringStream rss;
+ rss << std::fixed << std::setprecision( 3 ) << seconds;
+ return rss.str();
+ }
+
} // anonymous namespace
JunitReporter::JunitReporter( ReporterConfig const& _config )
@@ -16840,7 +16921,7 @@ namespace Catch {
if( m_config->showDurations() == ShowDurations::Never )
xml.writeAttribute( "time", "" );
else
- xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "time", formatDuration( suiteTime ) );
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
// Write properties if there are any
@@ -16885,12 +16966,13 @@ namespace Catch {
if ( !m_config->name().empty() )
className = m_config->name() + "." + className;
- writeSection( className, "", rootSection );
+ writeSection( className, "", rootSection, stats.testInfo.okToFail() );
}
- void JunitReporter::writeSection( std::string const& className,
- std::string const& rootName,
- SectionNode const& sectionNode ) {
+ void JunitReporter::writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode,
+ bool testOkToFail) {
std::string name = trim( sectionNode.stats.sectionInfo.name );
if( !rootName.empty() )
name = rootName + '/' + name;
@@ -16907,13 +16989,18 @@ namespace Catch {
xml.writeAttribute( "classname", className );
xml.writeAttribute( "name", name );
}
- xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
+ xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) );
// This is not ideal, but it should be enough to mimic gtest's
// junit output.
// Ideally the JUnit reporter would also handle `skipTest`
// events and write those out appropriately.
xml.writeAttribute( "status", "run" );
+ if (sectionNode.stats.assertions.failedButOk) {
+ xml.scopedElement("skipped")
+ .writeAttribute("message", "TEST_CASE tagged with !mayfail");
+ }
+
writeAssertions( sectionNode );
if( !sectionNode.stdOut.empty() )
@@ -16923,9 +17010,9 @@ namespace Catch {
}
for( auto const& childNode : sectionNode.childSections )
if( className.empty() )
- writeSection( name, "", *childNode );
+ writeSection( name, "", *childNode, testOkToFail );
else
- writeSection( className, name, *childNode );
+ writeSection( className, name, *childNode, testOkToFail );
}
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
@@ -17437,12 +17524,20 @@ namespace Catch {
#ifndef __OBJC__
+#ifndef CATCH_INTERNAL_CDECL
+#ifdef _MSC_VER
+#define CATCH_INTERNAL_CDECL __cdecl
+#else
+#define CATCH_INTERNAL_CDECL
+#endif
+#endif
+
#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
-extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
+extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
// Standard C/C++ main entry point
-int main (int argc, char * argv[]) {
+int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) {
#endif
return Catch::Session().run( argc, argv );
@@ -17570,9 +17665,9 @@ int main (int argc, char * const argv[]) {
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#define CATCH_BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+ INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
#define CATCH_BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+ INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
@@ -17674,9 +17769,9 @@ int main (int argc, char * const argv[]) {
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#define BENCHMARK(...) \
- INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+ INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
#define BENCHMARK_ADVANCED(name) \
- INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
+ INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
using Catch::Detail::Approx;
@@ -17723,8 +17818,8 @@ using Catch::Detail::Approx;
#define CATCH_WARN( msg ) (void)(0)
#define CATCH_CAPTURE( msg ) (void)(0)
-#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
@@ -17733,7 +17828,7 @@ using Catch::Detail::Approx;
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
@@ -17756,8 +17851,8 @@ using Catch::Detail::Approx;
#endif
// "BDD-style" convenience wrappers
-#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
#define CATCH_GIVEN( desc )
#define CATCH_AND_GIVEN( desc )
#define CATCH_WHEN( desc )
@@ -17805,10 +17900,10 @@ using Catch::Detail::Approx;
#define INFO( msg ) (void)(0)
#define UNSCOPED_INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
-#define CAPTURE( msg ) (void)(0)
+#define CAPTURE( ... ) (void)(0)
-#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
-#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
@@ -17816,7 +17911,7 @@ using Catch::Detail::Approx;
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
@@ -17846,8 +17941,8 @@ using Catch::Detail::Approx;
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
// "BDD-style" convenience wrappers
-#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
+#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
#define GIVEN( desc )
#define AND_GIVEN( desc )