mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-13 00:45:39 +02:00
Compare commits
80 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ee1450f268 | ||
![]() |
a2b2e1f707 | ||
![]() |
a7782d1d7c | ||
![]() |
d4b0b34561 | ||
![]() |
c359076e8a | ||
![]() |
20ace55034 | ||
![]() |
182c910b4b | ||
![]() |
02123776f2 | ||
![]() |
14bc25be00 | ||
![]() |
20d413b8b6 | ||
![]() |
e33de8fc05 | ||
![]() |
1127d847a1 | ||
![]() |
ca455815fd | ||
![]() |
d71b4617e9 | ||
![]() |
62fd660583 | ||
![]() |
0aa4dbae2e | ||
![]() |
ff151d2833 | ||
![]() |
958944d27a | ||
![]() |
216713a406 | ||
![]() |
e9e4117016 | ||
![]() |
8a06a6dce8 | ||
![]() |
33794a204c | ||
![]() |
f45dac8fc1 | ||
![]() |
f2f0dcc511 | ||
![]() |
dba29b60d6 | ||
![]() |
3d01f3ae32 | ||
![]() |
85c9544fa4 | ||
![]() |
4b9780201b | ||
![]() |
c4e3767e26 | ||
![]() |
eea3e9a5b5 | ||
![]() |
7727c15290 | ||
![]() |
531a149ae7 | ||
![]() |
9683570be7 | ||
![]() |
581c46249a | ||
![]() |
b15b862d86 | ||
![]() |
6971476563 | ||
![]() |
5c88067bd3 | ||
![]() |
86a4d704bc | ||
![]() |
469a717395 | ||
![]() |
42e368dd0a | ||
![]() |
1ff1f2741d | ||
![]() |
269f96e2bc | ||
![]() |
cec35630fb | ||
![]() |
b8b03da534 | ||
![]() |
8f277a54c0 | ||
![]() |
4cb3220a8a | ||
![]() |
b025a007b9 | ||
![]() |
68975e3ff3 | ||
![]() |
bcb9ea8cb5 | ||
![]() |
d4c9494eb5 | ||
![]() |
bed285af07 | ||
![]() |
de6fe184a9 | ||
![]() |
fe3dddcc6d | ||
![]() |
18ab353e55 | ||
![]() |
2375a7f5b7 | ||
![]() |
fac517d571 | ||
![]() |
578f8b8006 | ||
![]() |
92f8b01dfa | ||
![]() |
dc7e705672 | ||
![]() |
3ba745552b | ||
![]() |
ff349a50bf | ||
![]() |
aca2472d40 | ||
![]() |
765ac08f08 | ||
![]() |
8dd25b0410 | ||
![]() |
69297ceeb6 | ||
![]() |
2d30df3500 | ||
![]() |
77b2a7daea | ||
![]() |
e905edb10f | ||
![]() |
87074da73e | ||
![]() |
e6f5e05ebc | ||
![]() |
44900d5371 | ||
![]() |
7c75ecaef4 | ||
![]() |
fba0feeba1 | ||
![]() |
3e8800beb1 | ||
![]() |
314a05d809 | ||
![]() |
eadf4e32b6 | ||
![]() |
f9620d11be | ||
![]() |
00db4fb497 | ||
![]() |
2fc83e7e9c | ||
![]() |
a2e5ce2418 |
22
.travis.yml
22
.travis.yml
@@ -258,6 +258,15 @@ matrix:
|
|||||||
addons: *gcc7
|
addons: *gcc7
|
||||||
env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1
|
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
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
compiler: clang
|
compiler: clang
|
||||||
@@ -276,19 +285,6 @@ matrix:
|
|||||||
packages: ['clang-6.0', 'libstdc++-8-dev']
|
packages: ['clang-6.0', 'libstdc++-8-dev']
|
||||||
env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
|
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:
|
install:
|
||||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||||
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||||
|
15
BUILD.bazel
15
BUILD.bazel
@@ -3,8 +3,15 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
|
|||||||
|
|
||||||
# Header-only rule to export catch2/catch.hpp.
|
# Header-only rule to export catch2/catch.hpp.
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "catch2",
|
name = "catch2",
|
||||||
hdrs = ["single_include/catch2/catch.hpp"],
|
hdrs = ["single_include/catch2/catch.hpp"],
|
||||||
visibility = ["//visibility:public"],
|
includes = ["single_include/"],
|
||||||
includes = ["single_include/"],
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "catch2_with_main",
|
||||||
|
srcs = ["src/catch_with_main.cpp"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = ["//:catch2"],
|
||||||
)
|
)
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=${prefix}
|
||||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
|
|
||||||
Name: Catch2
|
Name: Catch2
|
||||||
Description: A modern, C++-native, header-only, test framework for C++11
|
Description: A modern, C++-native, header-only, test framework for C++11
|
||||||
|
@@ -4,6 +4,8 @@ cmake_minimum_required(VERSION 3.5)
|
|||||||
# disable testsuite in that case
|
# disable testsuite in that case
|
||||||
if(NOT DEFINED PROJECT_NAME)
|
if(NOT DEFINED PROJECT_NAME)
|
||||||
set(NOT_SUBPROJECT ON)
|
set(NOT_SUBPROJECT ON)
|
||||||
|
else()
|
||||||
|
set(NOT_SUBPROJECT OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Catch2's build breaks if done in-tree. You probably should not build
|
# 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()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
project(Catch2 LANGUAGES CXX VERSION 2.13.1)
|
project(Catch2 LANGUAGES CXX VERSION 2.13.10)
|
||||||
|
|
||||||
# Provide path for scripts
|
# Provide path for scripts
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
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_TESTING "Build SelfTest project" ON)
|
||||||
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
|
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
|
||||||
option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" 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_COVERAGE "Generate coverage for codecov.io" OFF)
|
||||||
option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
|
option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
|
||||||
option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
|
option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
|
||||||
option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON)
|
option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON)
|
||||||
|
|
||||||
|
|
||||||
# define some folders
|
# define some folders
|
||||||
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
||||||
@@ -103,6 +105,23 @@ endif()
|
|||||||
# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
|
# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
|
||||||
add_library(Catch2::Catch2 ALIAS Catch2)
|
add_library(Catch2::Catch2 ALIAS Catch2)
|
||||||
|
|
||||||
|
# Hacky support for compiling the impl into a static lib
|
||||||
|
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()
|
||||||
|
|
||||||
|
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
|
# Only perform the installation steps when Catch is not being used as
|
||||||
# a subproject via `add_subdirectory`, or the destinations will break,
|
# a subproject via `add_subdirectory`, or the destinations will break,
|
||||||
# see https://github.com/catchorg/Catch2/issues/1373
|
# see https://github.com/catchorg/Catch2/issues/1373
|
||||||
@@ -117,11 +136,17 @@ if (NOT_SUBPROJECT)
|
|||||||
${CATCH_CMAKE_CONFIG_DESTINATION}
|
${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
|
# create and install an export set for catch target as Catch2::Catch
|
||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
Catch2
|
${InstallationTargets}
|
||||||
EXPORT
|
EXPORT
|
||||||
Catch2Targets
|
Catch2Targets
|
||||||
DESTINATION
|
DESTINATION
|
||||||
|
@@ -2,14 +2,14 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://github.com/catchorg/catch2/releases)
|
[](https://github.com/catchorg/catch2/releases)
|
||||||
[](https://travis-ci.org/catchorg/Catch2)
|
[](https://travis-ci.org/catchorg/Catch2)
|
||||||
[](https://ci.appveyor.com/project/catchorg/catch2)
|
[](https://ci.appveyor.com/project/catchorg/catch2)
|
||||||
[](https://codecov.io/gh/catchorg/Catch2)
|
[](https://codecov.io/gh/catchorg/Catch2)
|
||||||
[](https://wandbox.org/permlink/6JUH8Eybx4CtvkJS)
|
[](https://wandbox.org/permlink/6JUH8Eybx4CtvkJS)
|
||||||
[](https://discord.gg/4CWS9zD)
|
[](https://discord.gg/4CWS9zD)
|
||||||
|
|
||||||
|
|
||||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.13.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
<a href="https://github.com/catchorg/Catch2/releases/download/v2.13.10/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||||
|
|
||||||
## Catch2 is released!
|
## Catch2 is released!
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ coverage:
|
|||||||
|
|
||||||
|
|
||||||
codecov:
|
codecov:
|
||||||
branch: master
|
branch: v2.x
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
layout: "diff"
|
layout: "diff"
|
||||||
|
@@ -10,7 +10,7 @@ class CatchConan(ConanFile):
|
|||||||
homepage = url
|
homepage = url
|
||||||
license = "BSL-1.0"
|
license = "BSL-1.0"
|
||||||
exports = "LICENSE.txt"
|
exports = "LICENSE.txt"
|
||||||
exports_sources = ("single_include/*", "CMakeLists.txt", "CMake/*", "contrib/*")
|
exports_sources = ("single_include/*", "CMakeLists.txt", "CMake/*", "contrib/*", "src/*")
|
||||||
generators = "cmake"
|
generators = "cmake"
|
||||||
|
|
||||||
def package(self):
|
def package(self):
|
||||||
|
@@ -33,6 +33,10 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
|||||||
[TEST_SUFFIX suffix]
|
[TEST_SUFFIX suffix]
|
||||||
[PROPERTIES name1 value1...]
|
[PROPERTIES name1 value1...]
|
||||||
[TEST_LIST var]
|
[TEST_LIST var]
|
||||||
|
[REPORTER reporter]
|
||||||
|
[OUTPUT_DIR dir]
|
||||||
|
[OUTPUT_PREFIX prefix}
|
||||||
|
[OUTPUT_SUFFIX suffix]
|
||||||
)
|
)
|
||||||
|
|
||||||
``catch_discover_tests`` sets up a post-build command on the test executable
|
``catch_discover_tests`` sets up a post-build command on the test executable
|
||||||
@@ -90,6 +94,28 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
|||||||
executable is being used in multiple calls to ``catch_discover_tests()``.
|
executable is being used in multiple calls to ``catch_discover_tests()``.
|
||||||
Note that this variable is only available in CTest.
|
Note that this variable is only available in CTest.
|
||||||
|
|
||||||
|
``REPORTER reporter``
|
||||||
|
Use the specified reporter when running the test case. The reporter will
|
||||||
|
be passed to the Catch executable as ``--reporter reporter``.
|
||||||
|
|
||||||
|
``OUTPUT_DIR dir``
|
||||||
|
If specified, the parameter is passed along as
|
||||||
|
``--out dir/<test_name>`` to Catch executable. The actual file name is the
|
||||||
|
same as the test name. This should be used instead of
|
||||||
|
``EXTRA_ARGS --out foo`` to avoid race conditions writing the result output
|
||||||
|
when using parallel test execution.
|
||||||
|
|
||||||
|
``OUTPUT_PREFIX prefix``
|
||||||
|
May be used in conjunction with ``OUTPUT_DIR``.
|
||||||
|
If specified, ``prefix`` is added to each output file name, like so
|
||||||
|
``--out dir/prefix<test_name>``.
|
||||||
|
|
||||||
|
``OUTPUT_SUFFIX suffix``
|
||||||
|
May be used in conjunction with ``OUTPUT_DIR``.
|
||||||
|
If specified, ``suffix`` is added to each output file name, like so
|
||||||
|
``--out dir/<test_name>suffix``. This can be used to add a file extension to
|
||||||
|
the output e.g. ".xml".
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
@@ -97,7 +123,7 @@ function(catch_discover_tests TARGET)
|
|||||||
cmake_parse_arguments(
|
cmake_parse_arguments(
|
||||||
""
|
""
|
||||||
""
|
""
|
||||||
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST"
|
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX"
|
||||||
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
|
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
|
||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
@@ -110,7 +136,7 @@ function(catch_discover_tests TARGET)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
## Generate a unique name based on the extra arguments
|
## Generate a unique name based on the extra arguments
|
||||||
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
|
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}")
|
||||||
string(SUBSTRING ${args_hash} 0 7 args_hash)
|
string(SUBSTRING ${args_hash} 0 7 args_hash)
|
||||||
|
|
||||||
# Define rule to generate test list for aforementioned test executable
|
# Define rule to generate test list for aforementioned test executable
|
||||||
@@ -134,6 +160,10 @@ function(catch_discover_tests TARGET)
|
|||||||
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||||
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||||
-D "TEST_LIST=${_TEST_LIST}"
|
-D "TEST_LIST=${_TEST_LIST}"
|
||||||
|
-D "TEST_REPORTER=${_REPORTER}"
|
||||||
|
-D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
|
||||||
|
-D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
|
||||||
|
-D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
|
||||||
-D "CTEST_FILE=${ctest_tests_file}"
|
-D "CTEST_FILE=${ctest_tests_file}"
|
||||||
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
|
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
@@ -172,4 +202,5 @@ endfunction()
|
|||||||
|
|
||||||
set(_CATCH_DISCOVER_TESTS_SCRIPT
|
set(_CATCH_DISCOVER_TESTS_SCRIPT
|
||||||
${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
|
${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
|
||||||
|
CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file"
|
||||||
)
|
)
|
||||||
|
@@ -6,13 +6,20 @@ set(suffix "${TEST_SUFFIX}")
|
|||||||
set(spec ${TEST_SPEC})
|
set(spec ${TEST_SPEC})
|
||||||
set(extra_args ${TEST_EXTRA_ARGS})
|
set(extra_args ${TEST_EXTRA_ARGS})
|
||||||
set(properties ${TEST_PROPERTIES})
|
set(properties ${TEST_PROPERTIES})
|
||||||
|
set(reporter ${TEST_REPORTER})
|
||||||
|
set(output_dir ${TEST_OUTPUT_DIR})
|
||||||
|
set(output_prefix ${TEST_OUTPUT_PREFIX})
|
||||||
|
set(output_suffix ${TEST_OUTPUT_SUFFIX})
|
||||||
set(script)
|
set(script)
|
||||||
set(suite)
|
set(suite)
|
||||||
set(tests)
|
set(tests)
|
||||||
|
|
||||||
function(add_command NAME)
|
function(add_command NAME)
|
||||||
set(_args "")
|
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_]")
|
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||||
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
|
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
|
||||||
else()
|
else()
|
||||||
@@ -32,6 +39,7 @@ execute_process(
|
|||||||
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
|
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
|
||||||
OUTPUT_VARIABLE output
|
OUTPUT_VARIABLE output
|
||||||
RESULT_VARIABLE result
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
)
|
)
|
||||||
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
|
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
|
||||||
if(${result} EQUAL 0)
|
if(${result} EQUAL 0)
|
||||||
@@ -48,6 +56,44 @@ endif()
|
|||||||
|
|
||||||
string(REPLACE "\n" ";" output "${output}")
|
string(REPLACE "\n" ";" output "${output}")
|
||||||
|
|
||||||
|
# Run test executable to get list of available reporters
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters
|
||||||
|
OUTPUT_VARIABLE reporters_output
|
||||||
|
RESULT_VARIABLE reporters_result
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
|
)
|
||||||
|
if(${reporters_result} EQUAL 0)
|
||||||
|
message(WARNING
|
||||||
|
"Test executable '${TEST_EXECUTABLE}' contains no reporters!\n"
|
||||||
|
)
|
||||||
|
elseif(${reporters_result} LESS 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Error running test executable '${TEST_EXECUTABLE}':\n"
|
||||||
|
" Result: ${reporters_result}\n"
|
||||||
|
" Output: ${reporters_output}\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
string(FIND "${reporters_output}" "${reporter}" reporter_is_valid)
|
||||||
|
if(reporter AND ${reporter_is_valid} EQUAL -1)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"\"${reporter}\" is not a valid reporter!\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prepare reporter
|
||||||
|
if(reporter)
|
||||||
|
set(reporter_arg "--reporter ${reporter}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prepare output dir
|
||||||
|
if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
|
||||||
|
set(output_dir "${TEST_WORKING_DIR}/${output_dir}")
|
||||||
|
if(NOT EXISTS ${output_dir})
|
||||||
|
file(MAKE_DIRECTORY ${output_dir})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Parse output
|
# Parse output
|
||||||
foreach(line ${output})
|
foreach(line ${output})
|
||||||
set(test ${line})
|
set(test ${line})
|
||||||
@@ -56,6 +102,12 @@ foreach(line ${output})
|
|||||||
foreach(char , [ ])
|
foreach(char , [ ])
|
||||||
string(REPLACE ${char} "\\${char}" test_name ${test_name})
|
string(REPLACE ${char} "\\${char}" test_name ${test_name})
|
||||||
endforeach(char)
|
endforeach(char)
|
||||||
|
# ...add output dir
|
||||||
|
if(output_dir)
|
||||||
|
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
|
||||||
|
set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# ...and add to script
|
# ...and add to script
|
||||||
add_command(add_test
|
add_command(add_test
|
||||||
"${prefix}${test}${suffix}"
|
"${prefix}${test}${suffix}"
|
||||||
@@ -63,6 +115,8 @@ foreach(line ${output})
|
|||||||
"${TEST_EXECUTABLE}"
|
"${TEST_EXECUTABLE}"
|
||||||
"${test_name}"
|
"${test_name}"
|
||||||
${extra_args}
|
${extra_args}
|
||||||
|
"${reporter_arg}"
|
||||||
|
"${output_dir_arg}"
|
||||||
)
|
)
|
||||||
add_command(set_tests_properties
|
add_command(set_tests_properties
|
||||||
"${prefix}${test}${suffix}"
|
"${prefix}${test}${suffix}"
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
#==================================================================================================#
|
#==================================================================================================#
|
||||||
# supported macros #
|
# supported macros #
|
||||||
# - TEST_CASE, #
|
# - TEST_CASE, #
|
||||||
|
# - TEMPLATE_TEST_CASE #
|
||||||
# - SCENARIO, #
|
# - SCENARIO, #
|
||||||
# - TEST_CASE_METHOD, #
|
# - TEST_CASE_METHOD, #
|
||||||
# - CATCH_TEST_CASE, #
|
# - CATCH_TEST_CASE, #
|
||||||
|
# - CATCH_TEMPLATE_TEST_CASE #
|
||||||
# - CATCH_SCENARIO, #
|
# - CATCH_SCENARIO, #
|
||||||
# - CATCH_TEST_CASE_METHOD. #
|
# - CATCH_TEST_CASE_METHOD. #
|
||||||
# #
|
# #
|
||||||
@@ -106,7 +108,8 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
|
|||||||
ParseAndAddCatchTests_RemoveComments(Contents)
|
ParseAndAddCatchTests_RemoveComments(Contents)
|
||||||
|
|
||||||
# Find definition of test names
|
# Find definition of test names
|
||||||
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
# https://regex101.com/r/JygOND/1
|
||||||
|
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([ \t\n]*\"[^\"]*\"[ \t\n]*(,[ \t\n]*\"[^\"]*\")?(,[ \t\n]*[^\,\)]*)*\\)[ \t\n]*\{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
||||||
|
|
||||||
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
|
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
|
||||||
ParseAndAddCatchTests_PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
ParseAndAddCatchTests_PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
||||||
@@ -117,13 +120,21 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# check CMP0110 policy for new add_test() behavior
|
||||||
|
if(POLICY CMP0110)
|
||||||
|
cmake_policy(GET CMP0110 _cmp0110_value) # new add_test() behavior
|
||||||
|
else()
|
||||||
|
# just to be thorough explicitly set the variable
|
||||||
|
set(_cmp0110_value)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(TestName ${Tests})
|
foreach(TestName ${Tests})
|
||||||
# Strip newlines
|
# Strip newlines
|
||||||
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
||||||
|
|
||||||
# Get test type and fixture if applicable
|
# Get test type and fixture if applicable
|
||||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
|
string(REGEX MATCH "(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
|
||||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
|
string(REGEX MATCH "(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
|
||||||
string(REGEX REPLACE "${TestType}\\([ \t]*" "" TestFixture "${TestTypeAndFixture}")
|
string(REGEX REPLACE "${TestType}\\([ \t]*" "" TestFixture "${TestTypeAndFixture}")
|
||||||
|
|
||||||
# Get string parts of test definition
|
# Get string parts of test definition
|
||||||
@@ -189,11 +200,21 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
|
|||||||
# Escape commas in the test spec
|
# Escape commas in the test spec
|
||||||
string(REPLACE "," "\\," Name ${Name})
|
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
|
# only with CMake 3.18.0 the escaped double quotes confuse the call. This change is reverted in 3.18.1
|
||||||
if(NOT ${CMAKE_VERSION} VERSION_EQUAL "3.18")
|
# And properly introduced in 3.19 with the CMP0110 policy
|
||||||
|
if(_cmp0110_value STREQUAL "NEW" OR ${CMAKE_VERSION} VERSION_EQUAL "3.18")
|
||||||
|
ParseAndAddCatchTests_PrintDebugMessage("CMP0110 set to NEW, no need for add_test(\"\") workaround")
|
||||||
|
else()
|
||||||
|
ParseAndAddCatchTests_PrintDebugMessage("CMP0110 set to OLD adding \"\" for add_test() workaround")
|
||||||
set(CTestName "\"${CTestName}\"")
|
set(CTestName "\"${CTestName}\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Handle template test cases
|
||||||
|
if("${TestTypeAndFixture}" MATCHES ".*TEMPLATE_.*")
|
||||||
|
set(Name "${Name} - *")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add the test and set its properties
|
# Add the test and set its properties
|
||||||
add_test(NAME "${CTestName}" COMMAND ${OptionalCatchTestLauncher} $<TARGET_FILE:${TestTarget}> ${Name} ${AdditionalCatchParameters})
|
add_test(NAME "${CTestName}" COMMAND ${OptionalCatchTestLauncher} $<TARGET_FILE:${TestTarget}> ${Name} ${AdditionalCatchParameters})
|
||||||
# Old CMake versions do not document VERSION_GREATER_EQUAL, so we use VERSION_GREATER with 3.8 instead
|
# Old CMake versions do not document VERSION_GREATER_EQUAL, so we use VERSION_GREATER with 3.8 instead
|
||||||
@@ -220,6 +241,7 @@ endfunction()
|
|||||||
|
|
||||||
# entry point
|
# entry point
|
||||||
function(ParseAndAddCatchTests TestTarget)
|
function(ParseAndAddCatchTests TestTarget)
|
||||||
|
message(DEPRECATION "ParseAndAddCatchTest: function deprecated because of possibility of missed test cases. Consider using 'catch_discover_tests' from 'Catch.cmake'")
|
||||||
ParseAndAddCatchTests_PrintDebugMessage("Started parsing ${TestTarget}")
|
ParseAndAddCatchTests_PrintDebugMessage("Started parsing ${TestTarget}")
|
||||||
get_target_property(SourceFiles ${TestTarget} SOURCES)
|
get_target_property(SourceFiles ${TestTarget} SOURCES)
|
||||||
ParseAndAddCatchTests_PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
ParseAndAddCatchTests_PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
||||||
|
@@ -36,6 +36,21 @@ add_subdirectory(lib/Catch2)
|
|||||||
target_link_libraries(tests Catch2::Catch2)
|
target_link_libraries(tests Catch2::Catch2)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Another possibility is to use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html):
|
||||||
|
```cmake
|
||||||
|
Include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
Catch2
|
||||||
|
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||||
|
GIT_TAG v2.13.9 # or a later release
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(Catch2)
|
||||||
|
|
||||||
|
target_link_libraries(tests Catch2::Catch2)
|
||||||
|
```
|
||||||
|
|
||||||
## Automatic test registration
|
## Automatic test registration
|
||||||
|
|
||||||
Catch2's repository also contains two CMake scripts that help users
|
Catch2's repository also contains two CMake scripts that help users
|
||||||
@@ -43,7 +58,7 @@ with automatically registering their `TEST_CASE`s with CTest. They
|
|||||||
can be found in the `contrib` folder, and are
|
can be found in the `contrib` folder, and are
|
||||||
|
|
||||||
1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
|
1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
|
||||||
2) `ParseAndAddCatchTests.cmake`
|
2) `ParseAndAddCatchTests.cmake` (deprecated)
|
||||||
|
|
||||||
If Catch2 has been installed in system, both of these can be used after
|
If Catch2 has been installed in system, both of these can be used after
|
||||||
doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
|
doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
|
||||||
@@ -83,6 +98,10 @@ catch_discover_tests(target
|
|||||||
[TEST_SUFFIX suffix]
|
[TEST_SUFFIX suffix]
|
||||||
[PROPERTIES name1 value1...]
|
[PROPERTIES name1 value1...]
|
||||||
[TEST_LIST var]
|
[TEST_LIST var]
|
||||||
|
[REPORTER reporter]
|
||||||
|
[OUTPUT_DIR dir]
|
||||||
|
[OUTPUT_PREFIX prefix]
|
||||||
|
[OUTPUT_SUFFIX suffix]
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -129,13 +148,46 @@ default `<target>_TESTS`. This can be useful when the same test
|
|||||||
executable is being used in multiple calls to `catch_discover_tests()`.
|
executable is being used in multiple calls to `catch_discover_tests()`.
|
||||||
Note that this variable is only available in CTest.
|
Note that this variable is only available in CTest.
|
||||||
|
|
||||||
|
* `REPORTER reporter`
|
||||||
|
|
||||||
|
Use the specified reporter when running the test case. The reporter will
|
||||||
|
be passed to the test runner as `--reporter reporter`.
|
||||||
|
|
||||||
|
* `OUTPUT_DIR dir`
|
||||||
|
|
||||||
|
If specified, the parameter is passed along as
|
||||||
|
`--out dir/<test_name>` to test executable. The actual file name is the
|
||||||
|
same as the test name. This should be used instead of
|
||||||
|
`EXTRA_ARGS --out foo` to avoid race conditions writing the result output
|
||||||
|
when using parallel test execution.
|
||||||
|
|
||||||
|
* `OUTPUT_PREFIX prefix`
|
||||||
|
|
||||||
|
May be used in conjunction with `OUTPUT_DIR`.
|
||||||
|
If specified, `prefix` is added to each output file name, like so
|
||||||
|
`--out dir/prefix<test_name>`.
|
||||||
|
|
||||||
|
* `OUTPUT_SUFFIX suffix`
|
||||||
|
|
||||||
|
May be used in conjunction with `OUTPUT_DIR`.
|
||||||
|
If specified, `suffix` is added to each output file name, like so
|
||||||
|
`--out dir/<test_name>suffix`. This can be used to add a file extension to
|
||||||
|
the output file name e.g. ".xml".
|
||||||
|
|
||||||
|
|
||||||
### `ParseAndAddCatchTests.cmake`
|
### `ParseAndAddCatchTests.cmake`
|
||||||
|
|
||||||
|
⚠ This script is [deprecated](https://github.com/catchorg/Catch2/pull/2120)
|
||||||
|
in Catch 2.13.4 and superseded by the above approach using `catch_discover_tests`.
|
||||||
|
See [#2092](https://github.com/catchorg/Catch2/issues/2092) for details.
|
||||||
|
|
||||||
`ParseAndAddCatchTests` works by parsing all implementation files
|
`ParseAndAddCatchTests` works by parsing all implementation files
|
||||||
associated with the provided target, and registering them via CTest's
|
associated with the provided target, and registering them via CTest's
|
||||||
`add_test`. This approach has some limitations, such as the fact that
|
`add_test`. This approach has some limitations, such as the fact that
|
||||||
commented-out tests will be registered anyway.
|
commented-out tests will be registered anyway. More serious, only a
|
||||||
|
subset of the assertion macros currently available in Catch can be
|
||||||
|
detected by this script and tests with any macros that cannot be
|
||||||
|
parsed are *silently ignored*.
|
||||||
|
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
@@ -21,12 +21,12 @@ to the codebase itself.
|
|||||||
|
|
||||||
## Using Git(Hub)
|
## Using Git(Hub)
|
||||||
|
|
||||||
Ongoing development happens in the `master` branch for Catch2 v2, and in
|
Ongoing development happens in the `v2.x` branch for Catch2 v2, and in
|
||||||
`dev-v3` for the next major version, v3.
|
`devel` for the next major version, v3.
|
||||||
|
|
||||||
Commits should be small and atomic. A commit is atomic when, after it is
|
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
|
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.
|
whether it is bisecting, reverting, or something else, easier.
|
||||||
|
|
||||||
_When submitting a pull request please do not include changes to the
|
_When submitting a pull request please do not include changes to the
|
||||||
|
@@ -72,6 +72,13 @@ Instead you will have to write this:
|
|||||||
REQUIRE_THAT(foo(), m1 || m2 || m3);
|
REQUIRE_THAT(foo(), m1 || m2 || m3);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `ParseAndAddCatchTests.cmake`
|
||||||
|
|
||||||
|
The CMake/CTest integration using `ParseAndAddCatchTests.cmake` is deprecated,
|
||||||
|
as it can be replaced by `Catch.cmake` that provides the function
|
||||||
|
`catch_discover_tests` to get tests directly from a CMake target via the
|
||||||
|
command line interface instead of parsing C++ code with regular expressions.
|
||||||
|
|
||||||
|
|
||||||
## Planned changes
|
## Planned changes
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ that allows users to implement their own generators.
|
|||||||
effects. The simplest usage is shown below, where the `SECTION` "one"
|
effects. The simplest usage is shown below, where the `SECTION` "one"
|
||||||
runs 4 (2\*2) times, and `SECTION` "two" is run 6 times (2\*3).
|
runs 4 (2\*2) times, and `SECTION` "two" is run 6 times (2\*3).
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
TEST_CASE("Generators") {
|
TEST_CASE("Generators") {
|
||||||
auto i = GENERATE(1, 2);
|
auto i = GENERATE(1, 2);
|
||||||
SECTION("one") {
|
SECTION("one") {
|
||||||
@@ -51,7 +51,7 @@ TEST_CASE("Generators") {
|
|||||||
}
|
}
|
||||||
SECTION("two") {
|
SECTION("two") {
|
||||||
auto k = GENERATE(4, 5, 6);
|
auto k = GENERATE(4, 5, 6);
|
||||||
REQUIRE(j != k);
|
REQUIRE(i != k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@@ -104,6 +104,20 @@ Both of these solutions have their problems, but should let you wring parallelis
|
|||||||
## 3rd party bugs
|
## 3rd party bugs
|
||||||
This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes).
|
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
|
### 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:
|
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
|
```cpp
|
||||||
|
@@ -94,6 +94,9 @@ A thread-safe header-only mocking framework for C++14.
|
|||||||
|
|
||||||
## Applications & Tools
|
## Applications & Tools
|
||||||
|
|
||||||
|
### [App Mesh](https://github.com/laoshanxi/app-mesh)
|
||||||
|
A high available cloud native micro-service application management platform implemented by modern C++.
|
||||||
|
|
||||||
### [ArangoDB](https://github.com/arangodb/arangodb)
|
### [ArangoDB](https://github.com/arangodb/arangodb)
|
||||||
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
|
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
|
||||||
|
|
||||||
|
@@ -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
|
`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
|
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
|
necessarily remain stable across different links, and thus it might be
|
||||||
hard to run directly.
|
hard to run directly.
|
||||||
|
|
||||||
|
@@ -87,7 +87,7 @@ int main( int argc, char* argv[] )
|
|||||||
int height = 0; // Some user variable you want to be able to set
|
int height = 0; // Some user variable you want to be able to set
|
||||||
|
|
||||||
// Build a new parser on top of Catch's
|
// Build a new parser on top of Catch's
|
||||||
using namespace Catch::clara;
|
using namespace Catch::Clara;
|
||||||
auto cli
|
auto cli
|
||||||
= session.cli() // Get Catch's composite command line parser
|
= session.cli() // Get Catch's composite command line parser
|
||||||
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
||||||
|
@@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
**Contents**<br>
|
**Contents**<br>
|
||||||
|
[2.13.10](#21310)<br>
|
||||||
|
[2.13.9](#2139)<br>
|
||||||
|
[2.13.8](#2138)<br>
|
||||||
|
[2.13.7](#2137)<br>
|
||||||
|
[2.13.6](#2136)<br>
|
||||||
|
[2.13.5](#2135)<br>
|
||||||
|
[2.13.4](#2134)<br>
|
||||||
|
[2.13.3](#2133)<br>
|
||||||
|
[2.13.2](#2132)<br>
|
||||||
[2.13.1](#2131)<br>
|
[2.13.1](#2131)<br>
|
||||||
[2.13.0](#2130)<br>
|
[2.13.0](#2130)<br>
|
||||||
[2.12.4](#2124)<br>
|
[2.12.4](#2124)<br>
|
||||||
@@ -42,6 +51,120 @@
|
|||||||
[Even Older versions](#even-older-versions)<br>
|
[Even Older versions](#even-older-versions)<br>
|
||||||
|
|
||||||
|
|
||||||
|
## 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 `<iterator>` 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
|
||||||
|
* Improved the hashing algorithm used for shuffling test cases (#2070)
|
||||||
|
* `TEST_CASE`s that differ only in the last character should be properly shuffled
|
||||||
|
* Note that this means that v2.13.4 gives you a different order of test cases than 2.13.3, even given the same seed.
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* Deprecated `ParseAndAddCatchTests` CMake integration (#2092)
|
||||||
|
* It is impossible to implement it properly for all the different test case variants Catch2 provides, and there are better options provided.
|
||||||
|
* Use `catch_discover_tests` instead, which uses runtime information about available tests.
|
||||||
|
* Fixed bug in `catch_discover_tests` that would cause it to fail when used in specific project structures (#2119)
|
||||||
|
* Added Bazel build file
|
||||||
|
* Added an experimental static library target to CMake
|
||||||
|
|
||||||
|
|
||||||
|
## 2.13.3
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fixed possible infinite loop when combining generators with section filter (`-c` option) (#2025)
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* Fixed `ParseAndAddCatchTests` not finding `TEST_CASE`s without tags (#2055, #2056)
|
||||||
|
* `ParseAndAddCatchTests` supports `CMP0110` policy for changing behaviour of `add_test` (#2057)
|
||||||
|
* This was the shortlived change in CMake 3.18.0 that temporarily broke `ParseAndAddCatchTests`
|
||||||
|
|
||||||
|
|
||||||
|
## 2.13.2
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
* Implemented workaround for AppleClang shadowing bug (#2030)
|
||||||
|
* Implemented workaround for NVCC ICE (#2005, #2027)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fixed detection of `std::uncaught_exceptions` support under non-msvc platforms (#2021)
|
||||||
|
* Fixed the experimental stdout/stderr capture under Windows (#2013)
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* `catch_discover_tests` has been improved significantly (#2023, #2039)
|
||||||
|
* You can now specify which reporter should be used
|
||||||
|
* You can now modify where the output will be written
|
||||||
|
* `WORKING_DIRECTORY` setting is respected
|
||||||
|
* `ParseAndAddCatchTests` now supports `TEMPLATE_TEST_CASE` macros (#2031)
|
||||||
|
* Various documentation fixes and improvements (#2022, #2028, #2034)
|
||||||
|
|
||||||
|
|
||||||
## 2.13.1
|
## 2.13.1
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
@@ -646,7 +769,7 @@ than `single_include/catch.hpp`.**
|
|||||||
* CLR objects (`T^`) can now be stringified (#1216)
|
* CLR objects (`T^`) can now be stringified (#1216)
|
||||||
* This affects code compiled as C++/CLI
|
* This affects code compiled as C++/CLI
|
||||||
* Added `PredicateMatcher`, a matcher that takes an arbitrary predicate function (#1236)
|
* Added `PredicateMatcher`, a matcher that takes an arbitrary predicate function (#1236)
|
||||||
* See [documentation for details](https://github.com/catchorg/Catch2/blob/master/docs/matchers.md)
|
* See [documentation for details](https://github.com/catchorg/Catch2/blob/v2.x/docs/matchers.md)
|
||||||
|
|
||||||
### Others
|
### Others
|
||||||
* Modified CMake-installed pkg-config to allow `#include <catch.hpp>`(#1239)
|
* Modified CMake-installed pkg-config to allow `#include <catch.hpp>`(#1239)
|
||||||
@@ -674,7 +797,7 @@ than `single_include/catch.hpp`.**
|
|||||||
* Added an option to warn (+ exit with error) when no tests were ran (#1158)
|
* Added an option to warn (+ exit with error) when no tests were ran (#1158)
|
||||||
* Use as `-w NoTests`
|
* Use as `-w NoTests`
|
||||||
* Added provisional support for Emscripten (#1114)
|
* Added provisional support for Emscripten (#1114)
|
||||||
* [Added a way to override the fallback stringifier](https://github.com/catchorg/Catch2/blob/master/docs/configuration.md#fallback-stringifier) (#1024)
|
* [Added a way to override the fallback stringifier](https://github.com/catchorg/Catch2/blob/v2.x/docs/configuration.md#fallback-stringifier) (#1024)
|
||||||
* This allows project's own stringification machinery to be easily reused for Catch
|
* This allows project's own stringification machinery to be easily reused for Catch
|
||||||
* `Catch::Session::run()` now accepts `char const * const *`, allowing it to accept array of string literals (#1031, #1178)
|
* `Catch::Session::run()` now accepts `char const * const *`, allowing it to accept array of string literals (#1031, #1178)
|
||||||
* The embedded version of Clara was bumped to v1.1.3
|
* The embedded version of Clara was bumped to v1.1.3
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
[Short answer](#short-answer)<br>
|
[Short answer](#short-answer)<br>
|
||||||
[Long answer](#long-answer)<br>
|
[Long answer](#long-answer)<br>
|
||||||
[Practical example](#practical-example)<br>
|
[Practical example](#practical-example)<br>
|
||||||
|
[Using the static library Catch2WithMain](#using-the-static-library-catch2withmain)<br>
|
||||||
[Other possible solutions](#other-possible-solutions)<br>
|
[Other possible solutions](#other-possible-solutions)<br>
|
||||||
|
|
||||||
Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
|
Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
|
||||||
@@ -64,6 +65,39 @@ tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
|
|||||||
Failed 1 test case, failed 1 assertion.
|
Failed 1 test case, failed 1 assertion.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Using the static library Catch2WithMain
|
||||||
|
|
||||||
|
Catch2 also provides a static library that implements the runner. Note
|
||||||
|
that this support is experimental, due to interactions between Catch2 v2
|
||||||
|
implementation and C++ linking limitations.
|
||||||
|
|
||||||
|
As with the `Catch2` target, the `Catch2WithMain` CMake target can be used
|
||||||
|
either from a subdirectory, or from installed build.
|
||||||
|
|
||||||
|
|
||||||
|
### CMake
|
||||||
|
```cmake
|
||||||
|
add_executable(tests-factorial tests-factorial.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(tests-factorial Catch2::Catch2WithMain)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bazel
|
||||||
|
```python
|
||||||
|
cc_test(
|
||||||
|
name = "hello_world_test",
|
||||||
|
srcs = [
|
||||||
|
"test/hello_world_test.cpp",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"lib_hello_world",
|
||||||
|
"@catch2//:catch2_with_main",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Other possible solutions
|
## Other possible solutions
|
||||||
You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles).
|
You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles).
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
## Getting Catch2
|
## Getting Catch2
|
||||||
|
|
||||||
The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/catchorg/Catch2/master/single_include/catch2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/catchorg/Catch2/v2.x/single_include/catch2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
||||||
|
|
||||||
Alternative ways of getting Catch2 include using your system package
|
Alternative ways of getting Catch2 include using your system package
|
||||||
manager, or installing it using [its CMake package](cmake-integration.md#installing-catch2-from-git-repository).
|
manager, or installing it using [its CMake package](cmake-integration.md#installing-catch2-from-git-repository).
|
||||||
|
@@ -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:
|
/* 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
|
* (technically C++17 but does not require -std in GCC/Clang). See
|
||||||
* https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list
|
* https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list
|
||||||
*
|
*
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 2
|
#define CATCH_VERSION_MAJOR 2
|
||||||
#define CATCH_VERSION_MINOR 13
|
#define CATCH_VERSION_MINOR 13
|
||||||
#define CATCH_VERSION_PATCH 1
|
#define CATCH_VERSION_PATCH 10
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang system_header
|
# pragma clang system_header
|
||||||
@@ -195,9 +195,9 @@
|
|||||||
|
|
||||||
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
|
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
|
||||||
#define CATCH_BENCHMARK(...) \
|
#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) \
|
#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
|
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||||
|
|
||||||
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
|
// 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)
|
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
|
||||||
#define BENCHMARK(...) \
|
#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) \
|
#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
|
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||||
|
|
||||||
using Catch::Detail::Approx;
|
using Catch::Detail::Approx;
|
||||||
@@ -350,8 +350,8 @@ using Catch::Detail::Approx;
|
|||||||
#define CATCH_WARN( msg ) (void)(0)
|
#define CATCH_WARN( msg ) (void)(0)
|
||||||
#define CATCH_CAPTURE( 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( ... ) 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_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_METHOD_AS_TEST_CASE( method, ... )
|
||||||
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
|
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
|
||||||
#define CATCH_SECTION( ... )
|
#define CATCH_SECTION( ... )
|
||||||
@@ -360,7 +360,7 @@ using Catch::Detail::Approx;
|
|||||||
#define CATCH_FAIL_CHECK( ... ) (void)(0)
|
#define CATCH_FAIL_CHECK( ... ) (void)(0)
|
||||||
#define CATCH_SUCCEED( ... ) (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
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
|
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
|
||||||
@@ -383,8 +383,8 @@ using Catch::Detail::Approx;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// "BDD-style" convenience wrappers
|
// "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( ... ) 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_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_GIVEN( desc )
|
||||||
#define CATCH_AND_GIVEN( desc )
|
#define CATCH_AND_GIVEN( desc )
|
||||||
#define CATCH_WHEN( desc )
|
#define CATCH_WHEN( desc )
|
||||||
@@ -433,10 +433,10 @@ using Catch::Detail::Approx;
|
|||||||
#define INFO( msg ) (void)(0)
|
#define INFO( msg ) (void)(0)
|
||||||
#define UNSCOPED_INFO( msg ) (void)(0)
|
#define UNSCOPED_INFO( msg ) (void)(0)
|
||||||
#define WARN( 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( ... ) 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_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 METHOD_AS_TEST_CASE( method, ... )
|
||||||
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
|
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
|
||||||
#define SECTION( ... )
|
#define SECTION( ... )
|
||||||
@@ -444,7 +444,7 @@ using Catch::Detail::Approx;
|
|||||||
#define FAIL( ... ) (void)(0)
|
#define FAIL( ... ) (void)(0)
|
||||||
#define FAIL_CHECK( ... ) (void)(0)
|
#define FAIL_CHECK( ... ) (void)(0)
|
||||||
#define SUCCEED( ... ) (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
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
|
#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 )
|
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
|
||||||
|
|
||||||
// "BDD-style" convenience wrappers
|
// "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( ... ) 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_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 GIVEN( desc )
|
||||||
#define AND_GIVEN( desc )
|
#define AND_GIVEN( desc )
|
||||||
|
@@ -19,8 +19,6 @@ namespace Catch {
|
|||||||
template <typename T, bool Destruct>
|
template <typename T, bool Destruct>
|
||||||
struct ObjectStorage
|
struct ObjectStorage
|
||||||
{
|
{
|
||||||
using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
|
|
||||||
|
|
||||||
ObjectStorage() : data() {}
|
ObjectStorage() : data() {}
|
||||||
|
|
||||||
ObjectStorage(const ObjectStorage& other)
|
ObjectStorage(const ObjectStorage& other)
|
||||||
@@ -64,7 +62,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TStorage data;
|
struct { alignas(T) unsigned char data[sizeof(T)]; } data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "detail/catch_run_for_at_least.hpp"
|
#include "detail/catch_run_for_at_least.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Benchmark {
|
namespace Benchmark {
|
||||||
|
@@ -68,7 +68,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
template <typename Clock>
|
template <typename Clock>
|
||||||
EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
|
EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
|
||||||
auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
|
auto time_limit = (std::min)(
|
||||||
|
resolution * clock_cost_estimation_tick_limit,
|
||||||
|
FloatDuration<Clock>(clock_cost_estimation_time_limit));
|
||||||
auto time_clock = [](int k) {
|
auto time_clock = [](int k) {
|
||||||
return Detail::measure<Clock>([k] {
|
return Detail::measure<Clock>([k] {
|
||||||
for (int i = 0; i < k; ++i) {
|
for (int i = 0; i < k; ++i) {
|
||||||
|
@@ -56,7 +56,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
iters *= 2;
|
iters *= 2;
|
||||||
}
|
}
|
||||||
throw optimized_away_error{};
|
Catch::throw_exception(optimized_away_error{});
|
||||||
}
|
}
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
} // namespace Benchmark
|
} // namespace Benchmark
|
||||||
|
@@ -152,7 +152,7 @@ namespace Catch {
|
|||||||
double sb = stddev.point;
|
double sb = stddev.point;
|
||||||
double mn = mean.point / n;
|
double mn = mean.point / n;
|
||||||
double mg_min = mn / 2.;
|
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 sg2 = sg * sg;
|
||||||
double sb2 = sb * sb;
|
double sb2 = sb * sb;
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ namespace Catch {
|
|||||||
return (nc / n) * (sb2 - nc * sg2);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -138,8 +138,8 @@ namespace Catch {
|
|||||||
double b2 = bias - z1;
|
double b2 = bias - z1;
|
||||||
double a1 = a(b1);
|
double a1 = a(b1);
|
||||||
double a2 = a(b2);
|
double a2 = a(b2);
|
||||||
auto lo = std::max(cumn(a1), 0);
|
auto lo = (std::max)(cumn(a1), 0);
|
||||||
auto hi = std::min(cumn(a2), n - 1);
|
auto hi = (std::min)(cumn(a2), n - 1);
|
||||||
|
|
||||||
return { point, resample[lo], resample[hi], confidence_level };
|
return { point, resample[lo], resample[hi], confidence_level };
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,7 @@ namespace Detail {
|
|||||||
Approx operator-() const;
|
Approx operator-() const;
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
Approx operator()( T const& value ) {
|
Approx operator()( T const& value ) const {
|
||||||
Approx approx( static_cast<double>(value) );
|
Approx approx( static_cast<double>(value) );
|
||||||
approx.m_epsilon = m_epsilon;
|
approx.m_epsilon = m_epsilon;
|
||||||
approx.m_margin = m_margin;
|
approx.m_margin = m_margin;
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
INTERNAL_CATCH_TRY { \
|
INTERNAL_CATCH_TRY { \
|
||||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||||
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
|
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); /* NOLINT(bugprone-chained-comparison) */ \
|
||||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||||
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
||||||
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
||||||
|
@@ -39,13 +39,9 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_lib_uncaught_exceptions)
|
// Only GCC compiler should be used in this block, so other compilers trying to
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
// mask themselves as GCC should be ignored.
|
||||||
#endif
|
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
|
||||||
|
|
||||||
// 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)
|
|
||||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
|
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
|
||||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
|
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
|
||||||
|
|
||||||
@@ -69,7 +65,7 @@
|
|||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
|
// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
|
||||||
# if !defined(__ibmxl__)
|
# if !defined(__ibmxl__) && !defined(__CUDACC__)
|
||||||
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
|
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -150,13 +146,6 @@
|
|||||||
// Visual C++
|
// Visual C++
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
|
|
||||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
|
|
||||||
|
|
||||||
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
|
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Universal Windows platform does not support SEH
|
// Universal Windows platform does not support SEH
|
||||||
// Or console colours (or console at all...)
|
// Or console colours (or console at all...)
|
||||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
@@ -165,13 +154,18 @@
|
|||||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if !defined(__clang__) // Handle Clang masquerading for msvc
|
||||||
|
|
||||||
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
||||||
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
||||||
// _MSVC_TRADITIONAL == 1 means old traditional non-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)
|
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
|
||||||
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
# endif // MSVC_TRADITIONAL
|
# 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 // __clang__
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
@@ -241,7 +235,7 @@
|
|||||||
// Check if byte is available and usable
|
// Check if byte is available and usable
|
||||||
# if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
# if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
||||||
# include <cstddef>
|
# include <cstddef>
|
||||||
# if __cpp_lib_byte > 0
|
# if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
|
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
|
||||||
# endif
|
# endif
|
||||||
# endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
# endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
||||||
@@ -287,10 +281,6 @@
|
|||||||
# define CATCH_CONFIG_CPP17_OPTIONAL
|
# define CATCH_CONFIG_CPP17_OPTIONAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
|
||||||
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
|
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
|
||||||
# define CATCH_CONFIG_CPP17_STRING_VIEW
|
# define CATCH_CONFIG_CPP17_STRING_VIEW
|
||||||
#endif
|
#endif
|
||||||
|
44
include/internal/catch_config_uncaught_exceptions.hpp
Normal file
44
include/internal/catch_config_uncaught_exceptions.hpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
// Copyright Catch2 Authors
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* Wrapper for UNCAUGHT_EXCEPTIONS configuration option
|
||||||
|
*
|
||||||
|
* For some functionality, Catch2 requires to know whether there is
|
||||||
|
* an active exception. Because `std::uncaught_exception` is deprecated
|
||||||
|
* in C++17, we want to use `std::uncaught_exceptions` if possible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
|
||||||
|
#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#if defined(__cpp_lib_uncaught_exceptions) \
|
||||||
|
&& !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
#endif // __cpp_lib_uncaught_exceptions
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
|
||||||
|
&& !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
|
||||||
|
&& !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
|
||||||
|
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
|
@@ -121,7 +121,10 @@ namespace {
|
|||||||
|
|
||||||
#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
|
#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
|
||||||
|
|
||||||
#include <unistd.h>
|
#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC )
|
||||||
|
# define CATCH_INTERNAL_HAS_ISATTY
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -170,7 +173,8 @@ namespace {
|
|||||||
#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
|
#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
|
||||||
!isDebuggerActive() &&
|
!isDebuggerActive() &&
|
||||||
#endif
|
#endif
|
||||||
#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
|
#if defined( CATCH_INTERNAL_HAS_ISATTY ) && \
|
||||||
|
!( defined( __DJGPP__ ) && defined( __STRICT_ANSI__ ) )
|
||||||
isatty(STDOUT_FILENO)
|
isatty(STDOUT_FILENO)
|
||||||
#else
|
#else
|
||||||
false
|
false
|
||||||
|
@@ -20,7 +20,7 @@ namespace Catch {
|
|||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
|
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
#define CATCH_TRAP() __asm__(".inst 0xd43e0000")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(CATCH_PLATFORM_IPHONE)
|
#elif defined(CATCH_PLATFORM_IPHONE)
|
||||||
|
@@ -13,12 +13,20 @@
|
|||||||
|
|
||||||
#ifndef __OBJC__
|
#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)
|
#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
|
||||||
// Standard C/C++ Win32 Unicode wmain entry point
|
// 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
|
#else
|
||||||
// Standard C/C++ main entry point
|
// Standard C/C++ main entry point
|
||||||
int main (int argc, char * argv[]) {
|
int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return Catch::Session().run( argc, argv );
|
return Catch::Session().run( argc, argv );
|
||||||
|
@@ -22,7 +22,7 @@ namespace Catch {
|
|||||||
// Extracts the actual name part of an enum instance
|
// Extracts the actual name part of an enum instance
|
||||||
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
|
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
|
||||||
StringRef extractInstanceName(StringRef enumInstance) {
|
StringRef extractInstanceName(StringRef enumInstance) {
|
||||||
// Find last occurence of ":"
|
// Find last occurrence of ":"
|
||||||
size_t name_start = enumInstance.size();
|
size_t name_start = enumInstance.size();
|
||||||
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
|
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
|
||||||
--name_start;
|
--name_start;
|
||||||
|
@@ -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_fatal_condition.h"
|
||||||
|
|
||||||
#include "catch_context.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__)
|
#include <algorithm>
|
||||||
# pragma GCC diagnostic push
|
|
||||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||||
#endif
|
|
||||||
|
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 )
|
#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Report the error condition
|
//! Signals fatal error message to the run context
|
||||||
void reportFatal( char const * const message ) {
|
void reportFatal( char const * const message ) {
|
||||||
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( 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 )
|
#if defined( CATCH_CONFIG_WINDOWS_SEH )
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct SignalDefs { DWORD id; const char* name; };
|
struct SignalDefs { DWORD id; const char* name; };
|
||||||
|
|
||||||
// There is no 1-1 mapping between signals and windows exceptions.
|
// There is no 1-1 mapping between signals and windows exceptions.
|
||||||
@@ -43,7 +85,7 @@ namespace Catch {
|
|||||||
{ static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
|
{ static_cast<DWORD>(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) {
|
for (auto const& def : signalDefs) {
|
||||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
|
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
|
||||||
reportFatal(def.name);
|
reportFatal(def.name);
|
||||||
@@ -54,39 +96,52 @@ namespace Catch {
|
|||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalConditionHandler::FatalConditionHandler() {
|
// Since we do not support multiple instantiations, we put these
|
||||||
isSet = true;
|
// into global variables and rely on cleaning them up in outlined
|
||||||
// 32k seems enough for Catch to handle stack overflow,
|
// constructors/destructors
|
||||||
// but the value was found experimentally, so there is no strong guarantee
|
static PVOID exceptionHandlerHandle = nullptr;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FatalConditionHandler::reset() {
|
|
||||||
if (isSet) {
|
// For MSVC, we reserve part of the stack memory for handling
|
||||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
// memory overflow structured exception.
|
||||||
SetThreadStackGuarantee(&guaranteeSize);
|
FatalConditionHandler::FatalConditionHandler() {
|
||||||
exceptionHandlerHandle = nullptr;
|
ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
|
||||||
isSet = false;
|
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() {
|
// We do not attempt to unset the stack guarantee, because
|
||||||
reset();
|
// 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;
|
void FatalConditionHandler::disengage_platform() {
|
||||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
||||||
PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
|
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 <signal.h>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@@ -94,10 +149,6 @@ namespace Catch {
|
|||||||
int id;
|
int id;
|
||||||
const char* name;
|
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[] = {
|
static SignalDefs signalDefs[] = {
|
||||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||||
@@ -108,8 +159,32 @@ namespace Catch {
|
|||||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
{ 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 = "<unknown signal>";
|
char const * name = "<unknown signal>";
|
||||||
for (auto const& def : signalDefs) {
|
for (auto const& def : signalDefs) {
|
||||||
if (sig == def.id) {
|
if (sig == def.id) {
|
||||||
@@ -117,16 +192,33 @@ namespace Catch {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset();
|
// We need to restore previous signal handlers and let them do
|
||||||
reportFatal(name);
|
// their thing, so that the users can have the debugger break
|
||||||
|
// when a signal is raised, and so on.
|
||||||
|
restorePreviousSignalHandlers();
|
||||||
|
reportFatal( name );
|
||||||
raise( sig );
|
raise( sig );
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalConditionHandler::FatalConditionHandler() {
|
FatalConditionHandler::FatalConditionHandler() {
|
||||||
isSet = true;
|
assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
|
||||||
|
if (altStackSize == 0) {
|
||||||
|
altStackSize = std::max(static_cast<size_t>(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;
|
stack_t sigStack;
|
||||||
sigStack.ss_sp = altStackMem;
|
sigStack.ss_sp = altStackMem;
|
||||||
sigStack.ss_size = sigStackSize;
|
sigStack.ss_size = altStackSize;
|
||||||
sigStack.ss_flags = 0;
|
sigStack.ss_flags = 0;
|
||||||
sigaltstack(&sigStack, &oldSigStack);
|
sigaltstack(&sigStack, &oldSigStack);
|
||||||
struct sigaction sa = { };
|
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__)
|
#if defined(__GNUC__)
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void FatalConditionHandler::disengage_platform() {
|
||||||
|
restorePreviousSignalHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||||
|
@@ -11,59 +11,58 @@
|
|||||||
|
|
||||||
#include "catch_platform.h"
|
#include "catch_platform.h"
|
||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
#include "catch_windows_h_proxy.h"
|
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#if defined( CATCH_CONFIG_WINDOWS_SEH )
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
// Wrapper for platform-specific fatal error (signals/SEH) handlers
|
||||||
|
//
|
||||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
|
// Tries to be cooperative with other handlers, and not step over
|
||||||
FatalConditionHandler();
|
// other handlers. This means that unknown structured exceptions
|
||||||
static void reset();
|
// are passed on, previous signal handlers are called, and so on.
|
||||||
~FatalConditionHandler();
|
//
|
||||||
|
// Can only be instantiated once, and assumes that once a signal
|
||||||
private:
|
// is caught, the binary will end up terminating. Thus, there
|
||||||
static bool isSet;
|
class FatalConditionHandler {
|
||||||
static ULONG guaranteeSize;
|
bool m_started = false;
|
||||||
static PVOID exceptionHandlerHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Catch
|
|
||||||
|
|
||||||
#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
namespace Catch {
|
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
|
||||||
|
|
||||||
static bool isSet;
|
|
||||||
static struct sigaction oldSigActions[];
|
|
||||||
static stack_t oldSigStack;
|
|
||||||
static char altStackMem[];
|
|
||||||
|
|
||||||
static void handleSignal( int sig );
|
|
||||||
|
|
||||||
|
// 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();
|
||||||
~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
|
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
|
||||||
|
class FatalConditionHandlerGuard {
|
||||||
|
FatalConditionHandler* m_handler;
|
||||||
#else
|
public:
|
||||||
|
FatalConditionHandlerGuard(FatalConditionHandler* handler):
|
||||||
namespace Catch {
|
m_handler(handler) {
|
||||||
struct FatalConditionHandler {
|
m_handler->engage();
|
||||||
void reset();
|
}
|
||||||
|
~FatalConditionHandlerGuard() {
|
||||||
|
m_handler->disengage();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||||
|
@@ -63,7 +63,7 @@ namespace Generators {
|
|||||||
if (!m_predicate(m_generator.get())) {
|
if (!m_predicate(m_generator.get())) {
|
||||||
// It might happen that there are no values that pass the
|
// It might happen that there are no values that pass the
|
||||||
// filter. In that case we throw an exception.
|
// filter. In that case we throw an exception.
|
||||||
auto has_initial_value = next();
|
auto has_initial_value = nextImpl();
|
||||||
if (!has_initial_value) {
|
if (!has_initial_value) {
|
||||||
Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
|
Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
|
||||||
}
|
}
|
||||||
@@ -75,6 +75,11 @@ namespace Generators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool next() override {
|
bool next() override {
|
||||||
|
return nextImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool nextImpl() {
|
||||||
bool success = m_generator.next();
|
bool success = m_generator.next();
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
|
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
|
||||||
#include "benchmark/catch_estimate.hpp"
|
#include "benchmark/catch_estimate.hpp"
|
||||||
#include "benchmark/catch_outlier_classification.hpp"
|
#include "benchmark/catch_outlier_classification.hpp"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||||
|
|
||||||
|
|
||||||
|
@@ -55,7 +55,8 @@ namespace {
|
|||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ulpDiff = std::abs(lc - rc);
|
// static cast as a workaround for IBM XLC
|
||||||
|
auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
|
||||||
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
|
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,4 +235,3 @@ Floating::WithinRelMatcher WithinRel(float target) {
|
|||||||
|
|
||||||
} // namespace Matchers
|
} // namespace Matchers
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
|
@@ -66,7 +66,7 @@ namespace Catch {
|
|||||||
if (tmpnam_s(m_buffer)) {
|
if (tmpnam_s(m_buffer)) {
|
||||||
CATCH_RUNTIME_ERROR("Could not get a temp filename");
|
CATCH_RUNTIME_ERROR("Could not get a temp filename");
|
||||||
}
|
}
|
||||||
if (fopen_s(&m_file, m_buffer, "w")) {
|
if (fopen_s(&m_file, m_buffer, "w+")) {
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
if (strerror_s(buffer, errno)) {
|
if (strerror_s(buffer, errno)) {
|
||||||
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
|
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
|
||||||
|
@@ -9,13 +9,19 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
||||||
|
|
||||||
|
// See e.g.:
|
||||||
|
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include <TargetConditionals.h>
|
# ifndef __has_extension
|
||||||
# if TARGET_OS_OSX == 1
|
# define __has_extension(x) 0
|
||||||
# define CATCH_PLATFORM_MAC
|
# endif
|
||||||
# elif TARGET_OS_IPHONE == 1
|
# include <TargetConditionals.h>
|
||||||
# define CATCH_PLATFORM_IPHONE
|
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
|
||||||
# endif
|
(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__)
|
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||||
# define CATCH_PLATFORM_LINUX
|
# define CATCH_PLATFORM_LINUX
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "catch_interfaces_registry_hub.h"
|
#include "catch_interfaces_registry_hub.h"
|
||||||
|
|
||||||
#include "catch_context.h"
|
#include "catch_context.h"
|
||||||
|
#include "catch_enforce.h"
|
||||||
#include "catch_test_case_registry_impl.h"
|
#include "catch_test_case_registry_impl.h"
|
||||||
#include "catch_reporter_registry.h"
|
#include "catch_reporter_registry.h"
|
||||||
#include "catch_exception_translator_registry.h"
|
#include "catch_exception_translator_registry.h"
|
||||||
|
@@ -71,13 +71,53 @@ namespace Catch {
|
|||||||
// `SECTION`s.
|
// `SECTION`s.
|
||||||
// **The check for m_children.empty cannot be removed**.
|
// **The check for m_children.empty cannot be removed**.
|
||||||
// doing so would break `GENERATE` _not_ followed by `SECTION`s.
|
// doing so would break `GENERATE` _not_ followed by `SECTION`s.
|
||||||
const bool should_wait_for_child =
|
const bool should_wait_for_child = [&]() {
|
||||||
!m_children.empty() &&
|
// No children -> nobody to wait for
|
||||||
std::find_if( m_children.begin(),
|
if ( m_children.empty() ) {
|
||||||
m_children.end(),
|
return false;
|
||||||
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
}
|
||||||
return tracker->hasStarted();
|
// If at least one child started executing, don't wait
|
||||||
} ) == m_children.end();
|
if ( std::find_if(
|
||||||
|
m_children.begin(),
|
||||||
|
m_children.end(),
|
||||||
|
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
||||||
|
return tracker->hasStarted();
|
||||||
|
} ) != m_children.end() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No children have started. We need to check if they _can_
|
||||||
|
// start, and thus we should wait for them, or they cannot
|
||||||
|
// start (due to filters), and we shouldn't wait for them
|
||||||
|
auto* parent = m_parent;
|
||||||
|
// This is safe: there is always at least one section
|
||||||
|
// tracker in a test case tracking tree
|
||||||
|
while ( !parent->isSectionTracker() ) {
|
||||||
|
parent = &( parent->parent() );
|
||||||
|
}
|
||||||
|
assert( parent &&
|
||||||
|
"Missing root (test case) level section" );
|
||||||
|
|
||||||
|
auto const& parentSection =
|
||||||
|
static_cast<SectionTracker&>( *parent );
|
||||||
|
auto const& filters = parentSection.getFilters();
|
||||||
|
// No filters -> no restrictions on running sections
|
||||||
|
if ( filters.empty() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto const& child : m_children ) {
|
||||||
|
if ( child->isSectionTracker() &&
|
||||||
|
std::find( filters.begin(),
|
||||||
|
filters.end(),
|
||||||
|
static_cast<SectionTracker&>( *child )
|
||||||
|
.trimmedName() ) !=
|
||||||
|
filters.end() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
|
||||||
// This check is a bit tricky, because m_generator->next()
|
// This check is a bit tricky, because m_generator->next()
|
||||||
// has a side-effect, where it consumes generator's current
|
// has a side-effect, where it consumes generator's current
|
||||||
@@ -412,9 +452,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RunContext::invokeActiveTestCase() {
|
void RunContext::invokeActiveTestCase() {
|
||||||
FatalConditionHandler fatalConditionHandler; // Handle signals
|
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
||||||
m_activeTestCase->invoke();
|
m_activeTestCase->invoke();
|
||||||
fatalConditionHandler.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunContext::handleUnfinishedSections() {
|
void RunContext::handleUnfinishedSections() {
|
||||||
|
@@ -146,6 +146,7 @@ namespace Catch {
|
|||||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||||
std::vector<ITracker*> m_activeSections;
|
std::vector<ITracker*> m_activeSections;
|
||||||
TrackerContext m_trackerContext;
|
TrackerContext m_trackerContext;
|
||||||
|
FatalConditionHandler m_fatalConditionhandler;
|
||||||
bool m_lastAssertionPassed = false;
|
bool m_lastAssertionPassed = false;
|
||||||
bool m_shouldReportUnexpected = true;
|
bool m_shouldReportUnexpected = true;
|
||||||
bool m_includeSuccessfulResults;
|
bool m_includeSuccessfulResults;
|
||||||
|
@@ -127,6 +127,10 @@ namespace Catch {
|
|||||||
filename.erase(0, lastSlash);
|
filename.erase(0, lastSlash);
|
||||||
filename[0] = '#';
|
filename[0] = '#';
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename.insert(0, "#");
|
||||||
|
}
|
||||||
|
|
||||||
auto lastDot = filename.find_last_of('.');
|
auto lastDot = filename.find_last_of('.');
|
||||||
if (lastDot != std::string::npos) {
|
if (lastDot != std::string::npos) {
|
||||||
@@ -289,7 +293,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Handle list request
|
// Handle list request
|
||||||
if( Option<std::size_t> listed = list( m_config ) )
|
if( Option<std::size_t> listed = list( m_config ) )
|
||||||
return static_cast<int>( *listed );
|
return (std::min) (MaxExitCode, static_cast<int>(*listed));
|
||||||
|
|
||||||
TestGroup tests { m_config };
|
TestGroup tests { m_config };
|
||||||
auto const totals = tests.execute();
|
auto const totals = tests.execute();
|
||||||
|
@@ -22,24 +22,28 @@ namespace Catch {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct TestHasher {
|
struct TestHasher {
|
||||||
explicit TestHasher(Catch::SimplePcg32& rng) {
|
using hash_t = uint64_t;
|
||||||
basis = rng();
|
|
||||||
basis <<= 32;
|
|
||||||
basis |= rng();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t basis;
|
explicit TestHasher( hash_t hashSuffix ):
|
||||||
|
m_hashSuffix{ hashSuffix } {}
|
||||||
|
|
||||||
uint64_t operator()(TestCase const& t) const {
|
uint32_t operator()( TestCase const& t ) const {
|
||||||
// Modified FNV-1a hash
|
// FNV-1a hash with multiplication fold.
|
||||||
static constexpr uint64_t prime = 1099511628211;
|
const hash_t prime = 1099511628211u;
|
||||||
uint64_t hash = basis;
|
hash_t hash = 14695981039346656037u;
|
||||||
for (const char c : t.name) {
|
for ( const char c : t.name ) {
|
||||||
hash ^= c;
|
hash ^= c;
|
||||||
hash *= prime;
|
hash *= prime;
|
||||||
}
|
}
|
||||||
return hash;
|
hash ^= m_hashSuffix;
|
||||||
|
hash *= prime;
|
||||||
|
const uint32_t low{ static_cast<uint32_t>( hash ) };
|
||||||
|
const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
|
||||||
|
return low * high;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
hash_t m_hashSuffix;
|
||||||
};
|
};
|
||||||
} // end unnamed namespace
|
} // end unnamed namespace
|
||||||
|
|
||||||
@@ -58,9 +62,9 @@ namespace Catch {
|
|||||||
|
|
||||||
case RunTests::InRandomOrder: {
|
case RunTests::InRandomOrder: {
|
||||||
seedRng( config );
|
seedRng( config );
|
||||||
TestHasher h( rng() );
|
TestHasher h{ config.rngSeed() };
|
||||||
|
|
||||||
using hashedTest = std::pair<uint64_t, TestCase const*>;
|
using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
|
||||||
std::vector<hashedTest> indexed_tests;
|
std::vector<hashedTest> indexed_tests;
|
||||||
indexed_tests.reserve( unsortedTestCases.size() );
|
indexed_tests.reserve( unsortedTestCases.size() );
|
||||||
|
|
||||||
|
@@ -233,6 +233,14 @@ namespace TestCaseTracking {
|
|||||||
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
|
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> const& SectionTracker::getFilters() const {
|
||||||
|
return m_filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const& SectionTracker::trimmedName() const {
|
||||||
|
return m_trimmed_name;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TestCaseTracking
|
} // namespace TestCaseTracking
|
||||||
|
|
||||||
using TestCaseTracking::ITracker;
|
using TestCaseTracking::ITracker;
|
||||||
|
@@ -163,6 +163,10 @@ namespace TestCaseTracking {
|
|||||||
|
|
||||||
void addInitialFilters( std::vector<std::string> const& filters );
|
void addInitialFilters( std::vector<std::string> const& filters );
|
||||||
void addNextFilters( std::vector<std::string> const& filters );
|
void addNextFilters( std::vector<std::string> const& filters );
|
||||||
|
//! Returns filters active in this tracker
|
||||||
|
std::vector<std::string> const& getFilters() const;
|
||||||
|
//! Returns whitespace-trimmed name of the tracked section
|
||||||
|
std::string const& trimmedName() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TestCaseTracking
|
} // namespace TestCaseTracking
|
||||||
|
@@ -71,34 +71,34 @@ struct AutoReg : NonCopyable {
|
|||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ struct AutoReg : NonCopyable {
|
|||||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||||
static void TestName()
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#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, ... ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||||
@@ -133,7 +133,7 @@ struct AutoReg : NonCopyable {
|
|||||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||||
void TestName::test()
|
void TestName::test()
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
#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, ... ) \
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
@@ -174,18 +174,18 @@ struct AutoReg : NonCopyable {
|
|||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
|
#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
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
|
#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
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
|
#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
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
|
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
|
||||||
@@ -265,7 +265,7 @@ struct AutoReg : NonCopyable {
|
|||||||
static void TestFunc()
|
static void TestFunc()
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
|
#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, ... ) \
|
#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
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
|
#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
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
|
#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
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
|
#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
|
#else
|
||||||
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
|
#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
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
|
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
|
||||||
@@ -396,7 +396,7 @@ struct AutoReg : NonCopyable {
|
|||||||
void TestName<TestType>::test()
|
void TestName<TestType>::test()
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
|
#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
|
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
#include "catch_uncaught_exceptions.h"
|
#include "catch_uncaught_exceptions.h"
|
||||||
|
#include "catch_config_uncaught_exceptions.hpp"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 13, 1, "", 0 );
|
static Version version( 2, 13, 10, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ namespace Catch {
|
|||||||
#else
|
#else
|
||||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||||
#endif
|
#endif
|
||||||
return std::string(timeStamp);
|
return std::string(timeStamp, timeStampSize-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fileNameTag(const std::vector<std::string> &tags) {
|
std::string fileNameTag(const std::vector<std::string> &tags) {
|
||||||
@@ -56,6 +57,17 @@ namespace Catch {
|
|||||||
return it->substr(1);
|
return it->substr(1);
|
||||||
return std::string();
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
JunitReporter::JunitReporter( ReporterConfig const& _config )
|
JunitReporter::JunitReporter( ReporterConfig const& _config )
|
||||||
@@ -125,7 +137,7 @@ namespace Catch {
|
|||||||
if( m_config->showDurations() == ShowDurations::Never )
|
if( m_config->showDurations() == ShowDurations::Never )
|
||||||
xml.writeAttribute( "time", "" );
|
xml.writeAttribute( "time", "" );
|
||||||
else
|
else
|
||||||
xml.writeAttribute( "time", suiteTime );
|
xml.writeAttribute( "time", formatDuration( suiteTime ) );
|
||||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||||
|
|
||||||
// Write properties if there are any
|
// Write properties if there are any
|
||||||
@@ -170,12 +182,13 @@ namespace Catch {
|
|||||||
if ( !m_config->name().empty() )
|
if ( !m_config->name().empty() )
|
||||||
className = m_config->name() + "." + className;
|
className = m_config->name() + "." + className;
|
||||||
|
|
||||||
writeSection( className, "", rootSection );
|
writeSection( className, "", rootSection, stats.testInfo.okToFail() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void JunitReporter::writeSection( std::string const& className,
|
void JunitReporter::writeSection( std::string const& className,
|
||||||
std::string const& rootName,
|
std::string const& rootName,
|
||||||
SectionNode const& sectionNode ) {
|
SectionNode const& sectionNode,
|
||||||
|
bool testOkToFail) {
|
||||||
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
||||||
if( !rootName.empty() )
|
if( !rootName.empty() )
|
||||||
name = rootName + '/' + name;
|
name = rootName + '/' + name;
|
||||||
@@ -192,15 +205,21 @@ namespace Catch {
|
|||||||
xml.writeAttribute( "classname", className );
|
xml.writeAttribute( "classname", className );
|
||||||
xml.writeAttribute( "name", name );
|
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
|
// This is not ideal, but it should be enough to mimic gtest's
|
||||||
// junit output.
|
// junit output.
|
||||||
// Ideally the JUnit reporter would also handle `skipTest`
|
// Ideally the JUnit reporter would also handle `skipTest`
|
||||||
// events and write those out appropriately.
|
// events and write those out appropriately.
|
||||||
xml.writeAttribute( "status", "run" );
|
xml.writeAttribute( "status", "run" );
|
||||||
|
|
||||||
|
if (sectionNode.stats.assertions.failedButOk) {
|
||||||
|
xml.scopedElement("skipped")
|
||||||
|
.writeAttribute("message", "TEST_CASE tagged with !mayfail");
|
||||||
|
}
|
||||||
|
|
||||||
writeAssertions( sectionNode );
|
writeAssertions( sectionNode );
|
||||||
|
|
||||||
|
|
||||||
if( !sectionNode.stdOut.empty() )
|
if( !sectionNode.stdOut.empty() )
|
||||||
xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
|
xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
|
||||||
if( !sectionNode.stdErr.empty() )
|
if( !sectionNode.stdErr.empty() )
|
||||||
@@ -208,9 +227,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
for( auto const& childNode : sectionNode.childSections )
|
for( auto const& childNode : sectionNode.childSections )
|
||||||
if( className.empty() )
|
if( className.empty() )
|
||||||
writeSection( name, "", *childNode );
|
writeSection( name, "", *childNode, testOkToFail );
|
||||||
else
|
else
|
||||||
writeSection( className, name, *childNode );
|
writeSection( className, name, *childNode, testOkToFail );
|
||||||
}
|
}
|
||||||
|
|
||||||
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
|
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
|
||||||
|
@@ -41,9 +41,10 @@ namespace Catch {
|
|||||||
|
|
||||||
void writeTestCase(TestCaseNode const& testCaseNode);
|
void writeTestCase(TestCaseNode const& testCaseNode);
|
||||||
|
|
||||||
void writeSection(std::string const& className,
|
void writeSection( std::string const& className,
|
||||||
std::string const& rootName,
|
std::string const& rootName,
|
||||||
SectionNode const& sectionNode);
|
SectionNode const& sectionNode,
|
||||||
|
bool testOkToFail );
|
||||||
|
|
||||||
void writeAssertions(SectionNode const& sectionNode);
|
void writeAssertions(SectionNode const& sectionNode);
|
||||||
void writeAssertion(AssertionStats const& stats);
|
void writeAssertion(AssertionStats const& stats);
|
||||||
|
@@ -124,6 +124,7 @@ set(INTERNAL_HEADERS
|
|||||||
${HEADER_DIR}/internal/catch_common.h
|
${HEADER_DIR}/internal/catch_common.h
|
||||||
${HEADER_DIR}/internal/catch_compiler_capabilities.h
|
${HEADER_DIR}/internal/catch_compiler_capabilities.h
|
||||||
${HEADER_DIR}/internal/catch_config.hpp
|
${HEADER_DIR}/internal/catch_config.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_config_uncaught_exceptions.hpp
|
||||||
${HEADER_DIR}/internal/catch_console_colour.h
|
${HEADER_DIR}/internal/catch_console_colour.h
|
||||||
${HEADER_DIR}/internal/catch_context.h
|
${HEADER_DIR}/internal/catch_context.h
|
||||||
${HEADER_DIR}/internal/catch_debug_console.h
|
${HEADER_DIR}/internal/catch_debug_console.h
|
||||||
@@ -353,7 +354,7 @@ endif()
|
|||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
|
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
|
||||||
if (CATCH_ENABLE_WERROR)
|
if (CATCH_ENABLE_WERROR)
|
||||||
target_compile_options( SelfTest PRIVATE -Werror )
|
target_compile_options( SelfTest PRIVATE -Werror -Wno-error=pragmas )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
# Clang specific options go here
|
# Clang specific options go here
|
||||||
@@ -418,6 +419,33 @@ set_tests_properties(FilteredSection-1 PROPERTIES FAIL_REGULAR_EXPRESSION "No te
|
|||||||
add_test(NAME FilteredSection-2 COMMAND $<TARGET_FILE:SelfTest> \#1394\ nested -c NestedRunSection -c s1)
|
add_test(NAME FilteredSection-2 COMMAND $<TARGET_FILE:SelfTest> \#1394\ nested -c NestedRunSection -c s1)
|
||||||
set_tests_properties(FilteredSection-2 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
|
set_tests_properties(FilteredSection-2 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME
|
||||||
|
FilteredSection::GeneratorsDontCauseInfiniteLoop-1
|
||||||
|
COMMAND
|
||||||
|
$<TARGET_FILE:SelfTest> "#2025: original repro" -c "fov_0"
|
||||||
|
)
|
||||||
|
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-1
|
||||||
|
PROPERTIES
|
||||||
|
PASS_REGULAR_EXPRESSION "inside with fov: 0" # This should happen
|
||||||
|
FAIL_REGULAR_EXPRESSION "inside with fov: 1" # This would mean there was no filtering
|
||||||
|
)
|
||||||
|
|
||||||
|
# GENERATE between filtered sections (both are selected)
|
||||||
|
add_test(
|
||||||
|
NAME
|
||||||
|
FilteredSection::GeneratorsDontCauseInfiniteLoop-2
|
||||||
|
COMMAND
|
||||||
|
$<TARGET_FILE:SelfTest> "#2025: same-level sections"
|
||||||
|
-c "A"
|
||||||
|
-c "B"
|
||||||
|
)
|
||||||
|
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-2
|
||||||
|
PROPERTIES
|
||||||
|
PASS_REGULAR_EXPRESSION "All tests passed \\(4 assertions in 1 test case\\)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
|
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
|
||||||
add_test(NAME ApprovalTests COMMAND ${PYTHON_EXECUTABLE} ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
add_test(NAME ApprovalTests COMMAND ${PYTHON_EXECUTABLE} ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
||||||
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
||||||
|
@@ -53,6 +53,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
|
|||||||
CATCH_SECTION("some section") {
|
CATCH_SECTION("some section") {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
CATCH_CAPTURE( i );
|
CATCH_CAPTURE( i );
|
||||||
|
CATCH_CAPTURE( i, i + 1 );
|
||||||
CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
|
CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
|
||||||
CATCH_FAIL_CHECK( "failure" );
|
CATCH_FAIL_CHECK( "failure" );
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,10 @@ foo f;
|
|||||||
|
|
||||||
// This test should not be run, because it won't be registered
|
// This test should not be run, because it won't be registered
|
||||||
TEST_CASE( "Disabled Macros" ) {
|
TEST_CASE( "Disabled Macros" ) {
|
||||||
|
|
||||||
|
CAPTURE( 1 );
|
||||||
|
CAPTURE( 1, "captured" );
|
||||||
|
|
||||||
std::cout << "This should not happen\n";
|
std::cout << "This should not happen\n";
|
||||||
FAIL();
|
FAIL();
|
||||||
}
|
}
|
||||||
|
@@ -628,6 +628,7 @@ GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
|||||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 3 for: 3 == 3
|
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 3 for: 3 == 3
|
||||||
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
|
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
|
||||||
GeneratorsImpl.tests.cpp:<line number>: passed: filter([] (int) { return false; }, value(1)), Catch::GeneratorException
|
GeneratorsImpl.tests.cpp:<line number>: passed: filter([] (int) { return false; }, value(1)), Catch::GeneratorException
|
||||||
|
GeneratorsImpl.tests.cpp:<line number>: passed: filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
|
||||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
|
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
|
||||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
||||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2 for: 2 == 2
|
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2 for: 2 == 2
|
||||||
@@ -846,6 +847,10 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), (Contains("st
|
|||||||
Matchers.tests.cpp:<line number>: 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:<line number>: 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:<line number>: passed: testStringForMatching(), !Contains("different") for: "this string contains 'abc' as a substring" not contains: "different"
|
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), !Contains("different") for: "this string contains 'abc' as a substring" not contains: "different"
|
||||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring"
|
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring"
|
||||||
|
Condition.tests.cpp:<line number>: failed: explicitly
|
||||||
|
Condition.tests.cpp:<line number>: failed: explicitly
|
||||||
|
Condition.tests.cpp:<line number>: failed: explicitly
|
||||||
|
Condition.tests.cpp:<line number>: failed: explicitly
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||||
Exception.tests.cpp:<line number>: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail"
|
Exception.tests.cpp:<line number>: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail"
|
||||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 3 > -6
|
Generators.tests.cpp:<line number>: passed: values > -6 for: 3 > -6
|
||||||
|
@@ -694,6 +694,46 @@ Matchers.tests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" not contains: "substring"
|
"this string contains 'abc' as a substring" not contains: "substring"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
A
|
||||||
|
1
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
A
|
||||||
|
2
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
B
|
||||||
|
1
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
B
|
||||||
|
2
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Mismatching exception messages failing the test
|
Mismatching exception messages failing the test
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -1380,6 +1420,6 @@ due to unexpected exception with message:
|
|||||||
Why would you throw a std::string?
|
Why would you throw a std::string?
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 322 | 248 passed | 70 failed | 4 failed as expected
|
test cases: 323 | 248 passed | 70 failed | 5 failed as expected
|
||||||
assertions: 1759 | 1607 passed | 131 failed | 21 failed as expected
|
assertions: 1764 | 1608 passed | 131 failed | 25 failed as expected
|
||||||
|
|
||||||
|
@@ -4968,6 +4968,9 @@ with expansion:
|
|||||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||||
REQUIRE_THROWS_AS( filter([] (int) { return false; }, value(1)), Catch::GeneratorException )
|
REQUIRE_THROWS_AS( filter([] (int) { return false; }, value(1)), Catch::GeneratorException )
|
||||||
|
|
||||||
|
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||||
|
REQUIRE_THROWS_AS( filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException )
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Generators internals
|
Generators internals
|
||||||
Take generator
|
Take generator
|
||||||
@@ -6492,6 +6495,46 @@ Matchers.tests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" not contains: "substring"
|
"this string contains 'abc' as a substring" not contains: "substring"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
A
|
||||||
|
1
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
A
|
||||||
|
2
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
B
|
||||||
|
1
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mayfail test case with nested sections
|
||||||
|
B
|
||||||
|
2
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Condition.tests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Mismatching exception messages failing the test
|
Mismatching exception messages failing the test
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -14138,6 +14181,6 @@ Misc.tests.cpp:<line number>
|
|||||||
Misc.tests.cpp:<line number>: PASSED:
|
Misc.tests.cpp:<line number>: PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 322 | 232 passed | 86 failed | 4 failed as expected
|
test cases: 323 | 232 passed | 86 failed | 5 failed as expected
|
||||||
assertions: 1776 | 1607 passed | 148 failed | 21 failed as expected
|
assertions: 1781 | 1608 passed | 148 failed | 25 failed as expected
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<testsuitesloose text artifact
|
||||||
>
|
>
|
||||||
<testsuite name="<exe-name>" errors="17" failures="132" tests="1777" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="17" failures="132" tests="1782" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
|
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
@@ -48,6 +48,7 @@ Nor would this
|
|||||||
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 1, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 1, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
<error type="TEST_CASE">
|
<error type="TEST_CASE">
|
||||||
FAILED:
|
FAILED:
|
||||||
expected exception
|
expected exception
|
||||||
@@ -56,6 +57,7 @@ Exception.tests.cpp:<line number>
|
|||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/inside REQUIRE_NOTHROW" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/inside REQUIRE_NOTHROW" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
<error message="thisThrows()" type="REQUIRE_NOTHROW">
|
<error message="thisThrows()" type="REQUIRE_NOTHROW">
|
||||||
FAILED:
|
FAILED:
|
||||||
REQUIRE_NOTHROW( thisThrows() )
|
REQUIRE_NOTHROW( thisThrows() )
|
||||||
@@ -68,6 +70,7 @@ Exception.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="#809" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="#809" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="#833" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="#833" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="#835 -- errno should not be touched by Catch" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="#835 -- errno should not be touched by Catch" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
<failure message="f() == 0" type="CHECK">
|
<failure message="f() == 0" type="CHECK">
|
||||||
FAILED:
|
FAILED:
|
||||||
CHECK( f() == 0 )
|
CHECK( f() == 0 )
|
||||||
@@ -443,6 +446,7 @@ Matchers.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="Epsilon only applies to Approx's value" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="Epsilon only applies to Approx's value" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
<failure message="data.int_seven == 6" type="CHECK">
|
<failure message="data.int_seven == 6" type="CHECK">
|
||||||
FAILED:
|
FAILED:
|
||||||
CHECK( data.int_seven == 6 )
|
CHECK( data.int_seven == 6 )
|
||||||
@@ -736,6 +740,7 @@ Message.tests.cpp:<line number>
|
|||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Inequality checks that should fail" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="Inequality checks that should fail" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
<failure message="data.int_seven != 7" type="CHECK">
|
<failure message="data.int_seven != 7" type="CHECK">
|
||||||
FAILED:
|
FAILED:
|
||||||
CHECK( data.int_seven != 7 )
|
CHECK( data.int_seven != 7 )
|
||||||
@@ -799,6 +804,34 @@ with expansion:
|
|||||||
Matchers.tests.cpp:<line number>
|
Matchers.tests.cpp:<line number>
|
||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Mayfail test case with nested sections/1/A" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
|
<failure type="FAIL">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Mayfail test case with nested sections/2/A" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
|
<failure type="FAIL">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Mayfail test case with nested sections/1/B" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
|
<failure type="FAIL">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Mayfail test case with nested sections/2/B" time="{duration}" status="run">
|
||||||
|
<skipped message="TEST_CASE tagged with !mayfail"/>
|
||||||
|
<failure type="FAIL">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Mismatching exception messages failing the test" time="{duration}" status="run">
|
<testcase classname="<exe-name>.global" name="Mismatching exception messages failing the test" time="{duration}" status="run">
|
||||||
<failure message="thisThrows(), "should fail"" type="REQUIRE_THROWS_WITH">
|
<failure message="thisThrows(), "should fail"" type="REQUIRE_THROWS_WITH">
|
||||||
FAILED:
|
FAILED:
|
||||||
|
@@ -575,6 +575,30 @@ Condition.tests.cpp:<line number>
|
|||||||
</skipped>
|
</skipped>
|
||||||
</testCase>
|
</testCase>
|
||||||
<testCase name="Inequality checks that should succeed" duration="{duration}"/>
|
<testCase name="Inequality checks that should succeed" duration="{duration}"/>
|
||||||
|
<testCase name="Mayfail test case with nested sections/1/A" duration="{duration}">
|
||||||
|
<skipped message="FAIL()">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</skipped>
|
||||||
|
</testCase>
|
||||||
|
<testCase name="Mayfail test case with nested sections/2/A" duration="{duration}">
|
||||||
|
<skipped message="FAIL()">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</skipped>
|
||||||
|
</testCase>
|
||||||
|
<testCase name="Mayfail test case with nested sections/1/B" duration="{duration}">
|
||||||
|
<skipped message="FAIL()">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</skipped>
|
||||||
|
</testCase>
|
||||||
|
<testCase name="Mayfail test case with nested sections/2/B" duration="{duration}">
|
||||||
|
<skipped message="FAIL()">
|
||||||
|
FAILED:
|
||||||
|
Condition.tests.cpp:<line number>
|
||||||
|
</skipped>
|
||||||
|
</testCase>
|
||||||
<testCase name="Ordering comparison checks that should fail" duration="{duration}">
|
<testCase name="Ordering comparison checks that should fail" duration="{duration}">
|
||||||
<failure message="CHECK(data.int_seven > 7)">
|
<failure message="CHECK(data.int_seven > 7)">
|
||||||
FAILED:
|
FAILED:
|
||||||
|
@@ -5720,7 +5720,15 @@ Nor would this
|
|||||||
filter([] (int) { return false; }, value(1)), Catch::GeneratorException
|
filter([] (int) { return false; }, value(1)), Catch::GeneratorException
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
<OverallResults successes="5" failures="0" expectedFailures="0"/>
|
<Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ), Catch::GeneratorException
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="6" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="Take generator" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
<Section name="Take generator" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||||
<Section name="Take less" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
<Section name="Take less" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||||
@@ -7956,6 +7964,43 @@ Nor would this
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Mayfail test case with nested sections" tags="[!mayfail]" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Section name="A" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Section name="1" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Failure filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" />
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="A" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Section name="2" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Failure filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" />
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="A" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="B" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Section name="1" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Failure filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" />
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="B" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Section name="2" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<Failure filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" />
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="1"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="B" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
|
<OverallResults successes="0" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Mismatching exception messages failing the test" tags="[!hide][!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<TestCase name="Mismatching exception messages failing the test" tags="[!hide][!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -16722,9 +16767,9 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="1607" failures="149" expectedFailures="21"/>
|
<OverallResults successes="1608" failures="149" expectedFailures="25"/>
|
||||||
<OverallResultsCases successes="232" failures="86" expectedFailures="4"/>
|
<OverallResultsCases successes="232" failures="86" expectedFailures="5"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="1607" failures="148" expectedFailures="21"/>
|
<OverallResults successes="1608" failures="148" expectedFailures="25"/>
|
||||||
<OverallResultsCases successes="232" failures="86" expectedFailures="4"/>
|
<OverallResultsCases successes="232" failures="86" expectedFailures="5"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@@ -53,6 +53,9 @@ TEST_CASE("Generators internals", "[generators][internals]") {
|
|||||||
|
|
||||||
// Completely filtered-out generator should throw on construction
|
// 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; }, value(1)), Catch::GeneratorException);
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
filter( []( int ) { return false; }, values( { 1, 2, 3 } ) ),
|
||||||
|
Catch::GeneratorException );
|
||||||
}
|
}
|
||||||
SECTION("Take generator") {
|
SECTION("Take generator") {
|
||||||
SECTION("Take less") {
|
SECTION("Take less") {
|
||||||
|
@@ -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
|
}} // namespace ApproxTests
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
// Wdouble-promotion is not supported until 3.8
|
// Wdouble-promotion is not supported until 3.8
|
||||||
# if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7)
|
# if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7)
|
||||||
# pragma clang diagnostic ignored "-Wdouble-promotion"
|
# pragma clang diagnostic ignored "-Wdouble-promotion"
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
@@ -89,6 +89,19 @@ TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
|
|||||||
CHECK( x == Approx( 1.301 ) );
|
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" )
|
TEST_CASE( "Inequality checks that should succeed" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
@@ -58,12 +58,12 @@ TEST_CASE("tables", "[generators]") {
|
|||||||
|
|
||||||
// Structured bindings make the table utility much nicer to use
|
// Structured bindings make the table utility much nicer to use
|
||||||
TEST_CASE( "strlen2", "[approvals][generators]" ) {
|
TEST_CASE( "strlen2", "[approvals][generators]" ) {
|
||||||
auto [test_input, expected] = GENERATE( table<std::string, size_t>({
|
using tuple_type = std::tuple<std::string, int>; // see above workaround
|
||||||
{"one", 3},
|
auto [test_input, expected] =
|
||||||
{"two", 3},
|
GENERATE( table<std::string, size_t>( { tuple_type{ "one", 3 },
|
||||||
{"three", 5},
|
tuple_type{ "two", 3 },
|
||||||
{"four", 4}
|
tuple_type{ "three", 5 },
|
||||||
}));
|
tuple_type{ "four", 4 } } ) );
|
||||||
|
|
||||||
REQUIRE( test_input.size() == expected );
|
REQUIRE( test_input.size() == expected );
|
||||||
}
|
}
|
||||||
@@ -99,11 +99,9 @@ TEST_CASE( "strlen3", "[generators]" ) {
|
|||||||
static auto eatCucumbers( int start, int eat ) -> int { return start-eat; }
|
static auto eatCucumbers( int start, int eat ) -> int { return start-eat; }
|
||||||
|
|
||||||
SCENARIO("Eating cucumbers", "[generators][approvals]") {
|
SCENARIO("Eating cucumbers", "[generators][approvals]") {
|
||||||
|
using tuple_type = std::tuple<int, int, int>;
|
||||||
auto [start, eat, left] = GENERATE( table<int,int,int> ({
|
auto [start, eat, left] = GENERATE( table<int, int, int>(
|
||||||
{ 12, 5, 7 },
|
{ tuple_type{ 12, 5, 7 }, tuple_type{ 20, 5, 15 } } ) );
|
||||||
{ 20, 5, 15 }
|
|
||||||
}));
|
|
||||||
|
|
||||||
GIVEN( "there are " << start << " cucumbers" )
|
GIVEN( "there are " << start << " cucumbers" )
|
||||||
WHEN( "I eat " << eat << " cucumbers" )
|
WHEN( "I eat " << eat << " cucumbers" )
|
||||||
|
@@ -242,12 +242,14 @@ namespace { namespace MatchersTests {
|
|||||||
|
|
||||||
~CustomAllocator() = default;
|
~CustomAllocator() = default;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSVC_LANG < 201703L
|
||||||
using std::allocator<T>::address;
|
using std::allocator<T>::address;
|
||||||
using std::allocator<T>::allocate;
|
|
||||||
using std::allocator<T>::construct;
|
using std::allocator<T>::construct;
|
||||||
using std::allocator<T>::deallocate;
|
|
||||||
using std::allocator<T>::max_size;
|
using std::allocator<T>::max_size;
|
||||||
using std::allocator<T>::destroy;
|
using std::allocator<T>::destroy;
|
||||||
|
#endif
|
||||||
|
using std::allocator<T>::allocate;
|
||||||
|
using std::allocator<T>::deallocate;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("Vector matchers", "[matchers][vector]") {
|
TEST_CASE("Vector matchers", "[matchers][vector]") {
|
||||||
|
@@ -241,6 +241,19 @@ std::ostream& operator<<(std::ostream& out, helper_1436<T1, T2> const& helper) {
|
|||||||
return out;
|
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]") {
|
TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") {
|
||||||
CAPTURE(std::vector<int>{1, 2, 3}[0, 1, 2],
|
CAPTURE(std::vector<int>{1, 2, 3}[0, 1, 2],
|
||||||
std::vector<int>{1, 2, 3}[(0, 1)],
|
std::vector<int>{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) );
|
CAPTURE( (1, 2), (2, 3) );
|
||||||
SUCCEED();
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
#if defined( __GNUG__ ) || defined(__clang__)
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
|
TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
|
||||||
CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
|
CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
|
||||||
|
@@ -402,3 +402,28 @@ TEST_CASE("#1514: stderr/stdout is not captured in tests aborted by an exception
|
|||||||
// FAIL aborts the test by throwing a Catch exception
|
// FAIL aborts the test by throwing a Catch exception
|
||||||
FAIL("1514");
|
FAIL("1514");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE( "#2025: -c shouldn't cause infinite loop", "[sections][generators][regression][.approvals]" ) {
|
||||||
|
SECTION( "Check cursor from buffer offset" ) {
|
||||||
|
auto bufPos = GENERATE_REF( range( 0, 44 ) );
|
||||||
|
WHEN( "Buffer position is " << bufPos ) { REQUIRE( 1 == 1 ); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("#2025: original repro", "[sections][generators][regression][.approvals]") {
|
||||||
|
auto fov = GENERATE(true, false);
|
||||||
|
DYNAMIC_SECTION("fov_" << fov) {
|
||||||
|
std::cout << "inside with fov: " << fov << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("#2025: same-level sections", "[sections][generators][regression][.approvals]") {
|
||||||
|
SECTION("A") {
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
auto i = GENERATE(1, 2, 3);
|
||||||
|
SECTION("B") {
|
||||||
|
REQUIRE(i < 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -28,7 +28,10 @@ filelocParser = re.compile(r'''
|
|||||||
''', re.VERBOSE)
|
''', re.VERBOSE)
|
||||||
lineNumberParser = re.compile(r' line="[0-9]*"')
|
lineNumberParser = re.compile(r' line="[0-9]*"')
|
||||||
hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b')
|
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]+"')
|
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')
|
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]+)?')
|
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<hex digits>", line)
|
line = hexParser.sub("0x<hex digits>", line)
|
||||||
|
|
||||||
# strip durations and timestamps
|
# strip durations and timestamps
|
||||||
line = durationsParser.sub(' time="{duration}"', line)
|
line = junitDurationsParser.sub(' time="{duration}"', line)
|
||||||
line = sonarqubeDurationParser.sub(' duration="{duration}"', line)
|
line = sonarqubeDurationParser.sub(' duration="{duration}"', line)
|
||||||
line = timestampsParser.sub('{iso8601-timestamp}', line)
|
line = timestampsParser.sub('{iso8601-timestamp}', line)
|
||||||
line = specialCaseParser.sub('file:\g<1>', line)
|
line = specialCaseParser.sub('file:\g<1>', line)
|
||||||
|
@@ -79,13 +79,15 @@ class Version:
|
|||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
def updateReadmeFile(version):
|
def updateReadmeFile(version):
|
||||||
import updateWandbox
|
|
||||||
|
# Wandbox no longer accepts the single-header upload, skip
|
||||||
|
# import updateWandbox
|
||||||
|
|
||||||
downloadParser = re.compile( r'<a href=\"https://github.com/catchorg/Catch2/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
downloadParser = re.compile( r'<a href=\"https://github.com/catchorg/Catch2/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
||||||
success, wandboxLink = updateWandbox.uploadFiles()
|
# success, wandboxLink = updateWandbox.uploadFiles()
|
||||||
if not success:
|
# if not success:
|
||||||
print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
# print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
||||||
exit(1)
|
# exit(1)
|
||||||
f = open( readmePath, 'r' )
|
f = open( readmePath, 'r' )
|
||||||
lines = []
|
lines = []
|
||||||
for line in f:
|
for line in f:
|
||||||
@@ -94,8 +96,8 @@ def updateReadmeFile(version):
|
|||||||
f = open( readmePath, 'w' )
|
f = open( readmePath, 'w' )
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = downloadParser.sub( r'<a href="https://github.com/catchorg/Catch2/releases/download/v{0}/catch.hpp">'.format(version.getVersionString()) , line)
|
line = downloadParser.sub( r'<a href="https://github.com/catchorg/Catch2/releases/download/v{0}/catch.hpp">'.format(version.getVersionString()) , line)
|
||||||
if '[]' in line:
|
# if '[]' in line:
|
||||||
line = '[]({0})'.format(wandboxLink)
|
# line = '[]({0})'.format(wandboxLink)
|
||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
|
|
||||||
@@ -127,8 +129,8 @@ def updateVersionDefine(version):
|
|||||||
def updateVersionPlaceholder(filename, version):
|
def updateVersionPlaceholder(filename, version):
|
||||||
with open(filename, 'rb') as file:
|
with open(filename, 'rb') as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
placeholderRegex = re.compile(b' in Catch X.Y.Z')
|
placeholderRegex = re.compile(b'in Catch X.Y.Z')
|
||||||
replacement = ' in Catch {}.{}.{}'.format(version.majorVersion, version.minorVersion, version.patchNumber).encode('ascii')
|
replacement = 'in Catch {}.{}.{}'.format(version.majorVersion, version.minorVersion, version.patchNumber).encode('ascii')
|
||||||
with open(filename, 'wb') as file:
|
with open(filename, 'wb') as file:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
file.write(placeholderRegex.sub(replacement, line))
|
file.write(placeholderRegex.sub(replacement, line))
|
||||||
|
File diff suppressed because it is too large
Load Diff
2
src/catch_with_main.cpp
Normal file
2
src/catch_with_main.cpp
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include <catch2/catch.hpp>
|
Reference in New Issue
Block a user