forked from catchorg/Catch2
Compare commits
92 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
15cf3caace | ||
|
12a8dfa2f2 | ||
|
797d3b04df | ||
|
82b8744b8c | ||
|
ce80358306 | ||
|
283e2e6d41 | ||
|
d6c7392b24 | ||
|
9ee4c1db52 | ||
|
76790604f5 | ||
|
e21c6aa94d | ||
|
7a59d5027f | ||
|
c8941cccb5 | ||
|
5eeb6aa361 | ||
|
1c1b447ede | ||
|
e1d81174db | ||
|
4846ad59e1 | ||
|
ff2b3c85a7 | ||
|
b55424d3b2 | ||
|
e69c7ce297 | ||
|
7be8ba36c1 | ||
|
ad120965cf | ||
|
f460a7d8f9 | ||
|
ebf89000f1 | ||
|
7d00cb83f1 | ||
|
e69afb6252 | ||
|
9fb38fcc14 | ||
|
0f49a600b0 | ||
|
5c0efa1cfc | ||
|
1579744ddd | ||
|
9b0e740e31 | ||
|
1af60ef5ab | ||
|
3743295ca8 | ||
|
ed582bde4d | ||
|
6c1145d922 | ||
|
b957eb4172 | ||
|
0eb99fb569 | ||
|
bf221583b1 | ||
|
44722f9ed3 | ||
|
35a57b070f | ||
|
1dce91d78e | ||
|
b8553d62a3 | ||
|
504607701b | ||
|
788f81230f | ||
|
c5301bf8bf | ||
|
d2a130f243 | ||
|
7be8a41adf | ||
|
021fcee636 | ||
|
3a47b8b072 | ||
|
2771a8ee9a | ||
|
7abd7db2c8 | ||
|
88d7b8da25 | ||
|
df0b0e64e1 | ||
|
4c7b7d04fe | ||
|
90988f578c | ||
|
e5fe3e877a | ||
|
6c5c4c43a0 | ||
|
c323658483 | ||
|
db570b7e24 | ||
|
0074926e5c | ||
|
6496c51c95 | ||
|
3dd523bdf5 | ||
|
8d5d49299b | ||
|
d0287e3b56 | ||
|
dd99a66cf4 | ||
|
ae590fe216 | ||
|
7f791fa08f | ||
|
0510d4755f | ||
|
e92b9c07c3 | ||
|
88a6ff0b65 | ||
|
9e7c281e6e | ||
|
64be2ad96c | ||
|
c651f239f0 | ||
|
43769a19f7 | ||
|
200d3ad824 | ||
|
aa7b0c9104 | ||
|
375f2052bd | ||
|
dc6b83bec9 | ||
|
f00257e374 | ||
|
414dcae34a | ||
|
d2d8455b57 | ||
|
ab30621138 | ||
|
1ca8f43b01 | ||
|
dfb83f20e9 | ||
|
319bddd5b8 | ||
|
931441251e | ||
|
ea1f326261 | ||
|
3641706923 | ||
|
3b801c4fda | ||
|
e11508b48a | ||
|
886d799b79 | ||
|
8b78087412 | ||
|
6c99b04c87 |
55
.travis.yml
55
.travis.yml
@@ -11,6 +11,7 @@ common_sources: &all_sources
|
|||||||
- llvm-toolchain-trusty-3.9
|
- llvm-toolchain-trusty-3.9
|
||||||
- llvm-toolchain-trusty-4.0
|
- llvm-toolchain-trusty-4.0
|
||||||
- llvm-toolchain-trusty-5.0
|
- llvm-toolchain-trusty-5.0
|
||||||
|
- llvm-toolchain-trusty-6.0
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@@ -67,6 +68,14 @@ matrix:
|
|||||||
packages: ['clang-5.0']
|
packages: ['clang-5.0']
|
||||||
env: COMPILER='clang++-5.0'
|
env: COMPILER='clang++-5.0'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: *all_sources
|
||||||
|
packages: ['clang-6.0']
|
||||||
|
env: COMPILER='clang++-6.0'
|
||||||
|
|
||||||
# 2/ Linux GCC Builds
|
# 2/ Linux GCC Builds
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
@@ -108,6 +117,14 @@ matrix:
|
|||||||
packages: ['g++-7']
|
packages: ['g++-7']
|
||||||
env: COMPILER='g++-7'
|
env: COMPILER='g++-7'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: &gcc8
|
||||||
|
apt:
|
||||||
|
sources: *all_sources
|
||||||
|
packages: ['g++-8']
|
||||||
|
env: COMPILER='g++-8'
|
||||||
|
|
||||||
# 3b/ Linux C++14 Clang builds
|
# 3b/ Linux C++14 Clang builds
|
||||||
# Note that we need newer libstdc++ for C++14 support
|
# Note that we need newer libstdc++ for C++14 support
|
||||||
- os: linux
|
- os: linux
|
||||||
@@ -144,6 +161,14 @@ matrix:
|
|||||||
packages: ['clang-5.0', 'libstdc++-6-dev']
|
packages: ['clang-5.0', 'libstdc++-6-dev']
|
||||||
env: COMPILER='clang++-5.0' CPP14=1
|
env: COMPILER='clang++-5.0' CPP14=1
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: *all_sources
|
||||||
|
packages: ['clang-6.0', 'libstdc++-6-dev']
|
||||||
|
env: COMPILER='clang++-6.0' CPP14=1
|
||||||
|
|
||||||
|
|
||||||
# 4a/ Linux C++14 GCC builds
|
# 4a/ Linux C++14 GCC builds
|
||||||
- os: linux
|
- os: linux
|
||||||
@@ -156,6 +181,11 @@ matrix:
|
|||||||
addons: *gcc7
|
addons: *gcc7
|
||||||
env: COMPILER='g++-7' CPP14=1
|
env: COMPILER='g++-7' CPP14=1
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: *gcc8
|
||||||
|
env: COMPILER='g++-8' CPP14=1
|
||||||
|
|
||||||
# 5/ OSX Clang Builds
|
# 5/ OSX Clang Builds
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7.3
|
osx_image: xcode7.3
|
||||||
@@ -219,7 +249,7 @@ install:
|
|||||||
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||||
- |
|
- |
|
||||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
|
CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.2-Linux-x86_64.tar.gz"
|
||||||
mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||||
@@ -232,27 +262,24 @@ before_script:
|
|||||||
# Regenerate single header file, so it is tested in the examples...
|
# Regenerate single header file, so it is tested in the examples...
|
||||||
- python scripts/generateSingleHeader.py
|
- python scripts/generateSingleHeader.py
|
||||||
|
|
||||||
- |
|
|
||||||
# Use Debug builds for running Valgrind and building examples
|
# Use Debug builds for running Valgrind and building examples
|
||||||
cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE}
|
- cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE}
|
||||||
# Don't bother with release build for coverage build
|
# Don't bother with release build for coverage build
|
||||||
cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
|
- cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
|
||||||
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- |
|
- cd Build-Debug
|
||||||
cd Build-Debug
|
- make -j 2
|
||||||
make -j 2
|
- CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
|
||||||
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
|
|
||||||
# Coverage collection does not work for OS X atm
|
# Coverage collection does not work for OS X atm
|
||||||
echo "${TRAVIS_OS_NAME}";
|
- |
|
||||||
echo "${COVERAGE}";
|
|
||||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]] && [[ "${COVERAGE}" == "1" ]]; then
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]] && [[ "${COVERAGE}" == "1" ]]; then
|
||||||
make gcov
|
make gcov
|
||||||
make lcov
|
make lcov
|
||||||
bash <(curl -s https://codecov.io/bash) -X gcov || echo "Codecov did not collect coverage reports"
|
bash <(curl -s https://codecov.io/bash) -X gcov || echo "Codecov did not collect coverage reports"
|
||||||
fi
|
fi
|
||||||
# Go to release build
|
- # Go to release build
|
||||||
cd ../Build-Release
|
- cd ../Build-Release
|
||||||
make -j 2
|
- make -j 2
|
||||||
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
|
- CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
|
||||||
|
10
CMake/Catch2Config.cmake.in
Normal file
10
CMake/Catch2Config.cmake.in
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
|
||||||
|
# Avoid repeatedly including the targets
|
||||||
|
if(NOT TARGET Catch2::Catch2)
|
||||||
|
# Provide path for scripts
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/Catch2Targets.cmake)
|
||||||
|
endif()
|
26
CMake/MiscFunctions.cmake
Normal file
26
CMake/MiscFunctions.cmake
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#checks that the given hard-coded list contains all headers + sources in the given folder
|
||||||
|
function(CheckFileList LIST_VAR FOLDER)
|
||||||
|
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
||||||
|
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
||||||
|
file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
|
||||||
|
"${FOLDER}/*.hpp"
|
||||||
|
"${FOLDER}/*.h")
|
||||||
|
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
||||||
|
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
||||||
|
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
||||||
|
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(CheckFileListRec LIST_VAR FOLDER)
|
||||||
|
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
||||||
|
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
||||||
|
file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
|
||||||
|
"${FOLDER}/*.hpp"
|
||||||
|
"${FOLDER}/*.h")
|
||||||
|
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
||||||
|
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
||||||
|
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
||||||
|
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
7
CMake/catch2.pc.in
Normal file
7
CMake/catch2.pc.in
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
|
|
||||||
|
Name: Catch2
|
||||||
|
Description: A modern, C++-native, header-only, test framework for C++11
|
||||||
|
URL: https://github.com/catchorg/Catch2
|
||||||
|
Version: @Catch2_VERSION@
|
||||||
|
Cflags: -I${includedir}
|
538
CMakeLists.txt
538
CMakeLists.txt
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.1)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
# detect if Catch is being bundled,
|
# detect if Catch is being bundled,
|
||||||
# disable testsuite in that case
|
# disable testsuite in that case
|
||||||
@@ -6,14 +6,23 @@ if(NOT DEFINED PROJECT_NAME)
|
|||||||
set(NOT_SUBPROJECT ON)
|
set(NOT_SUBPROJECT ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(Catch2 LANGUAGES CXX VERSION 2.2.1)
|
project(Catch2 LANGUAGES CXX VERSION 2.3.0)
|
||||||
|
|
||||||
|
# Provide path for scripts
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
|
option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
|
||||||
|
option(CATCH_BUILD_TESTING "Build SelfTest project" ON)
|
||||||
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
|
option(CATCH_BUILD_EXAMPLES "Build documentation examples" 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_HELPERS "Install contrib alongside library" ON)
|
||||||
|
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
@@ -27,428 +36,149 @@ if(USE_WMAIN)
|
|||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#checks that the given hard-coded list contains all headers + sources in the given folder
|
if (BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT)
|
||||||
function(CheckFileList LIST_VAR FOLDER)
|
add_subdirectory(projects)
|
||||||
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
|
||||||
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
|
||||||
file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
|
|
||||||
"${FOLDER}/*.hpp"
|
|
||||||
"${FOLDER}/*.h")
|
|
||||||
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
|
||||||
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
|
||||||
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
|
||||||
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
|
||||||
endforeach()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(CheckFileListRec LIST_VAR FOLDER)
|
|
||||||
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
|
||||||
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
|
||||||
file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
|
|
||||||
"${FOLDER}/*.hpp"
|
|
||||||
"${FOLDER}/*.h")
|
|
||||||
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
|
||||||
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
|
||||||
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
|
||||||
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
|
||||||
endforeach()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# define the sources of the self test
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(TEST_SOURCES
|
|
||||||
${SELF_TEST_DIR}/TestMain.cpp
|
|
||||||
${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
|
|
||||||
${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
|
|
||||||
)
|
|
||||||
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
|
|
||||||
|
|
||||||
# A set of impl files that just #include a single header
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(SURROGATE_SOURCES
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
|
||||||
)
|
|
||||||
CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
|
|
||||||
|
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(TOP_LEVEL_HEADERS
|
|
||||||
${HEADER_DIR}/catch.hpp
|
|
||||||
${HEADER_DIR}/catch_with_main.hpp
|
|
||||||
)
|
|
||||||
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
|
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(EXTERNAL_HEADERS
|
|
||||||
${HEADER_DIR}/external/clara.hpp
|
|
||||||
)
|
|
||||||
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
|
|
||||||
|
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(INTERNAL_HEADERS
|
|
||||||
${HEADER_DIR}/internal/catch_approx.h
|
|
||||||
${HEADER_DIR}/internal/catch_assertionhandler.h
|
|
||||||
${HEADER_DIR}/internal/catch_assertioninfo.h
|
|
||||||
${HEADER_DIR}/internal/catch_assertionresult.h
|
|
||||||
${HEADER_DIR}/internal/catch_capture.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_capture_matchers.h
|
|
||||||
${HEADER_DIR}/internal/catch_clara.h
|
|
||||||
${HEADER_DIR}/internal/catch_commandline.h
|
|
||||||
${HEADER_DIR}/internal/catch_common.h
|
|
||||||
${HEADER_DIR}/internal/catch_compiler_capabilities.h
|
|
||||||
${HEADER_DIR}/internal/catch_config.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_console_colour.h
|
|
||||||
${HEADER_DIR}/internal/catch_context.h
|
|
||||||
${HEADER_DIR}/internal/catch_debug_console.h
|
|
||||||
${HEADER_DIR}/internal/catch_debugger.h
|
|
||||||
${HEADER_DIR}/internal/catch_decomposer.h
|
|
||||||
${HEADER_DIR}/internal/catch_default_main.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_enforce.h
|
|
||||||
${HEADER_DIR}/internal/catch_errno_guard.h
|
|
||||||
${HEADER_DIR}/internal/catch_exception_translator_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_external_interfaces.h
|
|
||||||
${HEADER_DIR}/internal/catch_fatal_condition.h
|
|
||||||
${HEADER_DIR}/internal/catch_impl.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_capture.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_config.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_exception.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_reporter.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_runner.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_testcase.h
|
|
||||||
${HEADER_DIR}/internal/catch_leak_detector.h
|
|
||||||
${HEADER_DIR}/internal/catch_list.h
|
|
||||||
${HEADER_DIR}/internal/catch_matchers.h
|
|
||||||
${HEADER_DIR}/internal/catch_matchers_floating.h
|
|
||||||
${HEADER_DIR}/internal/catch_matchers_string.h
|
|
||||||
${HEADER_DIR}/internal/catch_matchers_vector.h
|
|
||||||
${HEADER_DIR}/internal/catch_message.h
|
|
||||||
${HEADER_DIR}/internal/catch_objc.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_objc_arc.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_option.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_platform.h
|
|
||||||
${HEADER_DIR}/internal/catch_random_number_generator.h
|
|
||||||
${HEADER_DIR}/internal/catch_reenable_warnings.h
|
|
||||||
${HEADER_DIR}/internal/catch_reporter_registrars.hpp
|
|
||||||
${HEADER_DIR}/internal/catch_reporter_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_result_type.h
|
|
||||||
${HEADER_DIR}/internal/catch_run_context.h
|
|
||||||
${HEADER_DIR}/internal/catch_benchmark.h
|
|
||||||
${HEADER_DIR}/internal/catch_section.h
|
|
||||||
${HEADER_DIR}/internal/catch_section_info.h
|
|
||||||
${HEADER_DIR}/internal/catch_session.h
|
|
||||||
${HEADER_DIR}/internal/catch_startup_exception_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_stream.h
|
|
||||||
${HEADER_DIR}/internal/catch_stringref.h
|
|
||||||
${HEADER_DIR}/internal/catch_string_manip.h
|
|
||||||
${HEADER_DIR}/internal/catch_suppress_warnings.h
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias.h
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_info.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_registry_impl.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_tracker.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_registry.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_spec.h
|
|
||||||
${HEADER_DIR}/internal/catch_test_spec_parser.h
|
|
||||||
${HEADER_DIR}/internal/catch_text.h
|
|
||||||
${HEADER_DIR}/internal/catch_timer.h
|
|
||||||
${HEADER_DIR}/internal/catch_tostring.h
|
|
||||||
${HEADER_DIR}/internal/catch_totals.h
|
|
||||||
${HEADER_DIR}/internal/catch_uncaught_exceptions.h
|
|
||||||
${HEADER_DIR}/internal/catch_user_interfaces.h
|
|
||||||
${HEADER_DIR}/internal/catch_version.h
|
|
||||||
${HEADER_DIR}/internal/catch_wildcard_pattern.h
|
|
||||||
${HEADER_DIR}/internal/catch_windows_h_proxy.h
|
|
||||||
${HEADER_DIR}/internal/catch_xmlwriter.h
|
|
||||||
)
|
|
||||||
set(IMPL_SOURCES
|
|
||||||
${HEADER_DIR}/internal/catch_approx.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_assertionhandler.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_assertionresult.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_benchmark.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_capture_matchers.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_commandline.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_common.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_config.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_console_colour.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_context.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_debug_console.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_debugger.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_decomposer.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_errno_guard.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_fatal_condition.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_capture.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_config.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_exception.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_runner.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_list.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_leak_detector.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_matchers.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_matchers_floating.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_matchers_string.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_message.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_registry_hub.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_random_number_generator.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_reporter_registry.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_result_type.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_run_context.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_section.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_section_info.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_session.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_stream.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_stringref.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_string_manip.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_info.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_case_tracker.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_registry.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_spec.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_test_spec_parser.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_timer.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_tostring.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_totals.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_version.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
|
|
||||||
${HEADER_DIR}/internal/catch_xmlwriter.cpp
|
|
||||||
)
|
|
||||||
set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
|
|
||||||
CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
|
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
|
||||||
set(REPORTER_HEADERS
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_automake.hpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_compact.h
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_console.h
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_junit.h
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_multi.h
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_xml.h
|
|
||||||
)
|
|
||||||
set(REPORTER_SOURCES
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_bases.cpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_compact.cpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_console.cpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_junit.cpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_multi.cpp
|
|
||||||
${HEADER_DIR}/reporters/catch_reporter_xml.cpp
|
|
||||||
)
|
|
||||||
set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
|
|
||||||
CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
|
|
||||||
|
|
||||||
# Specify the headers, too, so CLion recognises them as project files
|
|
||||||
set(HEADERS
|
|
||||||
${TOP_LEVEL_HEADERS}
|
|
||||||
${EXTERNAL_HEADERS}
|
|
||||||
${INTERNAL_HEADERS}
|
|
||||||
${REPORTER_HEADERS}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Provide some groupings for IDEs
|
|
||||||
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
|
||||||
SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
|
|
||||||
|
|
||||||
|
|
||||||
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
|
||||||
# without building all of our selftests.
|
|
||||||
|
|
||||||
if(DEFINED NO_SELFTEST)
|
|
||||||
message(DEPRECATION "*** CMake option NO_SELFTEST is deprecated; use BUILD_TESTING instead")
|
|
||||||
if (NO_SELFTEST)
|
|
||||||
set(BUILD_TESTING OFF CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
|
|
||||||
else()
|
|
||||||
set(BUILD_TESTING ON CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CTest)
|
|
||||||
|
|
||||||
if (BUILD_TESTING AND NOT_SUBPROJECT)
|
|
||||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
|
||||||
target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
|
|
||||||
|
|
||||||
if(USE_CPP14)
|
|
||||||
message(STATUS "Enabling C++14")
|
|
||||||
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
|
|
||||||
else()
|
|
||||||
message(STATUS "Enabling C++11")
|
|
||||||
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
|
|
||||||
set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
|
|
||||||
|
|
||||||
if (CATCH_ENABLE_COVERAGE)
|
|
||||||
set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
|
||||||
find_package(codecov)
|
|
||||||
add_coverage(SelfTest)
|
|
||||||
list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
|
|
||||||
coverage_evaluate()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Add per compiler options
|
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
|
||||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic)
|
|
||||||
if (CATCH_ENABLE_WERROR)
|
|
||||||
target_compile_options( SelfTest PRIVATE -Werror)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# Clang specific options go here
|
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
|
||||||
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
|
||||||
endif()
|
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
|
||||||
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
|
|
||||||
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
|
|
||||||
if (CATCH_ENABLE_WERROR)
|
|
||||||
target_compile_options( SelfTest PRIVATE /WX)
|
|
||||||
endif()
|
|
||||||
# Force MSVC to consider everything as encoded in utf-8
|
|
||||||
target_compile_options( SelfTest PRIVATE /utf-8 )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# configure unit tests via CTest
|
|
||||||
include(CTest)
|
|
||||||
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
|
|
||||||
|
|
||||||
add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
|
||||||
set_tests_properties(ListTests PROPERTIES
|
|
||||||
PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
|
|
||||||
FAIL_REGULAR_EXPRESSION "Hidden Test"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
|
|
||||||
set_tests_properties(ListTags PROPERTIES
|
|
||||||
PASS_REGULAR_EXPRESSION "[0-9]+ tags"
|
|
||||||
FAIL_REGULAR_EXPRESSION "[.]")
|
|
||||||
|
|
||||||
add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
|
|
||||||
set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
|
|
||||||
|
|
||||||
add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
|
|
||||||
set_tests_properties(ListTestNamesOnly PROPERTIES
|
|
||||||
PASS_REGULAR_EXPRESSION "Regex string matcher"
|
|
||||||
FAIL_REGULAR_EXPRESSION "Hidden Test")
|
|
||||||
|
|
||||||
add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
|
|
||||||
set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
|
|
||||||
|
|
||||||
add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
|
|
||||||
set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
|
|
||||||
|
|
||||||
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
|
|
||||||
add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
|
||||||
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
|
||||||
|
|
||||||
if (CATCH_USE_VALGRIND)
|
|
||||||
add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
|
|
||||||
add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
|
||||||
set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
|
||||||
add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
|
|
||||||
set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif() # !NO_SELFTEST
|
|
||||||
|
|
||||||
|
|
||||||
if(CATCH_BUILD_EXAMPLES)
|
if(CATCH_BUILD_EXAMPLES)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(DIRECTORY "single_include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/catch")
|
|
||||||
|
|
||||||
install(DIRECTORY docs/ DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
|
||||||
|
|
||||||
## Provide some pkg-config integration
|
|
||||||
# Don't bother on Windows
|
|
||||||
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
|
||||||
|
|
||||||
set(PKGCONFIG_INSTALL_DIR
|
|
||||||
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
|
|
||||||
CACHE PATH "Path where catch.pc is installed"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/catch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/catch.pc @ONLY)
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# add catch as a 'linkable' target
|
# add catch as a 'linkable' target
|
||||||
add_library(Catch INTERFACE)
|
add_library(Catch2 INTERFACE)
|
||||||
|
|
||||||
# depend on some obvious c++11 features so the dependency is transitively added dependants
|
|
||||||
target_compile_features(Catch INTERFACE cxx_auto_type cxx_constexpr cxx_noexcept)
|
|
||||||
|
|
||||||
target_include_directories(Catch
|
|
||||||
|
# depend on some obvious c++11 features so the dependency is transitively added dependents
|
||||||
|
target_compile_features(Catch2
|
||||||
|
INTERFACE
|
||||||
|
cxx_alignas
|
||||||
|
cxx_alignof
|
||||||
|
cxx_attributes
|
||||||
|
cxx_auto_type
|
||||||
|
cxx_constexpr
|
||||||
|
cxx_defaulted_functions
|
||||||
|
cxx_deleted_functions
|
||||||
|
cxx_final
|
||||||
|
cxx_lambdas
|
||||||
|
cxx_noexcept
|
||||||
|
cxx_override
|
||||||
|
cxx_range_for
|
||||||
|
cxx_rvalue_references
|
||||||
|
cxx_static_assert
|
||||||
|
cxx_strong_enums
|
||||||
|
cxx_trailing_return_types
|
||||||
|
cxx_unicode_literals
|
||||||
|
cxx_user_literals
|
||||||
|
cxx_variadic_macros
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(Catch2
|
||||||
INTERFACE
|
INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
|
||||||
$<INSTALL_INTERFACE:include/catch>
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
$<INSTALL_INTERFACE:include>)
|
)
|
||||||
|
|
||||||
# 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::Catch ALIAS Catch)
|
add_library(Catch2::Catch2 ALIAS Catch2)
|
||||||
|
|
||||||
set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
|
set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
|
||||||
|
|
||||||
# create and install an export set for catch target as Catch2::Catch
|
|
||||||
install(TARGETS Catch EXPORT Catch2Config DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
|
|
||||||
install(EXPORT Catch2Config
|
|
||||||
NAMESPACE Catch2::
|
|
||||||
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
|
|
||||||
|
|
||||||
# install Catch2ConfigVersion.cmake file to handle versions in find_package
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
configure_package_config_file(
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/CMake/Catch2Config.cmake.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake
|
||||||
|
INSTALL_DESTINATION
|
||||||
|
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# create and install an export set for catch target as Catch2::Catch
|
||||||
|
install(
|
||||||
|
TARGETS
|
||||||
|
Catch2
|
||||||
|
EXPORT
|
||||||
|
Catch2Targets
|
||||||
|
DESTINATION
|
||||||
|
${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT
|
||||||
|
Catch2Targets
|
||||||
|
NAMESPACE
|
||||||
|
Catch2::
|
||||||
|
DESTINATION
|
||||||
|
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
||||||
COMPATIBILITY SameMajorVersion)
|
COMPATIBILITY
|
||||||
|
SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
install(FILES
|
install(
|
||||||
|
DIRECTORY
|
||||||
|
"single_include/"
|
||||||
|
DESTINATION
|
||||||
|
"${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
||||||
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
|
DESTINATION
|
||||||
|
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install documentation
|
||||||
|
if(CATCH_INSTALL_DOCS)
|
||||||
|
install(
|
||||||
|
DIRECTORY
|
||||||
|
docs/
|
||||||
|
DESTINATION
|
||||||
|
"${CMAKE_INSTALL_DOCDIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CATCH_INSTALL_HELPERS)
|
||||||
|
# Install CMake scripts
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
"contrib/ParseAndAddCatchTests.cmake"
|
||||||
|
"contrib/Catch.cmake"
|
||||||
|
"contrib/CatchAddTests.cmake"
|
||||||
|
DESTINATION
|
||||||
|
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install debugger helpers
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
"contrib/gdbinit"
|
||||||
|
"contrib/lldbinit"
|
||||||
|
DESTINATION
|
||||||
|
${CMAKE_INSTALL_DATAROOTDIR}/Catch2
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## Provide some pkg-config integration
|
||||||
|
set(PKGCONFIG_INSTALL_DIR
|
||||||
|
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
|
||||||
|
CACHE PATH "Path where catch2.pc is installed"
|
||||||
|
)
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/catch2.pc
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/catch2.pc"
|
||||||
|
DESTINATION
|
||||||
|
${PKGCONFIG_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
@@ -5,9 +5,11 @@
|
|||||||
[](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/zDKMK3eGMC9IP2jy)
|
[](https://wandbox.org/permlink/Gcuv2Xx3wmWIPNzy)
|
||||||
|
[](https://discord.gg/4CWS9zD)
|
||||||
|
|
||||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.2.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.3.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||||
|
|
||||||
## Catch2 is released!
|
## Catch2 is released!
|
||||||
|
|
||||||
@@ -32,5 +34,5 @@ This documentation comprises these three parts:
|
|||||||
|
|
||||||
## More
|
## More
|
||||||
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
|
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
|
||||||
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum) or our [Discord](https://discord.gg/4CWS9zD)
|
||||||
* See [who else is using Catch2](docs/opensource-users.md#top)
|
* See [who else is using Catch2](docs/opensource-users.md#top)
|
||||||
|
@@ -33,6 +33,8 @@ environment:
|
|||||||
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- os: Visual Studio 2017
|
||||||
exclude:
|
exclude:
|
||||||
- os: Visual Studio 2015
|
- os: Visual Studio 2015
|
||||||
additional_flags: "/permissive- /std:c++latest"
|
additional_flags: "/permissive- /std:c++latest"
|
||||||
@@ -62,7 +64,7 @@ matrix:
|
|||||||
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { python -m pip install codecov }
|
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { python -m pip --disable-pip-version-check install codecov }
|
||||||
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { .\misc\installOpenCppCoverage.ps1 }
|
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { .\misc\installOpenCppCoverage.ps1 }
|
||||||
|
|
||||||
# Win32 and x64 are CMake-compatible solution platform names.
|
# Win32 and x64 are CMake-compatible solution platform names.
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
|
||||||
|
|
||||||
Name: Catch
|
|
||||||
Description: Testing library for C++
|
|
||||||
Version: @Catch2_VERSION@
|
|
||||||
Cflags: -I${includedir}
|
|
14
codecov.yml
14
codecov.yml
@@ -9,6 +9,12 @@ coverage:
|
|||||||
patch:
|
patch:
|
||||||
default:
|
default:
|
||||||
target: 80%
|
target: 80%
|
||||||
|
ignore:
|
||||||
|
- "projects/SelfTest"
|
||||||
|
- "**/catch_reporter_tap.hpp"
|
||||||
|
- "**/catch_reporter_automake.hpp"
|
||||||
|
- "**/catch_reporter_teamcity.hpp"
|
||||||
|
- "**/external/clara.hpp"
|
||||||
|
|
||||||
|
|
||||||
codecov:
|
codecov:
|
||||||
@@ -16,11 +22,3 @@ codecov:
|
|||||||
|
|
||||||
comment:
|
comment:
|
||||||
layout: "diff"
|
layout: "diff"
|
||||||
|
|
||||||
coverage:
|
|
||||||
ignore:
|
|
||||||
- "projects/SelfTest"
|
|
||||||
- "**/catch_reporter_tap.hpp"
|
|
||||||
- "**/catch_reporter_automake.hpp"
|
|
||||||
- "**/catch_reporter_teamcity.hpp"
|
|
||||||
- "**/external/clara.hpp"
|
|
||||||
|
22
conanfile.py
22
conanfile.py
@@ -1,19 +1,31 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from conans import ConanFile
|
from conans import ConanFile, CMake
|
||||||
|
|
||||||
|
|
||||||
class CatchConan(ConanFile):
|
class CatchConan(ConanFile):
|
||||||
name = "Catch"
|
name = "Catch"
|
||||||
version = "2.2.1"
|
version = "2.3.0"
|
||||||
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
||||||
author = "philsquared"
|
author = "philsquared"
|
||||||
generators = "cmake"
|
generators = "cmake"
|
||||||
exports_sources = "single_include/*"
|
# Only needed until conan 1.5 is released
|
||||||
url = "https://github.com/philsquared/Catch"
|
settings = "compiler", "arch"
|
||||||
|
exports_sources = "single_include/*", "CMakeLists.txt", "CMake/catch2.pc.in", "LICENSE.txt"
|
||||||
|
url = "https://github.com/catchorg/Catch2"
|
||||||
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
|
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def package(self):
|
def package(self):
|
||||||
self.copy(pattern="catch.hpp", src="single_include", dst="include")
|
cmake = CMake(self)
|
||||||
|
cmake.definitions["BUILD_TESTING"] = "OFF"
|
||||||
|
cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
|
||||||
|
cmake.definitions["CATCH_INSTALL_HELPERS"] = "ON"
|
||||||
|
cmake.configure()
|
||||||
|
cmake.install()
|
||||||
|
|
||||||
|
self.copy(pattern="LICENSE.txt", dst="licenses")
|
||||||
|
|
||||||
def package_id(self):
|
def package_id(self):
|
||||||
self.info.header_only()
|
self.info.header_only()
|
||||||
|
@@ -50,8 +50,7 @@ string(REPLACE "\n" ";" output "${output}")
|
|||||||
|
|
||||||
# Parse output
|
# Parse output
|
||||||
foreach(line ${output})
|
foreach(line ${output})
|
||||||
# Test name; strip spaces to get just the name...
|
set(test ${line})
|
||||||
string(REGEX REPLACE " +" "" test "${line}")
|
|
||||||
# ...and add to script
|
# ...and add to script
|
||||||
add_command(add_test
|
add_command(add_test
|
||||||
"${prefix}${test}${suffix}"
|
"${prefix}${test}${suffix}"
|
||||||
|
@@ -143,6 +143,9 @@ function(ParseFile SourceFile TestTarget)
|
|||||||
endif()
|
endif()
|
||||||
string(REPLACE "]" ";" Tags "${Tags}")
|
string(REPLACE "]" ";" Tags "${Tags}")
|
||||||
string(REPLACE "[" "" Tags "${Tags}")
|
string(REPLACE "[" "" Tags "${Tags}")
|
||||||
|
else()
|
||||||
|
# unset tags variable from previous loop
|
||||||
|
unset(Tags)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND Labels ${Tags})
|
list(APPEND Labels ${Tags})
|
||||||
|
16
contrib/gdbinit
Normal file
16
contrib/gdbinit
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#
|
||||||
|
# This file provides a way to skip stepping into Catch code when debugging with gdb.
|
||||||
|
#
|
||||||
|
# With the gdb "skip" command you can tell gdb to skip files or functions during debugging.
|
||||||
|
# see https://xaizek.github.io/2016-05-26/skipping-standard-library-in-gdb/ for an example
|
||||||
|
#
|
||||||
|
# Basically the following line tells gdb to skip all functions containing the
|
||||||
|
# regexp "Catch", which matches the complete Catch namespace.
|
||||||
|
# If you want to skip just some parts of the Catch code you can modify the
|
||||||
|
# regexp accordingly.
|
||||||
|
#
|
||||||
|
# If you want to permanently skip stepping into Catch code copy the following
|
||||||
|
# line into your ~/.gdbinit file
|
||||||
|
#
|
||||||
|
|
||||||
|
skip -rfu Catch
|
16
contrib/lldbinit
Normal file
16
contrib/lldbinit
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#
|
||||||
|
# This file provides a way to skip stepping into Catch code when debugging with lldb.
|
||||||
|
#
|
||||||
|
# With the setting "target.process.thread.step-avoid-regexp" you can tell lldb
|
||||||
|
# to skip functions matching the regexp
|
||||||
|
#
|
||||||
|
# Basically the following line tells lldb to skip all functions containing the
|
||||||
|
# regexp "Catch", which matches the complete Catch namespace.
|
||||||
|
# If you want to skip just some parts of the Catch code you can modify the
|
||||||
|
# regexp accordingly.
|
||||||
|
#
|
||||||
|
# If you want to permanently skip stepping into Catch code copy the following
|
||||||
|
# line into your ~/.lldbinit file
|
||||||
|
#
|
||||||
|
|
||||||
|
settings set target.process.thread.step-avoid-regexp Catch
|
@@ -20,7 +20,10 @@ Fine tuning:
|
|||||||
|
|
||||||
Running:
|
Running:
|
||||||
* [Command line](command-line.md#top)
|
* [Command line](command-line.md#top)
|
||||||
* [CI and Build system integration](build-systems.md#top)
|
|
||||||
|
Odds and ends:
|
||||||
|
* [CMake integration](cmake-integration.md#top)
|
||||||
|
* [CI and other miscellaneous pieces](ci-and-misc.md#top)
|
||||||
|
|
||||||
FAQ:
|
FAQ:
|
||||||
* [Why are my tests slow to compile?](slow-compiles.md#top)
|
* [Why are my tests slow to compile?](slow-compiles.md#top)
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
[Exceptions](#exceptions)<br>
|
[Exceptions](#exceptions)<br>
|
||||||
[Matcher expressions](#matcher-expressions)<br>
|
[Matcher expressions](#matcher-expressions)<br>
|
||||||
[Thread Safety](#thread-safety)<br>
|
[Thread Safety](#thread-safety)<br>
|
||||||
|
[Expressions with commas](#expressions-with-commas)<br>
|
||||||
|
|
||||||
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
|
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
|
||||||
|
|
||||||
@@ -54,33 +55,45 @@ This expression is too complex because of the `||` operator. If you want to chec
|
|||||||
|
|
||||||
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
|
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
|
||||||
|
|
||||||
Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```Approx```. ```Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
|
Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called `Approx`. `Approx` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
REQUIRE( performComputation() == Approx( 2.1 ) );
|
REQUIRE( performComputation() == Approx( 2.1 ) );
|
||||||
```
|
```
|
||||||
|
|
||||||
This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation.
|
Catch also provides a UDL for `Approx`; `_a`. It resides in
|
||||||
|
the `Catch::literals` namespace and can be used like so:
|
||||||
|
```cpp
|
||||||
|
using namespace Catch::literals;
|
||||||
|
REQUIRE( performComputation() == 2.1_a );
|
||||||
|
```
|
||||||
|
|
||||||
* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits<float>::epsilon()*100`.
|
`Approx` is constructed with defaults that should cover most simple cases.
|
||||||
* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`.
|
For the more complex cases, `Approx` provides 3 customization points:
|
||||||
* __scale__ - scale serves to adjust the epsilon's multiplicator. By default set to `0.0`.
|
|
||||||
|
* __epsilon__ - epsilon serves to set the percentage by which a result
|
||||||
|
can differ from `Approx`'s value before it is rejected.
|
||||||
|
_By default set to `std::numeric_limits<float>::epsilon()*100`._
|
||||||
|
* __margin__ - margin serves to set the the absolute value by which
|
||||||
|
a result can differ from `Approx`'s value before it is rejected.
|
||||||
|
_By default set to `0.0`._
|
||||||
|
* __scale__ - scale is used to change the magnitude of `Approx` for relative check.
|
||||||
|
_By default set to `0.0`._
|
||||||
|
|
||||||
#### epsilon example
|
#### epsilon example
|
||||||
```cpp
|
```cpp
|
||||||
Approx target = Approx(100).epsilon(0.01);
|
Approx target = Approx(100).epsilon(0.01);
|
||||||
100.0 == target; // Obviously true
|
100.0 == target; // Obviously true
|
||||||
200.0 == target; // Obviously still false
|
200.0 == target; // Obviously still false
|
||||||
100.5 == target; // True, because we set target to allow up to 1% error
|
100.5 == target; // True, because we set target to allow up to 1% difference
|
||||||
```
|
```
|
||||||
|
|
||||||
#### margin example
|
#### margin example
|
||||||
_Margin check is used only if the relative (epsilon and scale based) check fails._
|
|
||||||
```cpp
|
```cpp
|
||||||
Approx target = Approx(100).margin(5);
|
Approx target = Approx(100).margin(5);
|
||||||
100.0 == target; // Obviously true
|
100.0 == target; // Obviously true
|
||||||
200.0 == target; // Obviously still false
|
200.0 == target; // Obviously still false
|
||||||
104.0 == target; // True, because we set target to allow absolute error up to 5
|
104.0 == target; // True, because we set target to allow absolute difference of at most 5
|
||||||
```
|
```
|
||||||
|
|
||||||
#### scale
|
#### scale
|
||||||
@@ -155,6 +168,34 @@ Matchers can be composed using `&&`, `||` and `!` operators.
|
|||||||
Currently assertions in Catch are not thread safe.
|
Currently assertions in Catch are not thread safe.
|
||||||
For more details, along with workarounds, see the section on [the limitations page](limitations.md#thread-safe-assertions).
|
For more details, along with workarounds, see the section on [the limitations page](limitations.md#thread-safe-assertions).
|
||||||
|
|
||||||
|
## Expressions with commas
|
||||||
|
|
||||||
|
Because the preprocessor parses code using different rules than the
|
||||||
|
compiler, multiple-argument assertions (e.g. `REQUIRE_THROWS_AS`) have
|
||||||
|
problems with commas inside the provided expressions. As an example
|
||||||
|
`REQUIRE_THROWS_AS(std::pair<int, int>(1, 2), std::invalid_argument);`
|
||||||
|
will fail to compile, because the preprocessor sees 3 arguments provided,
|
||||||
|
but the macro accepts only 2. There are two possible workarounds.
|
||||||
|
|
||||||
|
1) Use typedef:
|
||||||
|
```cpp
|
||||||
|
using int_pair = std::pair<int, int>;
|
||||||
|
REQUIRE_THROWS_AS(int_pair(1, 2), std::invalid_argument);
|
||||||
|
```
|
||||||
|
|
||||||
|
This solution is always applicable, but makes the meaning of the code
|
||||||
|
less clear.
|
||||||
|
|
||||||
|
2) Parenthesize the expression:
|
||||||
|
```cpp
|
||||||
|
TEST_CASE_METHOD((Fixture<int, int>), "foo", "[bar]") {
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This solution is not always applicable, because it might require extra
|
||||||
|
changes on the Catch's side to work.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md#top)
|
[Home](Readme.md#top)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# CI and build system integration
|
# CI and other odd pieces
|
||||||
|
|
||||||
|
This page talks about how Catch integrates with Continuous Integration
|
||||||
Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
|
Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
|
||||||
|
|
||||||
## Continuous Integration systems
|
## Continuous Integration systems
|
||||||
@@ -71,105 +72,31 @@ Catch offers prototypal support for being included in precompiled headers, but b
|
|||||||
* include "catch.hpp" again
|
* include "catch.hpp" again
|
||||||
|
|
||||||
|
|
||||||
### CMake
|
|
||||||
|
|
||||||
In general we recommend "vendoring" Catch's single-include releases inside your own repository. If you do this, the following example shows a minimal CMake project:
|
|
||||||
```CMake
|
|
||||||
cmake_minimum_required(VERSION 3.0)
|
|
||||||
|
|
||||||
project(cmake_test)
|
|
||||||
|
|
||||||
# Prepare "Catch" library for other executables
|
|
||||||
set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/catch)
|
|
||||||
add_library(Catch INTERFACE)
|
|
||||||
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# Make test executable
|
|
||||||
set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
|
|
||||||
add_executable(tests ${TEST_SOURCES})
|
|
||||||
target_link_libraries(tests Catch)
|
|
||||||
```
|
|
||||||
Note that it assumes that the path to the Catch's header is `catch/catch.hpp` from the `CMakeLists.txt` file.
|
|
||||||
|
|
||||||
|
|
||||||
You can also use the following CMake snippet to automatically fetch the entire Catch repository from github and configure it as an external project:
|
|
||||||
```CMake
|
|
||||||
cmake_minimum_required(VERSION 2.8.8)
|
|
||||||
project(catch_builder CXX)
|
|
||||||
include(ExternalProject)
|
|
||||||
find_package(Git REQUIRED)
|
|
||||||
|
|
||||||
ExternalProject_Add(
|
|
||||||
catch
|
|
||||||
PREFIX ${CMAKE_BINARY_DIR}/catch
|
|
||||||
GIT_REPOSITORY https://github.com/philsquared/Catch.git
|
|
||||||
TIMEOUT 10
|
|
||||||
UPDATE_COMMAND ${GIT_EXECUTABLE} pull
|
|
||||||
CONFIGURE_COMMAND ""
|
|
||||||
BUILD_COMMAND ""
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
LOG_DOWNLOAD ON
|
|
||||||
)
|
|
||||||
|
|
||||||
# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
|
|
||||||
ExternalProject_Get_Property(catch source_dir)
|
|
||||||
set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
|
|
||||||
```
|
|
||||||
|
|
||||||
If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
|
|
||||||
|
|
||||||
```CMake
|
|
||||||
# Includes Catch in the project:
|
|
||||||
add_subdirectory(${EXT_PROJECTS_DIR}/catch)
|
|
||||||
include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES})
|
|
||||||
enable_testing(true) # Enables unit-testing.
|
|
||||||
```
|
|
||||||
|
|
||||||
The advantage of this approach is that you can always automatically update Catch to the latest release. The disadvantage is that it means bringing in lot more than you need.
|
|
||||||
|
|
||||||
|
|
||||||
### Automatic test registration
|
|
||||||
We provide 2 CMake scripts that can automatically register Catch-based
|
|
||||||
tests with CTest,
|
|
||||||
* `contrib/ParseAndAddCatchTests.cmake`
|
|
||||||
* `contrib/CatchAddTests.cmake`
|
|
||||||
|
|
||||||
The first is based on parsing the test implementation files, and attempts
|
|
||||||
to register all `TEST_CASE`s using their tags as labels. This means that
|
|
||||||
these:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
TEST_CASE("Test1", "[unit]") {
|
|
||||||
int a = 1;
|
|
||||||
int b = 2;
|
|
||||||
REQUIRE(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Test2") {
|
|
||||||
int a = 1;
|
|
||||||
int b = 2;
|
|
||||||
REQUIRE(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Test3", "[a][b][c]") {
|
|
||||||
int a = 1;
|
|
||||||
int b = 2;
|
|
||||||
REQUIRE(a == b);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
would be registered as 3 tests, `Test1`, `Test2` and `Test3`,
|
|
||||||
and 4 CTest labels would be created, `a`, `b`, `c` and `unit`.
|
|
||||||
|
|
||||||
|
|
||||||
The second is based on parsing the output of a Catch binary given
|
|
||||||
`--list-test-names-only`. This means that it deals with inactive
|
|
||||||
(e.g. commented-out) tests better, but requires CMake 3.10 for full
|
|
||||||
functionality.
|
|
||||||
|
|
||||||
### CodeCoverage module (GCOV, LCOV...)
|
### CodeCoverage module (GCOV, LCOV...)
|
||||||
|
|
||||||
If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
|
If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
|
||||||
|
|
||||||
|
|
||||||
|
### pkg-config
|
||||||
|
|
||||||
|
Catch2 provides a rudimentary pkg-config integration, by registering itself
|
||||||
|
under the name `catch2`. This means that after Catch2 is installed, you
|
||||||
|
can use `pkg-config` to get its include path: `pkg-config --cflags catch2`.
|
||||||
|
|
||||||
|
### gdb and lldb scripts
|
||||||
|
|
||||||
|
Catch2's `contrib` folder also contains two simple debugger scripts,
|
||||||
|
`gdbinit` for `gdb` and `lldbinit` for `lldb`. If loaded into their
|
||||||
|
respective debugger, these will tell it to step over Catch2's internals
|
||||||
|
when stepping through code.
|
||||||
|
|
||||||
|
|
||||||
|
## CMake
|
||||||
|
|
||||||
|
[As it has been getting kinda long, the documentation of Catch2's
|
||||||
|
integration with CMake has been moved to its own page.](cmake-integration.md#top)
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md#top)
|
[Home](Readme.md#top)
|
189
docs/cmake-integration.md
Normal file
189
docs/cmake-integration.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<a id="top"></a>
|
||||||
|
# CMake integration
|
||||||
|
|
||||||
|
Because we use CMake to build Catch2, we also provide a couple of
|
||||||
|
integration points for our users.
|
||||||
|
|
||||||
|
1) Catch2 exports a (namespaced) CMake target
|
||||||
|
2) Catch2's repository contains CMake scripts for automatic registration
|
||||||
|
of `TEST_CASE`s in CTest
|
||||||
|
|
||||||
|
## CMake target
|
||||||
|
|
||||||
|
Catch2's CMake build exports an interface target `Catch2::Catch2`. Linking
|
||||||
|
against it will add the proper include path and all necessary capabilities
|
||||||
|
to the resulting binary.
|
||||||
|
|
||||||
|
This means that if Catch2 has been installed on the system, it should be
|
||||||
|
enough to do:
|
||||||
|
```cmake
|
||||||
|
find_package(Catch2 REQUIRED)
|
||||||
|
target_link_libraries(tests Catch2::Catch2)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
This target is also provided when Catch2 is used as a subdirectory.
|
||||||
|
Assuming that Catch2 has been cloned to `lib/Catch2`:
|
||||||
|
```cmake
|
||||||
|
add_subdirectory(lib/Catch2)
|
||||||
|
target_link_libraries(tests Catch2::Catch2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Automatic test registration
|
||||||
|
|
||||||
|
Catch2's repository also contains two CMake scripts that help users
|
||||||
|
with automatically registering their `TEST_CASE`s with CTest. They
|
||||||
|
can be found in the `contrib` folder, and are
|
||||||
|
|
||||||
|
1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
|
||||||
|
2) `ParseAndAddCatchTests.cmake`
|
||||||
|
|
||||||
|
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
|
||||||
|
to your CMake module path.
|
||||||
|
|
||||||
|
### `Catch.cmake` and `AddCatchTests.cmake`
|
||||||
|
|
||||||
|
`Catch.cmake` provides function `catch_discover_tests` to get tests from
|
||||||
|
a target. This function works by running the resulting executable with
|
||||||
|
`--list-test-names-only` flag, and then parsing the output to find all
|
||||||
|
existing tests.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
```cmake
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(baz LANGUAGES CXX VERSION 0.0.1)
|
||||||
|
|
||||||
|
find_package(Catch2 REQUIRED)
|
||||||
|
add_executable(foo test.cpp)
|
||||||
|
target_link_libraries(foo Catch2::Catch2)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
include(Catch)
|
||||||
|
catch_discover_tests(foo)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Customization
|
||||||
|
`catch_discover_tests` can be given several extra argumets:
|
||||||
|
```cmake
|
||||||
|
catch_discover_tests(target
|
||||||
|
[TEST_SPEC arg1...]
|
||||||
|
[EXTRA_ARGS arg1...]
|
||||||
|
[WORKING_DIRECTORY dir]
|
||||||
|
[TEST_PREFIX prefix]
|
||||||
|
[TEST_SUFFIX suffix]
|
||||||
|
[PROPERTIES name1 value1...]
|
||||||
|
[TEST_LIST var]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
* `TEST_SPEC arg1...`
|
||||||
|
|
||||||
|
Specifies test cases, wildcarded test cases, tags and tag expressions to
|
||||||
|
pass to the Catch executable alongside the `--list-test-names-only` flag.
|
||||||
|
|
||||||
|
|
||||||
|
* `EXTRA_ARGS arg1...`
|
||||||
|
|
||||||
|
Any extra arguments to pass on the command line to each test case.
|
||||||
|
|
||||||
|
|
||||||
|
* `WORKING_DIRECTORY dir`
|
||||||
|
|
||||||
|
Specifies the directory in which to run the discovered test cases. If this
|
||||||
|
option is not provided, the current binary directory is used.
|
||||||
|
|
||||||
|
|
||||||
|
* `TEST_PREFIX prefix`
|
||||||
|
|
||||||
|
Specifies a _prefix_ to be added to the name of each discovered test case.
|
||||||
|
This can be useful when the same test executable is being used in multiple
|
||||||
|
calls to `catch_discover_tests()`, with different `TEST_SPEC` or `EXTRA_ARGS`.
|
||||||
|
|
||||||
|
|
||||||
|
* `TEST_SUFFIX suffix`
|
||||||
|
|
||||||
|
Same as `TEST_PREFIX`, except it specific the _suffix_ for the test names.
|
||||||
|
Both `TEST_PREFIX` and `TEST_SUFFIX` can be specified at the same time.
|
||||||
|
|
||||||
|
|
||||||
|
* `PROPERTIES name1 value1...`
|
||||||
|
|
||||||
|
Specifies additional properties to be set on all tests discovered by this
|
||||||
|
invocation of `catch_discover_tests`.
|
||||||
|
|
||||||
|
|
||||||
|
* `TEST_LIST var`
|
||||||
|
|
||||||
|
Make the list of tests available in the variable `var`, rather than the
|
||||||
|
default `<target>_TESTS`. This can be useful when the same test
|
||||||
|
executable is being used in multiple calls to `catch_discover_tests()`.
|
||||||
|
Note that this variable is only available in CTest.
|
||||||
|
|
||||||
|
|
||||||
|
### `ParseAndAddCatchTests.cmake`
|
||||||
|
|
||||||
|
`ParseAndAddCatchTests` works by parsing all implementation files
|
||||||
|
associated with the provided target, and registering them via CTest's
|
||||||
|
`add_test`. This approach has some limitations, such as the fact that
|
||||||
|
commented-out tests will be registered anyway.
|
||||||
|
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(baz LANGUAGES CXX VERSION 0.0.1)
|
||||||
|
|
||||||
|
find_package(Catch2 REQUIRED)
|
||||||
|
add_executable(foo test.cpp)
|
||||||
|
target_link_libraries(foo Catch2::Catch2)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
include(ParseAndAddCatchTests)
|
||||||
|
ParseAndAddCatchTests(foo)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Customization
|
||||||
|
|
||||||
|
`ParseAndAddCatchTests` provides some customization points:
|
||||||
|
* `PARSE_CATCH_TESTS_VERBOSE` -- When `ON`, the script prints debug
|
||||||
|
messages. Defaults to `OFF`.
|
||||||
|
* `PARSE_CATCH_TESTS_NO_HIDDEN_TESTS` -- When `ON`, hidden tests (tests
|
||||||
|
tagged with any of `[!hide]`, `[.]` or `[.foo]`) will not be registered.
|
||||||
|
Defaults to `OFF`.
|
||||||
|
* `PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME` -- When `ON`, adds fixture
|
||||||
|
class name to the test name in CTest. Defaults to `ON`.
|
||||||
|
* `PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME` -- When `ON`, adds target
|
||||||
|
name to the test name in CTest. Defaults to `ON`.
|
||||||
|
* `PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS` -- When `ON`, adds test
|
||||||
|
file to `CMAKE_CONFIGURE_DEPENDS`. This means that the CMake configuration
|
||||||
|
step will be re-ran when the test files change, letting new tests be
|
||||||
|
automatically discovered. Defaults to `OFF`.
|
||||||
|
|
||||||
|
|
||||||
|
## CMake project options
|
||||||
|
|
||||||
|
Catch2's CMake project also provides some options for other projects
|
||||||
|
that consume it. These are
|
||||||
|
|
||||||
|
* `CATCH_BUILD_TESTING` -- When `ON`, Catch2's SelfTest project will be
|
||||||
|
built. Defaults to `ON`. Note that Catch2 also obeys `BUILD_TESTING` CMake
|
||||||
|
variable, so _both_ of them need to be `ON` for the SelfTest to be built,
|
||||||
|
and either of them can be set to `OFF` to disable building SelfTest.
|
||||||
|
* `CATCH_BUILD_EXAMPLES` -- When `ON`, Catch2's usage examples will be
|
||||||
|
built. Defaults to `OFF`.
|
||||||
|
* `CATCH_INSTALL_DOCS` -- When `ON`, Catch2's documentation will be
|
||||||
|
included in the installation. Defaults to `ON`.
|
||||||
|
* `CATCH_INSTALL_HELPERS` -- When `ON`, Catch2's contrib folder will be
|
||||||
|
included in the installation. Defaults to `ON`.
|
||||||
|
* `BUILD_TESTING` -- When `ON` and the project is not used as a subproject,
|
||||||
|
Catch2's test binary will be built. Defaults to `ON`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[Home](Readme.md#top)
|
@@ -24,6 +24,7 @@
|
|||||||
[Usage](#usage)<br>
|
[Usage](#usage)<br>
|
||||||
[Specify the section to run](#specify-the-section-to-run)<br>
|
[Specify the section to run](#specify-the-section-to-run)<br>
|
||||||
[Filenames as tags](#filenames-as-tags)<br>
|
[Filenames as tags](#filenames-as-tags)<br>
|
||||||
|
[Override output colouring](#use-colour)<br>
|
||||||
|
|
||||||
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
|
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
|
||||||
Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
|
Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
|
||||||
@@ -57,6 +58,7 @@ Click one of the followings links to take you straight to that option - or scrol
|
|||||||
<a href="#libidentify"> ` --libidentify`</a><br />
|
<a href="#libidentify"> ` --libidentify`</a><br />
|
||||||
<a href="#wait-for-keypress"> ` --wait-for-keypress`</a><br />
|
<a href="#wait-for-keypress"> ` --wait-for-keypress`</a><br />
|
||||||
<a href="#benchmark-resolution-multiple"> ` --benchmark-resolution-multiple`</a><br />
|
<a href="#benchmark-resolution-multiple"> ` --benchmark-resolution-multiple`</a><br />
|
||||||
|
<a href="#use-colour"> ` --use-colour`</a><br />
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
@@ -122,7 +124,9 @@ The JUnit reporter is an xml format that follows the structure of the JUnit XML
|
|||||||
## Breaking into the debugger
|
## Breaking into the debugger
|
||||||
<pre>-b, --break</pre>
|
<pre>-b, --break</pre>
|
||||||
|
|
||||||
In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
|
Under most debuggers Catch2 is capable of automatically breaking on a test
|
||||||
|
failure. This allows the user to see the current state of the test during
|
||||||
|
failure.
|
||||||
|
|
||||||
<a id="showing-results-for-successful-tests"></a>
|
<a id="showing-results-for-successful-tests"></a>
|
||||||
## Showing results for successful tests
|
## Showing results for successful tests
|
||||||
@@ -329,6 +333,16 @@ filename it is found in, with any extension stripped, prefixed with the `#` char
|
|||||||
|
|
||||||
So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`.
|
So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`.
|
||||||
|
|
||||||
|
<a id="use-colour"></a>
|
||||||
|
## Override output colouring
|
||||||
|
<pre>--use-colour <yes|no|auto></pre>
|
||||||
|
|
||||||
|
Catch colours output for terminals, but omits colouring when it detects that
|
||||||
|
output is being sent to a pipe. This is done to avoid interfering with automated
|
||||||
|
processing of output.
|
||||||
|
|
||||||
|
`--use-colour yes` forces coloured output, `--use-colour no` disables coloured
|
||||||
|
output. The default behaviour is `--use-colour auto`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -66,24 +66,32 @@ By default a console width of 80 is assumed but this can be controlled by defini
|
|||||||
|
|
||||||
CATCH_CONFIG_NOSTDOUT
|
CATCH_CONFIG_NOSTDOUT
|
||||||
|
|
||||||
Catch does not use ```std::cout```, ```std::cerr``` and ```std::clog``` directly but gets them from ```Catch::cout()```, ```Catch::cerr()``` and ```Catch::clog``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
|
To support platforms that do not provide `std::cout`, `std::cerr` and
|
||||||
|
`std::clog`, Catch does not usem the directly, but rather calls
|
||||||
|
`Catch::cout`, `Catch::cerr` and `Catch::clog`. You can replace their
|
||||||
|
implementation by defining `CATCH_CONFIG_NOSTDOUT` and implementing
|
||||||
|
them yourself, their signatures are:
|
||||||
|
|
||||||
std::ostream& cout();
|
std::ostream& cout();
|
||||||
std::ostream& cerr();
|
std::ostream& cerr();
|
||||||
std::ostream& clog();
|
std::ostream& clog();
|
||||||
|
|
||||||
This can be useful on certain platforms that do not provide the standard iostreams, such as certain embedded systems.
|
[You can see an example of replacing these functions here.](
|
||||||
|
../examples/231-Cfg-OutputStreams.cpp)
|
||||||
|
|
||||||
|
|
||||||
## Fallback stringifier
|
## Fallback stringifier
|
||||||
|
|
||||||
By default Catch's stringification machinery falls back to a "{?}". To
|
By default, when Catch's stringification machinery has to stringify
|
||||||
let projects reuse their own existing stringification machinery, this
|
a type that does not specialize `StringMaker`, does not overload `operator<<`,
|
||||||
fallback can be overridden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER`
|
is not an enumeration and is not a range, it uses `"{?}"`. This can be
|
||||||
to a name of a function that should perform the stringification instead.
|
overriden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` to name of a
|
||||||
|
function that should perform the stringification instead.
|
||||||
|
|
||||||
The provided function must return std::string and must accept any type
|
All types that do not provide `StringMaker` specialization or `operator<<`
|
||||||
(e.g. via overloading).
|
overload will be sent to this function (this includes enums and ranges).
|
||||||
|
The provided function must return `std::string` and must accept any type,
|
||||||
|
e.g. via overloading.
|
||||||
|
|
||||||
_Note that if the provided function does not handle a type and this type
|
_Note that if the provided function does not handle a type and this type
|
||||||
requires to be stringified, the compilation will fail._
|
requires to be stringified, the compilation will fail._
|
||||||
@@ -99,6 +107,19 @@ This means that defining `CATCH_CONFIG_DEFAULT_REPORTER` to `"console"`
|
|||||||
is equivalent with the out-of-the-box experience.
|
is equivalent with the out-of-the-box experience.
|
||||||
|
|
||||||
|
|
||||||
|
## C++11 toggles
|
||||||
|
|
||||||
|
CATCH_CONFIG_CPP11_TO_STRING // Use `std::to_string`
|
||||||
|
|
||||||
|
Because we support platforms whose standard library does not contain
|
||||||
|
`std::to_string`, it is possible to force Catch to use a workaround
|
||||||
|
based on `std::stringstream`. On platforms other than Android,
|
||||||
|
the default is to use `std::to_string`. On Android, the default is to
|
||||||
|
use the `stringstream` workaround. As always, it is possible to override
|
||||||
|
Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or
|
||||||
|
`CATCH_CONFIG_NO_CPP11_TO_STRING`.
|
||||||
|
|
||||||
|
|
||||||
## C++17 toggles
|
## C++17 toggles
|
||||||
|
|
||||||
CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception
|
CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception
|
||||||
@@ -121,6 +142,7 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`.
|
|||||||
CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression
|
CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression
|
||||||
CATCH_CONFIG_DISABLE // Disables assertions and test case registration
|
CATCH_CONFIG_DISABLE // Disables assertions and test case registration
|
||||||
CATCH_CONFIG_WCHAR // Enables use of wchart_t
|
CATCH_CONFIG_WCHAR // Enables use of wchart_t
|
||||||
|
CATCH_CONFIG_EXPERIMENTAL_REDIRECT // Enables the new (experimental) way of capturing stdout/stderr
|
||||||
|
|
||||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
||||||
|
|
||||||
@@ -131,14 +153,19 @@ Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC,
|
|||||||
`CATCH_CONFIG_WCHAR` is on by default, but can be disabled. Currently
|
`CATCH_CONFIG_WCHAR` is on by default, but can be disabled. Currently
|
||||||
it is only used in support for DJGPP cross-compiler.
|
it is only used in support for DJGPP cross-compiler.
|
||||||
|
|
||||||
These toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
|
With the exception of `CATCH_CONFIG_EXPERIMENTAL_REDIRECT`,
|
||||||
|
these toggles can be disabled by using `_NO_` form of the toggle,
|
||||||
|
e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
|
||||||
|
|
||||||
### `CATCH_CONFIG_FAST_COMPILE`
|
### `CATCH_CONFIG_FAST_COMPILE`
|
||||||
Defining this flag speeds up compilation of test files by ~20%, by making 2 changes:
|
This compile-time flag speeds up compilation of assertion macros by ~20%,
|
||||||
* The `-b` (`--break`) flag no longer makes Catch break into debugger in the same stack frame as the failed test, but rather in a stack frame *below*.
|
by disabling the generation of assertion-local try-catch blocks for
|
||||||
* Non-exception family of macros ({`REQUIRE`,`CHECK`}{`_`,`_FALSE`, `_THAT`}, no longer use local try-catch block. This disables exception translation, but should not lead to false negatives.
|
non-exception family of assertion macros ({`REQUIRE`,`CHECK`}{``,`_FALSE`, `_THAT`}).
|
||||||
|
This disables translation of exceptions thrown under these assertions, but
|
||||||
|
should not lead to false negatives.
|
||||||
|
|
||||||
`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag and throwing unexpected exceptions will be unpredictable.
|
`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined,
|
||||||
|
in all translation units that are linked into single test binary.
|
||||||
|
|
||||||
### `CATCH_CONFIG_DISABLE_MATCHERS`
|
### `CATCH_CONFIG_DISABLE_MATCHERS`
|
||||||
When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matchers are ifdef-ed away from the translation unit. Doing so will speed up compilation of that TU.
|
When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matchers are ifdef-ed away from the translation unit. Doing so will speed up compilation of that TU.
|
||||||
|
@@ -21,7 +21,9 @@ TEST_CASE( "Looped section" ) {
|
|||||||
This section outlines some missing features, what is their status and their possible workarounds.
|
This section outlines some missing features, what is their status and their possible workarounds.
|
||||||
|
|
||||||
### Thread safe assertions
|
### Thread safe assertions
|
||||||
Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros.
|
Catch2's assertion macros are not thread safe. This does not mean that
|
||||||
|
you cannot use threads inside Catch's test, but that only single thread
|
||||||
|
can interact with Catch's assertions and other macros.
|
||||||
|
|
||||||
This means that this is ok
|
This means that this is ok
|
||||||
```cpp
|
```cpp
|
||||||
@@ -49,8 +51,8 @@ because only one thread passes the `REQUIRE` macro and this is not
|
|||||||
REQUIRE(cnt == 16);
|
REQUIRE(cnt == 16);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Because C++11 provides the necessary tools to do this, we are planning
|
||||||
_This limitation is highly unlikely to be lifted before Catch 2 is released._
|
to remove this limitation in the future.
|
||||||
|
|
||||||
### Process isolation in a test
|
### Process isolation in a test
|
||||||
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
|
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
|
||||||
|
@@ -1,18 +1,25 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# List of examples
|
# List of examples
|
||||||
|
|
||||||
|
## Already available
|
||||||
|
|
||||||
- Test Case: [Single-file](../examples/010-TestCase.cpp)
|
- Test Case: [Single-file](../examples/010-TestCase.cpp)
|
||||||
- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-1.cpp)
|
- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-2.cpp)
|
||||||
- Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp)
|
- Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp)
|
||||||
|
- Fixture: [Sections](../examples/100-Fix-Section.cpp)
|
||||||
|
- Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp)
|
||||||
|
- BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)
|
||||||
|
- Listener: [Listeners](../examples/210-Evt-EventListeners.cpp)
|
||||||
|
- Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp)
|
||||||
|
|
||||||
|
## Planned
|
||||||
|
|
||||||
- Assertion: [REQUIRE_THAT and Matchers](../examples/040-Asn-RequireThat.cpp)
|
- Assertion: [REQUIRE_THAT and Matchers](../examples/040-Asn-RequireThat.cpp)
|
||||||
- Assertion: [REQUIRE_NO_THROW](../examples/050-Asn-RequireNoThrow.cpp)
|
- Assertion: [REQUIRE_NO_THROW](../examples/050-Asn-RequireNoThrow.cpp)
|
||||||
- Assertion: [REQUIRE_THROWS](../examples/050-Asn-RequireThrows.cpp)
|
- Assertion: [REQUIRE_THROWS](../examples/050-Asn-RequireThrows.cpp)
|
||||||
- Assertion: [REQUIRE_THROWS_AS](../examples/070-Asn-RequireThrowsAs.cpp)
|
- Assertion: [REQUIRE_THROWS_AS](../examples/070-Asn-RequireThrowsAs.cpp)
|
||||||
- Assertion: [REQUIRE_THROWS_WITH](../examples/080-Asn-RequireThrowsWith.cpp)
|
- Assertion: [REQUIRE_THROWS_WITH](../examples/080-Asn-RequireThrowsWith.cpp)
|
||||||
- Assertion: [REQUIRE_THROWS_MATCHES](../examples/090-Asn-RequireThrowsMatches.cpp)
|
- Assertion: [REQUIRE_THROWS_MATCHES](../examples/090-Asn-RequireThrowsMatches.cpp)
|
||||||
- Fixture: [Sections](../examples/100-Fix-Section.cpp)
|
|
||||||
- Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp)
|
|
||||||
- BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)
|
|
||||||
- Floating point: [Approx - Comparisons](../examples/130-Fpt-Approx.cpp)
|
- Floating point: [Approx - Comparisons](../examples/130-Fpt-Approx.cpp)
|
||||||
- Logging: [CAPTURE - Capture expression](../examples/140-Log-Capture.cpp)
|
- Logging: [CAPTURE - Capture expression](../examples/140-Log-Capture.cpp)
|
||||||
- Logging: [INFO - Provide information with failure](../examples/150-Log-Info.cpp)
|
- Logging: [INFO - Provide information with failure](../examples/150-Log-Info.cpp)
|
||||||
@@ -21,7 +28,6 @@
|
|||||||
- Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp)
|
- Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp)
|
||||||
- Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp)
|
- Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp)
|
||||||
- Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp)
|
- Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp)
|
||||||
- Listener: [Listeners](../examples/210-Evt-EventListeners.cpp)
|
|
||||||
- Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp)
|
- Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp)
|
||||||
- Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp)
|
- Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp)
|
||||||
- Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp)
|
- Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp)
|
||||||
|
@@ -72,12 +72,6 @@ This would log something like:
|
|||||||
|
|
||||||
<pre>"theAnswer := 42"</pre>
|
<pre>"theAnswer := 42"</pre>
|
||||||
|
|
||||||
## Deprecated macros
|
|
||||||
|
|
||||||
**SCOPED_INFO and SCOPED_CAPTURE**
|
|
||||||
|
|
||||||
These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md#top)
|
[Home](Readme.md#top)
|
||||||
|
@@ -53,6 +53,25 @@ The floating point matchers are `WithinULP` and `WithinAbs`. `WithinAbs` accepts
|
|||||||
Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s.
|
Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s.
|
||||||
|
|
||||||
|
|
||||||
|
### Generic matchers
|
||||||
|
Catch also aims to provide a set of generic matchers. Currently this set
|
||||||
|
contains only a matcher that takes arbitrary callable predicate and applies
|
||||||
|
it onto the provided object.
|
||||||
|
|
||||||
|
Because of type inference limitations, the argument type of the predicate
|
||||||
|
has to be provided explicitly. Example:
|
||||||
|
```cpp
|
||||||
|
REQUIRE_THAT("Hello olleH",
|
||||||
|
Predicate<std::string>(
|
||||||
|
[] (std::string const& str) -> bool { return str.front() == str.back(); },
|
||||||
|
"First and last character should be equal")
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
The second argument is an optional description of the predicate, and is
|
||||||
|
used only during reporting of the result.
|
||||||
|
|
||||||
|
|
||||||
## Custom matchers
|
## Custom matchers
|
||||||
It's easy to provide your own matchers to extend Catch or just to work with your own types.
|
It's easy to provide your own matchers to extend Catch or just to work with your own types.
|
||||||
|
|
||||||
|
@@ -47,6 +47,9 @@ A header-only template engine for modern C++.
|
|||||||
### [JSON for Modern C++](https://github.com/nlohmann/json)
|
### [JSON for Modern C++](https://github.com/nlohmann/json)
|
||||||
A, single-header, JSON parsing library that takes advantage of what C++ has to offer.
|
A, single-header, JSON parsing library that takes advantage of what C++ has to offer.
|
||||||
|
|
||||||
|
### [libcluon](https://github.com/chrberger/libcluon)
|
||||||
|
A single-header-only library written in C++14 to glue distributed software components (UDP, TCP, shared memory) supporting natively Protobuf, LCM/ZCM, MsgPack, and JSON for dynamic message transformations in-between.
|
||||||
|
|
||||||
### [MNMLSTC Core](https://github.com/mnmlstc/core)
|
### [MNMLSTC Core](https://github.com/mnmlstc/core)
|
||||||
A small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions.
|
A small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions.
|
||||||
|
|
||||||
|
@@ -1,5 +1,99 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
|
|
||||||
|
# 2.3.0
|
||||||
|
|
||||||
|
**This release changes the include paths provided by our CMake and
|
||||||
|
pkg-config integration. The proper include path for the single-header
|
||||||
|
when using one of the above is now `<catch2/catch.hpp>`. This change
|
||||||
|
also necessitated changes to paths inside the repository, so that the
|
||||||
|
single-header version is now at `single_include/catch2/catch.hpp`, rather
|
||||||
|
than `single_include/catch.hpp`.**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
* Fixed Objective-C++ build
|
||||||
|
* `-Wunused-variable` suppression no longer leaks from Catch's header under Clang
|
||||||
|
* Implementation of the experimental new output capture can now be disabled (#1335)
|
||||||
|
* This allows building Catch2 on platforms that do not provide things like `dup` or `tmpfile`.
|
||||||
|
* The JUnit and XML reporters will no longer skip over successful tests when running without `-s` (#1264, #1267, #1310)
|
||||||
|
* See improvements for more details
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* pkg-config and CMake integration has been rewritten
|
||||||
|
* If you use them, the new include path is `#include <catch2/catch.hpp>`
|
||||||
|
* CMake installation now also installs scripts from `contrib/`
|
||||||
|
* For details see the [new documentation](cmake-integration.md#top)
|
||||||
|
* Reporters now have a new customization point, `ReporterPreferences::shouldReportAllAssertions`
|
||||||
|
* When this is set to `false` and the tests are run without `-s`, passing assertions are not sent to the reporter.
|
||||||
|
* Defaults to `false`.
|
||||||
|
* Added `DYNAMIC_SECTION`, a section variant that constructs its name using stream
|
||||||
|
* This means that you can do `DYNAMIC_SECTION("For X := " << x)`.
|
||||||
|
|
||||||
|
|
||||||
|
# 2.2.3
|
||||||
|
|
||||||
|
**To fix some of the bugs, some behavior had to change in potentially breaking manner.**
|
||||||
|
**This means that even though this is a patch release, it might not be a drop-in replacement.**
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
* Listeners are now called before reporter
|
||||||
|
* This was always documented to be the case, now it actually works that way
|
||||||
|
* Catch's commandline will no longer accept multiple reporters
|
||||||
|
* This was done because multiple reporters never worked properly and broke things in non-obvious ways
|
||||||
|
* **This has potential to be a breaking change**
|
||||||
|
* MinGW is now detected as Windows platform w/o SEH support (#1257)
|
||||||
|
* This means that Catch2 no longer tries to use POSIX signal handling when compiled with MinGW
|
||||||
|
* Fixed potential UB in parsing tags using non-ASCII characters (#1266)
|
||||||
|
* Note that Catch2 still supports only ASCII test names/tags/etc
|
||||||
|
* `TEST_CASE_METHOD` can now be used on classnames containing commas (#1245)
|
||||||
|
* You have to enclose the classname in extra set of parentheses
|
||||||
|
* Fixed insufficient alt stack size for POSIX signal handling (#1225)
|
||||||
|
* Fixed compilation error on Android due to missing `std::to_string` in C++11 mode (#1280)
|
||||||
|
* Fixed the order of user-provided `FALLBACK_STRINGIFIER` in stringification machinery (#1024)
|
||||||
|
* It was intended to be replacement for built-in fallbacks, but it was used _after_ them.
|
||||||
|
* **This has potential to be a breaking change**
|
||||||
|
* Fixed compilation error when a type has an `operator<<` with templated lhs (#1285, #1306)
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* Added a new, experimental, output capture (#1243)
|
||||||
|
* This capture can also redirect output written via C apis, e.g. `printf`
|
||||||
|
* To opt-in, define `CATCH_CONFIG_EXPERIMENTAL_REDIRECT` in the implementation file
|
||||||
|
* Added a new fallback stringifier for classes derived from `std::exception`
|
||||||
|
* Both `StringMaker` specialization and `operator<<` overload are given priority
|
||||||
|
|
||||||
|
## Miscellaneous
|
||||||
|
* `contrib/` now contains dbg scripts that skip over Catch's internals (#904, #1283)
|
||||||
|
* `gdbinit` for gdb `lldbinit` for lldb
|
||||||
|
* `CatchAddTests.cmake` no longer strips whitespace from tests (#1265, #1281)
|
||||||
|
* Online documentation now describes `--use-colour` option (#1263)
|
||||||
|
|
||||||
|
|
||||||
|
# 2.2.2
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
* Fixed bug in `WithinAbs::match()` failing spuriously (#1228)
|
||||||
|
* Fixed clang-tidy diagnostic about virtual call in destructor (#1226)
|
||||||
|
* Reduced the number of GCC warnings suppression leaking out of the header (#1090, #1091)
|
||||||
|
* Only `-Wparentheses` should be leaking now
|
||||||
|
* Added upper bound on the time benchmark timer calibration is allowed to take (#1237)
|
||||||
|
* On platforms where `std::chrono::high_resolution_clock`'s resolution is low, the calibration would appear stuck
|
||||||
|
* Fixed compilation error when stringifying static arrays of `unsigned char`s (#1238)
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* XML encoder now hex-encodes invalid UTF-8 sequences (#1207)
|
||||||
|
* This affects xml and junit reporters
|
||||||
|
* Some invalid UTF-8 parts are left as is, e.g. surrogate pairs. This is because certain extensions of UTF-8 allow them, such as WTF-8.
|
||||||
|
* CLR objects (`T^`) can now be stringified (#1216)
|
||||||
|
* This affects code compiled as C++/CLI
|
||||||
|
* 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)
|
||||||
|
|
||||||
|
## Others
|
||||||
|
* Modified CMake-installed pkg-config to allow `#include <catch.hpp>`(#1239)
|
||||||
|
* The plans to standardize on `#include <catch2/catch.hpp>` are still in effect
|
||||||
|
|
||||||
|
|
||||||
# 2.2.1
|
# 2.2.1
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
@@ -49,17 +49,5 @@ on a specific version of the single-include header.
|
|||||||
|
|
||||||
## Optional steps
|
## Optional steps
|
||||||
|
|
||||||
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they *should* happen, but they can happen the next day without losing anything significant.
|
Because Catch's [vcpkg](https://github.com/Microsoft/vcpkg) port updates
|
||||||
|
itself automagically, there are no optional steps at this time.
|
||||||
|
|
||||||
### vcpkg update
|
|
||||||
|
|
||||||
Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of necessary work for you, it creates a branch and commits necessary changes. You should review these changes, push and open a PR against vcpkg's upstream.
|
|
||||||
|
|
||||||
Note that the script assumes you have your fork of vcpkg checked out in a directory next to the directory where you have checked out Catch, like so:
|
|
||||||
```
|
|
||||||
GitHub
|
|
||||||
Catch
|
|
||||||
vcpkg
|
|
||||||
```
|
|
||||||
|
|
||||||
|
@@ -12,7 +12,10 @@
|
|||||||
|
|
||||||
## 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/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/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.
|
||||||
|
|
||||||
|
Alternative ways of getting Catch2 include using your system package
|
||||||
|
manager, or installing it using its CMake package.
|
||||||
|
|
||||||
The full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
The full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
||||||
|
|
||||||
@@ -23,6 +26,9 @@ Catch2 is header only. All you need to do is drop the file somewhere reachable f
|
|||||||
|
|
||||||
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
|
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
|
||||||
|
|
||||||
|
_If you have installed Catch2 from system package manager, or CMake
|
||||||
|
package, you need to include the header as `#include <catch2/catch.hpp>`_
|
||||||
|
|
||||||
## Writing tests
|
## Writing tests
|
||||||
|
|
||||||
Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
|
Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
// Let Catch provide main():
|
// Let Catch provide main():
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
// That's it
|
// That's it
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
// Let Catch provide main():
|
// Let Catch provide main():
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
int Factorial( int number ) {
|
int Factorial( int number ) {
|
||||||
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
// Let Catch provide main():
|
// Let Catch provide main():
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
|
TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// main() provided by Catch in file 020-TestCase-1.cpp.
|
// main() provided by Catch in file 020-TestCase-1.cpp.
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
int Factorial( int number ) {
|
int Factorial( int number ) {
|
||||||
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// main() provided in 000-CatchMain.cpp
|
// main() provided in 000-CatchMain.cpp
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
std::string one() {
|
std::string one() {
|
||||||
return "1";
|
return "1";
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
// main() provided in 000-CatchMain.cpp
|
// main() provided in 000-CatchMain.cpp
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
|
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
// main() provided in 000-CatchMain.cpp
|
// main() provided in 000-CatchMain.cpp
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
class DBConnection
|
class DBConnection
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// main() provided in 000-CatchMain.cpp
|
// main() provided in 000-CatchMain.cpp
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
SCENARIO( "vectors can be sized and resized", "[vector]" ) {
|
SCENARIO( "vectors can be sized and resized", "[vector]" ) {
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
// Let Catch provide the required interfaces:
|
// Let Catch provide the required interfaces:
|
||||||
#define CATCH_CONFIG_EXTERNAL_INTERFACES
|
#define CATCH_CONFIG_EXTERNAL_INTERFACES
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include <catch2/catch.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -187,8 +187,7 @@ void print( std::ostream& os, int const level, std::string const& title, Catch::
|
|||||||
|
|
||||||
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
|
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
|
||||||
os << ws(level ) << title << ":\n"
|
os << ws(level ) << title << ":\n"
|
||||||
<< ws(level+1) << "- name: " << info.name << "\n"
|
<< ws(level+1) << "- name: " << info.name << "\n";
|
||||||
<< ws(level+1) << "- description: '" << info.description << "'\n";
|
|
||||||
print( os, level+1 , "- lineInfo", info.lineInfo );
|
print( os, level+1 , "- lineInfo", info.lineInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
examples/231-Cfg-OutputStreams.cpp
Normal file
49
examples/231-Cfg-OutputStreams.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// 231-Cfg-OutputStreams.cpp
|
||||||
|
// Show how to replace the streams with a simple custom made streambuf.
|
||||||
|
|
||||||
|
// Note that this reimplementation _does not_ follow `std::cerr`
|
||||||
|
// semantic, because it buffers the output. For most uses however,
|
||||||
|
// there is no important difference between having `std::cerr` buffered
|
||||||
|
// or unbuffered.
|
||||||
|
|
||||||
|
#define CATCH_CONFIG_NOSTDOUT
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
class out_buff : public std::stringbuf {
|
||||||
|
std::FILE* m_stream;
|
||||||
|
public:
|
||||||
|
out_buff(std::FILE* stream) :m_stream(stream) {}
|
||||||
|
~out_buff() { pubsync(); }
|
||||||
|
int sync() {
|
||||||
|
int ret = 0;
|
||||||
|
for (unsigned char c : str()) {
|
||||||
|
if (putc(c, m_stream) == EOF) {
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reset the buffer to avoid printing it multiple times
|
||||||
|
str("");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
std::ostream& cout() {
|
||||||
|
static std::ostream ret(new out_buff(stdout));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
std::ostream& clog() {
|
||||||
|
static std::ostream ret(new out_buff(stderr));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
std::ostream& cerr() {
|
||||||
|
return clog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("This binary uses putc to write out output", "[compilation-only]") {
|
||||||
|
SUCCEED("Nothing to test.");
|
||||||
|
}
|
@@ -17,6 +17,7 @@ set( HEADER_DIR ${CATCH_DIR}/single_include )
|
|||||||
|
|
||||||
set( SOURCES_SINGLE_FILE
|
set( SOURCES_SINGLE_FILE
|
||||||
010-TestCase.cpp
|
010-TestCase.cpp
|
||||||
|
231-Cfg-OutputStreams.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# multiple-file modules:
|
# multiple-file modules:
|
||||||
@@ -68,16 +69,16 @@ set( TARGETS_ALL ${TARGETS_SINGLE_FILE} ${TARGETS_IDIOMATIC_TESTS} 0
|
|||||||
|
|
||||||
# define program targets:
|
# define program targets:
|
||||||
|
|
||||||
add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch.hpp )
|
add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch2/catch.hpp )
|
||||||
|
|
||||||
add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch.hpp )
|
add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch2/catch.hpp )
|
||||||
|
|
||||||
foreach( name ${TARGETS_SINGLE_FILE} )
|
foreach( name ${TARGETS_SINGLE_FILE} )
|
||||||
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch.hpp )
|
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch2/catch.hpp )
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
foreach( name ${TARGETS_IDIOMATIC_TESTS} )
|
foreach( name ${TARGETS_IDIOMATIC_TESTS} )
|
||||||
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch.hpp )
|
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
foreach( name ${TARGETS_ALL} )
|
foreach( name ${TARGETS_ALL} )
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
|
||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 2
|
#define CATCH_VERSION_MAJOR 2
|
||||||
#define CATCH_VERSION_MINOR 2
|
#define CATCH_VERSION_MINOR 3
|
||||||
#define CATCH_VERSION_PATCH 1
|
#define CATCH_VERSION_PATCH 0
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang system_header
|
# pragma clang system_header
|
||||||
@@ -33,8 +33,10 @@
|
|||||||
# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
|
# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
|
||||||
# undef CATCH_CONFIG_DISABLE_MATCHERS
|
# undef CATCH_CONFIG_DISABLE_MATCHERS
|
||||||
# endif
|
# endif
|
||||||
|
# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
|
||||||
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
|
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CATCH_CONFIG_IMPL_ONLY)
|
#if !defined(CATCH_CONFIG_IMPL_ONLY)
|
||||||
#include "internal/catch_platform.h"
|
#include "internal/catch_platform.h"
|
||||||
@@ -135,6 +137,7 @@
|
|||||||
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
||||||
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||||
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||||
|
#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
|
||||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||||
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||||
@@ -144,11 +147,11 @@
|
|||||||
// "BDD-style" convenience wrappers
|
// "BDD-style" convenience wrappers
|
||||||
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
|
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
|
||||||
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
||||||
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc )
|
#define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
|
||||||
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc )
|
#define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
|
||||||
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
|
#define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
|
||||||
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc )
|
#define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
|
||||||
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
|
#define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
|
||||||
|
|
||||||
// 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
|
||||||
#else
|
#else
|
||||||
@@ -194,6 +197,7 @@
|
|||||||
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
||||||
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||||
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||||
|
#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
|
||||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||||
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||||
@@ -207,15 +211,16 @@
|
|||||||
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
|
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
|
||||||
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
||||||
|
|
||||||
#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc )
|
#define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
|
||||||
#define WHEN( desc ) SECTION( std::string(" When: ") + desc )
|
#define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
|
||||||
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
|
#define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
|
||||||
#define THEN( desc ) SECTION( std::string(" Then: ") + desc )
|
#define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
|
||||||
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc )
|
#define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
|
||||||
|
|
||||||
using Catch::Detail::Approx;
|
using Catch::Detail::Approx;
|
||||||
|
|
||||||
#else
|
#else // CATCH_CONFIG_DISABLE
|
||||||
|
|
||||||
//////
|
//////
|
||||||
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
|
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
|
||||||
#ifdef CATCH_CONFIG_PREFIX_ALL
|
#ifdef CATCH_CONFIG_PREFIX_ALL
|
||||||
@@ -260,6 +265,7 @@ using Catch::Detail::Approx;
|
|||||||
#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( ... )
|
||||||
|
#define CATCH_DYNAMIC_SECTION( ... )
|
||||||
#define CATCH_FAIL( ... ) (void)(0)
|
#define CATCH_FAIL( ... ) (void)(0)
|
||||||
#define CATCH_FAIL_CHECK( ... ) (void)(0)
|
#define CATCH_FAIL_CHECK( ... ) (void)(0)
|
||||||
#define CATCH_SUCCEED( ... ) (void)(0)
|
#define CATCH_SUCCEED( ... ) (void)(0)
|
||||||
@@ -319,6 +325,7 @@ using Catch::Detail::Approx;
|
|||||||
#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( ... )
|
||||||
|
#define DYNAMIC_SECTION( ... )
|
||||||
#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)
|
||||||
|
@@ -35,6 +35,13 @@ namespace Detail {
|
|||||||
return Approx( 0 );
|
return Approx( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Approx Approx::operator-() const {
|
||||||
|
auto temp(*this);
|
||||||
|
temp.m_value = -temp.m_value;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string Approx::toString() const {
|
std::string Approx::toString() const {
|
||||||
ReusableStringStream rss;
|
ReusableStringStream rss;
|
||||||
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
|
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
|
||||||
@@ -49,6 +56,15 @@ namespace Detail {
|
|||||||
|
|
||||||
} // end namespace Detail
|
} // end namespace Detail
|
||||||
|
|
||||||
|
namespace literals {
|
||||||
|
Detail::Approx operator "" _a(long double val) {
|
||||||
|
return Detail::Approx(val);
|
||||||
|
}
|
||||||
|
Detail::Approx operator "" _a(unsigned long long val) {
|
||||||
|
return Detail::Approx(val);
|
||||||
|
}
|
||||||
|
} // end namespace literals
|
||||||
|
|
||||||
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@ namespace Detail {
|
|||||||
|
|
||||||
static Approx custom();
|
static Approx custom();
|
||||||
|
|
||||||
|
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 ) {
|
||||||
Approx approx( static_cast<double>(value) );
|
Approx approx( static_cast<double>(value) );
|
||||||
@@ -121,7 +123,12 @@ namespace Detail {
|
|||||||
double m_scale;
|
double m_scale;
|
||||||
double m_value;
|
double m_value;
|
||||||
};
|
};
|
||||||
}
|
} // end namespace Detail
|
||||||
|
|
||||||
|
namespace literals {
|
||||||
|
Detail::Approx operator "" _a(long double val);
|
||||||
|
Detail::Approx operator "" _a(unsigned long long val);
|
||||||
|
} // end namespace literals
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct StringMaker<Catch::Detail::Approx> {
|
struct StringMaker<Catch::Detail::Approx> {
|
||||||
|
@@ -18,10 +18,12 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace {
|
||||||
auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
|
auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
|
||||||
expr.streamReconstructedExpression( os );
|
expr.streamReconstructedExpression( os );
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LazyExpression::LazyExpression( bool isNegated )
|
LazyExpression::LazyExpression( bool isNegated )
|
||||||
: m_isNegated( isNegated )
|
: m_isNegated( isNegated )
|
||||||
|
@@ -115,7 +115,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
|
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
|
||||||
do { \
|
do { \
|
||||||
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
|
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
|
||||||
catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
|
catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
|
||||||
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
||||||
} while( false )
|
} while( false )
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "catch_capture.hpp"
|
#include "catch_capture.hpp"
|
||||||
#include "catch_matchers.h"
|
#include "catch_matchers.h"
|
||||||
#include "catch_matchers_floating.h"
|
#include "catch_matchers_floating.h"
|
||||||
|
#include "catch_matchers_generic.hpp"
|
||||||
#include "catch_matchers_string.h"
|
#include "catch_matchers_string.h"
|
||||||
#include "catch_matchers_vector.h"
|
#include "catch_matchers_vector.h"
|
||||||
|
|
||||||
|
@@ -130,7 +130,7 @@ namespace Catch {
|
|||||||
| Opt( config.outputFilename, "filename" )
|
| Opt( config.outputFilename, "filename" )
|
||||||
["-o"]["--out"]
|
["-o"]["--out"]
|
||||||
( "output filename" )
|
( "output filename" )
|
||||||
| Opt( config.reporterNames, "name" )
|
| Opt( config.reporterName, "name" )
|
||||||
["-r"]["--reporter"]
|
["-r"]["--reporter"]
|
||||||
( "reporter to use (defaults to console)" )
|
( "reporter to use (defaults to console)" )
|
||||||
| Opt( config.name, "name" )
|
| Opt( config.name, "name" )
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
// Many features, at point of detection, define an _INTERNAL_ macro, so they
|
// Many features, at point of detection, define an _INTERNAL_ macro, so they
|
||||||
// can be combined, en-mass, with the _NO_ forms later.
|
// can be combined, en-mass, with the _NO_ forms later.
|
||||||
|
|
||||||
|
#include "catch_platform.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@@ -56,6 +57,12 @@
|
|||||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||||
_Pragma( "clang diagnostic pop" )
|
_Pragma( "clang diagnostic pop" )
|
||||||
|
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
|
||||||
|
_Pragma( "clang diagnostic push" ) \
|
||||||
|
_Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
|
||||||
|
# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
|
||||||
|
_Pragma( "clang diagnostic pop" )
|
||||||
|
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
|
|
||||||
@@ -76,6 +83,24 @@
|
|||||||
# define CATCH_CONFIG_COLOUR_NONE
|
# define CATCH_CONFIG_COLOUR_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Android somehow still does not support std::to_string
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Not all Windows environments support SEH properly
|
||||||
|
#if defined(__MINGW32__)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PS4
|
||||||
|
#if defined(__ORBIS__)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Cygwin
|
// Cygwin
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
@@ -126,7 +151,7 @@
|
|||||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
||||||
# define CATCH_CONFIG_COUNTER
|
# define CATCH_CONFIG_COUNTER
|
||||||
#endif
|
#endif
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
|
||||||
# define CATCH_CONFIG_WINDOWS_SEH
|
# define CATCH_CONFIG_WINDOWS_SEH
|
||||||
#endif
|
#endif
|
||||||
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
|
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
|
||||||
@@ -138,10 +163,21 @@
|
|||||||
# define CATCH_CONFIG_WCHAR
|
# define CATCH_CONFIG_WCHAR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
|
||||||
|
# define CATCH_CONFIG_CPP11_TO_STRING
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
#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
|
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
|
||||||
|
# define CATCH_CONFIG_NEW_CAPTURE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||||
@@ -151,6 +187,10 @@
|
|||||||
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
|
||||||
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
|
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
|
||||||
|
# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
|
||||||
|
@@ -37,8 +37,8 @@ namespace Catch {
|
|||||||
bool Config::listReporters() const { return m_data.listReporters; }
|
bool Config::listReporters() const { return m_data.listReporters; }
|
||||||
|
|
||||||
std::string Config::getProcessName() const { return m_data.processName; }
|
std::string Config::getProcessName() const { return m_data.processName; }
|
||||||
|
std::string const& Config::getReporterName() const { return m_data.reporterName; }
|
||||||
|
|
||||||
std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
|
|
||||||
std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
|
std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
|
||||||
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
|
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
|
||||||
|
|
||||||
|
@@ -54,8 +54,12 @@ namespace Catch {
|
|||||||
std::string outputFilename;
|
std::string outputFilename;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string processName;
|
std::string processName;
|
||||||
|
#ifndef CATCH_CONFIG_DEFAULT_REPORTER
|
||||||
|
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
|
||||||
|
#endif
|
||||||
|
std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
|
||||||
|
#undef CATCH_CONFIG_DEFAULT_REPORTER
|
||||||
|
|
||||||
std::vector<std::string> reporterNames;
|
|
||||||
std::vector<std::string> testsOrTags;
|
std::vector<std::string> testsOrTags;
|
||||||
std::vector<std::string> sectionsToRun;
|
std::vector<std::string> sectionsToRun;
|
||||||
};
|
};
|
||||||
@@ -76,8 +80,8 @@ namespace Catch {
|
|||||||
bool listReporters() const;
|
bool listReporters() const;
|
||||||
|
|
||||||
std::string getProcessName() const;
|
std::string getProcessName() const;
|
||||||
|
std::string const& getReporterName() const;
|
||||||
|
|
||||||
std::vector<std::string> const& getReporterNames() const;
|
|
||||||
std::vector<std::string> const& getTestsOrTags() const;
|
std::vector<std::string> const& getTestsOrTags() const;
|
||||||
std::vector<std::string> const& getSectionsToRun() const override;
|
std::vector<std::string> const& getSectionsToRun() const override;
|
||||||
|
|
||||||
|
@@ -94,6 +94,11 @@ 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.
|
||||||
|
constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
|
||||||
|
|
||||||
static SignalDefs signalDefs[] = {
|
static SignalDefs signalDefs[] = {
|
||||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||||
{ SIGILL, "SIGILL - Illegal instruction signal" },
|
{ SIGILL, "SIGILL - Illegal instruction signal" },
|
||||||
@@ -121,7 +126,7 @@ namespace Catch {
|
|||||||
isSet = true;
|
isSet = true;
|
||||||
stack_t sigStack;
|
stack_t sigStack;
|
||||||
sigStack.ss_sp = altStackMem;
|
sigStack.ss_sp = altStackMem;
|
||||||
sigStack.ss_size = SIGSTKSZ;
|
sigStack.ss_size = sigStackSize;
|
||||||
sigStack.ss_flags = 0;
|
sigStack.ss_flags = 0;
|
||||||
sigaltstack(&sigStack, &oldSigStack);
|
sigaltstack(&sigStack, &oldSigStack);
|
||||||
struct sigaction sa = { };
|
struct sigaction sa = { };
|
||||||
@@ -153,7 +158,7 @@ namespace Catch {
|
|||||||
bool FatalConditionHandler::isSet = false;
|
bool FatalConditionHandler::isSet = false;
|
||||||
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
||||||
stack_t FatalConditionHandler::oldSigStack = {};
|
stack_t FatalConditionHandler::oldSigStack = {};
|
||||||
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
char FatalConditionHandler::altStackMem[sigStackSize] = {};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "catch_interfaces_reporter.h"
|
#include "catch_interfaces_reporter.h"
|
||||||
#include "../reporters/catch_reporter_multi.h"
|
#include "../reporters/catch_reporter_listening.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@@ -111,25 +111,4 @@ namespace Catch {
|
|||||||
IReporterFactory::~IReporterFactory() = default;
|
IReporterFactory::~IReporterFactory() = default;
|
||||||
IReporterRegistry::~IReporterRegistry() = default;
|
IReporterRegistry::~IReporterRegistry() = default;
|
||||||
|
|
||||||
void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) {
|
|
||||||
|
|
||||||
if( !existingReporter ) {
|
|
||||||
existingReporter = std::move( additionalReporter );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MultipleReporters* multi = nullptr;
|
|
||||||
|
|
||||||
if( existingReporter->isMulti() ) {
|
|
||||||
multi = static_cast<MultipleReporters*>( existingReporter.get() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters );
|
|
||||||
newMulti->add( std::move( existingReporter ) );
|
|
||||||
multi = newMulti.get();
|
|
||||||
existingReporter = std::move( newMulti );
|
|
||||||
}
|
|
||||||
multi->add( std::move( additionalReporter ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -42,6 +42,7 @@ namespace Catch {
|
|||||||
|
|
||||||
struct ReporterPreferences {
|
struct ReporterPreferences {
|
||||||
bool shouldRedirectStdOut = false;
|
bool shouldRedirectStdOut = false;
|
||||||
|
bool shouldReportAllAssertions = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -226,8 +227,6 @@ namespace Catch {
|
|||||||
virtual Listeners const& getListeners() const = 0;
|
virtual Listeners const& getListeners() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter );
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "catch_matchers_floating.h"
|
#include "catch_matchers_floating.h"
|
||||||
|
#include "catch_to_string.hpp"
|
||||||
#include "catch_tostring.h"
|
#include "catch_tostring.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -88,7 +89,7 @@ namespace Floating {
|
|||||||
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
|
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
|
||||||
// But without the subtraction to allow for INFINITY in comparison
|
// But without the subtraction to allow for INFINITY in comparison
|
||||||
bool WithinAbsMatcher::match(double const& matchee) const {
|
bool WithinAbsMatcher::match(double const& matchee) const {
|
||||||
return (matchee + m_margin >= m_target) && (m_target + m_margin >= m_margin);
|
return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WithinAbsMatcher::describe() const {
|
std::string WithinAbsMatcher::describe() const {
|
||||||
@@ -115,7 +116,7 @@ namespace Floating {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string WithinUlpsMatcher::describe() const {
|
std::string WithinUlpsMatcher::describe() const {
|
||||||
return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
|
return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}// namespace Floating
|
}// namespace Floating
|
||||||
|
9
include/internal/catch_matchers_generic.cpp
Normal file
9
include/internal/catch_matchers_generic.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include "catch_matchers_generic.hpp"
|
||||||
|
|
||||||
|
std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
|
||||||
|
if (desc.empty()) {
|
||||||
|
return "matches undescribed predicate";
|
||||||
|
} else {
|
||||||
|
return "matches predicate: \"" + desc + '"';
|
||||||
|
}
|
||||||
|
}
|
58
include/internal/catch_matchers_generic.hpp
Normal file
58
include/internal/catch_matchers_generic.hpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin Hořeňovský on 03/04/2017.
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef TWOBLUECUBES_CATCH_MATCHERS_GENERIC_HPP_INCLUDED
|
||||||
|
#define TWOBLUECUBES_CATCH_MATCHERS_GENERIC_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include "catch_common.h"
|
||||||
|
#include "catch_matchers.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
namespace Matchers {
|
||||||
|
namespace Generic {
|
||||||
|
|
||||||
|
namespace Detail {
|
||||||
|
std::string finalizeDescription(const std::string& desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class PredicateMatcher : public MatcherBase<T> {
|
||||||
|
std::function<bool(T const&)> m_predicate;
|
||||||
|
std::string m_description;
|
||||||
|
public:
|
||||||
|
|
||||||
|
PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
|
||||||
|
:m_predicate(std::move(elem)),
|
||||||
|
m_description(Detail::finalizeDescription(descr))
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool match( T const& item ) const override {
|
||||||
|
return m_predicate(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string describe() const override {
|
||||||
|
return m_description;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Generic
|
||||||
|
|
||||||
|
// The following functions create the actual matcher objects.
|
||||||
|
// The user has to explicitly specify type to the function, because
|
||||||
|
// infering std::function<bool(T const&)> is hard (but possible) and
|
||||||
|
// requires a lot of TMP.
|
||||||
|
template<typename T>
|
||||||
|
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
|
||||||
|
return Generic::PredicateMatcher<T>(predicate, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Matchers
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
#endif // TWOBLUECUBES_CATCH_MATCHERS_GENERIC_HPP_INCLUDED
|
@@ -93,7 +93,7 @@ namespace Catch {
|
|||||||
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
||||||
const char* className = class_getName( cls );
|
const char* className = class_getName( cls );
|
||||||
|
|
||||||
getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
|
getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
|
||||||
noTestMethods++;
|
noTestMethods++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
139
include/internal/catch_output_redirect.cpp
Normal file
139
include/internal/catch_output_redirect.cpp
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin on 28/04/2018.
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "catch_output_redirect.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_NEW_CAPTURE)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <io.h> //_dup and _dup2
|
||||||
|
#define dup _dup
|
||||||
|
#define dup2 _dup2
|
||||||
|
#define fileno _fileno
|
||||||
|
#else
|
||||||
|
#include <unistd.h> // dup and dup2
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
|
||||||
|
: m_originalStream( originalStream ),
|
||||||
|
m_redirectionStream( redirectionStream ),
|
||||||
|
m_prevBuf( m_originalStream.rdbuf() )
|
||||||
|
{
|
||||||
|
m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
|
||||||
|
}
|
||||||
|
|
||||||
|
RedirectedStream::~RedirectedStream() {
|
||||||
|
m_originalStream.rdbuf( m_prevBuf );
|
||||||
|
}
|
||||||
|
|
||||||
|
RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
|
||||||
|
auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
|
||||||
|
|
||||||
|
RedirectedStdErr::RedirectedStdErr()
|
||||||
|
: m_cerr( Catch::cerr(), m_rss.get() ),
|
||||||
|
m_clog( Catch::clog(), m_rss.get() )
|
||||||
|
{}
|
||||||
|
auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_NEW_CAPTURE)
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
TempFile::TempFile() {
|
||||||
|
if (tmpnam_s(m_buffer)) {
|
||||||
|
throw std::runtime_error("Could not get a temp filename");
|
||||||
|
}
|
||||||
|
if (fopen_s(&m_file, m_buffer, "w")) {
|
||||||
|
char buffer[100];
|
||||||
|
if (strerror_s(buffer, errno)) {
|
||||||
|
throw std::runtime_error("Could not translate errno to string");
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TempFile::TempFile() {
|
||||||
|
m_file = std::tmpfile();
|
||||||
|
if (!m_file) {
|
||||||
|
throw std::runtime_error("Could not create a temp file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TempFile::~TempFile() {
|
||||||
|
// TBD: What to do about errors here?
|
||||||
|
std::fclose(m_file);
|
||||||
|
// We manually create the file on Windows only, on Linux
|
||||||
|
// it will be autodeleted
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
std::remove(m_buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE* TempFile::getFile() {
|
||||||
|
return m_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TempFile::getContents() {
|
||||||
|
std::stringstream sstr;
|
||||||
|
char buffer[100] = {};
|
||||||
|
std::rewind(m_file);
|
||||||
|
while (std::fgets(buffer, sizeof(buffer), m_file)) {
|
||||||
|
sstr << buffer;
|
||||||
|
}
|
||||||
|
return sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
|
||||||
|
m_originalStdout(dup(1)),
|
||||||
|
m_originalStderr(dup(2)),
|
||||||
|
m_stdoutDest(stdout_dest),
|
||||||
|
m_stderrDest(stderr_dest) {
|
||||||
|
dup2(fileno(m_stdoutFile.getFile()), 1);
|
||||||
|
dup2(fileno(m_stderrFile.getFile()), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputRedirect::~OutputRedirect() {
|
||||||
|
Catch::cout() << std::flush;
|
||||||
|
fflush(stdout);
|
||||||
|
// Since we support overriding these streams, we flush cerr
|
||||||
|
// even though std::cerr is unbuffered
|
||||||
|
Catch::cerr() << std::flush;
|
||||||
|
Catch::clog() << std::flush;
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
|
dup2(m_originalStdout, 1);
|
||||||
|
dup2(m_originalStderr, 2);
|
||||||
|
|
||||||
|
m_stdoutDest += m_stdoutFile.getContents();
|
||||||
|
m_stderrDest += m_stderrFile.getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CATCH_CONFIG_NEW_CAPTURE
|
||||||
|
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_NEW_CAPTURE)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#undef dup
|
||||||
|
#undef dup2
|
||||||
|
#undef fileno
|
||||||
|
#endif
|
||||||
|
#endif
|
101
include/internal/catch_output_redirect.h
Normal file
101
include/internal/catch_output_redirect.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin on 28/04/2018.
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
|
||||||
|
#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
|
||||||
|
|
||||||
|
#include "catch_platform.h"
|
||||||
|
#include "catch_stream.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
class RedirectedStream {
|
||||||
|
std::ostream& m_originalStream;
|
||||||
|
std::ostream& m_redirectionStream;
|
||||||
|
std::streambuf* m_prevBuf;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
|
||||||
|
~RedirectedStream();
|
||||||
|
};
|
||||||
|
|
||||||
|
class RedirectedStdOut {
|
||||||
|
ReusableStringStream m_rss;
|
||||||
|
RedirectedStream m_cout;
|
||||||
|
public:
|
||||||
|
RedirectedStdOut();
|
||||||
|
auto str() const -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// StdErr has two constituent streams in C++, std::cerr and std::clog
|
||||||
|
// This means that we need to redirect 2 streams into 1 to keep proper
|
||||||
|
// order of writes
|
||||||
|
class RedirectedStdErr {
|
||||||
|
ReusableStringStream m_rss;
|
||||||
|
RedirectedStream m_cerr;
|
||||||
|
RedirectedStream m_clog;
|
||||||
|
public:
|
||||||
|
RedirectedStdErr();
|
||||||
|
auto str() const -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_NEW_CAPTURE)
|
||||||
|
|
||||||
|
// Windows's implementation of std::tmpfile is terrible (it tries
|
||||||
|
// to create a file inside system folder, thus requiring elevated
|
||||||
|
// privileges for the binary), so we have to use tmpnam(_s) and
|
||||||
|
// create the file ourselves there.
|
||||||
|
class TempFile {
|
||||||
|
public:
|
||||||
|
TempFile(TempFile const&) = delete;
|
||||||
|
TempFile& operator=(TempFile const&) = delete;
|
||||||
|
TempFile(TempFile&&) = delete;
|
||||||
|
TempFile& operator=(TempFile&&) = delete;
|
||||||
|
|
||||||
|
TempFile();
|
||||||
|
~TempFile();
|
||||||
|
|
||||||
|
std::FILE* getFile();
|
||||||
|
std::string getContents();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::FILE* m_file = nullptr;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
char m_buffer[L_tmpnam] = { 0 };
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class OutputRedirect {
|
||||||
|
public:
|
||||||
|
OutputRedirect(OutputRedirect const&) = delete;
|
||||||
|
OutputRedirect& operator=(OutputRedirect const&) = delete;
|
||||||
|
OutputRedirect(OutputRedirect&&) = delete;
|
||||||
|
OutputRedirect& operator=(OutputRedirect&&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
|
||||||
|
~OutputRedirect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_originalStdout = -1;
|
||||||
|
int m_originalStderr = -1;
|
||||||
|
TempFile m_stdoutFile;
|
||||||
|
TempFile m_stderrFile;
|
||||||
|
std::string& m_stdoutDest;
|
||||||
|
std::string& m_stderrDest;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
|
@@ -20,7 +20,7 @@
|
|||||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||||
# define CATCH_PLATFORM_LINUX
|
# define CATCH_PLATFORM_LINUX
|
||||||
|
|
||||||
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
|
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
# define CATCH_PLATFORM_WINDOWS
|
# define CATCH_PLATFORM_WINDOWS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -9,23 +9,21 @@
|
|||||||
#include "catch_context.h"
|
#include "catch_context.h"
|
||||||
#include "catch_interfaces_config.h"
|
#include "catch_interfaces_config.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
void seedRng( IConfig const& config ) {
|
std::mt19937& rng() {
|
||||||
if( config.rngSeed() != 0 )
|
static std::mt19937 s_rng;
|
||||||
std::srand( config.rngSeed() );
|
return s_rng;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seedRng( IConfig const& config ) {
|
||||||
|
if( config.rngSeed() != 0 ) {
|
||||||
|
std::srand( config.rngSeed() );
|
||||||
|
rng().seed( config.rngSeed() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int rngSeed() {
|
unsigned int rngSeed() {
|
||||||
return getCurrentContext().getConfig()->rngSeed();
|
return getCurrentContext().getConfig()->rngSeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
|
|
||||||
return std::rand() % n;
|
|
||||||
}
|
|
||||||
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
|
|
||||||
return std::rand() % (max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -8,31 +8,16 @@
|
|||||||
#define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct IConfig;
|
struct IConfig;
|
||||||
|
|
||||||
|
std::mt19937& rng();
|
||||||
void seedRng( IConfig const& config );
|
void seedRng( IConfig const& config );
|
||||||
|
|
||||||
unsigned int rngSeed();
|
unsigned int rngSeed();
|
||||||
|
|
||||||
struct RandomNumberGenerator {
|
|
||||||
using result_type = unsigned int;
|
|
||||||
|
|
||||||
static constexpr result_type (min)() { return 0; }
|
|
||||||
static constexpr result_type (max)() { return 1000000; }
|
|
||||||
|
|
||||||
result_type operator()( result_type n ) const;
|
|
||||||
result_type operator()() const;
|
|
||||||
|
|
||||||
template<typename V>
|
|
||||||
static void shuffle( V& vector ) {
|
|
||||||
RandomNumberGenerator rng;
|
|
||||||
std::shuffle( vector.begin(), vector.end(), rng );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "catch_enforce.h"
|
#include "catch_enforce.h"
|
||||||
#include "catch_random_number_generator.h"
|
#include "catch_random_number_generator.h"
|
||||||
#include "catch_stream.h"
|
#include "catch_stream.h"
|
||||||
|
#include "catch_output_redirect.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -10,55 +11,13 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
class RedirectedStream {
|
|
||||||
std::ostream& m_originalStream;
|
|
||||||
std::ostream& m_redirectionStream;
|
|
||||||
std::streambuf* m_prevBuf;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
|
|
||||||
: m_originalStream( originalStream ),
|
|
||||||
m_redirectionStream( redirectionStream ),
|
|
||||||
m_prevBuf( m_originalStream.rdbuf() )
|
|
||||||
{
|
|
||||||
m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
|
|
||||||
}
|
|
||||||
~RedirectedStream() {
|
|
||||||
m_originalStream.rdbuf( m_prevBuf );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RedirectedStdOut {
|
|
||||||
ReusableStringStream m_rss;
|
|
||||||
RedirectedStream m_cout;
|
|
||||||
public:
|
|
||||||
RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
|
|
||||||
auto str() const -> std::string { return m_rss.str(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// StdErr has two constituent streams in C++, std::cerr and std::clog
|
|
||||||
// This means that we need to redirect 2 streams into 1 to keep proper
|
|
||||||
// order of writes
|
|
||||||
class RedirectedStdErr {
|
|
||||||
ReusableStringStream m_rss;
|
|
||||||
RedirectedStream m_cerr;
|
|
||||||
RedirectedStream m_clog;
|
|
||||||
public:
|
|
||||||
RedirectedStdErr()
|
|
||||||
: m_cerr( Catch::cerr(), m_rss.get() ),
|
|
||||||
m_clog( Catch::clog(), m_rss.get() )
|
|
||||||
{}
|
|
||||||
auto str() const -> std::string { return m_rss.str(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
|
RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
|
||||||
: m_runInfo(_config->name()),
|
: m_runInfo(_config->name()),
|
||||||
m_context(getCurrentMutableContext()),
|
m_context(getCurrentMutableContext()),
|
||||||
m_config(_config),
|
m_config(_config),
|
||||||
m_reporter(std::move(reporter)),
|
m_reporter(std::move(reporter)),
|
||||||
m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
|
m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
|
||||||
m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
|
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
|
||||||
{
|
{
|
||||||
m_context.setRunner(this);
|
m_context.setRunner(this);
|
||||||
m_context.setConfig(m_config);
|
m_context.setConfig(m_config);
|
||||||
@@ -249,7 +208,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Recreate section for test case (as we will lose the one that was in scope)
|
// Recreate section for test case (as we will lose the one that was in scope)
|
||||||
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
||||||
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
|
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
|
||||||
|
|
||||||
Counts assertions;
|
Counts assertions;
|
||||||
assertions.failed = 1;
|
assertions.failed = 1;
|
||||||
@@ -287,7 +246,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
|
void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
|
||||||
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
||||||
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
|
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
|
||||||
m_reporter->sectionStarting(testCaseSection);
|
m_reporter->sectionStarting(testCaseSection);
|
||||||
Counts prevAssertions = m_totals.assertions;
|
Counts prevAssertions = m_totals.assertions;
|
||||||
double duration = 0;
|
double duration = 0;
|
||||||
@@ -299,13 +258,19 @@ namespace Catch {
|
|||||||
Timer timer;
|
Timer timer;
|
||||||
try {
|
try {
|
||||||
if (m_reporter->getPreferences().shouldRedirectStdOut) {
|
if (m_reporter->getPreferences().shouldRedirectStdOut) {
|
||||||
|
#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
|
||||||
RedirectedStdOut redirectedStdOut;
|
RedirectedStdOut redirectedStdOut;
|
||||||
RedirectedStdErr redirectedStdErr;
|
RedirectedStdErr redirectedStdErr;
|
||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
invokeActiveTestCase();
|
invokeActiveTestCase();
|
||||||
redirectedCout += redirectedStdOut.str();
|
redirectedCout += redirectedStdOut.str();
|
||||||
redirectedCerr += redirectedStdErr.str();
|
redirectedCerr += redirectedStdErr.str();
|
||||||
|
#else
|
||||||
|
OutputRedirect r(redirectedCout, redirectedCerr);
|
||||||
|
timer.start();
|
||||||
|
invokeActiveTestCase();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
timer.start();
|
timer.start();
|
||||||
invokeActiveTestCase();
|
invokeActiveTestCase();
|
||||||
|
@@ -99,7 +99,7 @@ namespace Catch {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// !TBD We need to do this another way!
|
// !TBD We need to do this another way!
|
||||||
bool aborting() const override;
|
bool aborting() const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ namespace Catch {
|
|||||||
|
|
||||||
Section::~Section() {
|
Section::~Section() {
|
||||||
if( m_sectionIncluded ) {
|
if( m_sectionIncluded ) {
|
||||||
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
|
||||||
if( uncaught_exceptions() )
|
if( uncaught_exceptions() )
|
||||||
getResultCapture().sectionEndedEarly( endInfo );
|
getResultCapture().sectionEndedEarly( endInfo );
|
||||||
else
|
else
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
||||||
|
|
||||||
|
#include "catch_compiler_capabilities.h"
|
||||||
#include "catch_section_info.h"
|
#include "catch_section_info.h"
|
||||||
#include "catch_totals.h"
|
#include "catch_totals.h"
|
||||||
#include "catch_timer.h"
|
#include "catch_timer.h"
|
||||||
@@ -36,6 +37,13 @@ namespace Catch {
|
|||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
#define INTERNAL_CATCH_SECTION( ... ) \
|
||||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
|
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
|
||||||
|
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
||||||
|
CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
|
||||||
|
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
|
||||||
|
CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
||||||
|
@@ -11,15 +11,9 @@ namespace Catch {
|
|||||||
|
|
||||||
SectionInfo::SectionInfo
|
SectionInfo::SectionInfo
|
||||||
( SourceLineInfo const& _lineInfo,
|
( SourceLineInfo const& _lineInfo,
|
||||||
std::string const& _name,
|
std::string const& _name )
|
||||||
std::string const& _description )
|
|
||||||
: name( _name ),
|
: name( _name ),
|
||||||
description( _description ),
|
|
||||||
lineInfo( _lineInfo )
|
lineInfo( _lineInfo )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
|
|
||||||
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -16,19 +16,22 @@
|
|||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct SectionInfo {
|
struct SectionInfo {
|
||||||
|
SectionInfo
|
||||||
|
( SourceLineInfo const& _lineInfo,
|
||||||
|
std::string const& _name );
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
SectionInfo
|
SectionInfo
|
||||||
( SourceLineInfo const& _lineInfo,
|
( SourceLineInfo const& _lineInfo,
|
||||||
std::string const& _name,
|
std::string const& _name,
|
||||||
std::string const& _description = std::string() );
|
std::string const& ) : SectionInfo( _lineInfo, _name ) {}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description; // !Deprecated: this will always be empty
|
||||||
SourceLineInfo lineInfo;
|
SourceLineInfo lineInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SectionEndInfo {
|
struct SectionEndInfo {
|
||||||
SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
|
|
||||||
|
|
||||||
SectionInfo sectionInfo;
|
SectionInfo sectionInfo;
|
||||||
Counts prevAssertions;
|
Counts prevAssertions;
|
||||||
double durationInSeconds;
|
double durationInSeconds;
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "catch_text.h"
|
#include "catch_text.h"
|
||||||
#include "catch_stream.h"
|
#include "catch_stream.h"
|
||||||
#include "catch_windows_h_proxy.h"
|
#include "catch_windows_h_proxy.h"
|
||||||
|
#include "../reporters/catch_reporter_listening.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -36,33 +37,26 @@ namespace Catch {
|
|||||||
return reporter;
|
return reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_DEFAULT_REPORTER
|
|
||||||
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
|
IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
|
||||||
auto const& reporterNames = config->getReporterNames();
|
if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
|
||||||
if (reporterNames.empty())
|
return createReporter(config->getReporterName(), config);
|
||||||
return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config);
|
|
||||||
|
|
||||||
IStreamingReporterPtr reporter;
|
|
||||||
for (auto const& name : reporterNames)
|
|
||||||
addReporter(reporter, createReporter(name, config));
|
|
||||||
return reporter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CATCH_CONFIG_DEFAULT_REPORTER
|
auto multi = std::unique_ptr<ListeningReporter>(new ListeningReporter);
|
||||||
|
|
||||||
void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) {
|
|
||||||
auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
|
auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
|
||||||
for (auto const& listener : listeners)
|
for (auto const& listener : listeners) {
|
||||||
addReporter(reporters, listener->create(Catch::ReporterConfig(config)));
|
multi->addListener(listener->create(Catch::ReporterConfig(config)));
|
||||||
|
}
|
||||||
|
multi->addReporter(createReporter(config->getReporterName(), config));
|
||||||
|
return std::move(multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Catch::Totals runTests(std::shared_ptr<Config> const& config) {
|
Catch::Totals runTests(std::shared_ptr<Config> const& config) {
|
||||||
IStreamingReporterPtr reporter = makeReporter(config);
|
// FixMe: Add listeners in order first, then add reporters.
|
||||||
addListeners(reporter, config);
|
|
||||||
|
auto reporter = makeReporter(config);
|
||||||
|
|
||||||
RunContext context(config, std::move(reporter));
|
RunContext context(config, std::move(reporter));
|
||||||
|
|
||||||
|
@@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
char toLowerCh(char c) {
|
||||||
|
return static_cast<char>( std::tolower( c ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool startsWith( std::string const& s, std::string const& prefix ) {
|
bool startsWith( std::string const& s, std::string const& prefix ) {
|
||||||
return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
|
return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
|
||||||
}
|
}
|
||||||
@@ -29,9 +35,6 @@ namespace Catch {
|
|||||||
bool contains( std::string const& s, std::string const& infix ) {
|
bool contains( std::string const& s, std::string const& infix ) {
|
||||||
return s.find( infix ) != std::string::npos;
|
return s.find( infix ) != std::string::npos;
|
||||||
}
|
}
|
||||||
char toLowerCh(char c) {
|
|
||||||
return static_cast<char>( std::tolower( c ) );
|
|
||||||
}
|
|
||||||
void toLowerInPlace( std::string& s ) {
|
void toLowerInPlace( std::string& s ) {
|
||||||
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
|
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
|
||||||
}
|
}
|
||||||
|
@@ -10,15 +10,17 @@
|
|||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable: 161 1682)
|
# pragma warning(disable: 161 1682)
|
||||||
# else // __ICC
|
# else // __ICC
|
||||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wpadded"
|
# pragma clang diagnostic ignored "-Wpadded"
|
||||||
# pragma clang diagnostic ignored "-Wswitch-enum"
|
# pragma clang diagnostic ignored "-Wswitch-enum"
|
||||||
# pragma clang diagnostic ignored "-Wcovered-switch-default"
|
# pragma clang diagnostic ignored "-Wcovered-switch-default"
|
||||||
# endif
|
# endif
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
# pragma GCC diagnostic ignored "-Wunused-variable"
|
// GCC likes to warn on REQUIREs, and we cannot suppress them
|
||||||
|
// locally because g++'s support for _Pragma is lacking in older,
|
||||||
|
// still supported, versions
|
||||||
# pragma GCC diagnostic ignored "-Wparentheses"
|
# pragma GCC diagnostic ignored "-Wparentheses"
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
# pragma GCC diagnostic ignored "-Wpadded"
|
# pragma GCC diagnostic ignored "-Wpadded"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace {
|
||||||
TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
||||||
if( startsWith( tag, '.' ) ||
|
if( startsWith( tag, '.' ) ||
|
||||||
tag == "!hide" )
|
tag == "!hide" )
|
||||||
@@ -37,7 +38,7 @@ namespace Catch {
|
|||||||
return TestCaseInfo::None;
|
return TestCaseInfo::None;
|
||||||
}
|
}
|
||||||
bool isReservedTag( std::string const& tag ) {
|
bool isReservedTag( std::string const& tag ) {
|
||||||
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
|
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
|
||||||
}
|
}
|
||||||
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||||
CATCH_ENFORCE( !isReservedTag(tag),
|
CATCH_ENFORCE( !isReservedTag(tag),
|
||||||
@@ -45,6 +46,7 @@ namespace Catch {
|
|||||||
<< "Tag names starting with non alpha-numeric characters are reserved\n"
|
<< "Tag names starting with non alpha-numeric characters are reserved\n"
|
||||||
<< _lineInfo );
|
<< _lineInfo );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TestCase makeTestCase( ITestInvoker* _testCase,
|
TestCase makeTestCase( ITestInvoker* _testCase,
|
||||||
std::string const& _className,
|
std::string const& _className,
|
||||||
|
@@ -28,7 +28,7 @@ namespace Catch {
|
|||||||
break;
|
break;
|
||||||
case RunTests::InRandomOrder:
|
case RunTests::InRandomOrder:
|
||||||
seedRng( config );
|
seedRng( config );
|
||||||
RandomNumberGenerator::shuffle( sorted );
|
std::shuffle( sorted.begin(), sorted.end(), rng() );
|
||||||
break;
|
break;
|
||||||
case RunTests::InDeclarationOrder:
|
case RunTests::InDeclarationOrder:
|
||||||
// already in declaration order
|
// already in declaration order
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#include "catch_enforce.h"
|
#include "catch_enforce.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -73,8 +73,8 @@ namespace TestCaseTracking {
|
|||||||
TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
|
TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
|
||||||
bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
|
bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
|
||||||
return
|
return
|
||||||
tracker->nameAndLocation().name == m_nameAndLocation.name &&
|
tracker->nameAndLocation().location == m_nameAndLocation.location &&
|
||||||
tracker->nameAndLocation().location == m_nameAndLocation.location;
|
tracker->nameAndLocation().name == m_nameAndLocation.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||||
|
@@ -47,12 +47,17 @@ struct AutoReg : NonCopyable {
|
|||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
|
||||||
|
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
|
||||||
|
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
|
||||||
|
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
|
||||||
|
|
||||||
#if defined(CATCH_CONFIG_DISABLE)
|
#if defined(CATCH_CONFIG_DISABLE)
|
||||||
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
|
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
|
||||||
static void TestName()
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
|
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
|
||||||
namespace{ \
|
namespace{ \
|
||||||
struct TestName : ClassName { \
|
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
|
||||||
void test(); \
|
void test(); \
|
||||||
}; \
|
}; \
|
||||||
} \
|
} \
|
||||||
@@ -64,7 +69,7 @@ struct AutoReg : NonCopyable {
|
|||||||
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||||
static void TestName(); \
|
static void TestName(); \
|
||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
|
||||||
static void TestName()
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||||
@@ -80,7 +85,7 @@ struct AutoReg : NonCopyable {
|
|||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||||
namespace{ \
|
namespace{ \
|
||||||
struct TestName : ClassName{ \
|
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
|
||||||
void test(); \
|
void test(); \
|
||||||
}; \
|
}; \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||||
@@ -93,7 +98,7 @@ struct AutoReg : NonCopyable {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
|
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,33 +10,45 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
static const uint64_t nanosecondsInSecond = 1000000000;
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
|
auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
|
||||||
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
|
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
auto estimateClockResolution() -> uint64_t {
|
auto estimateClockResolution() -> uint64_t {
|
||||||
uint64_t sum = 0;
|
uint64_t sum = 0;
|
||||||
static const uint64_t iterations = 1000000;
|
static const uint64_t iterations = 1000000;
|
||||||
|
|
||||||
|
auto startTime = getCurrentNanosecondsSinceEpoch();
|
||||||
|
|
||||||
for( std::size_t i = 0; i < iterations; ++i ) {
|
for( std::size_t i = 0; i < iterations; ++i ) {
|
||||||
|
|
||||||
uint64_t ticks;
|
uint64_t ticks;
|
||||||
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
|
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
|
||||||
do {
|
do {
|
||||||
ticks = getCurrentNanosecondsSinceEpoch();
|
ticks = getCurrentNanosecondsSinceEpoch();
|
||||||
}
|
} while( ticks == baseTicks );
|
||||||
while( ticks == baseTicks );
|
|
||||||
|
|
||||||
auto delta = ticks - baseTicks;
|
auto delta = ticks - baseTicks;
|
||||||
sum += delta;
|
sum += delta;
|
||||||
|
|
||||||
|
// If we have been calibrating for over 3 seconds -- the clock
|
||||||
|
// is terrible and we should move on.
|
||||||
|
// TBD: How to signal that the measured resolution is probably wrong?
|
||||||
|
if (ticks > startTime + 3 * nanosecondsInSecond) {
|
||||||
|
return sum / i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
|
// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
|
||||||
// - and potentially do more iterations if there's a high variance.
|
// - and potentially do more iterations if there's a high variance.
|
||||||
return sum/iterations;
|
return sum/iterations;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto getEstimatedClockResolution() -> uint64_t {
|
auto getEstimatedClockResolution() -> uint64_t {
|
||||||
static auto s_resolution = estimateClockResolution();
|
static auto s_resolution = estimateClockResolution();
|
||||||
return s_resolution;
|
return s_resolution;
|
||||||
|
28
include/internal/catch_to_string.hpp
Normal file
28
include/internal/catch_to_string.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin on 9/5/2018.
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED
|
||||||
|
#define TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "catch_compiler_capabilities.h"
|
||||||
|
#include "catch_stream.h"
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
template <typename T>
|
||||||
|
std::string to_string(T const& t) {
|
||||||
|
#if defined(CATCH_CONFIG_CPP11_TO_STRING)
|
||||||
|
return std::to_string(t);
|
||||||
|
#else
|
||||||
|
ReusableStringStream rss;
|
||||||
|
rss << t;
|
||||||
|
return rss.str();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED
|
@@ -236,7 +236,6 @@ std::string ratio_string<std::nano>::symbol() { return "n"; }
|
|||||||
std::string ratio_string<std::micro>::symbol() { return "u"; }
|
std::string ratio_string<std::micro>::symbol() { return "u"; }
|
||||||
std::string ratio_string<std::milli>::symbol() { return "m"; }
|
std::string ratio_string<std::milli>::symbol() { return "m"; }
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
@@ -62,19 +62,38 @@ namespace Catch {
|
|||||||
std::string convertUnknownEnumToString( E e );
|
std::string convertUnknownEnumToString( E e );
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
typename std::enable_if<
|
||||||
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
|
!std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
|
||||||
(void)value;
|
std::string>::type convertUnstreamable( T const& ) {
|
||||||
return Detail::unprintableString;
|
return Detail::unprintableString;
|
||||||
#else
|
|
||||||
return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
typename std::enable_if<
|
||||||
|
!std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
|
||||||
|
std::string>::type convertUnstreamable(T const& ex) {
|
||||||
|
return ex.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_enum<T>::value
|
||||||
|
, std::string>::type convertUnstreamable( T const& value ) {
|
||||||
return convertUnknownEnumToString( value );
|
return convertUnknownEnumToString( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_MANAGED)
|
||||||
|
//! Convert a CLR string to a utf8 std::string
|
||||||
|
template<typename T>
|
||||||
|
std::string clrReferenceToString( T^ ref ) {
|
||||||
|
if (ref == nullptr)
|
||||||
|
return std::string("null");
|
||||||
|
auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
|
||||||
|
cli::pin_ptr<System::Byte> p = &bytes[0];
|
||||||
|
return std::string(reinterpret_cast<char const *>(p), bytes->Length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
|
|
||||||
@@ -86,7 +105,9 @@ namespace Catch {
|
|||||||
typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
||||||
convert(const Fake& value) {
|
convert(const Fake& value) {
|
||||||
ReusableStringStream rss;
|
ReusableStringStream rss;
|
||||||
rss << value;
|
// NB: call using the function-like syntax to avoid ambiguity with
|
||||||
|
// user-defined templated operator<< under clang.
|
||||||
|
rss.operator<<(value);
|
||||||
return rss.str();
|
return rss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +115,11 @@ namespace Catch {
|
|||||||
static
|
static
|
||||||
typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
||||||
convert( const Fake& value ) {
|
convert( const Fake& value ) {
|
||||||
|
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
|
||||||
return Detail::convertUnstreamable(value);
|
return Detail::convertUnstreamable(value);
|
||||||
|
#else
|
||||||
|
return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,6 +137,13 @@ namespace Catch {
|
|||||||
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
|
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_MANAGED)
|
||||||
|
template <typename T>
|
||||||
|
std::string stringify( T^ e ) {
|
||||||
|
return ::Catch::StringMaker<T^>::convert(e);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
// Some predefined specializations
|
// Some predefined specializations
|
||||||
@@ -135,6 +167,7 @@ namespace Catch {
|
|||||||
struct StringMaker<char *> {
|
struct StringMaker<char *> {
|
||||||
static std::string convert(char * str);
|
static std::string convert(char * str);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_WCHAR
|
#ifdef CATCH_CONFIG_WCHAR
|
||||||
template<>
|
template<>
|
||||||
struct StringMaker<wchar_t const *> {
|
struct StringMaker<wchar_t const *> {
|
||||||
@@ -146,22 +179,24 @@ namespace Catch {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
|
||||||
|
// while keeping string semantics?
|
||||||
template<int SZ>
|
template<int SZ>
|
||||||
struct StringMaker<char[SZ]> {
|
struct StringMaker<char[SZ]> {
|
||||||
static std::string convert(const char* str) {
|
static std::string convert(char const* str) {
|
||||||
return ::Catch::Detail::stringify(std::string{ str });
|
return ::Catch::Detail::stringify(std::string{ str });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<int SZ>
|
template<int SZ>
|
||||||
struct StringMaker<signed char[SZ]> {
|
struct StringMaker<signed char[SZ]> {
|
||||||
static std::string convert(const char* str) {
|
static std::string convert(signed char const* str) {
|
||||||
return ::Catch::Detail::stringify(std::string{ str });
|
return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<int SZ>
|
template<int SZ>
|
||||||
struct StringMaker<unsigned char[SZ]> {
|
struct StringMaker<unsigned char[SZ]> {
|
||||||
static std::string convert(const char* str) {
|
static std::string convert(unsigned char const* str) {
|
||||||
return ::Catch::Detail::stringify(std::string{ str });
|
return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,6 +280,15 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(_MANAGED)
|
||||||
|
template <typename T>
|
||||||
|
struct StringMaker<T^> {
|
||||||
|
static std::string convert( T^ ref ) {
|
||||||
|
return ::Catch::Detail::clrReferenceToString(ref);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
std::string rangeToString(InputIterator first, InputIterator last) {
|
std::string rangeToString(InputIterator first, InputIterator last) {
|
||||||
@@ -374,6 +418,13 @@ namespace Catch {
|
|||||||
!std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
|
!std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(_MANAGED) // Managed types are never ranges
|
||||||
|
template <typename T>
|
||||||
|
struct is_range<T^> {
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename Range>
|
template<typename Range>
|
||||||
std::string rangeToString( Range const& range ) {
|
std::string rangeToString( Range const& range ) {
|
||||||
return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
|
return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
|
||||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 2, 1, "", 0 );
|
static Version version( 2, 3, 0, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,29 +7,68 @@
|
|||||||
|
|
||||||
#include "catch_xmlwriter.h"
|
#include "catch_xmlwriter.h"
|
||||||
|
|
||||||
|
#include "catch_enforce.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
|
using uchar = unsigned char;
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
size_t trailingBytes(unsigned char c) {
|
||||||
|
if ((c & 0xE0) == 0xC0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ((c & 0xF0) == 0xE0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if ((c & 0xF8) == 0xF0) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t headerValue(unsigned char c) {
|
||||||
|
if ((c & 0xE0) == 0xC0) {
|
||||||
|
return c & 0x1F;
|
||||||
|
}
|
||||||
|
if ((c & 0xF0) == 0xE0) {
|
||||||
|
return c & 0x0F;
|
||||||
|
}
|
||||||
|
if ((c & 0xF8) == 0xF0) {
|
||||||
|
return c & 0x07;
|
||||||
|
}
|
||||||
|
CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
|
||||||
|
}
|
||||||
|
|
||||||
|
void hexEscapeChar(std::ostream& os, unsigned char c) {
|
||||||
|
os << "\\x"
|
||||||
|
<< std::uppercase << std::hex << std::setfill('0') << std::setw(2)
|
||||||
|
<< static_cast<int>(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
|
XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
|
||||||
: m_str( str ),
|
: m_str( str ),
|
||||||
m_forWhat( forWhat )
|
m_forWhat( forWhat )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void XmlEncode::encodeTo( std::ostream& os ) const {
|
void XmlEncode::encodeTo( std::ostream& os ) const {
|
||||||
|
|
||||||
// Apostrophe escaping not necessary if we always use " to write attributes
|
// Apostrophe escaping not necessary if we always use " to write attributes
|
||||||
// (see: http://www.w3.org/TR/xml/#syntax)
|
// (see: http://www.w3.org/TR/xml/#syntax)
|
||||||
|
|
||||||
for( std::size_t i = 0; i < m_str.size(); ++ i ) {
|
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
|
||||||
char c = m_str[i];
|
uchar c = m_str[idx];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '<': os << "<"; break;
|
case '<': os << "<"; break;
|
||||||
case '&': os << "&"; break;
|
case '&': os << "&"; break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
// See: http://www.w3.org/TR/xml/#syntax
|
// See: http://www.w3.org/TR/xml/#syntax
|
||||||
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
|
if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
|
||||||
os << ">";
|
os << ">";
|
||||||
else
|
else
|
||||||
os << c;
|
os << c;
|
||||||
@@ -43,15 +82,70 @@ namespace Catch {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Escape control chars - based on contribution by @espenalb in PR #465 and
|
// Check for control characters and invalid utf-8
|
||||||
// by @mrpi PR #588
|
|
||||||
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
|
// Escape control characters in standard ascii
|
||||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||||
os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
|
if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
|
||||||
<< static_cast<int>( c );
|
hexEscapeChar(os, c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Plain ASCII: Write it to stream
|
||||||
|
if (c < 0x7F) {
|
||||||
os << c;
|
os << c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UTF-8 territory
|
||||||
|
// Check if the encoding is valid and if it is not, hex escape bytes.
|
||||||
|
// Important: We do not check the exact decoded values for validity, only the encoding format
|
||||||
|
// First check that this bytes is a valid lead byte:
|
||||||
|
// This means that it is not encoded as 1111 1XXX
|
||||||
|
// Or as 10XX XXXX
|
||||||
|
if (c < 0xC0 ||
|
||||||
|
c >= 0xF8) {
|
||||||
|
hexEscapeChar(os, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto encBytes = trailingBytes(c);
|
||||||
|
// Are there enough bytes left to avoid accessing out-of-bounds memory?
|
||||||
|
if (idx + encBytes - 1 >= m_str.size()) {
|
||||||
|
hexEscapeChar(os, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// The header is valid, check data
|
||||||
|
// The next encBytes bytes must together be a valid utf-8
|
||||||
|
// This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
|
||||||
|
bool valid = true;
|
||||||
|
uint32_t value = headerValue(c);
|
||||||
|
for (std::size_t n = 1; n < encBytes; ++n) {
|
||||||
|
uchar nc = m_str[idx + n];
|
||||||
|
valid &= ((nc & 0xC0) == 0x80);
|
||||||
|
value = (value << 6) | (nc & 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Wrong bit pattern of following bytes
|
||||||
|
(!valid) ||
|
||||||
|
// Overlong encodings
|
||||||
|
(value < 0x80) ||
|
||||||
|
(0x80 <= value && value < 0x800 && encBytes > 2) ||
|
||||||
|
(0x800 < value && value < 0x10000 && encBytes > 3) ||
|
||||||
|
// Encoded value out of range
|
||||||
|
(value >= 0x110000)
|
||||||
|
) {
|
||||||
|
hexEscapeChar(os, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got here, this is in fact a valid(ish) utf-8 sequence
|
||||||
|
for (std::size_t n = 0; n < encBytes; ++n) {
|
||||||
|
os << m_str[idx + n];
|
||||||
|
}
|
||||||
|
idx += encBytes - 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
@@ -245,9 +245,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReporterPreferences CompactReporter::getPreferences() const {
|
ReporterPreferences CompactReporter::getPreferences() const {
|
||||||
ReporterPreferences prefs;
|
return m_reporterPrefs;
|
||||||
prefs.shouldRedirectStdOut = false;
|
|
||||||
return prefs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompactReporter::noMatchingTestCases( std::string const& spec ) {
|
void CompactReporter::noMatchingTestCases( std::string const& spec ) {
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include "../internal/catch_tostring.h"
|
#include "../internal/catch_tostring.h"
|
||||||
#include "../internal/catch_reporter_registrars.hpp"
|
#include "../internal/catch_reporter_registrars.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -62,6 +62,7 @@ namespace Catch {
|
|||||||
xml( _config.stream() )
|
xml( _config.stream() )
|
||||||
{
|
{
|
||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
|
m_reporterPrefs.shouldReportAllAssertions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JunitReporter::~JunitReporter() {}
|
JunitReporter::~JunitReporter() {}
|
||||||
|
142
include/reporters/catch_reporter_listening.cpp
Normal file
142
include/reporters/catch_reporter_listening.cpp
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Created by Phil on 5/08/2015.
|
||||||
|
* Copyright 2015 Two Blue Cubes Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "catch_reporter_listening.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
ListeningReporter::ListeningReporter() {
|
||||||
|
// We will assume that listeners will always want all assertions
|
||||||
|
m_preferences.shouldReportAllAssertions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
|
||||||
|
m_listeners.push_back( std::move( listener ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
|
||||||
|
assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
|
||||||
|
m_reporter = std::move( reporter );
|
||||||
|
m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReporterPreferences ListeningReporter::getPreferences() const {
|
||||||
|
return m_preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
|
||||||
|
return std::set<Verbosity>{ };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->noMatchingTestCases( spec );
|
||||||
|
}
|
||||||
|
m_reporter->noMatchingTestCases( spec );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->benchmarkStarting( benchmarkInfo );
|
||||||
|
}
|
||||||
|
m_reporter->benchmarkStarting( benchmarkInfo );
|
||||||
|
}
|
||||||
|
void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->benchmarkEnded( benchmarkStats );
|
||||||
|
}
|
||||||
|
m_reporter->benchmarkEnded( benchmarkStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testRunStarting( testRunInfo );
|
||||||
|
}
|
||||||
|
m_reporter->testRunStarting( testRunInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testGroupStarting( groupInfo );
|
||||||
|
}
|
||||||
|
m_reporter->testGroupStarting( groupInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testCaseStarting( testInfo );
|
||||||
|
}
|
||||||
|
m_reporter->testCaseStarting( testInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->sectionStarting( sectionInfo );
|
||||||
|
}
|
||||||
|
m_reporter->sectionStarting( sectionInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->assertionStarting( assertionInfo );
|
||||||
|
}
|
||||||
|
m_reporter->assertionStarting( assertionInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
// The return value indicates if the messages buffer should be cleared:
|
||||||
|
bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
|
||||||
|
for( auto const& listener : m_listeners ) {
|
||||||
|
static_cast<void>( listener->assertionEnded( assertionStats ) );
|
||||||
|
}
|
||||||
|
return m_reporter->assertionEnded( assertionStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->sectionEnded( sectionStats );
|
||||||
|
}
|
||||||
|
m_reporter->sectionEnded( sectionStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testCaseEnded( testCaseStats );
|
||||||
|
}
|
||||||
|
m_reporter->testCaseEnded( testCaseStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testGroupEnded( testGroupStats );
|
||||||
|
}
|
||||||
|
m_reporter->testGroupEnded( testGroupStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->testRunEnded( testRunStats );
|
||||||
|
}
|
||||||
|
m_reporter->testRunEnded( testRunStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
|
||||||
|
for ( auto const& listener : m_listeners ) {
|
||||||
|
listener->skipTest( testInfo );
|
||||||
|
}
|
||||||
|
m_reporter->skipTest( testInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListeningReporter::isMulti() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Catch
|
@@ -11,12 +11,17 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
class MultipleReporters : public IStreamingReporter {
|
class ListeningReporter : public IStreamingReporter {
|
||||||
using Reporters = std::vector<IStreamingReporterPtr>;
|
using Reporters = std::vector<IStreamingReporterPtr>;
|
||||||
Reporters m_reporters;
|
Reporters m_listeners;
|
||||||
|
IStreamingReporterPtr m_reporter = nullptr;
|
||||||
|
ReporterPreferences m_preferences;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void add( IStreamingReporterPtr&& reporter );
|
ListeningReporter();
|
||||||
|
|
||||||
|
void addListener( IStreamingReporterPtr&& listener );
|
||||||
|
void addReporter( IStreamingReporterPtr&& reporter );
|
||||||
|
|
||||||
public: // IStreamingReporter
|
public: // IStreamingReporter
|
||||||
|
|
@@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Created by Phil on 5/08/2015.
|
|
||||||
* Copyright 2015 Two Blue Cubes Ltd. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "catch_reporter_multi.h"
|
|
||||||
|
|
||||||
namespace Catch {
|
|
||||||
|
|
||||||
void MultipleReporters::add( IStreamingReporterPtr&& reporter ) {
|
|
||||||
m_reporters.push_back( std::move( reporter ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ReporterPreferences MultipleReporters::getPreferences() const {
|
|
||||||
return m_reporters[0]->getPreferences();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<Verbosity> MultipleReporters::getSupportedVerbosities() {
|
|
||||||
return std::set<Verbosity>{ };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MultipleReporters::noMatchingTestCases( std::string const& spec ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->noMatchingTestCases( spec );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->benchmarkStarting( benchmarkInfo );
|
|
||||||
}
|
|
||||||
void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->benchmarkEnded( benchmarkStats );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testRunStarting( testRunInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::testGroupStarting( GroupInfo const& groupInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testGroupStarting( groupInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MultipleReporters::testCaseStarting( TestCaseInfo const& testInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testCaseStarting( testInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::sectionStarting( SectionInfo const& sectionInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->sectionStarting( sectionInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::assertionStarting( AssertionInfo const& assertionInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->assertionStarting( assertionInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
// The return value indicates if the messages buffer should be cleared:
|
|
||||||
bool MultipleReporters::assertionEnded( AssertionStats const& assertionStats ) {
|
|
||||||
bool clearBuffer = false;
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
clearBuffer |= reporter->assertionEnded( assertionStats );
|
|
||||||
return clearBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::sectionEnded( SectionStats const& sectionStats ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->sectionEnded( sectionStats );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::testCaseEnded( TestCaseStats const& testCaseStats ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testCaseEnded( testCaseStats );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::testGroupEnded( TestGroupStats const& testGroupStats ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testGroupEnded( testGroupStats );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleReporters::testRunEnded( TestRunStats const& testRunStats ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->testRunEnded( testRunStats );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MultipleReporters::skipTest( TestCaseInfo const& testInfo ) {
|
|
||||||
for( auto const& reporter : m_reporters )
|
|
||||||
reporter->skipTest( testInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MultipleReporters::isMulti() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Catch
|
|
@@ -30,9 +30,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReporterPreferences getPreferences() const override {
|
ReporterPreferences getPreferences() const override {
|
||||||
ReporterPreferences prefs;
|
return m_reporterPrefs;
|
||||||
prefs.shouldRedirectStdOut = false;
|
|
||||||
return prefs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void noMatchingTestCases( std::string const& spec ) override {
|
void noMatchingTestCases( std::string const& spec ) override {
|
||||||
|
@@ -24,6 +24,7 @@ namespace Catch {
|
|||||||
m_xml(_config.stream())
|
m_xml(_config.stream())
|
||||||
{
|
{
|
||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
|
m_reporterPrefs.shouldReportAllAssertions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlReporter::~XmlReporter() = default;
|
XmlReporter::~XmlReporter() = default;
|
||||||
@@ -80,8 +81,7 @@ namespace Catch {
|
|||||||
StreamingReporterBase::sectionStarting( sectionInfo );
|
StreamingReporterBase::sectionStarting( sectionInfo );
|
||||||
if( m_sectionDepth++ > 0 ) {
|
if( m_sectionDepth++ > 0 ) {
|
||||||
m_xml.startElement( "Section" )
|
m_xml.startElement( "Section" )
|
||||||
.writeAttribute( "name", trim( sectionInfo.name ) )
|
.writeAttribute( "name", trim( sectionInfo.name ) );
|
||||||
.writeAttribute( "description", sectionInfo.description );
|
|
||||||
writeSourceInfo( sectionInfo.lineInfo );
|
writeSourceInfo( sectionInfo.lineInfo );
|
||||||
m_xml.ensureTagClosed();
|
m_xml.ensureTagClosed();
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
/*
|
|
||||||
* Created by Martin on 16/01/2017.
|
|
||||||
*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CATCH_CONFIG_MAIN
|
|
||||||
#include "catch.hpp"
|
|
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Created by Martin on 16/01/2017.
|
|
||||||
*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
TEST_CASE("Successful tests -- REQUIRE", "[Success]") {
|
|
||||||
const std::size_t sz = 1 * 1024 * 1024;
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::size_t> vec; vec.reserve(sz);
|
|
||||||
for (std::size_t i = 0; i < sz; ++i){
|
|
||||||
vec.push_back(i);
|
|
||||||
REQUIRE(vec.back() == i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
TEST_CASE("Successful tests -- CHECK", "[Success]") {
|
|
||||||
const std::size_t sz = 1 * 1024 * 1024;
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::size_t> vec; vec.reserve(sz);
|
|
||||||
for (std::size_t i = 0; i < sz; ++i){
|
|
||||||
vec.push_back(i);
|
|
||||||
CHECK(vec.back() == i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") {
|
|
||||||
const std::size_t sz = 1024 * 1024;
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::size_t> vec; vec.reserve(sz);
|
|
||||||
for (std::size_t i = 0; i < sz; ++i){
|
|
||||||
vec.push_back(i);
|
|
||||||
CHECK(vec.size() == i);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
This is very much a work in progress.
|
|
||||||
The past results are standardized to a developer's machine,
|
|
||||||
the benchmarking script is basic and there are only 3 benchmarks,
|
|
||||||
but this should get better in time. For now, at least there is something to go by.
|
|
@@ -1,3 +0,0 @@
|
|||||||
Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s)
|
|
||||||
Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s)
|
|
||||||
Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s)
|
|
@@ -1,3 +0,0 @@
|
|||||||
Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s)
|
|
||||||
Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s)
|
|
||||||
Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s)
|
|
@@ -1,3 +0,0 @@
|
|||||||
Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s)
|
|
||||||
Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s)
|
|
||||||
Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s)
|
|
@@ -1,3 +0,0 @@
|
|||||||
Successful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s)
|
|
||||||
Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s)
|
|
||||||
Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s)
|
|
@@ -1,3 +0,0 @@
|
|||||||
Successful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s)
|
|
||||||
Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s)
|
|
||||||
Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s)
|
|
329
projects/CMakeLists.txt
Normal file
329
projects/CMakeLists.txt
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
include(MiscFunctions)
|
||||||
|
|
||||||
|
# define the sources of the self test
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(TEST_SOURCES
|
||||||
|
${SELF_TEST_DIR}/TestMain.cpp
|
||||||
|
${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
|
||||||
|
${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
|
||||||
|
)
|
||||||
|
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
|
||||||
|
|
||||||
|
# A set of impl files that just #include a single header
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(SURROGATE_SOURCES
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
||||||
|
)
|
||||||
|
CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
|
||||||
|
|
||||||
|
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(TOP_LEVEL_HEADERS
|
||||||
|
${HEADER_DIR}/catch.hpp
|
||||||
|
${HEADER_DIR}/catch_with_main.hpp
|
||||||
|
)
|
||||||
|
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
|
||||||
|
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(EXTERNAL_HEADERS
|
||||||
|
${HEADER_DIR}/external/clara.hpp
|
||||||
|
)
|
||||||
|
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
|
||||||
|
|
||||||
|
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(INTERNAL_HEADERS
|
||||||
|
${HEADER_DIR}/internal/catch_approx.h
|
||||||
|
${HEADER_DIR}/internal/catch_assertionhandler.h
|
||||||
|
${HEADER_DIR}/internal/catch_assertioninfo.h
|
||||||
|
${HEADER_DIR}/internal/catch_assertionresult.h
|
||||||
|
${HEADER_DIR}/internal/catch_capture.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_capture_matchers.h
|
||||||
|
${HEADER_DIR}/internal/catch_clara.h
|
||||||
|
${HEADER_DIR}/internal/catch_commandline.h
|
||||||
|
${HEADER_DIR}/internal/catch_common.h
|
||||||
|
${HEADER_DIR}/internal/catch_compiler_capabilities.h
|
||||||
|
${HEADER_DIR}/internal/catch_config.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_console_colour.h
|
||||||
|
${HEADER_DIR}/internal/catch_context.h
|
||||||
|
${HEADER_DIR}/internal/catch_debug_console.h
|
||||||
|
${HEADER_DIR}/internal/catch_debugger.h
|
||||||
|
${HEADER_DIR}/internal/catch_decomposer.h
|
||||||
|
${HEADER_DIR}/internal/catch_default_main.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_enforce.h
|
||||||
|
${HEADER_DIR}/internal/catch_errno_guard.h
|
||||||
|
${HEADER_DIR}/internal/catch_exception_translator_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_external_interfaces.h
|
||||||
|
${HEADER_DIR}/internal/catch_fatal_condition.h
|
||||||
|
${HEADER_DIR}/internal/catch_impl.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_capture.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_config.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_exception.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_reporter.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_runner.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_testcase.h
|
||||||
|
${HEADER_DIR}/internal/catch_leak_detector.h
|
||||||
|
${HEADER_DIR}/internal/catch_list.h
|
||||||
|
${HEADER_DIR}/internal/catch_matchers.h
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_floating.h
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_generic.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_string.h
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_vector.h
|
||||||
|
${HEADER_DIR}/internal/catch_message.h
|
||||||
|
${HEADER_DIR}/internal/catch_objc.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_objc_arc.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_option.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_output_redirect.h
|
||||||
|
${HEADER_DIR}/internal/catch_platform.h
|
||||||
|
${HEADER_DIR}/internal/catch_random_number_generator.h
|
||||||
|
${HEADER_DIR}/internal/catch_reenable_warnings.h
|
||||||
|
${HEADER_DIR}/internal/catch_reporter_registrars.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_reporter_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_result_type.h
|
||||||
|
${HEADER_DIR}/internal/catch_run_context.h
|
||||||
|
${HEADER_DIR}/internal/catch_benchmark.h
|
||||||
|
${HEADER_DIR}/internal/catch_section.h
|
||||||
|
${HEADER_DIR}/internal/catch_section_info.h
|
||||||
|
${HEADER_DIR}/internal/catch_session.h
|
||||||
|
${HEADER_DIR}/internal/catch_startup_exception_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_stream.h
|
||||||
|
${HEADER_DIR}/internal/catch_stringref.h
|
||||||
|
${HEADER_DIR}/internal/catch_string_manip.h
|
||||||
|
${HEADER_DIR}/internal/catch_suppress_warnings.h
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias.h
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_info.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_registry_impl.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_tracker.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_registry.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_spec.h
|
||||||
|
${HEADER_DIR}/internal/catch_test_spec_parser.h
|
||||||
|
${HEADER_DIR}/internal/catch_text.h
|
||||||
|
${HEADER_DIR}/internal/catch_timer.h
|
||||||
|
${HEADER_DIR}/internal/catch_to_string.hpp
|
||||||
|
${HEADER_DIR}/internal/catch_tostring.h
|
||||||
|
${HEADER_DIR}/internal/catch_totals.h
|
||||||
|
${HEADER_DIR}/internal/catch_uncaught_exceptions.h
|
||||||
|
${HEADER_DIR}/internal/catch_user_interfaces.h
|
||||||
|
${HEADER_DIR}/internal/catch_version.h
|
||||||
|
${HEADER_DIR}/internal/catch_wildcard_pattern.h
|
||||||
|
${HEADER_DIR}/internal/catch_windows_h_proxy.h
|
||||||
|
${HEADER_DIR}/internal/catch_xmlwriter.h
|
||||||
|
)
|
||||||
|
set(IMPL_SOURCES
|
||||||
|
${HEADER_DIR}/internal/catch_approx.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_assertionhandler.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_assertionresult.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_benchmark.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_capture_matchers.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_commandline.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_common.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_config.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_console_colour.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_context.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_debug_console.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_debugger.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_decomposer.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_errno_guard.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_fatal_condition.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_capture.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_config.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_exception.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_runner.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_list.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_leak_detector.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_matchers.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_floating.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_generic.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_matchers_string.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_message.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_output_redirect.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_registry_hub.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_random_number_generator.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_reporter_registry.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_result_type.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_run_context.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_section.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_section_info.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_session.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_stream.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_stringref.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_string_manip.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_info.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_case_tracker.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_registry.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_spec.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_test_spec_parser.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_timer.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_tostring.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_totals.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_version.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_xmlwriter.cpp
|
||||||
|
)
|
||||||
|
set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
|
||||||
|
CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
|
||||||
|
|
||||||
|
# Please keep these ordered alphabetically
|
||||||
|
set(REPORTER_HEADERS
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_automake.hpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_compact.h
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_console.h
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_junit.h
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_listening.h
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_xml.h
|
||||||
|
)
|
||||||
|
set(REPORTER_SOURCES
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_bases.cpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_compact.cpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_console.cpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_junit.cpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_listening.cpp
|
||||||
|
${HEADER_DIR}/reporters/catch_reporter_xml.cpp
|
||||||
|
)
|
||||||
|
set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
|
||||||
|
CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
|
||||||
|
|
||||||
|
# Specify the headers, too, so CLion recognises them as project files
|
||||||
|
set(HEADERS
|
||||||
|
${TOP_LEVEL_HEADERS}
|
||||||
|
${EXTERNAL_HEADERS}
|
||||||
|
${INTERNAL_HEADERS}
|
||||||
|
${REPORTER_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Provide some groupings for IDEs
|
||||||
|
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
||||||
|
SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
||||||
|
target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
|
||||||
|
|
||||||
|
if(USE_CPP14)
|
||||||
|
message(STATUS "Enabling C++14")
|
||||||
|
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
|
||||||
|
else()
|
||||||
|
message(STATUS "Enabling C++11")
|
||||||
|
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||||
|
set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
if (CATCH_ENABLE_COVERAGE)
|
||||||
|
set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
|
||||||
|
find_package(codecov)
|
||||||
|
add_coverage(SelfTest)
|
||||||
|
list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
|
||||||
|
coverage_evaluate()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add per compiler options
|
||||||
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||||
|
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
|
||||||
|
if (CATCH_ENABLE_WERROR)
|
||||||
|
target_compile_options( SelfTest PRIVATE -Werror)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
# Clang specific options go here
|
||||||
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
|
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
||||||
|
endif()
|
||||||
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||||
|
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
|
||||||
|
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
|
||||||
|
if (CATCH_ENABLE_WERROR)
|
||||||
|
target_compile_options( SelfTest PRIVATE /WX)
|
||||||
|
endif()
|
||||||
|
# Force MSVC to consider everything as encoded in utf-8
|
||||||
|
target_compile_options( SelfTest PRIVATE /utf-8 )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# configure unit tests via CTest
|
||||||
|
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
|
||||||
|
|
||||||
|
add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
||||||
|
set_tests_properties(ListTests PROPERTIES
|
||||||
|
PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
|
||||||
|
FAIL_REGULAR_EXPRESSION "Hidden Test"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
|
||||||
|
set_tests_properties(ListTags PROPERTIES
|
||||||
|
PASS_REGULAR_EXPRESSION "[0-9]+ tags"
|
||||||
|
FAIL_REGULAR_EXPRESSION "[.]")
|
||||||
|
|
||||||
|
add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
|
||||||
|
set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
|
||||||
|
|
||||||
|
add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
|
||||||
|
set_tests_properties(ListTestNamesOnly PROPERTIES
|
||||||
|
PASS_REGULAR_EXPRESSION "Regex string matcher"
|
||||||
|
FAIL_REGULAR_EXPRESSION "Hidden Test")
|
||||||
|
|
||||||
|
add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
|
||||||
|
set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
|
||||||
|
|
||||||
|
add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
|
||||||
|
set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
|
||||||
|
|
||||||
|
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
|
||||||
|
add_test(NAME ApprovalTests COMMAND python ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
||||||
|
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
||||||
|
|
||||||
|
if (CATCH_USE_VALGRIND)
|
||||||
|
add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
|
||||||
|
add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
||||||
|
set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
||||||
|
add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
|
||||||
|
set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
||||||
|
endif()
|
@@ -10,6 +10,9 @@ Compilation.tests.cpp:<line number>: passed: t1 > t2 for: {?} > {?}
|
|||||||
Compilation.tests.cpp:<line number>: passed: t1 <= t2 for: {?} <= {?}
|
Compilation.tests.cpp:<line number>: passed: t1 <= t2 for: {?} <= {?}
|
||||||
Compilation.tests.cpp:<line number>: passed: t1 >= t2 for: {?} >= {?}
|
Compilation.tests.cpp:<line number>: passed: t1 >= t2 for: {?} >= {?}
|
||||||
Misc.tests.cpp:<line number>: passed:
|
Misc.tests.cpp:<line number>: passed:
|
||||||
|
Compilation.tests.cpp:<line number>: passed: std::memcmp(uarr, "123", sizeof(uarr)) == 0 for: 0 == 0 with 2 messages: 'uarr := "123"' and 'sarr := "456"'
|
||||||
|
Compilation.tests.cpp:<line number>: passed: std::memcmp(sarr, "456", sizeof(sarr)) == 0 for: 0 == 0 with 2 messages: 'uarr := "123"' and 'sarr := "456"'
|
||||||
|
Compilation.tests.cpp:<line number>: passed:
|
||||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
||||||
@@ -57,6 +60,12 @@ Class.tests.cpp:<line number>: failed: s == "world" for: "hello" == "world"
|
|||||||
Class.tests.cpp:<line number>: passed: s == "hello" for: "hello" == "hello"
|
Class.tests.cpp:<line number>: passed: s == "hello" for: "hello" == "hello"
|
||||||
Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
|
Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
|
||||||
Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
|
Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
|
||||||
|
Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: -d == -1.23_a for: -1.23 == Approx( -1.23 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d == 1.2_a .epsilon(.1) for: 1.23 == Approx( 1.2 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d != 1.2_a .epsilon(.001) for: 1.23 != Approx( 1.2 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d == 1_a .epsilon(.3) for: 1.23 == Approx( 1.0 )
|
||||||
Misc.tests.cpp:<line number>: passed: with 1 message: 'that's not flying - that's failing in style'
|
Misc.tests.cpp:<line number>: passed: with 1 message: 'that's not flying - that's failing in style'
|
||||||
Misc.tests.cpp:<line number>: failed: explicitly with 1 message: 'to infinity and beyond'
|
Misc.tests.cpp:<line number>: failed: explicitly with 1 message: 'to infinity and beyond'
|
||||||
Tricky.tests.cpp:<line number>: failed: &o1 == &o2 for: 0x<hex digits> == 0x<hex digits>
|
Tricky.tests.cpp:<line number>: failed: &o1 == &o2 for: 0x<hex digits> == 0x<hex digits>
|
||||||
@@ -97,6 +106,10 @@ Approx.tests.cpp:<line number>: passed: 0 == Approx( dZero) for: 0 == Approx( 0.
|
|||||||
Approx.tests.cpp:<line number>: passed: 0 == Approx( dSmall ).margin( 0.001 ) for: 0 == Approx( 0.00001 )
|
Approx.tests.cpp:<line number>: passed: 0 == Approx( dSmall ).margin( 0.001 ) for: 0 == Approx( 0.00001 )
|
||||||
Approx.tests.cpp:<line number>: passed: 1.234f == Approx( dMedium ) for: 1.234f == Approx( 1.234 )
|
Approx.tests.cpp:<line number>: passed: 1.234f == Approx( dMedium ) for: 1.234f == Approx( 1.234 )
|
||||||
Approx.tests.cpp:<line number>: passed: dMedium == Approx( 1.234f ) for: 1.234 == Approx( 1.2339999676 )
|
Approx.tests.cpp:<line number>: passed: dMedium == Approx( 1.234f ) for: 1.234 == Approx( 1.2339999676 )
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 1, Predicate<int>(alwaysTrue, "always true") for: 1 matches predicate: "always true"
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 1, !Predicate<int>(alwaysFalse, "always false") for: 1 not matches predicate: "always false"
|
||||||
|
Matchers.tests.cpp:<line number>: passed: "Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal") for: "Hello olleH" matches predicate: "First and last character should be equal"
|
||||||
|
Matchers.tests.cpp:<line number>: passed: "This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } ) for: "This wouldn't pass" not matches undescribed predicate
|
||||||
Tricky.tests.cpp:<line number>: passed: true
|
Tricky.tests.cpp:<line number>: passed: true
|
||||||
Tricky.tests.cpp:<line number>: passed: true
|
Tricky.tests.cpp:<line number>: passed: true
|
||||||
Tricky.tests.cpp:<line number>: passed: true
|
Tricky.tests.cpp:<line number>: passed: true
|
||||||
@@ -204,14 +217,21 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this
|
|||||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" (case insensitive)
|
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" (case insensitive)
|
||||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("this string contains 'ABC' as a substring") for: "this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring"
|
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("this string contains 'ABC' as a substring") for: "this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring"
|
||||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "something else" (case insensitive)
|
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "something else" (case insensitive)
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" for: "This exception has overriden what() method"
|
||||||
|
==
|
||||||
|
"This exception has overriden what() method"
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" for: "OperatorException" == "OperatorException"
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException" for: "StringMakerException"
|
||||||
|
==
|
||||||
|
"StringMakerException"
|
||||||
Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1}
|
Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1}
|
||||||
Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1}
|
Matchers.tests.cpp:<line number>: failed: expected exception, got none; expression was: doesNotThrow(), SpecialException, ExceptionMatcher{1}
|
||||||
Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
|
Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
|
||||||
Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
|
Matchers.tests.cpp:<line number>: failed: unexpected exception with message: 'Unknown exception'; expression was: throwsAsInt(1), SpecialException, ExceptionMatcher{1}
|
||||||
Matchers.tests.cpp:<line number>: failed: throws(3), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1
|
Matchers.tests.cpp:<line number>: failed: throws(3), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
|
||||||
Matchers.tests.cpp:<line number>: failed: throws(4), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1
|
Matchers.tests.cpp:<line number>: failed: throws(4), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
|
||||||
Matchers.tests.cpp:<line number>: passed: throws(1), SpecialException, ExceptionMatcher{1} for: {?} special exception has value of 1
|
Matchers.tests.cpp:<line number>: passed: throws(1), SpecialException, ExceptionMatcher{1} for: SpecialException::what special exception has value of 1
|
||||||
Matchers.tests.cpp:<line number>: passed: throws(2), SpecialException, ExceptionMatcher{2} for: {?} special exception has value of 2
|
Matchers.tests.cpp:<line number>: passed: throws(2), SpecialException, ExceptionMatcher{2} for: SpecialException::what special exception has value of 2
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive)
|
Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive)
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected"
|
Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected"
|
||||||
@@ -235,6 +255,10 @@ Matchers.tests.cpp:<line number>: passed: 0., WithinAbs(1., 1) for: 0.0 is withi
|
|||||||
Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
|
Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
|
||||||
Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
|
Matchers.tests.cpp:<line number>: passed: 0., !WithinAbs(1., 0.99) for: 0.0 not is within 0.99 of 1.0
|
||||||
Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
|
Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 11., !WithinAbs(10., 0.5) for: 11.0 not is within 0.5 of 10.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 10., !WithinAbs(11., 0.5) for: 10.0 not is within 0.5 of 11.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: -10., WithinAbs(-10., 0.5) for: -10.0 is within 0.5 of -10.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: -10., WithinAbs(-9.6, 0.5) for: -10.0 is within 0.5 of -9.6
|
||||||
Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0
|
Matchers.tests.cpp:<line number>: passed: 1., WithinULP(1., 0) for: 1.0 is within 0 ULPs of 1.0
|
||||||
Matchers.tests.cpp:<line number>: passed: nextafter(1., 2.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
|
Matchers.tests.cpp:<line number>: passed: nextafter(1., 2.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
|
||||||
Matchers.tests.cpp:<line number>: passed: nextafter(1., 0.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
|
Matchers.tests.cpp:<line number>: passed: nextafter(1., 0.), WithinULP(1., 1) for: 1.0 is within 1 ULPs of 1.0
|
||||||
@@ -255,6 +279,10 @@ Matchers.tests.cpp:<line number>: passed: 0.f, !WithinAbs(1.f, 0.99f) for: 0.0f
|
|||||||
Matchers.tests.cpp:<line number>: passed: 0.f, !WithinAbs(1.f, 0.99f) for: 0.0f not is within 0.9900000095 of 1.0
|
Matchers.tests.cpp:<line number>: passed: 0.f, !WithinAbs(1.f, 0.99f) for: 0.0f not is within 0.9900000095 of 1.0
|
||||||
Matchers.tests.cpp:<line number>: passed: 0.f, WithinAbs(-0.f, 0) for: 0.0f is within 0.0 of -0.0
|
Matchers.tests.cpp:<line number>: passed: 0.f, WithinAbs(-0.f, 0) for: 0.0f is within 0.0 of -0.0
|
||||||
Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
|
Matchers.tests.cpp:<line number>: passed: NAN, !WithinAbs(NAN, 0) for: nanf not is within 0.0 of nan
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 11.f, !WithinAbs(10.f, 0.5f) for: 11.0f not is within 0.5 of 10.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: 10.f, !WithinAbs(11.f, 0.5f) for: 10.0f not is within 0.5 of 11.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: -10.f, WithinAbs(-10.f, 0.5f) for: -10.0f is within 0.5 of -10.0
|
||||||
|
Matchers.tests.cpp:<line number>: passed: -10.f, WithinAbs(-9.6f, 0.5f) for: -10.0f is within 0.5 of -9.6000003815
|
||||||
Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.0f
|
Matchers.tests.cpp:<line number>: passed: 1.f, WithinULP(1.f, 0) for: 1.0f is within 0 ULPs of 1.0f
|
||||||
Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 2.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
|
Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 2.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
|
||||||
Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 0.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
|
Matchers.tests.cpp:<line number>: passed: nextafter(1.f, 0.f), WithinULP(1.f, 1) for: 1.0f is within 1 ULPs of 1.0f
|
||||||
@@ -498,7 +526,6 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( tcA ) == false for: false
|
|||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcB ) == false for: false == false
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcB ) == false for: false == false
|
||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcC ) == false for: false == false
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcC ) == false for: false == false
|
||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcD ) == true for: true == true
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( tcD ) == true for: true == true
|
||||||
Tricky.tests.cpp:<line number>: passed: (std::pair<int, int>( 1, 2 )) == aNicePair for: {?} == {?}
|
|
||||||
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
||||||
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
||||||
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
||||||
@@ -514,7 +541,7 @@ CmdLine.tests.cpp:<line number>: passed: config.processName == "test" for: "test
|
|||||||
CmdLine.tests.cpp:<line number>: passed: config.shouldDebugBreak == false for: false == false
|
CmdLine.tests.cpp:<line number>: passed: config.shouldDebugBreak == false for: false == false
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.abortAfter == -1 for: -1 == -1
|
CmdLine.tests.cpp:<line number>: passed: config.abortAfter == -1 for: -1 == -1
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.noThrow == false for: false == false
|
CmdLine.tests.cpp:<line number>: passed: config.noThrow == false for: false == false
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames.empty() for: true
|
CmdLine.tests.cpp:<line number>: passed: config.reporterName == "console" for: "console" == "console"
|
||||||
CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false
|
CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false
|
||||||
CmdLine.tests.cpp:<line number>: passed: result for: {?}
|
CmdLine.tests.cpp:<line number>: passed: result for: {?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true
|
CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true
|
||||||
@@ -529,15 +556,12 @@ CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true
|
|||||||
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(fakeTestCase("test1")) == false for: false == false
|
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(fakeTestCase("test1")) == false for: false == false
|
||||||
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(fakeTestCase("alwaysIncluded")) for: true
|
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(fakeTestCase("alwaysIncluded")) for: true
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-r", "console"}) for: {?}
|
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-r", "console"}) for: {?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames[0] == "console" for: "console" == "console"
|
CmdLine.tests.cpp:<line number>: passed: config.reporterName == "console" for: "console" == "console"
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-r", "xml"}) for: {?}
|
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-r", "xml"}) for: {?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames[0] == "xml" for: "xml" == "xml"
|
CmdLine.tests.cpp:<line number>: passed: config.reporterName == "xml" for: "xml" == "xml"
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-r", "xml", "-r", "junit"}) for: {?}
|
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames.size() == 2 for: 2 == 2
|
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames[0] == "xml" for: "xml" == "xml"
|
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames[1] == "junit" for: "junit" == "junit"
|
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--reporter", "junit"}) for: {?}
|
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--reporter", "junit"}) for: {?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.reporterNames[0] == "junit" for: "junit" == "junit"
|
CmdLine.tests.cpp:<line number>: passed: config.reporterName == "junit" for: "junit" == "junit"
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: !(cli.parse({ "test", "-r", "xml", "-r", "junit" })) for: !{?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-b"}) for: {?}
|
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-b"}) for: {?}
|
||||||
CmdLine.tests.cpp:<line number>: passed: config.shouldDebugBreak == true for: true == true
|
CmdLine.tests.cpp:<line number>: passed: config.shouldDebugBreak == true for: true == true
|
||||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--break"}) for: {?}
|
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--break"}) for: {?}
|
||||||
@@ -595,6 +619,8 @@ A string sent to stderr via clog
|
|||||||
Approx.tests.cpp:<line number>: passed: d == Approx( 1.23 ) for: 1.23 == Approx( 1.23 )
|
Approx.tests.cpp:<line number>: passed: d == Approx( 1.23 ) for: 1.23 == Approx( 1.23 )
|
||||||
Approx.tests.cpp:<line number>: passed: d != Approx( 1.22 ) for: 1.23 != Approx( 1.22 )
|
Approx.tests.cpp:<line number>: passed: d != Approx( 1.22 ) for: 1.23 != Approx( 1.22 )
|
||||||
Approx.tests.cpp:<line number>: passed: d != Approx( 1.24 ) for: 1.23 != Approx( 1.24 )
|
Approx.tests.cpp:<line number>: passed: d != Approx( 1.24 ) for: 1.23 != Approx( 1.24 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
|
||||||
|
Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
|
||||||
Approx.tests.cpp:<line number>: passed: Approx( d ) == 1.23 for: Approx( 1.23 ) == 1.23
|
Approx.tests.cpp:<line number>: passed: Approx( d ) == 1.23 for: Approx( 1.23 ) == 1.23
|
||||||
Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.22 for: Approx( 1.23 ) != 1.22
|
Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.22 for: Approx( 1.23 ) != 1.22
|
||||||
Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.24 for: Approx( 1.23 ) != 1.24
|
Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.24 for: Approx( 1.23 ) != 1.24
|
||||||
@@ -897,6 +923,48 @@ Xml.tests.cpp:<line number>: passed: encode( stringWithQuotes, Catch::XmlEncode:
|
|||||||
"don't "quote" me on that"
|
"don't "quote" me on that"
|
||||||
Xml.tests.cpp:<line number>: passed: encode( "[/x01]" ) == "[//x01]" for: "[/x01]" == "[/x01]"
|
Xml.tests.cpp:<line number>: passed: encode( "[/x01]" ) == "[//x01]" for: "[/x01]" == "[/x01]"
|
||||||
Xml.tests.cpp:<line number>: passed: encode( "[/x7F]" ) == "[//x7F]" for: "[/x7F]" == "[/x7F]"
|
Xml.tests.cpp:<line number>: passed: encode( "[/x7F]" ) == "[//x7F]" for: "[/x7F]" == "[/x7F]"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode(u8"Here be 👾") == u8"Here be 👾" for: "Here be 👾" == "Here be 👾"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode(u8"šš") == u8"šš" for: "šš" == "šš"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xDF/xBF") == "/xDF/xBF" for: "߿" == "߿"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE0/xA0/x80") == "/xE0/xA0/x80" for: "ࠀ" == "ࠀ"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xED/x9F/xBF") == "/xED/x9F/xBF" for: "" == ""
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xEE/x80/x80") == "/xEE/x80/x80" for: "" == ""
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xEF/xBF/xBF") == "/xEF/xBF/xBF" for: "" == ""
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0/x90/x80/x80") == "/xF0/x90/x80/x80" for: "𐀀" == "𐀀"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF4/x8F/xBF/xBF") == "/xF4/x8F/xBF/xBF" for: "" == ""
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("Here /xFF be 👾") == u8"Here //xFF be 👾" for: "Here /xFF be 👾" == "Here /xFF be 👾"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xFF") == "//xFF" for: "/xFF" == "/xFF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xC5/xC5/xA0") == u8"//xC5Š" for: "/xC5Š" == "/xC5Š"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF4/x90/x80/x80") == u8"//xF4//x90//x80//x80" for: "/xF4/x90/x80/x80" == "/xF4/x90/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xC0/x80") == u8"//xC0//x80" for: "/xC0/x80" == "/xC0/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80/x80/x80") == u8"//xF0//x80//x80//x80" for: "/xF0/x80/x80/x80" == "/xF0/x80/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xC1/xBF") == u8"//xC1//xBF" for: "/xC1/xBF" == "/xC1/xBF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE0/x9F/xBF") == u8"//xE0//x9F//xBF" for: "/xE0/x9F/xBF" == "/xE0/x9F/xBF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0/x8F/xBF/xBF") == u8"//xF0//x8F//xBF//xBF" for: "/xF0/x8F/xBF/xBF" == "/xF0/x8F/xBF/xBF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xED/xA0/x80") == "/xED/xA0/x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xED/xAF/xBF") == "/xED/xAF/xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xED/xB0/x80") == "/xED/xB0/x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xED/xBF/xBF") == "/xED/xBF/xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/x80") == u8"//x80" for: "/x80" == "/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/x81") == u8"//x81" for: "/x81" == "/x81"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xBC") == u8"//xBC" for: "/xBC" == "/xBC"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xBF") == u8"//xBF" for: "/xBF" == "/xBF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF5/x80/x80/x80") == u8"//xF5//x80//x80//x80" for: "/xF5/x80/x80/x80" == "/xF5/x80/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF6/x80/x80/x80") == u8"//xF6//x80//x80//x80" for: "/xF6/x80/x80/x80" == "/xF6/x80/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF7/x80/x80/x80") == u8"//xF7//x80//x80//x80" for: "/xF7/x80/x80/x80" == "/xF7/x80/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xDE") == u8"//xDE" for: "/xDE" == "/xDE"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xDF") == u8"//xDF" for: "/xDF" == "/xDF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE0") == u8"//xE0" for: "/xE0" == "/xE0"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xEF") == u8"//xEF" for: "/xEF" == "/xEF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0") == u8"//xF0" for: "/xF0" == "/xF0"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF4") == u8"//xF4" for: "/xF4" == "/xF4"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE0/x80") == u8"//xE0//x80" for: "/xE0/x80" == "/xE0/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE0/xBF") == u8"//xE0//xBF" for: "/xE0/xBF" == "/xE0/xBF"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xE1/x80") == u8"//xE1//x80" for: "/xE1/x80" == "/xE1/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80") == u8"//xF0//x80" for: "/xF0/x80" == "/xF0/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF4/x80") == u8"//xF4//x80" for: "/xF4/x80" == "/xF4/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80/x80") == u8"//xF0//x80//x80" for: "/xF0/x80/x80" == "/xF0/x80/x80"
|
||||||
|
Xml.tests.cpp:<line number>: passed: encode("/xF4/x80/x80") == u8"//xF4//x80//x80" for: "/xF4/x80/x80" == "/xF4/x80/x80"
|
||||||
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( empty ) == "{ }" for: "{ }" == "{ }"
|
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( empty ) == "{ }" for: "{ }" == "{ }"
|
||||||
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( oneValue ) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
|
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( oneValue ) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
|
||||||
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"
|
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"
|
||||||
@@ -927,6 +995,15 @@ Misc.tests.cpp:<line number>: passed: l == std::numeric_limits<long long>::max()
|
|||||||
==
|
==
|
||||||
9223372036854775807 (0x<hex digits>)
|
9223372036854775807 (0x<hex digits>)
|
||||||
Misc.tests.cpp:<line number>: failed: b > a for: 0 > 1
|
Misc.tests.cpp:<line number>: failed: b > a for: 0 > 1
|
||||||
|
Misc.tests.cpp:<line number>: failed: b > a for: 1 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 2 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 3 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 4 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 5 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 6 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 7 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 8 > 1
|
||||||
|
Misc.tests.cpp:<line number>: passed: b > a for: 9 > 1
|
||||||
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[0] (1) is even'
|
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[0] (1) is even'
|
||||||
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[1] (1) is even'
|
Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[1] (1) is even'
|
||||||
Misc.tests.cpp:<line number>: passed: ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if fib[2] (2) is even'
|
Misc.tests.cpp:<line number>: passed: ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if fib[2] (2) is even'
|
||||||
@@ -1004,6 +1081,9 @@ ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(item)
|
|||||||
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( item ) == "operator<<( has_operator )" for: "operator<<( has_operator )"
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( item ) == "operator<<( has_operator )" for: "operator<<( has_operator )"
|
||||||
==
|
==
|
||||||
"operator<<( has_operator )"
|
"operator<<( has_operator )"
|
||||||
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( item ) == "operator<<( has_template_operator )" for: "operator<<( has_template_operator )"
|
||||||
|
==
|
||||||
|
"operator<<( has_template_operator )"
|
||||||
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }" for: "{ StringMaker<has_maker> }"
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }" for: "{ StringMaker<has_maker> }"
|
||||||
==
|
==
|
||||||
"{ StringMaker<has_maker> }"
|
"{ StringMaker<has_maker> }"
|
||||||
@@ -1080,5 +1160,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
|
|||||||
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
||||||
Misc.tests.cpp:<line number>: passed:
|
Misc.tests.cpp:<line number>: passed:
|
||||||
Misc.tests.cpp:<line number>: passed:
|
Misc.tests.cpp:<line number>: passed:
|
||||||
Failed 62 test cases, failed 121 assertions.
|
Failed 62 test cases, failed 122 assertions.
|
||||||
|
|
||||||
|
@@ -335,12 +335,12 @@ Matchers.tests.cpp:<line number>
|
|||||||
Matchers.tests.cpp:<line number>: FAILED:
|
Matchers.tests.cpp:<line number>: FAILED:
|
||||||
CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} )
|
CHECK_THROWS_MATCHES( throws(3), SpecialException, ExceptionMatcher{1} )
|
||||||
with expansion:
|
with expansion:
|
||||||
{?} special exception has value of 1
|
SpecialException::what special exception has value of 1
|
||||||
|
|
||||||
Matchers.tests.cpp:<line number>: FAILED:
|
Matchers.tests.cpp:<line number>: FAILED:
|
||||||
REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} )
|
REQUIRE_THROWS_MATCHES( throws(4), SpecialException, ExceptionMatcher{1} )
|
||||||
with expansion:
|
with expansion:
|
||||||
{?} special exception has value of 1
|
SpecialException::what special exception has value of 1
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Expected exceptions that don't throw or unexpected exceptions fail the test
|
Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||||
@@ -968,7 +968,7 @@ explicitly with message:
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
looped SECTION tests
|
looped SECTION tests
|
||||||
s1
|
b is currently: 0
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Misc.tests.cpp:<line number>
|
Misc.tests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -978,6 +978,18 @@ Misc.tests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0 > 1
|
0 > 1
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
looped SECTION tests
|
||||||
|
b is currently: 1
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Misc.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Misc.tests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( b > a )
|
||||||
|
with expansion:
|
||||||
|
1 > 1
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
looped tests
|
looped tests
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -1028,8 +1040,8 @@ with message:
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
more nested SECTION tests
|
more nested SECTION tests
|
||||||
s1
|
doesn't equal
|
||||||
s2
|
equal
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Misc.tests.cpp:<line number>
|
Misc.tests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -1084,6 +1096,6 @@ due to unexpected exception with message:
|
|||||||
Why would you throw a std::string?
|
Why would you throw a std::string?
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 202 | 149 passed | 49 failed | 4 failed as expected
|
test cases: 208 | 155 passed | 49 failed | 4 failed as expected
|
||||||
assertions: 1007 | 879 passed | 107 failed | 21 failed as expected
|
assertions: 1081 | 952 passed | 108 failed | 21 failed as expected
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user