forked from catchorg/Catch2
Compare commits
215 Commits
Author | SHA1 | Date | |
---|---|---|---|
017a63da62 | |||
b90d0b7267 | |||
efba988ccc | |||
004228efb2 | |||
e0aaba6cf8 | |||
a09bef23ed | |||
3e018ef131 | |||
adb66f55a7 | |||
377c9a746d | |||
ea48ae0f75 | |||
2d1739b429 | |||
1c59034be4 | |||
52a84788e0 | |||
3e328f55fc | |||
b18e67522f | |||
4b086bd5b5 | |||
aac594aae3 | |||
a49fa0edbe | |||
d271683c14 | |||
0bb8e1247e | |||
32d97caf42 | |||
bc93b29789 | |||
df5cf2d323 | |||
b62c0256b2 | |||
1ea84cb734 | |||
2a5d3736e8 | |||
3dcc923351 | |||
589c40077b | |||
d4e0b1d093 | |||
b8443e67da | |||
5604ec7266 | |||
6f012f2d1d | |||
98e61c31df | |||
e641485132 | |||
a3ceb8f007 | |||
b819432271 | |||
9ceae8f51f | |||
5ffc8a84cd | |||
6e0fa4be68 | |||
a0ada2e935 | |||
e4694f58da | |||
fc7f0a02b8 | |||
211b330346 | |||
d36fe214a6 | |||
a34c053f0a | |||
4cdb203ec3 | |||
8014bf1124 | |||
49d87cf182 | |||
eedcc82d31 | |||
8e8259091c | |||
7869e5b007 | |||
a49af4648c | |||
417b2bcf5c | |||
8f0feaa6d2 | |||
b95163bd3a | |||
2809be87cc | |||
ac369b7b83 | |||
1aa3e4abfa | |||
e5c5a636a9 | |||
2bf30e9e5a | |||
b591cb9a03 | |||
714d01c07c | |||
c6990cdf91 | |||
da8786b8fd | |||
5577322062 | |||
1b03c5ab6a | |||
7dd3c19027 | |||
29d26d3179 | |||
ca764ec8d9 | |||
250f0ee7fb | |||
09e4830199 | |||
8f85d08e9f | |||
3ae076ce8d | |||
94425ad59b | |||
0354d50278 | |||
cdd83c2e15 | |||
9a07dde16d | |||
6e091d3991 | |||
95d85fb186 | |||
3a3f152979 | |||
4fe2432e05 | |||
c3a41e26a7 | |||
4838039b65 | |||
2a221b8fcd | |||
79ce6930a2 | |||
d762a7ca6c | |||
f23b6b8b85 | |||
4597b43912 | |||
f64d914bff | |||
d07999ddff | |||
e04dc5105b | |||
cffb031ce1 | |||
f3ec843ba6 | |||
55ed17f97b | |||
6a502cc2f5 | |||
6a009fabcb | |||
7a8a0205b4 | |||
4dc06bdb70 | |||
08b597b3e2 | |||
46d166406d | |||
4ec8d53e91 | |||
e7984e3711 | |||
90d89377ea | |||
0692317bc5 | |||
e8b31108d6 | |||
95fc8d62a2 | |||
0c015aa887 | |||
f69f821853 | |||
485dbdc0e7 | |||
0afd52b98d | |||
38b05f1400 | |||
db9866677e | |||
4101ff314a | |||
68da5a6d19 | |||
e4a25ad5ff | |||
5d6c744d38 | |||
5dd0639520 | |||
a2515755c3 | |||
807941eb31 | |||
a2e20b07f8 | |||
ace70407a2 | |||
613e1466f9 | |||
d8f45cd5f1 | |||
3afd077b55 | |||
e95bf48445 | |||
932a405e18 | |||
9a037204fa | |||
374c050a42 | |||
8b8e3ee117 | |||
af1ed708e4 | |||
041498b221 | |||
d5a5883a10 | |||
6fea473414 | |||
68e7fdce20 | |||
b4c9bf5802 | |||
e952fa8946 | |||
84a178f0b0 | |||
f9db24a824 | |||
9bee606dd6 | |||
be4f6ab8e1 | |||
fd6c7aee6d | |||
cd6de9cd34 | |||
40f6a5b8a4 | |||
95b0eb2b6c | |||
0b28d3daf2 | |||
8435dcbb61 | |||
99347df70e | |||
658b5f63ef | |||
c6535a080e | |||
673ec550f5 | |||
ff78e7c45a | |||
da023b2f9a | |||
470561cbbd | |||
417202b743 | |||
0952b76e16 | |||
bbeb192ec9 | |||
e4f4335b07 | |||
8c07899715 | |||
d5c623b3b6 | |||
061a183036 | |||
70ac6dbb9f | |||
593161ddd8 | |||
71e500f4b5 | |||
ad942885ce | |||
e058a37614 | |||
72b72ca937 | |||
a8a6b3159d | |||
9e2616aeac | |||
c5ffd2e3f0 | |||
0f24a8c06f | |||
b0260c615d | |||
a63ce953a0 | |||
b753f05d74 | |||
9bab7c8229 | |||
d8c4512b25 | |||
2e08bfe9cc | |||
d2a59ad37b | |||
10dfca34ac | |||
45d4096756 | |||
4e6938d78e | |||
1ca8cefa9a | |||
ca66dd243c | |||
44632c3d71 | |||
aa28196e8b | |||
5d8055319e | |||
b1835e1de9 | |||
8cd413572a | |||
30e4dbef1c | |||
90b3946e9c | |||
9202a77498 | |||
d8230a8d4d | |||
c6178601c5 | |||
2e0ae01b05 | |||
1f71d1f760 | |||
fe690a68ef | |||
c9a37c59c4 | |||
3cfef738e7 | |||
5cb9e47034 | |||
044b616127 | |||
f88049169e | |||
7b13a8f85a | |||
6da5e0862a | |||
2049113935 | |||
d4ae1b18c0 | |||
2081caa452 | |||
a5a013811c | |||
1400127d6f | |||
7fed25ad1f | |||
5530303be7 | |||
29fa1edcc7 | |||
1cb8bafb1f | |||
0837132ce3 | |||
26df0781a5 | |||
3523c39f44 | |||
2585d280d1 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,3 +26,4 @@ Build
|
||||
.idea
|
||||
cmake-build-debug
|
||||
cmake-build-release
|
||||
.vs
|
112
.travis.yml
112
.travis.yml
@ -11,25 +11,25 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang']
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang34
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: &clang35
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.5']
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang35
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -38,12 +38,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.6']
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang36
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -52,12 +52,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.7']
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang37
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -66,12 +66,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8']
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
# 2/ Linux GCC Builds
|
||||
@ -81,12 +81,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.4']
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc44
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -95,12 +95,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.7']
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc47
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -109,12 +109,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc48
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -123,12 +123,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9']
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc49
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -137,12 +137,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5']
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc5
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
@ -151,20 +151,17 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6']
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc6
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Debug'
|
||||
|
||||
# 3a/ Linux C++11 GCC builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc48
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
addons: *gcc48
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=1
|
||||
|
||||
- os: linux
|
||||
@ -175,10 +172,7 @@ matrix:
|
||||
# 3b/ Linux C++11 Clang builds
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8']
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=1
|
||||
|
||||
- os: linux
|
||||
@ -186,27 +180,69 @@ matrix:
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=1
|
||||
|
||||
# 4a/ Linux C++14 GCC builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc6
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Release' CPP14=1
|
||||
|
||||
# 4/ OSX Clang Builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc6
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP14=1
|
||||
|
||||
# 4b/ Linux C++14 Clang builds
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP14=1
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP14=1
|
||||
|
||||
|
||||
# 5/ OSX Clang Builds
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP11=1
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP11=1
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP14=1
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP14=1
|
||||
|
||||
|
||||
install:
|
||||
@ -218,13 +254,13 @@ install:
|
||||
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}
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
which cmake || brew install cmake
|
||||
which cmake || brew install cmake
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- export CXX=${COMPILER}
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11}
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11} -DUSE_CPP14=${CPP14}
|
||||
- cd Build
|
||||
|
||||
script:
|
||||
|
@ -19,6 +19,10 @@ elseif(USE_CPP14)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(USE_WMAIN)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
||||
endif()
|
||||
|
||||
#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}")
|
||||
@ -55,6 +59,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/CmdLineTests.cpp
|
||||
${SELF_TEST_DIR}/CompilationTests.cpp
|
||||
${SELF_TEST_DIR}/ConditionTests.cpp
|
||||
${SELF_TEST_DIR}/DecompositionTests.cpp
|
||||
${SELF_TEST_DIR}/EnumToString.cpp
|
||||
${SELF_TEST_DIR}/ExceptionTests.cpp
|
||||
${SELF_TEST_DIR}/GeneratorTests.cpp
|
||||
@ -70,6 +75,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/ToStringWhich.cpp
|
||||
${SELF_TEST_DIR}/TrickyTests.cpp
|
||||
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
||||
${SELF_TEST_DIR}/MatchersTests.cpp
|
||||
)
|
||||
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
|
||||
|
||||
@ -134,6 +140,7 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_debugger.h
|
||||
${HEADER_DIR}/internal/catch_debugger.hpp
|
||||
${HEADER_DIR}/internal/catch_default_main.hpp
|
||||
${HEADER_DIR}/internal/catch_errno_guard.hpp
|
||||
${HEADER_DIR}/internal/catch_evaluate.hpp
|
||||
${HEADER_DIR}/internal/catch_exception_translator_registry.hpp
|
||||
${HEADER_DIR}/internal/catch_expression_lhs.hpp
|
||||
@ -154,6 +161,9 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_legacy_reporter_adapter.hpp
|
||||
${HEADER_DIR}/internal/catch_list.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers_string.h
|
||||
${HEADER_DIR}/internal/catch_matchers_string.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers_vector.h
|
||||
${HEADER_DIR}/internal/catch_message.h
|
||||
${HEADER_DIR}/internal/catch_message.hpp
|
||||
${HEADER_DIR}/internal/catch_notimplemented_exception.h
|
||||
@ -206,11 +216,13 @@ CheckFileList(INTERNAL_HEADERS ${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.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_console.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_junit.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_multi.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_xml.hpp
|
||||
)
|
||||
@ -238,28 +250,35 @@ SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES})
|
||||
|
||||
# configure the executable
|
||||
include_directories(${HEADER_DIR})
|
||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
|
||||
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
|
||||
|
||||
# Add desired warnings
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra )
|
||||
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
|
||||
endif()
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||
target_compile_options( SelfTest PRIVATE /W4 )
|
||||
target_compile_options( Benchmark PRIVATE /W4 )
|
||||
endif()
|
||||
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
||||
# without building all of our selftests.
|
||||
if (NOT NO_SELFTEST)
|
||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
|
||||
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
|
||||
|
||||
# Add desired warnings
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra )
|
||||
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
|
||||
endif()
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX )
|
||||
target_compile_options( Benchmark PRIVATE /W4 )
|
||||
endif()
|
||||
|
||||
|
||||
# configure unit tests via CTest
|
||||
enable_testing()
|
||||
add_test(NAME RunTests COMMAND SelfTest)
|
||||
# configure unit tests via CTest
|
||||
enable_testing()
|
||||
add_test(NAME RunTests COMMAND SelfTest)
|
||||
|
||||
add_test(NAME ListTests COMMAND SelfTest --list-tests)
|
||||
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
|
||||
add_test(NAME ListTests COMMAND SelfTest --list-tests)
|
||||
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
|
||||
|
||||
add_test(NAME ListTags COMMAND SelfTest --list-tags)
|
||||
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
|
||||
add_test(NAME ListTags COMMAND SelfTest --list-tags)
|
||||
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
|
||||
|
||||
install(DIRECTORY "single_include/" DESTINATION "include/catch/")
|
||||
endif() # !NO_SELFTEST
|
||||
|
||||
|
||||
install(DIRECTORY "single_include/" DESTINATION "include/catch")
|
||||
|
@ -1,10 +1,10 @@
|
||||

|
||||
|
||||
*v1.7.2*
|
||||
[](https://github.com/philsquared/catch/releases)
|
||||
[](https://travis-ci.org/philsquared/Catch)
|
||||
[](https://ci.appveyor.com/project/philsquared/catch/branch/master)
|
||||
|
||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.7.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.9.5/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
|
||||
## What's the Catch?
|
||||
|
||||
|
61
appveyor.yml
Normal file
61
appveyor.yml
Normal file
@ -0,0 +1,61 @@
|
||||
# version string format -- This will be overwritten later anyway
|
||||
version: "{build}"
|
||||
|
||||
os:
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2015
|
||||
- Visual Studio 2013
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- additional_flags: "/permissive- /std:c++latest"
|
||||
wmain: 0
|
||||
|
||||
- additional_flags: ""
|
||||
wmain: 0
|
||||
|
||||
- additional_flags: "/D_UNICODE /DUNICODE"
|
||||
wmain: 1
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
-
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
os: Visual Studio 2015
|
||||
-
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
os: Visual Studio 2013
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
# Set build version to git commit-hash
|
||||
- ps: Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_BRANCH) - $($env:APPVEYOR_REPO_COMMIT)"
|
||||
|
||||
# fetch repository as zip archive
|
||||
shallow_clone: true
|
||||
|
||||
# Win32 and x64 are CMake-compatible solution platform names.
|
||||
# This allows us to pass %PLATFORM% to CMake -A.
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
# build Configurations, i.e. Debug, Release, etc.
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
#Cmake will autodetect the compiler, but we set the arch
|
||||
before_build:
|
||||
- set CXXFLAGS=%additional_flags%
|
||||
- cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
|
||||
|
||||
# build with MSBuild
|
||||
build:
|
||||
project: Build\CatchSelfTest.sln # path to Visual Studio solution or project
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
|
||||
|
||||
test_script:
|
||||
- cd Build
|
||||
- ctest -V -j 2 -C %CONFIGURATION%
|
BIN
catch-hand-icon.png
Normal file
BIN
catch-hand-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
BIN
catch-icon-tiny.png
Normal file
BIN
catch-icon-tiny.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.7 KiB |
149
contrib/ParseAndAddCatchTests.cmake
Normal file
149
contrib/ParseAndAddCatchTests.cmake
Normal file
@ -0,0 +1,149 @@
|
||||
#==================================================================================================#
|
||||
# supported macros #
|
||||
# - TEST_CASE, #
|
||||
# - SCENARIO, #
|
||||
# - TEST_CASE_METHOD, #
|
||||
# - CATCH_TEST_CASE, #
|
||||
# - CATCH_SCENARIO, #
|
||||
# - CATCH_TEST_CASE_METHOD. #
|
||||
# #
|
||||
# Usage #
|
||||
# 1. make sure this module is in the path or add this otherwise: #
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
|
||||
# 2. make sure that you've enabled testing option for the project by the call: #
|
||||
# enable_testing() #
|
||||
# 3. add the lines to the script for testing target (sample CMakeLists.txt): #
|
||||
# project(testing_target) #
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
|
||||
# enable_testing() #
|
||||
# #
|
||||
# find_path(CATCH_INCLUDE_DIR "catch.hpp") #
|
||||
# include_directories(${INCLUDE_DIRECTORIES} ${CATCH_INCLUDE_DIR}) #
|
||||
# #
|
||||
# file(GLOB SOURCE_FILES "*.cpp") #
|
||||
# add_executable(${PROJECT_NAME} ${SOURCE_FILES}) #
|
||||
# #
|
||||
# include(ParseAndAddCatchTests) #
|
||||
# ParseAndAddCatchTests(${PROJECT_NAME}) #
|
||||
# #
|
||||
# The following variables affect the behavior of the script: #
|
||||
# #
|
||||
# PARSE_CATCH_TESTS_VERBOSE (Default OFF) #
|
||||
# -- enables debug messages #
|
||||
# #
|
||||
#==================================================================================================#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
|
||||
option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF)
|
||||
|
||||
function(PrintDebugMessage)
|
||||
if(PARSE_CATCH_TESTS_VERBOSE)
|
||||
message(STATUS "ParseAndAddCatchTests: ${ARGV}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# This removes the contents between
|
||||
# - block comments (i.e. /* ... */)
|
||||
# - full line comments (i.e. // ... )
|
||||
# contents have been read into '${CppCode}'.
|
||||
# !keep partial line comments
|
||||
function(RemoveComments CppCode)
|
||||
string(ASCII 2 CMakeBeginBlockComment)
|
||||
string(ASCII 3 CMakeEndBlockComment)
|
||||
string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "\\*/" "${CMakeEndBlockComment}" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "${CMakeBeginBlockComment}[^${CMakeEndBlockComment}]*${CMakeEndBlockComment}" "" ${CppCode} "${${CppCode}}")
|
||||
string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" ${CppCode} "${${CppCode}}")
|
||||
|
||||
set(${CppCode} "${${CppCode}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Worker function
|
||||
function(ParseFile SourceFile TestTarget)
|
||||
# According to CMake docs EXISTS behavior is well-defined only for full paths.
|
||||
get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
|
||||
if(NOT EXISTS ${SourceFile})
|
||||
message(WARNING "Cannot find source file: ${SourceFile}")
|
||||
return()
|
||||
endif()
|
||||
PrintDebugMessage("parsing ${SourceFile}")
|
||||
file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
|
||||
|
||||
# Remove block and fullline comments
|
||||
RemoveComments(Contents)
|
||||
|
||||
# Find definition of test names
|
||||
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
||||
|
||||
foreach(TestName ${Tests})
|
||||
# Strip newlines
|
||||
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
||||
|
||||
# Get test type and fixture if applicable
|
||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
|
||||
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
|
||||
string(REPLACE "${TestType}(" "" TestFixture "${TestTypeAndFixture}")
|
||||
|
||||
# Get string parts of test definition
|
||||
string(REGEX MATCHALL "\"+([^\\^\"]|\\\\\")+\"+" TestStrings "${TestName}")
|
||||
|
||||
# Strip wrapping quotation marks
|
||||
string(REGEX REPLACE "^\"(.*)\"$" "\\1" TestStrings "${TestStrings}")
|
||||
string(REPLACE "\";\"" ";" TestStrings "${TestStrings}")
|
||||
|
||||
# Validate that a test name and tags have been provided
|
||||
list(LENGTH TestStrings TestStringsLength)
|
||||
if(TestStringsLength GREATER 2 OR TestStringsLength LESS 1)
|
||||
message(FATAL_ERROR "You must provide a valid test name and tags for all tests in ${SourceFile}")
|
||||
endif()
|
||||
|
||||
# Assign name and tags
|
||||
list(GET TestStrings 0 Name)
|
||||
if("${TestType}" STREQUAL "SCENARIO")
|
||||
set(Name "Scenario: ${Name}")
|
||||
endif()
|
||||
if(TestFixture)
|
||||
set(CTestName "${TestFixture}:${Name}")
|
||||
else()
|
||||
set(CTestName "${Name}")
|
||||
endif()
|
||||
set(CTestName "${TestTarget}:${CTestName}")
|
||||
# add target to labels to enable running all tests added from this target
|
||||
set(Labels ${TestTarget})
|
||||
if(TestStringsLength EQUAL 2)
|
||||
list(GET TestStrings 1 Tags)
|
||||
string(TOLOWER "${Tags}" Tags)
|
||||
# remove target from labels if the test is hidden
|
||||
if("${Tags}" MATCHES ".*\\[!?(hide|\\.)\\].*")
|
||||
list(REMOVE_ITEM Labels ${TestTarget})
|
||||
endif()
|
||||
string(REPLACE "]" ";" Tags "${Tags}")
|
||||
string(REPLACE "[" "" Tags "${Tags}")
|
||||
endif()
|
||||
|
||||
list(APPEND Labels ${Tags})
|
||||
|
||||
PrintDebugMessage("Adding test \"${CTestName}\"")
|
||||
if(Labels)
|
||||
PrintDebugMessage("Setting labels to ${Labels}")
|
||||
endif()
|
||||
|
||||
# Add the test and set its properties
|
||||
add_test(NAME "\"${CTestName}\"" COMMAND ${TestTarget} ${Name} ${AdditionalCatchParameters})
|
||||
set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
|
||||
LABELS "${Labels}")
|
||||
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# entry point
|
||||
function(ParseAndAddCatchTests TestTarget)
|
||||
PrintDebugMessage("Started parsing ${TestTarget}")
|
||||
get_target_property(SourceFiles ${TestTarget} SOURCES)
|
||||
PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
||||
foreach(SourceFile ${SourceFiles})
|
||||
ParseFile(${SourceFile} ${TestTarget})
|
||||
endforeach()
|
||||
PrintDebugMessage("Finished parsing ${TestTarget}")
|
||||
endfunction()
|
@ -1,21 +1,29 @@
|
||||
These are the currently documented areas of the framework. There is more to come.
|
||||
|
||||
Before looking at this material be sure to read the [tutorial](tutorial.md)
|
||||
To get the most out of Catch, start with the [tutorial](tutorial.md).
|
||||
Once you're up and running consider the following reference material.
|
||||
|
||||
Writing tests:
|
||||
* [Assertion macros](assertions.md)
|
||||
* [Matchers](matchers.md)
|
||||
* [Logging macros](logging.md)
|
||||
* [Test cases and sections](test-cases-and-sections.md)
|
||||
* [Test fixtures](test-fixtures.md)
|
||||
* [Command line](command-line.md)
|
||||
* [Build systems](build-systems.md)
|
||||
* [Reporters](reporters.md)
|
||||
* [Event Listeners](event-listeners.md)
|
||||
|
||||
Fine tuning:
|
||||
* [Supplying your own main()](own-main.md)
|
||||
* [Configuration](configuration.md)
|
||||
* [Compile-time configuration](configuration.md)
|
||||
* [String Conversions](tostring.md)
|
||||
|
||||
Running:
|
||||
* [Command line](command-line.md)
|
||||
* [CI and Build system integration](build-systems.md)
|
||||
|
||||
FAQ:
|
||||
* [Why are my tests slow to compile?](slow-compiles.md)
|
||||
* [Known limitations](limitations.md)
|
||||
|
||||
Other
|
||||
|
||||
|
||||
Other:
|
||||
* [Why Catch?](why-catch.md)
|
||||
* [Open Source Projects using Catch](opensource-users.md)
|
||||
* [Contributing](contributing.md)
|
||||
|
@ -53,13 +53,32 @@ Catch provides a way to perform tolerant comparisons of floating point values th
|
||||
REQUIRE( performComputation() == Approx( 2.1 ) );
|
||||
```
|
||||
|
||||
By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficent the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```Approx``` instance. e.g.:
|
||||
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.
|
||||
|
||||
```
|
||||
REQUIRE( 22/7 == Approx( 3.141 ).epsilon( 0.01 ) );
|
||||
* __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`.
|
||||
* __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`.
|
||||
* __scale__ - scale serves to adjust the base for comparison used by epsilon, can be used when By default set to `1.0`.
|
||||
|
||||
#### epsilon example
|
||||
```cpp
|
||||
Approx target = Approx(100).epsilon(0.01);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
100.5 == target; // True, because we set target to allow up to 1% error
|
||||
```
|
||||
|
||||
When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```Approx``` instance.
|
||||
#### margin example
|
||||
_Margin check is used only if the relative (epsilon and scale based) check fails._
|
||||
```cpp
|
||||
Approx target = Approx(100).margin(5);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
104.0 == target; // True, because we set target to allow absolute error up to 5
|
||||
```
|
||||
|
||||
#### scale
|
||||
Scale can be useful if the computation leading to the result worked on different scale, than is used by the results (and thus expected errors are on a different scale than would be expected based on the results alone).
|
||||
|
||||
|
||||
## Exceptions
|
||||
|
||||
@ -76,7 +95,7 @@ Expects that an exception (of any type) is be thrown during evaluation of the ex
|
||||
* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
|
||||
* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
|
||||
|
||||
Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
|
||||
Expects that an exception of the _specified type_ is thrown during evaluation of the expression. Note that the _exception type_ is used verbatim and you should include (const) reference.
|
||||
|
||||
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
|
||||
* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
|
||||
@ -105,15 +124,18 @@ REQUIRE_NOTHROW([&](){
|
||||
|
||||
## Matcher expressions
|
||||
|
||||
To support Matchers a slightly different form is used. Matchers will be more fully documented elsewhere. *Note that Matchers are still at early stage development and are subject to change.*
|
||||
To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md).
|
||||
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
|
||||
|
||||
Currently only string matchers are implemented and consist of: `Contains`, `Equals`, `StartsWith` and `EndsWith`.
|
||||
|
||||
Matchers can be composed using `&&`, `||` and `!` operators.
|
||||
|
||||
## Thread Safety
|
||||
|
||||
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).
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -1,10 +1,10 @@
|
||||
# Integration with build systems
|
||||
# CI and build system 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.
|
||||
|
||||
# Continuous Integration systems
|
||||
|
||||
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (as has been done with TeamCity).
|
||||
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP and Automake reporters).
|
||||
|
||||
Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
|
||||
|
||||
@ -26,14 +26,8 @@ The advantage of this format is that the JUnit Ant schema is widely understood b
|
||||
|
||||
The disadvantage is that this schema was designed to correspond to how JUnit works - and there is a significant mismatch with how Catch works. Additionally the format is not streamable (because opening elements hold counts of failed and passing tests as attributes) - so the whole test run must complete before it can be written.
|
||||
|
||||
## TeamCity Reporter
|
||||
```-r teamcity```
|
||||
|
||||
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
|
||||
|
||||
```catch_reporter_teamcity.hpp``` can be found in the ```include\reporters``` directory. It should be included in the same file that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. The ```#include``` should be placed after ```#include```ing Catch itself.
|
||||
|
||||
e.g.:
|
||||
## Other reporters
|
||||
Other reporters are not part of the single-header distribution and need to be downloaded and included separately. All reporters are stored in `include/reporters` directory in the git repository, and are named `catch_reporter_*.hpp`. For example, to use the TeamCity reporter you need to download `include/reporters/catch_reporter_teamcity.hpp` and include it after Catch itself.
|
||||
|
||||
```
|
||||
#define CATCH_CONFIG_MAIN
|
||||
@ -41,14 +35,47 @@ e.g.:
|
||||
#include "catch_reporter_teamcity.hpp"
|
||||
```
|
||||
|
||||
### TeamCity Reporter
|
||||
```-r teamcity```
|
||||
|
||||
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
|
||||
|
||||
Being specific to TeamCity this is the best reporter to use with it - but it is completely unsuitable for any other purpose. It is a streaming format (it writes as it goes) - although test results don't appear in the TeamCity interface until the completion of a suite (usually the whole test run).
|
||||
|
||||
### Automake Reporter
|
||||
```-r automake```
|
||||
|
||||
The Automake Reporter writes out the [meta tags](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) expected by automake via `make check`.
|
||||
|
||||
### TAP (Test Anything Protocol) Reporter
|
||||
```-r tap```
|
||||
|
||||
Because of the incremental nature of Catch's test suites and ability to run specific tests, our implementation of TAP reporter writes out the number of tests in a suite last.
|
||||
|
||||
# Low-level tools
|
||||
|
||||
## CMake
|
||||
|
||||
You can use the following CMake script to automatically fetch Catch from github and configure it as an external project:
|
||||
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)
|
||||
@ -81,6 +108,36 @@ 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
|
||||
If you are also using ctest, `contrib/ParseAndAddCatchTests.cmake` is a CMake script that attempts to parse your test files and automatically register all test cases, using 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 ctest 4 labels would be created, `a`, `b`, `c` and `unit`.
|
||||
|
||||
### 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
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
||||
[Home](Readme.md)
|
||||
|
@ -222,7 +222,7 @@ Prints the command line arguments to stdout
|
||||
|
||||
<a id="run-section"></a>
|
||||
## Specify the section to run
|
||||
<pre>-s, --section <section name></pre>
|
||||
<pre>-c, --section <section name></pre>
|
||||
|
||||
To limit execution to a specific section within a test case, use this option one or more times.
|
||||
To narrow to sub-sections use multiple instances, where each subsequent instance specifies a deeper nesting level.
|
||||
|
@ -1,12 +1,16 @@
|
||||
# Commercial users of Catch
|
||||
|
||||
As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too. Many companies like to keep this
|
||||
information internal, and that's fine, but if you're more open it would be great if we could list the names of as
|
||||
many organisations as possible that use Catch somewhere in their codebase. Enterprise environments often tend to be
|
||||
far more conservative in their tool adoption - and being aware that other companies are using Catch can ease the
|
||||
path in.
|
||||
As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too.
|
||||
Many organisations like to keep this information internal, and that's fine,
|
||||
but if you're more open it would be great if we could list the names of as
|
||||
many organisations as possible that use Catch somewhere in their codebase.
|
||||
Enterprise environments often tend to be far more conservative in their tool adoption -
|
||||
and being aware that other companies are using Catch can ease the path in.
|
||||
|
||||
So if you are aware of Catch usage in your organisation, and are fairly confident there is no issue with sharing this
|
||||
fact then please let us know - either directly, via a PR or [issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
|
||||
fact then please let us know - either directly, via a PR or
|
||||
[issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
|
||||
|
||||
- Bloomberg
|
||||
- NASA
|
||||
- [Inscopix Inc.](https://www.inscopix.com/)
|
||||
|
@ -52,17 +52,18 @@ This can be useful on certain platforms that do not provide ```std::cout``` and
|
||||
|
||||
# C++ conformance toggles
|
||||
|
||||
CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported?
|
||||
CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported?
|
||||
CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods
|
||||
CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported?
|
||||
CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported
|
||||
CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient
|
||||
CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type
|
||||
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
|
||||
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
|
||||
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
|
||||
CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and <type_traits>
|
||||
CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported?
|
||||
CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported?
|
||||
CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods
|
||||
CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported?
|
||||
CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported
|
||||
CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient
|
||||
CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type
|
||||
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
|
||||
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
|
||||
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
|
||||
CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and <type_traits>
|
||||
CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK // Use C++11 expression SFINAE to check if class can be inserted to std::ostream
|
||||
|
||||
Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative.
|
||||
So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support.
|
||||
@ -70,15 +71,51 @@ You may also suppress any of these features by using the `_NO_` form, e.g. `CATC
|
||||
|
||||
All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
|
||||
|
||||
## `CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK`
|
||||
|
||||
This flag is off by default, but allows you to resolve problems caused by types with private base class that are streamable, but the classes themselves are not. Without it, the following code will cause a compilation error:
|
||||
```cpp
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
struct A {};
|
||||
std::ostream &operator<< (std::ostream &o, const A &v) { return o << 0; }
|
||||
|
||||
struct B : private A {
|
||||
bool operator==(int){ return true;}
|
||||
};
|
||||
|
||||
B f ();
|
||||
std::ostream g ();
|
||||
|
||||
TEST_CASE ("Error in streamable check") {
|
||||
B x;
|
||||
REQUIRE (x == 4);
|
||||
}
|
||||
```
|
||||
|
||||
# Other toggles
|
||||
|
||||
CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases
|
||||
CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows
|
||||
CATCH_CONFIG_FAST_COMPILE // Sacrifices some (rather minor) features for compilation speed
|
||||
CATCH_CONFIG_POSIX_SIGNALS // Enable handling POSIX signals
|
||||
CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap
|
||||
|
||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API supports.
|
||||
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.
|
||||
|
||||
`CATCH_CONFIG_POSIX_SIGNALS` is on by default, except when Catch is compiled under `Cygwin`, where it is disabled by default (but can be force-enabled by defining `CATCH_CONFIG_POSIX_SIGNALS`).
|
||||
|
||||
`CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running.
|
||||
|
||||
Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
|
||||
|
||||
## `CATCH_CONFIG_FAST_COMPILE`
|
||||
Defining this flag speeds up compilation of test files by ~20%, by making 2 changes:
|
||||
* 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*.
|
||||
* The `REQUIRE` family of macros (`REQUIRE`, `REQUIRE_FALSE` and `REQUIRE_THAT`) no longer uses local try-catch block. This disables exception translation, 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.
|
||||
|
||||
# Windows header clutter
|
||||
|
||||
On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros:
|
||||
|
73
docs/event-listeners.md
Normal file
73
docs/event-listeners.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Event Listeners
|
||||
|
||||
A `Listener` is a class you can register with Catch that will then be passed events,
|
||||
such as a test case starting or ending, as they happen during a test run.
|
||||
`Listeners` are actually types of `Reporters`, with a few small differences:
|
||||
|
||||
1. Once registered in code they are automatically used - you don't need to specify them on the command line
|
||||
2. They are called in addition to (just before) any reporters, and you can register multiple listeners.
|
||||
3. They derive from `Catch::TestEventListenerBase`, which has default stubs for all the events,
|
||||
so you are not forced to implement events you're not interested in.
|
||||
4. You register a listener with `CATCH_REGISTER_LISTENER`
|
||||
|
||||
|
||||
## Implementing a Listener
|
||||
|
||||
In your main source file (i.e. the one that has the `#define` for `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`),
|
||||
simply derive a class from `Catch::TestEventListenerBase` and implement the methods you are interested in.
|
||||
Then register it using `INTERNAL_CATCH_REGISTER_LISTENER`.
|
||||
|
||||
For example:
|
||||
|
||||
```c++
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
struct MyListener : Catch::TestEventListenerBase {
|
||||
|
||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||
|
||||
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
// Perform some setup before a test case is run
|
||||
}
|
||||
|
||||
virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
// Tear-down after a test case is run
|
||||
}
|
||||
};
|
||||
CATCH_REGISTER_LISTENER( MyListener )
|
||||
```
|
||||
|
||||
_Note that you should not use any assertion macros within a Listener!_
|
||||
|
||||
## Events that can be hooked
|
||||
|
||||
The following are the methods that can be overriden in the Listener:
|
||||
|
||||
```c++
|
||||
// The whole test run, starting and ending
|
||||
virtual void testRunStarting( TestRunInfo const& testRunInfo );
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats );
|
||||
|
||||
// Test cases starting and ending
|
||||
virtual void testCaseStarting( TestCaseInfo const& testInfo );
|
||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats );
|
||||
|
||||
// Sections starting and ending
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo );
|
||||
virtual void sectionEnded( SectionStats const& sectionStats );
|
||||
|
||||
// Assertions before/ after
|
||||
virtual void assertionStarting( AssertionInfo const& assertionInfo );
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats );
|
||||
|
||||
// A test is being skipped (because it is "hidden")
|
||||
virtual void skipTest( TestCaseInfo const& testInfo );
|
||||
```
|
||||
|
||||
More information about the events (e.g. name of the test case) is contained in the structs passed as arguments -
|
||||
just look in the source code to see what fields are available.
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -1,6 +1,32 @@
|
||||
# Logging macros
|
||||
|
||||
Additional messages can be logged during a test case.
|
||||
Additional messages can be logged during a test case. Note that the messages are scoped and thus will not be reported if failure occurs in scope preceding the message declaration. An example:
|
||||
|
||||
```cpp
|
||||
TEST_CASE("Foo") {
|
||||
INFO("Test case start");
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
INFO("The number is " << i);
|
||||
CHECK(i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Bar") {
|
||||
INFO("Test case start");
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
INFO("The number is " << i);
|
||||
CHECK(i == i);
|
||||
}
|
||||
CHECK(false);
|
||||
}
|
||||
```
|
||||
When the `CHECK` fails in the "Foo" test case, then two messages will be printed.
|
||||
```
|
||||
Test case start
|
||||
The number is 1
|
||||
```
|
||||
When the last `CHECK` fails in the "Bar" test case, then only one message will be printed: `Test case start`.
|
||||
|
||||
|
||||
## Streaming macros
|
||||
|
||||
@ -26,6 +52,10 @@ The message is always reported but does not fail the test.
|
||||
|
||||
The message is reported and the test case fails.
|
||||
|
||||
**FAIL_CHECK(** _message expression_ **)**
|
||||
|
||||
AS `FAIL`, but does not abort the test
|
||||
|
||||
## Quickly capture a variable value
|
||||
|
||||
**CAPTURE(** _expression_ **)**
|
||||
|
103
docs/matchers.md
Normal file
103
docs/matchers.md
Normal file
@ -0,0 +1,103 @@
|
||||
# Matchers
|
||||
|
||||
Matchers are an alternative way to do assertions which are easily extensible and composable.
|
||||
This makes them well suited to use with more complex types (such as collections) or your own custom types.
|
||||
Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks.
|
||||
|
||||
## In use
|
||||
|
||||
Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments.
|
||||
The first argument is the thing (object or value) under test. The second part is a match _expression_,
|
||||
which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators.
|
||||
|
||||
For example, to assert that a string ends with a certain substring:
|
||||
|
||||
```c++
|
||||
std::string str = getStringFromSomewhere();
|
||||
REQUIRE_THAT( str, EndsWith( "as a service" ) );
|
||||
```
|
||||
|
||||
The matcher objects can take multiple arguments, allowing more fine tuning.
|
||||
The built-in string matchers, for example, take a second argument specifying whether the comparison is
|
||||
case sensitive or not:
|
||||
|
||||
```c++
|
||||
REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) );
|
||||
```
|
||||
|
||||
And matchers can be combined:
|
||||
|
||||
```c++
|
||||
REQUIRE_THAT( str,
|
||||
EndsWith( "as a service" ) ||
|
||||
(StartsWith( "Big data" ) && !Contains( "web scale" ) ) );
|
||||
```
|
||||
|
||||
## Built in matchers
|
||||
Currently Catch has some string matchers and some vector matchers.
|
||||
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
||||
|
||||
|
||||
## Custom matchers
|
||||
It's easy to provide your own matchers to extend Catch or just to work with your own types.
|
||||
|
||||
You need to provide two things:
|
||||
1. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested.
|
||||
The constructor takes and stores any arguments needed (e.g. something to compare against) and you must
|
||||
override two methods: `match()` and `describe()`.
|
||||
2. A simple builder function. This is what is actually called from the test code and allows overloading.
|
||||
|
||||
Here's an example for asserting that an integer falls within a given range
|
||||
(note that it is all inline for the sake of keeping the example short):
|
||||
|
||||
```c++
|
||||
// The matcher class
|
||||
class IntRange : public Catch::MatcherBase<int> {
|
||||
int m_begin, m_end;
|
||||
public:
|
||||
IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
|
||||
|
||||
// Performs the test for this matcher
|
||||
virtual bool match( int const& i ) const override {
|
||||
return i >= m_begin && i <= m_end;
|
||||
}
|
||||
|
||||
// Produces a string describing what this matcher does. It should
|
||||
// include any provided data (the begin/ end in this case) and
|
||||
// be written as if it were stating a fact (in the output it will be
|
||||
// preceded by the value under test).
|
||||
virtual std::string describe() const {
|
||||
std::ostringstream ss;
|
||||
ss << "is between " << m_begin << " and " << m_end;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// The builder function
|
||||
inline IntRange IsBetween( int begin, int end ) {
|
||||
return IntRange( begin, end );
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Usage
|
||||
TEST_CASE("Integers are within a range")
|
||||
{
|
||||
CHECK_THAT( 3, IsBetween( 1, 10 ) );
|
||||
CHECK_THAT( 100, IsBetween( 1, 10 ) );
|
||||
}
|
||||
```
|
||||
|
||||
Running this test gives the following in the console:
|
||||
|
||||
```
|
||||
/**/TestFile.cpp:123: FAILED:
|
||||
CHECK_THAT( 100, IsBetween( 1, 10 ) )
|
||||
with expansion:
|
||||
100 is between 1 and 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -1,6 +1,6 @@
|
||||
# Open Source projects using Catch
|
||||
|
||||
Catch is great for open source. With it's [liberal license](../LICENSE_1_0.txt) and single-header, dependency-free, distribution
|
||||
Catch is great for open source. With it's [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution
|
||||
it's easy to just drop the header into your project and start writing tests - what's not to like?
|
||||
|
||||
As a result Catch is now being used in many Open Source projects, including some quite well known ones.
|
||||
@ -34,6 +34,18 @@ A, single-header, JSON parsing library that takes advantage of what C++ has to o
|
||||
### [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
|
||||
|
||||
### [nanodbc](https://github.com/lexicalunit/nanodbc/)
|
||||
A small C++ library wrapper for the native C ODBC API.
|
||||
|
||||
### [Nonius](https://github.com/libnonius/nonius)
|
||||
A header-only framework for benchmarking small snippets of C++ code.
|
||||
|
||||
### [SOCI](https://github.com/SOCI/soci)
|
||||
The C++ Database Access Library
|
||||
|
||||
### [polymorphic_value](https://github.com/jbcoe/polymorphic_value)
|
||||
A polymorphic value-type for C++
|
||||
|
||||
### [Ppconsul](https://github.com/oliora/ppconsul)
|
||||
A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure
|
||||
|
||||
@ -45,9 +57,15 @@ A thread safe header only mocking framework for C++14
|
||||
|
||||
## Applications & Tools
|
||||
|
||||
### [ArangoDB](https://github.com/arangodb/arangodb)
|
||||
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
|
||||
|
||||
### [MAME](https://github.com/mamedev/mame)
|
||||
MAME originally stood for Multiple Arcade Machine Emulator
|
||||
|
||||
### [Newsbeuter](https://github.com/akrennmair/newsbeuter)
|
||||
Newsbeuter is an open-source RSS/Atom feed reader for text terminals.
|
||||
|
||||
### [Standardese](https://github.com/foonathan/standardese)
|
||||
Standardese aims to be a nextgen Doxygen
|
||||
|
||||
|
@ -1,3 +1,176 @@
|
||||
# 1.9.5
|
||||
|
||||
### Fixes
|
||||
* Truthy expressions are now reconstructed properly, not as booleans (#914)
|
||||
* Various warnings are no longer erroneously suppressed in test files (files that include `catch.hpp`, but do not define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`) (#871)
|
||||
* Catch no longer fails to link when main is compiled as C++, but linked against Objective-C (#855)
|
||||
* Fixed incorrect gcc version detection when deciding to use `__COUNTER__` (#928)
|
||||
* Previously any GCC with minor version less than 3 would be incorrectly classified as not supporting `__COUNTER__`.
|
||||
* Suppressed C4996 warning caused by upcoming updated to MSVC 2017, marking `std::uncaught_exception` as deprecated. (#927)
|
||||
|
||||
### Improvements
|
||||
* CMake integration script now incorporates debug messages and registers tests in an improved way (#911)
|
||||
* Various documentation improvements
|
||||
|
||||
|
||||
|
||||
# 1.9.4
|
||||
|
||||
### Fixes
|
||||
* `CATCH_FAIL` macro no longer causes compilation error without variadic macro support
|
||||
* `INFO` messages are no longer cleared after being reported once
|
||||
|
||||
### Improvements and minor changes
|
||||
* Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined.
|
||||
* Note that Catch still officially supports only ASCII
|
||||
|
||||
# 1.9.3
|
||||
|
||||
### Fixes
|
||||
* Completed the fix for (lack of) uint64_t in earlier Visual Studios
|
||||
|
||||
# 1.9.2
|
||||
|
||||
### Improvements and minor changes
|
||||
* All of `Approx`'s member functions now accept strong typedefs in C++11 mode (#888)
|
||||
* Previously `Approx::scale`, `Approx::epsilon`, `Approx::margin` and `Approx::operator()` didn't.
|
||||
|
||||
|
||||
### Fixes
|
||||
* POSIX signals are now disabled by default under QNX (#889)
|
||||
* QNX does not support current enough (2001) POSIX specification
|
||||
* JUnit no longer counts exceptions as failures if given test case is marked as ok to fail.
|
||||
* `Catch::Option` should now have its storage properly aligned.
|
||||
* Catch no longer attempts to define `uint64_t` on windows (#862)
|
||||
* This was causing trouble when compiled under Cygwin
|
||||
|
||||
### Other
|
||||
* Catch is now compiled under MSVC 2017 using `std:c++latest` (C++17 mode) in CI
|
||||
* We now provide cmake script that autoregisters Catch tests into ctest.
|
||||
* See `contrib` folder.
|
||||
|
||||
|
||||
# 1.9.1
|
||||
|
||||
### Fixes
|
||||
* Unexpected exceptions are no longer ignored by default (#885, #887)
|
||||
|
||||
|
||||
# 1.9.0
|
||||
|
||||
|
||||
### Improvements and minor changes
|
||||
* Catch no longer attempts to ensure the exception type passed by user in `REQUIRE_THROWS_AS` is a constant reference.
|
||||
* It was causing trouble when `REQUIRE_THROWS_AS` was used inside templated functions
|
||||
* This actually reverts changes made in v1.7.2
|
||||
* Catch's `Version` struct should no longer be double freed when multiple instances of Catch tests are loaded into single program (#858)
|
||||
* It is now a static variable in an inline function instead of being an `extern`ed struct.
|
||||
* Attempt to register invalid tag or tag alias now throws instead of calling `exit()`.
|
||||
* Because this happen before entering main, it still aborts execution
|
||||
* Further improvements to this are coming
|
||||
* `CATCH_CONFIG_FAST_COMPILE` now speeds-up compilation of `REQUIRE*` assertions by further ~15%.
|
||||
* The trade-off is disabling translation of unexpected exceptions into text.
|
||||
* When Catch is compiled using C++11, `Approx` is now constructible with anything that can be explicitly converted to `double`.
|
||||
* Captured messages are now printed on unexpected exceptions
|
||||
|
||||
### Fixes:
|
||||
* Clang's `-Wexit-time-destructors` should be suppressed for Catch's internals
|
||||
* GCC's `-Wparentheses` is now suppressed for all TU's that include `catch.hpp`.
|
||||
* This is functionally a revert of changes made in 1.8.0, where we tried using `_Pragma` based suppression. This should have kept the suppression local to Catch's assertions, but bugs in GCC's handling of `_Pragma`s in C++ mode meant that it did not always work.
|
||||
* You can now tell Catch to use C++11-based check when checking whether a type can be streamed to output.
|
||||
* This fixes cases when an unstreamable type has streamable private base (#877)
|
||||
* [Details can be found in documentation](configuration.md#catch_config_cpp11_stream_insertable_check)
|
||||
|
||||
|
||||
### Other notes:
|
||||
* We have added VS 2017 to our CI
|
||||
* Work on Catch 2 should start soon
|
||||
|
||||
|
||||
|
||||
# 1.8.2
|
||||
|
||||
|
||||
### Improvements and minor changes
|
||||
* TAP reporter now behaves as if `-s` was always set
|
||||
* This should be more consistent with the protocol desired behaviour.
|
||||
* Compact reporter now obeys `-d yes` argument (#780)
|
||||
* The format is "XXX.123 s: <section-name>" (3 decimal places are always present).
|
||||
* Before it did not report the durations at all.
|
||||
* XML reporter now behaves the same way as Console reporter in regards to `INFO`
|
||||
* This means it reports `INFO` messages on success, if output on success (`-s`) is enabled.
|
||||
* Previously it only reported `INFO` messages on failure.
|
||||
* `CAPTURE(expr)` now stringifies `expr` in the same way assertion macros do (#639)
|
||||
* Listeners are now finally [documented](event-listeners.md).
|
||||
* Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion.
|
||||
|
||||
|
||||
### Fixes:
|
||||
* Catch no longer attempts to reconstruct expression that led to a fatal error (#810)
|
||||
* This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition.
|
||||
* Fixed (C4265) missing virtual destructor warning in Matchers (#844)
|
||||
* `std::string`s are now taken by `const&` everywhere (#842).
|
||||
* Previously some places were taking them by-value.
|
||||
* Catch should no longer change errno (#835).
|
||||
* This was caused by libstdc++ bug that we now work around.
|
||||
* Catch now provides `FAIL_CHECK( ... )` macro (#765).
|
||||
* Same as `FAIL( ... )`, but does not abort the test.
|
||||
* Functions like `fabs`, `tolower`, `memset`, `isalnum` are now used with `std::` qualification (#543).
|
||||
* Clara no longer assumes first argument (binary name) is always present (#729)
|
||||
* If it is missing, empty string is used as default.
|
||||
* Clara no longer reads 1 character past argument string (#830)
|
||||
* Regression in Objective-C bindings (Matchers) fixed (#854)
|
||||
|
||||
|
||||
### Other notes:
|
||||
* We have added VS 2013 and 2015 to our CI
|
||||
* Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser).
|
||||
|
||||
|
||||
|
||||
# 1.8.1
|
||||
|
||||
### Fixes
|
||||
|
||||
Cygwin issue with `gettimeofday` - `#define` was not early enough
|
||||
|
||||
# 1.8.0
|
||||
|
||||
### New features/ minor changes
|
||||
|
||||
* Matchers have new, simpler (and documented) interface.
|
||||
* Catch provides string and vector matchers.
|
||||
* For details see [Matchers documentation](matchers.md).
|
||||
* Changed console reporter test duration reporting format (#322)
|
||||
* Old format: `Some simple comparisons between doubles completed in 0.000123s`
|
||||
* New format: `xxx.123s: Some simple comparisons between doubles` _(There will always be exactly 3 decimal places)_
|
||||
* Added opt-in leak detection under MSVC + Windows (#439)
|
||||
* Enable it by compiling Catch's main with `CATCH_CONFIG_WINDOWS_CRTDBG`
|
||||
* Introduced new compile-time flag, `CATCH_CONFIG_FAST_COMPILE`, trading features for compilation speed.
|
||||
* Moves debug breaks out of tests and into implementation, speeding up test compilation time (~10% on linux).
|
||||
* _More changes are coming_
|
||||
* Added [TAP (Test Anything Protocol)](https://testanything.org/) and [Automake](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) reporters.
|
||||
* These are not present in the default single-include header and need to be downloaded from GitHub separately.
|
||||
* For details see [documentation about integrating with build systems](build-systems.md).
|
||||
* XML reporter now reports filename as part of the `Section` and `TestCase` tags.
|
||||
* `Approx` now supports an optional margin of absolute error
|
||||
* It has also received [new documentation](assertions.md).
|
||||
|
||||
### Fixes
|
||||
* Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
|
||||
* Fixed C4512 ("assignment operator could not be generated") warnings under VS2013.
|
||||
* Cygwin compatibility fixes
|
||||
* Signal handling is no longer compiled by default.
|
||||
* Usage of `gettimeofday` inside Catch should no longer cause compilation errors.
|
||||
* Improved `-Wparentheses` supression for gcc (#674)
|
||||
* When compiled with gcc 4.8 or newer, the supression is localized to assertions only
|
||||
* Otherwise it is supressed for the whole TU
|
||||
* Fixed test spec parser issue (with escapes in multiple names)
|
||||
|
||||
### Other
|
||||
* Various documentation fixes and improvements
|
||||
|
||||
|
||||
# 1.7.2
|
||||
|
||||
### Fixes and minor improvements
|
||||
@ -24,16 +197,13 @@ Other:
|
||||
### Fixes:
|
||||
* Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`.
|
||||
* Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC.
|
||||
* For specifics, look into the [documentation](docs/configuration.md).
|
||||
* For specifics, look into the [documentation](configuration.md).
|
||||
* Fixed compilation error under MinGW caused by improper compiler detection.
|
||||
* Fixed XML reporter sometimes leaving an empty output file when a test ends with signal/structured exception.
|
||||
* Fixed XML reporter not reporting captured stdout/stderr.
|
||||
* Fixed possible infinite recursion in Windows SEH.
|
||||
* Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
## 1.7.0
|
||||
|
||||
### Features/ Changes:
|
||||
@ -41,7 +211,7 @@ Release notes were not maintained prior to v1.6.0, but you should be able to wor
|
||||
* Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s.
|
||||
* Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s.
|
||||
* Catch can now run specific sections within test cases.
|
||||
* For now the support is only basic (no wildcards or tags), for details see the [documentation](docs/command-line.md).
|
||||
* For now the support is only basic (no wildcards or tags), for details see the [documentation](command-line.md).
|
||||
* Catch now supports SEH on Windows as well as signals on Linux.
|
||||
* After receiving a signal, Catch reports failing assertion and then passes the signal onto the previous handler.
|
||||
* Approx can be used to compare values against strong typedefs (available in C++11 mode only).
|
||||
@ -78,7 +248,7 @@ Release notes were not maintained prior to v1.6.0, but you should be able to wor
|
||||
* Approval tests can now be run on Windows
|
||||
* CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project
|
||||
* Catch now defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including `windows.h`
|
||||
* This can be disabled if needed, see [documentation](docs/configuration.md) for details.
|
||||
* This can be disabled if needed, see [documentation](configuration.md) for details.
|
||||
|
||||
|
||||
## 1.6.0
|
||||
@ -102,6 +272,9 @@ Release notes were not maintained prior to v1.6.0, but you should be able to wor
|
||||
* Tweaks and changes to scripts - particularly for Approval test - to make them more portable
|
||||
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
||||
|
44
docs/release-process.md
Normal file
44
docs/release-process.md
Normal file
@ -0,0 +1,44 @@
|
||||
# How to release
|
||||
|
||||
When enough changes have accumulated, it is time to release new version of Catch. This document describes the proces in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory.
|
||||
|
||||
|
||||
## Approval testing
|
||||
|
||||
Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py <path/to/SelfTest>`.
|
||||
|
||||
There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes.
|
||||
|
||||
|
||||
## Incrementing version number
|
||||
|
||||
Catch uses a variant of [semantic versioning](http://semver.org/), with breaking API changes (and thus major version increments) being very rare. Thus, the release will usually increment the patch version, when it only contains couple of bugfixes, or minor version, when it contains new functionality, or larger changes in implementation of current functionality.
|
||||
|
||||
After deciding which part of version number should be incremented, you can use one of the `*Release.py` scripts to perform the required changes to Catch.
|
||||
|
||||
|
||||
## Generate updated single-include header
|
||||
|
||||
After updating version number, regenerate single-include header using `generateSingleHeader.py`.
|
||||
|
||||
|
||||
## Release notes
|
||||
|
||||
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`.
|
||||
|
||||
|
||||
## Commit and push update to GitHub
|
||||
|
||||
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub.
|
||||
|
||||
|
||||
## Release on GitHub
|
||||
|
||||
After pushing changes to GitHub, GitHub release *needs* to be created. Tag version and release title should be same as the new version, description should contain the release notes for the current release. Single header version of `catch.hpp` *needs* to be attached as a binary, as that is where the official download link links to. Preferably it should use linux line endings.
|
||||
|
||||
|
||||
## vcpkg update
|
||||
|
||||
As a last step, optionally update Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg) with Catch's new version. `updateVcpkgPackage.py` can do a lot of neccessary work for you, but it assumes that you have your fork of vcpkg checked out in a directory next to the directory, where you have checked out Catch.
|
||||
|
||||
It creates a branch and commits neccessary changes, that you then should review, synchronize and open a PR against.
|
45
docs/reporters.md
Normal file
45
docs/reporters.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Reporters
|
||||
|
||||
Catch has a modular reporting system and comes bundled with a handful of useful reporters built in.
|
||||
You can also write your own reporters.
|
||||
|
||||
## Using different reporters
|
||||
|
||||
The reporter to use can easily be controlled from the command line.
|
||||
To specify a reporter use [`-r` or `--reporter`](command-line.md#choosing-a-reporter-to-use), followed by the name of the reporter, e.g.:
|
||||
|
||||
```
|
||||
-r xml
|
||||
```
|
||||
|
||||
If you don't specify a reporter then the console reporter is used by default.
|
||||
There are four reporters built in to the single include:
|
||||
|
||||
* `console` writes as lines of text, formatted to a typical terminal width, with colours if a capable terminal is detected.
|
||||
* `compact` similar to `console` but optimised for minimal output - each entry on one line
|
||||
* `junit` writes xml that corresponds to Ant's [junitreport](http://help.catchsoftware.com/display/ET/JUnit+Format) target. Useful for build systems that understand Junit. If you are using Jenkins with Catch 1.x, you can improve quality of output by applying changes in [#923](https://github.com/philsquared/Catch/pull/923).
|
||||
Because of the way the junit format is structured the run must complete before anything is written.
|
||||
* `xml` writes an xml format tailored to Catch. Unlike `junit` this is a streaming format so results are delivered progressively.
|
||||
|
||||
There are a few additional reporters, for specific build systems, in the Catch repository (in `include\reporters`) which you can `#include` in your project if you would like to make use of them.
|
||||
Do this in one source file - typically the same one you have `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`.
|
||||
|
||||
* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands.
|
||||
Use this when building as part of a TeamCity build to see results as they happen.
|
||||
* `tap` writes in the TAP ([Test Anything Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol)) format.
|
||||
* `automake` writes in a format that correspond to [automake .trs](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html) files
|
||||
|
||||
You see what reporters are available from the command line by running with `--list-reporters`.
|
||||
|
||||
By default all these reports are written to stdout, but can be redirected to a file with [`-o` or `--out`](command-line.md#sending-output-to-a-file)
|
||||
|
||||
## Writing your own reporter
|
||||
|
||||
You can write your own custom reporter and register it with Catch.
|
||||
At time of writing the interface is subject to some changes so is not, yet, documented here.
|
||||
If you are determined you shouldn't have too much trouble working it out from the existing implementations -
|
||||
but do keep in mind upcoming changes (these will be minor, simplifying, changes such as not needing to forward calls to the base class).
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -56,6 +56,8 @@ tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
|
||||
Failed 1 test case, failed 1 assertion.
|
||||
```
|
||||
|
||||
## Other possible solutions
|
||||
You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles).
|
||||
|
||||
---
|
||||
|
||||
|
@ -28,7 +28,7 @@ The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects
|
||||
|
||||
For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run)
|
||||
|
||||
Tag names are not case sensitive.
|
||||
Tag names are not case sensitive and can contain any ASCII characters. This means that tags `[tag with spaces]` and `[I said "good day"]` are both allowed tags and can be filtered on. Escapes are not supported however and `[\]]` is not a valid tag.
|
||||
|
||||
### Special Tags
|
||||
|
||||
@ -38,10 +38,10 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
|
||||
|
||||
* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
|
||||
|
||||
* `[!shouldfail]` - reverse the failing logic of the test: if the test is successful if it fails, and vice-versa.
|
||||
|
||||
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
|
||||
|
||||
* `[!shouldfail]` - like `[!mayfail]` but *fails* the test if it *passes*. This can be useful if you want to be notified of accidental, or third-party, fixes.
|
||||
|
||||
* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers.
|
||||
|
||||
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
||||
|
@ -16,16 +16,7 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
|
||||
|
||||
(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
|
||||
|
||||
You should put this function in the same namespace as your type.
|
||||
|
||||
Alternatively you may prefer to write it as a member function:
|
||||
|
||||
```
|
||||
std::ostream& T::operator << ( std::ostream& os ) const {
|
||||
os << convertMyTypeToString( *this );
|
||||
return os;
|
||||
}
|
||||
```
|
||||
You should put this function in the same namespace as your type and it has to be declared before including Catch's header.
|
||||
|
||||
## Catch::toString overload
|
||||
|
||||
@ -39,11 +30,12 @@ namespace Catch {
|
||||
}
|
||||
```
|
||||
|
||||
Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace.
|
||||
Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace and must be declared _before_ Catch's header is included.
|
||||
|
||||
**Please note that overloading `Catch::toString` is currently considered legacy and will not be supported in the next major version of Catch.**
|
||||
|
||||
## Catch::StringMaker<T> specialisation
|
||||
|
||||
There are some cases where overloading toString does not work as expected. Specialising StringMaker<T> gives you more precise, and reliable, control - but at the cost of slightly more code and complexity:
|
||||
Another way of telling Catch how to convert a type to string is specialising `Catch::StringMaker` template. This allows you to have separate way of stringifying types for Catch, than you have for writing it to a stream and also doesn't require you to declare it before including Catch's header.
|
||||
|
||||
```
|
||||
namespace Catch {
|
||||
|
@ -68,7 +68,7 @@ with expansion:
|
||||
0 == 1
|
||||
```
|
||||
|
||||
Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That let's us immediately see what the problem is.
|
||||
Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That lets us immediately see what the problem is.
|
||||
|
||||
Let's change the factorial function to:
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
#include "internal/catch_generators.hpp"
|
||||
#include "internal/catch_interfaces_exception.h"
|
||||
#include "internal/catch_approx.hpp"
|
||||
#include "internal/catch_matchers.hpp"
|
||||
#include "internal/catch_matchers_string.h"
|
||||
#include "internal/catch_matchers_vector.h"
|
||||
#include "internal/catch_compiler_capabilities.h"
|
||||
#include "internal/catch_interfaces_tag_alias_registry.h"
|
||||
|
||||
@ -50,6 +51,29 @@
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
|
||||
// !TBD: Move the leak detector code into a separate header
|
||||
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
|
||||
#include <crtdbg.h>
|
||||
class LeakDetector {
|
||||
public:
|
||||
LeakDetector() {
|
||||
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
||||
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||
flag |= _CRTDBG_ALLOC_MEM_DF;
|
||||
_CrtSetDbgFlag(flag);
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
|
||||
// Change this to leaking allocation's number to break there
|
||||
_CrtSetBreakAlloc(-1);
|
||||
}
|
||||
};
|
||||
#else
|
||||
class LeakDetector {};
|
||||
#endif
|
||||
|
||||
LeakDetector leakDetector;
|
||||
|
||||
#include "internal/catch_impl.hpp"
|
||||
#endif
|
||||
|
||||
@ -67,33 +91,44 @@
|
||||
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
|
||||
#ifdef CATCH_CONFIG_PREFIX_ALL
|
||||
|
||||
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
|
||||
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
|
||||
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
|
||||
#else
|
||||
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
|
||||
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
|
||||
#endif
|
||||
|
||||
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
|
||||
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
|
||||
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
|
||||
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
|
||||
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
|
||||
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
|
||||
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
|
||||
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
|
||||
|
||||
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
|
||||
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
|
||||
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
|
||||
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
|
||||
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
|
||||
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
|
||||
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
|
||||
|
||||
#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" )
|
||||
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
|
||||
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
|
||||
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
|
||||
#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
|
||||
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
|
||||
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
|
||||
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
|
||||
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
|
||||
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
|
||||
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
|
||||
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
|
||||
#else
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
|
||||
#endif
|
||||
|
||||
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
|
||||
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
|
||||
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
|
||||
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
@ -101,16 +136,18 @@
|
||||
#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_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
|
||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __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_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#else
|
||||
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
#define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
|
||||
#define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
|
||||
#define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
|
||||
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
|
||||
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
|
||||
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
|
||||
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
|
||||
#define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#endif
|
||||
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
|
||||
|
||||
@ -136,50 +173,64 @@
|
||||
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
|
||||
#else
|
||||
|
||||
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
|
||||
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
|
||||
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
|
||||
|
||||
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
|
||||
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
|
||||
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
|
||||
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
|
||||
#else
|
||||
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr )
|
||||
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
|
||||
#endif
|
||||
|
||||
#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
|
||||
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
|
||||
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
|
||||
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
|
||||
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
|
||||
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
|
||||
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
|
||||
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
|
||||
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
|
||||
|
||||
#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
|
||||
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
|
||||
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
|
||||
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
|
||||
#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
|
||||
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
|
||||
|
||||
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
|
||||
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
|
||||
#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
|
||||
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
|
||||
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
|
||||
|
||||
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
|
||||
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
|
||||
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
|
||||
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
|
||||
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
|
||||
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
|
||||
#else
|
||||
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
|
||||
#endif
|
||||
|
||||
|
||||
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
|
||||
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
|
||||
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
|
||||
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __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 SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
|
||||
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __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 SECTION( ... ) INTERNAL_CATCH_SECTION( __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 SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#else
|
||||
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
|
||||
#define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
|
||||
#define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
|
||||
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
|
||||
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
|
||||
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
|
||||
#define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
|
||||
#define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||
#endif
|
||||
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
|
||||
|
||||
|
@ -125,7 +125,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void showHelp( std::string const& processName ) {
|
||||
Catch::cout() << "\nCatch v" << libraryVersion << "\n";
|
||||
Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
|
||||
|
||||
m_cli.usage( Catch::cout(), processName );
|
||||
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
|
||||
@ -166,6 +166,32 @@ namespace Catch {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
int run( int argc, wchar_t const* const* const argv ) {
|
||||
|
||||
char **utf8Argv = new char *[ argc ];
|
||||
|
||||
for ( int i = 0; i < argc; ++i ) {
|
||||
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
|
||||
|
||||
utf8Argv[ i ] = new char[ bufSize ];
|
||||
|
||||
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
|
||||
}
|
||||
|
||||
int returnCode = applyCommandLine( argc, utf8Argv );
|
||||
if( returnCode == 0 )
|
||||
returnCode = run();
|
||||
|
||||
for ( int i = 0; i < argc; ++i )
|
||||
delete [] utf8Argv[ i ];
|
||||
|
||||
delete [] utf8Argv;
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
#endif
|
||||
|
||||
int run() {
|
||||
if( m_configData.showHelp )
|
||||
return 0;
|
||||
|
9
include/external/clara.h
vendored
9
include/external/clara.h
vendored
@ -41,6 +41,7 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
// Use optional outer namespace
|
||||
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
|
||||
@ -397,7 +398,7 @@ namespace Clara {
|
||||
_dest = _source;
|
||||
}
|
||||
char toLowerCh(char c) {
|
||||
return static_cast<char>( ::tolower( c ) );
|
||||
return static_cast<char>( std::tolower( c ) );
|
||||
}
|
||||
inline void convertInto( std::string const& _source, bool& _dest ) {
|
||||
std::string sourceLC = _source;
|
||||
@ -553,12 +554,13 @@ namespace Clara {
|
||||
}
|
||||
|
||||
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
|
||||
for( std::size_t i = 0; i <= arg.size(); ++i ) {
|
||||
for( std::size_t i = 0; i < arg.size(); ++i ) {
|
||||
char c = arg[i];
|
||||
if( c == '"' )
|
||||
inQuotes = !inQuotes;
|
||||
mode = handleMode( i, c, arg, tokens );
|
||||
}
|
||||
mode = handleMode( arg.size(), '\0', arg, tokens );
|
||||
}
|
||||
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||
switch( mode ) {
|
||||
@ -591,6 +593,7 @@ namespace Clara {
|
||||
default: from = i; return ShortOpt;
|
||||
}
|
||||
}
|
||||
|
||||
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||
if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
|
||||
return mode;
|
||||
@ -924,7 +927,7 @@ namespace Clara {
|
||||
}
|
||||
|
||||
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
|
||||
std::string processName = args[0];
|
||||
std::string processName = args.empty() ? std::string() : args[0];
|
||||
std::size_t lastSlash = processName.find_last_of( "/\\" );
|
||||
if( lastSlash != std::string::npos )
|
||||
processName = processName.substr( lastSlash+1 );
|
||||
|
@ -24,12 +24,14 @@ namespace Detail {
|
||||
public:
|
||||
explicit Approx ( double value )
|
||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
||||
m_margin( 0.0 ),
|
||||
m_scale( 1.0 ),
|
||||
m_value( value )
|
||||
{}
|
||||
|
||||
Approx( Approx const& other )
|
||||
: m_epsilon( other.m_epsilon ),
|
||||
m_margin( other.m_margin ),
|
||||
m_scale( other.m_scale ),
|
||||
m_value( other.m_value )
|
||||
{}
|
||||
@ -38,19 +40,31 @@ namespace Detail {
|
||||
return Approx( 0 );
|
||||
}
|
||||
|
||||
Approx operator()( double value ) {
|
||||
Approx approx( value );
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx operator()( T value ) {
|
||||
Approx approx( static_cast<double>(value) );
|
||||
approx.epsilon( m_epsilon );
|
||||
approx.margin( m_margin );
|
||||
approx.scale( m_scale );
|
||||
return approx;
|
||||
}
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
explicit Approx( T value ): Approx(static_cast<double>(value))
|
||||
{}
|
||||
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
auto lhs_v = double(lhs);
|
||||
return std::fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs_v), std::fabs(rhs.m_value) ) );
|
||||
bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
|
||||
if (relativeOK) {
|
||||
return true;
|
||||
}
|
||||
return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
@ -69,32 +83,61 @@ namespace Detail {
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
friend bool operator <= ( T lhs, Approx const& rhs )
|
||||
{
|
||||
return double(lhs) < rhs.m_value || lhs == rhs;
|
||||
friend bool operator <= ( T lhs, Approx const& rhs ) {
|
||||
return double(lhs) < rhs.m_value || lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
friend bool operator <= ( Approx const& lhs, T rhs )
|
||||
{
|
||||
return lhs.m_value < double(rhs) || lhs == rhs;
|
||||
friend bool operator <= ( Approx const& lhs, T rhs ) {
|
||||
return lhs.m_value < double(rhs) || lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
friend bool operator >= ( T lhs, Approx const& rhs )
|
||||
{
|
||||
return double(lhs) > rhs.m_value || lhs == rhs;
|
||||
friend bool operator >= ( T lhs, Approx const& rhs ) {
|
||||
return double(lhs) > rhs.m_value || lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
friend bool operator >= ( Approx const& lhs, T rhs )
|
||||
{
|
||||
return lhs.m_value > double(rhs) || lhs == rhs;
|
||||
friend bool operator >= ( Approx const& lhs, T rhs ) {
|
||||
return lhs.m_value > double(rhs) || lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx& epsilon( T newEpsilon ) {
|
||||
m_epsilon = double(newEpsilon);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx& margin( T newMargin ) {
|
||||
m_margin = double(newMargin);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
Approx& scale( T newScale ) {
|
||||
m_scale = double(newScale);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Approx operator()( double value ) {
|
||||
Approx approx( value );
|
||||
approx.epsilon( m_epsilon );
|
||||
approx.margin( m_margin );
|
||||
approx.scale( m_scale );
|
||||
return approx;
|
||||
}
|
||||
|
||||
|
||||
friend bool operator == ( double lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
return std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
if (relativeOK) {
|
||||
return true;
|
||||
}
|
||||
return std::fabs(lhs - rhs.m_value) < rhs.m_margin;
|
||||
}
|
||||
|
||||
friend bool operator == ( Approx const& lhs, double rhs ) {
|
||||
@ -109,36 +152,37 @@ namespace Detail {
|
||||
return !operator==( rhs, lhs );
|
||||
}
|
||||
|
||||
friend bool operator <= ( double lhs, Approx const& rhs )
|
||||
{
|
||||
return lhs < rhs.m_value || lhs == rhs;
|
||||
friend bool operator <= ( double lhs, Approx const& rhs ) {
|
||||
return lhs < rhs.m_value || lhs == rhs;
|
||||
}
|
||||
|
||||
friend bool operator <= ( Approx const& lhs, double rhs )
|
||||
{
|
||||
return lhs.m_value < rhs || lhs == rhs;
|
||||
friend bool operator <= ( Approx const& lhs, double rhs ) {
|
||||
return lhs.m_value < rhs || lhs == rhs;
|
||||
}
|
||||
|
||||
friend bool operator >= ( double lhs, Approx const& rhs )
|
||||
{
|
||||
return lhs > rhs.m_value || lhs == rhs;
|
||||
friend bool operator >= ( double lhs, Approx const& rhs ) {
|
||||
return lhs > rhs.m_value || lhs == rhs;
|
||||
}
|
||||
|
||||
friend bool operator >= ( Approx const& lhs, double rhs )
|
||||
{
|
||||
return lhs.m_value > rhs || lhs == rhs;
|
||||
friend bool operator >= ( Approx const& lhs, double rhs ) {
|
||||
return lhs.m_value > rhs || lhs == rhs;
|
||||
}
|
||||
#endif
|
||||
|
||||
Approx& epsilon( double newEpsilon ) {
|
||||
m_epsilon = newEpsilon;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Approx& margin( double newMargin ) {
|
||||
m_margin = newMargin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Approx& scale( double newScale ) {
|
||||
m_scale = newScale;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
@ -148,6 +192,7 @@ namespace Detail {
|
||||
|
||||
private:
|
||||
double m_epsilon;
|
||||
double m_margin;
|
||||
double m_scale;
|
||||
double m_value;
|
||||
};
|
||||
|
@ -32,6 +32,9 @@ namespace Catch {
|
||||
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
|
||||
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
|
||||
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
|
||||
|
||||
private:
|
||||
DecomposedExpression& operator = (DecomposedExpression const&);
|
||||
};
|
||||
|
||||
struct AssertionInfo
|
||||
|
@ -16,9 +16,43 @@
|
||||
#include "catch_tostring.h"
|
||||
#include "catch_interfaces_runner.h"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_type_traits.hpp"
|
||||
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// We can speedup compilation significantly by breaking into debugger lower in
|
||||
// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
|
||||
// macro in each assertion
|
||||
#define INTERNAL_CATCH_REACT( resultBuilder ) \
|
||||
resultBuilder.react();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
|
||||
// macros.
|
||||
// This can potentially cause false negative, if the test code catches
|
||||
// the exception before it propagates back up to the runner.
|
||||
#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
__catchResult.setExceptionGuard(); \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
( __catchResult <= expr ).endExpression(); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
__catchResult.unsetExceptionGuard(); \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
|
||||
|
||||
#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
||||
__catchResult.setExceptionGuard(); \
|
||||
__catchResult.captureMatch( arg, matcher, #matcher ); \
|
||||
__catchResult.unsetExceptionGuard(); \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::alwaysFalse() )
|
||||
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// In the event of a failure works out if the debugger needs to be invoked
|
||||
// and/or an exception thrown and takes appropriate action.
|
||||
@ -27,15 +61,17 @@
|
||||
#define INTERNAL_CATCH_REACT( resultBuilder ) \
|
||||
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
|
||||
resultBuilder.react();
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
|
||||
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
try { \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
( __catchResult <= expr ).endExpression(); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
__catchResult.useActiveException( resultDisposition ); \
|
||||
@ -45,17 +81,17 @@
|
||||
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
||||
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
|
||||
#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
|
||||
INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
|
||||
if( Catch::getResultCapture().getLastResult()->succeeded() )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
|
||||
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
|
||||
#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
|
||||
INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
|
||||
if( !Catch::getResultCapture().getLastResult()->succeeded() )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
|
||||
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
try { \
|
||||
@ -69,7 +105,7 @@
|
||||
} while( Catch::alwaysFalse() )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
|
||||
#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
|
||||
if( __catchResult.allowThrows() ) \
|
||||
@ -86,7 +122,7 @@
|
||||
} while( Catch::alwaysFalse() )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
|
||||
#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
|
||||
if( __catchResult.allowThrows() ) \
|
||||
@ -94,7 +130,7 @@
|
||||
static_cast<void>(expr); \
|
||||
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
||||
} \
|
||||
catch( Catch::add_const<Catch::add_lvalue_reference<exceptionType>::type>::type ) { \
|
||||
catch( exceptionType ) { \
|
||||
__catchResult.captureResult( Catch::ResultWas::Ok ); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
@ -108,7 +144,7 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
|
||||
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
|
||||
__catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
|
||||
@ -116,7 +152,7 @@
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::alwaysFalse() )
|
||||
#else
|
||||
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
|
||||
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
|
||||
__catchResult << log + ::Catch::StreamEndStop(); \
|
||||
@ -126,11 +162,11 @@
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_INFO( log, macroName ) \
|
||||
#define INTERNAL_CATCH_INFO( macroName, log ) \
|
||||
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
|
||||
#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
||||
try { \
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "catch_compiler_capabilities.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct IConfig;
|
||||
|
@ -27,6 +27,7 @@
|
||||
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
|
||||
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
|
||||
// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
|
||||
// ****************
|
||||
// Note to maintainers: if new toggles are added please document them
|
||||
// in configuration.md, too
|
||||
@ -62,11 +63,43 @@
|
||||
# endif
|
||||
|
||||
# if defined(CATCH_CPP11_OR_GREATER)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
|
||||
# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
_Pragma( "clang diagnostic push" ) \
|
||||
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||
_Pragma( "clang diagnostic pop" )
|
||||
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "clang diagnostic push" ) \
|
||||
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "clang diagnostic pop" )
|
||||
# endif
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// We know some environments not to support full POSIX signals
|
||||
#if defined(__CYGWIN__) || defined(__QNX__)
|
||||
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cygwin
|
||||
#ifdef __CYGWIN__
|
||||
|
||||
// Required for some versions of Cygwin to declare gettimeofday
|
||||
// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
|
||||
# define _BSD_SOURCE
|
||||
|
||||
#endif // __CYGWIN__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Borland
|
||||
#ifdef __BORLANDC__
|
||||
@ -96,9 +129,6 @@
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||
# endif
|
||||
|
||||
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
|
||||
# endif
|
||||
|
||||
// - otherwise more recent versions define __cplusplus >= 201103L
|
||||
// and will get picked up below
|
||||
@ -140,7 +170,7 @@
|
||||
|
||||
// Use __COUNTER__ if the compiler supports it
|
||||
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
|
||||
( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
|
||||
( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
|
||||
( defined __clang__ && __clang_major__ >= 3 )
|
||||
|
||||
#define CATCH_INTERNAL_CONFIG_COUNTER
|
||||
@ -239,9 +269,18 @@
|
||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||
# define CATCH_CONFIG_WINDOWS_SEH
|
||||
#endif
|
||||
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
|
||||
#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
# define CATCH_CONFIG_POSIX_SIGNALS
|
||||
#endif
|
||||
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
||||
#endif
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
#endif
|
||||
|
||||
// noexcept support:
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
|
||||
|
||||
#include "catch_console_colour.hpp"
|
||||
#include "catch_errno_guard.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
@ -148,6 +149,7 @@ namespace {
|
||||
};
|
||||
|
||||
IColourImpl* platformColourInstance() {
|
||||
ErrnoGuard guard;
|
||||
Ptr<IConfig const> config = getCurrentContext().getConfig();
|
||||
UseColour::YesOrNo colourMode = config
|
||||
? config->useColour()
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
|
||||
#include "catch_debugger.h"
|
||||
#include "catch_errno_guard.hpp"
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
@ -72,6 +73,9 @@
|
||||
// be strace, for example) in /proc/$PID/status, so just get it from
|
||||
// there instead.
|
||||
bool isDebuggerActive(){
|
||||
// Libstdc++ has a bug, where std::ifstream sets errno to 0
|
||||
// This way our users can properly assert over errno values
|
||||
ErrnoGuard guard;
|
||||
std::ifstream in("/proc/self/status");
|
||||
for( std::string line; std::getline(in, line); ) {
|
||||
static const int PREFIX_LEN = 11;
|
||||
|
@ -10,8 +10,14 @@
|
||||
|
||||
#ifndef __OBJC__
|
||||
|
||||
#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
|
||||
// Standard C/C++ Win32 Unicode wmain entry point
|
||||
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
|
||||
#else
|
||||
// Standard C/C++ main entry point
|
||||
int main (int argc, char * argv[]) {
|
||||
#endif
|
||||
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
return ( result < 0xff ? result : 0xff );
|
||||
}
|
||||
|
25
include/internal/catch_errno_guard.hpp
Normal file
25
include/internal/catch_errno_guard.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Created by Martin on 06/03/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_ERRNO_GUARD_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class ErrnoGuard {
|
||||
public:
|
||||
ErrnoGuard():m_oldErrno(errno){}
|
||||
~ErrnoGuard() { errno = m_oldErrno; }
|
||||
private:
|
||||
int m_oldErrno;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
|
@ -11,6 +11,7 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
|
||||
#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
@ -27,6 +27,8 @@ class ExpressionLhs : public DecomposedExpression {
|
||||
public:
|
||||
ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
|
||||
|
||||
ExpressionLhs& operator = ( const ExpressionLhs& );
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
|
||||
operator == ( RhsT const& rhs ) {
|
||||
@ -79,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
|
||||
dest = Catch::toString( m_truthy );
|
||||
dest = Catch::toString( m_lhs );
|
||||
}
|
||||
|
||||
private:
|
||||
@ -105,6 +107,8 @@ public:
|
||||
BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
|
||||
: m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
|
||||
|
||||
BinaryExpression& operator = ( BinaryExpression& );
|
||||
|
||||
void endExpression() const {
|
||||
m_rb
|
||||
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
|
||||
|
@ -28,7 +28,7 @@ namespace Catch {
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
|
||||
@ -53,7 +53,6 @@ namespace Catch {
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reset();
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
@ -103,6 +102,17 @@ namespace Catch {
|
||||
|
||||
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
||||
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
# else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace Catch {
|
||||
@ -183,6 +193,8 @@ namespace Catch {
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#endif // not Windows
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "catch_context.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
@ -124,7 +123,7 @@ public:
|
||||
private:
|
||||
|
||||
void move( CompositeGenerator& other ) {
|
||||
std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
|
||||
m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
|
||||
m_totalSize += other.m_totalSize;
|
||||
other.m_composed.clear();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "catch_result_builder.hpp"
|
||||
#include "catch_tag_alias_registry.hpp"
|
||||
#include "catch_test_case_tracker.hpp"
|
||||
#include "catch_matchers_string.hpp"
|
||||
|
||||
#include "../reporters/catch_reporter_multi.hpp"
|
||||
#include "../reporters/catch_reporter_xml.hpp"
|
||||
@ -90,11 +91,7 @@ namespace Catch {
|
||||
TestSpec::NamePattern::~NamePattern() {}
|
||||
TestSpec::TagPattern::~TagPattern() {}
|
||||
TestSpec::ExcludedPattern::~ExcludedPattern() {}
|
||||
|
||||
Matchers::Impl::StdString::Equals::~Equals() {}
|
||||
Matchers::Impl::StdString::Contains::~Contains() {}
|
||||
Matchers::Impl::StdString::StartsWith::~StartsWith() {}
|
||||
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||
Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
|
||||
|
||||
void Config::dummy() {}
|
||||
|
||||
|
@ -38,6 +38,8 @@ namespace Catch {
|
||||
virtual std::string getCurrentTestName() const = 0;
|
||||
virtual const AssertionResult* getLastResult() const = 0;
|
||||
|
||||
virtual void exceptionEarlyReported() = 0;
|
||||
|
||||
virtual void handleFatalErrorCondition( std::string const& message ) = 0;
|
||||
};
|
||||
|
||||
|
@ -20,12 +20,15 @@ namespace Catch {
|
||||
struct IExceptionTranslator;
|
||||
struct IReporterRegistry;
|
||||
struct IReporterFactory;
|
||||
struct ITagAliasRegistry;
|
||||
|
||||
struct IRegistryHub {
|
||||
virtual ~IRegistryHub();
|
||||
|
||||
virtual IReporterRegistry const& getReporterRegistry() const = 0;
|
||||
virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
|
||||
virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
|
||||
|
||||
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
|
||||
};
|
||||
|
||||
@ -35,6 +38,7 @@ namespace Catch {
|
||||
virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
|
||||
virtual void registerTest( TestCase const& testInfo ) = 0;
|
||||
virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
|
||||
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
|
||||
};
|
||||
|
||||
IRegistryHub& getRegistryHub();
|
||||
|
@ -8,318 +8,169 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
namespace Generic {
|
||||
template<typename ExpressionT> class AllOf;
|
||||
template<typename ExpressionT> class AnyOf;
|
||||
template<typename ExpressionT> class Not;
|
||||
}
|
||||
template<typename ArgT> struct MatchAllOf;
|
||||
template<typename ArgT> struct MatchAnyOf;
|
||||
template<typename ArgT> struct MatchNotOf;
|
||||
|
||||
template<typename ExpressionT>
|
||||
struct Matcher : SharedImpl<IShared>
|
||||
{
|
||||
typedef ExpressionT ExpressionType;
|
||||
|
||||
virtual ~Matcher() {}
|
||||
virtual Ptr<Matcher> clone() const = 0;
|
||||
virtual bool match( ExpressionT const& expr ) const = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
|
||||
Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
|
||||
Generic::Not<ExpressionT> operator ! () const;
|
||||
};
|
||||
|
||||
template<typename DerivedT, typename ExpressionT>
|
||||
struct MatcherImpl : Matcher<ExpressionT> {
|
||||
|
||||
virtual Ptr<Matcher<ExpressionT> > clone() const {
|
||||
return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
|
||||
}
|
||||
};
|
||||
|
||||
namespace Generic {
|
||||
template<typename ExpressionT>
|
||||
class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
|
||||
class MatcherUntypedBase {
|
||||
public:
|
||||
explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
|
||||
Not( Not const& other ) : m_matcher( other.m_matcher ) {}
|
||||
|
||||
virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
|
||||
return !m_matcher->match( expr );
|
||||
std::string toString() const {
|
||||
if( m_cachedToString.empty() )
|
||||
m_cachedToString = describe();
|
||||
return m_cachedToString;
|
||||
}
|
||||
|
||||
virtual std::string toString() const CATCH_OVERRIDE {
|
||||
return "not " + m_matcher->toString();
|
||||
}
|
||||
protected:
|
||||
virtual ~MatcherUntypedBase();
|
||||
virtual std::string describe() const = 0;
|
||||
mutable std::string m_cachedToString;
|
||||
private:
|
||||
Ptr< Matcher<ExpressionT> > m_matcher;
|
||||
MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
|
||||
};
|
||||
|
||||
template<typename ExpressionT>
|
||||
class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
|
||||
public:
|
||||
template<typename ObjectT>
|
||||
struct MatcherMethod {
|
||||
virtual bool match( ObjectT const& arg ) const = 0;
|
||||
};
|
||||
template<typename PtrT>
|
||||
struct MatcherMethod<PtrT*> {
|
||||
virtual bool match( PtrT* arg ) const = 0;
|
||||
};
|
||||
|
||||
AllOf() {}
|
||||
AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
|
||||
template<typename ObjectT, typename ComparatorT = ObjectT>
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
|
||||
|
||||
AllOf& add( Matcher<ExpressionT> const& matcher ) {
|
||||
m_matchers.push_back( matcher.clone() );
|
||||
return *this;
|
||||
}
|
||||
virtual bool match( ExpressionT const& expr ) const
|
||||
{
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i )
|
||||
if( !m_matchers[i]->match( expr ) )
|
||||
|
||||
MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
|
||||
MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
|
||||
MatchNotOf<ComparatorT> operator ! () const;
|
||||
};
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchAllOf : MatcherBase<ArgT> {
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if (!m_matchers[i]->match(arg))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "( ";
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
std::string description;
|
||||
description.reserve( 4 + m_matchers.size()*32 );
|
||||
description += "( ";
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if( i != 0 )
|
||||
oss << " and ";
|
||||
oss << m_matchers[i]->toString();
|
||||
description += " and ";
|
||||
description += m_matchers[i]->toString();
|
||||
}
|
||||
oss << " )";
|
||||
return oss.str();
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
|
||||
AllOf operator && ( Matcher<ExpressionT> const& other ) const {
|
||||
AllOf allOfExpr( *this );
|
||||
allOfExpr.add( other );
|
||||
return allOfExpr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||
};
|
||||
|
||||
template<typename ExpressionT>
|
||||
class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
|
||||
public:
|
||||
|
||||
AnyOf() {}
|
||||
AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
|
||||
|
||||
AnyOf& add( Matcher<ExpressionT> const& matcher ) {
|
||||
m_matchers.push_back( matcher.clone() );
|
||||
MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
}
|
||||
virtual bool match( ExpressionT const& expr ) const
|
||||
{
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i )
|
||||
if( m_matchers[i]->match( expr ) )
|
||||
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
template<typename ArgT>
|
||||
struct MatchAnyOf : MatcherBase<ArgT> {
|
||||
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if (m_matchers[i]->match(arg))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "( ";
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
std::string description;
|
||||
description.reserve( 4 + m_matchers.size()*32 );
|
||||
description += "( ";
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if( i != 0 )
|
||||
oss << " or ";
|
||||
oss << m_matchers[i]->toString();
|
||||
description += " or ";
|
||||
description += m_matchers[i]->toString();
|
||||
}
|
||||
oss << " )";
|
||||
return oss.str();
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
|
||||
AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
|
||||
AnyOf anyOfExpr( *this );
|
||||
anyOfExpr.add( other );
|
||||
return anyOfExpr;
|
||||
MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
|
||||
} // namespace Generic
|
||||
template<typename ArgT>
|
||||
struct MatchNotOf : MatcherBase<ArgT> {
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
|
||||
Generic::AllOf<ExpressionT> allOfExpr;
|
||||
allOfExpr.add( *this );
|
||||
allOfExpr.add( other );
|
||||
return allOfExpr;
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
|
||||
Generic::AnyOf<ExpressionT> anyOfExpr;
|
||||
anyOfExpr.add( *this );
|
||||
anyOfExpr.add( other );
|
||||
return anyOfExpr;
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
|
||||
return Generic::Not<ExpressionT>( *this );
|
||||
}
|
||||
|
||||
|
||||
namespace StdString {
|
||||
|
||||
inline std::string makeString( std::string const& str ) { return str; }
|
||||
inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
|
||||
|
||||
struct CasedString
|
||||
{
|
||||
CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
|
||||
: m_caseSensitivity( caseSensitivity ),
|
||||
m_str( adjustString( str ) )
|
||||
{}
|
||||
std::string adjustString( std::string const& str ) const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? toLower( str )
|
||||
: str;
|
||||
MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
|
||||
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
return !m_underlyingMatcher.match( arg );
|
||||
}
|
||||
std::string toStringSuffix() const
|
||||
{
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? " (case insensitive)"
|
||||
: std::string();
|
||||
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "not " + m_underlyingMatcher.toString();
|
||||
}
|
||||
CaseSensitive::Choice m_caseSensitivity;
|
||||
std::string m_str;
|
||||
MatcherBase<ArgT> const& m_underlyingMatcher;
|
||||
};
|
||||
|
||||
struct Equals : MatcherImpl<Equals, std::string> {
|
||||
Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( str, caseSensitivity )
|
||||
{}
|
||||
Equals( Equals const& other ) : m_data( other.m_data ){}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
|
||||
return MatchAllOf<ComparatorT>() && *this && other;
|
||||
}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
|
||||
return MatchAnyOf<ComparatorT>() || *this || other;
|
||||
}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
|
||||
return MatchNotOf<ComparatorT>( *this );
|
||||
}
|
||||
|
||||
virtual ~Equals();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return m_data.m_str == m_data.adjustString( expr );;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "equals: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct Contains : MatcherImpl<Contains, std::string> {
|
||||
Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
Contains( Contains const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~Contains();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "contains: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct StartsWith : MatcherImpl<StartsWith, std::string> {
|
||||
StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
|
||||
StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~StartsWith();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return startsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "starts with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct EndsWith : MatcherImpl<EndsWith, std::string> {
|
||||
EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~EndsWith();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return endsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "ends with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
} // namespace StdString
|
||||
} // namespace Impl
|
||||
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
|
||||
return Impl::Generic::Not<ExpressionT>( m );
|
||||
// - deprecated: prefer ||, && and !
|
||||
template<typename T>
|
||||
inline Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
|
||||
return Impl::MatchNotOf<T>( underlyingMatcher );
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2 ) {
|
||||
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
|
||||
return Impl::MatchAllOf<T>() && m1 && m2;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2,
|
||||
Impl::Matcher<ExpressionT> const& m3 ) {
|
||||
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
|
||||
return Impl::MatchAllOf<T>() && m1 && m2 && m3;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2 ) {
|
||||
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
|
||||
return Impl::MatchAnyOf<T>() || m1 || m2;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2,
|
||||
Impl::Matcher<ExpressionT> const& m3 ) {
|
||||
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
|
||||
}
|
||||
|
||||
inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Equals( str, caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Contains( substr, caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
|
||||
return Impl::StdString::StartsWith( substr );
|
||||
}
|
||||
inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
|
||||
return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
|
||||
}
|
||||
inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
|
||||
return Impl::StdString::EndsWith( substr );
|
||||
}
|
||||
inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
|
||||
return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
|
||||
template<typename T>
|
||||
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
|
||||
return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
|
67
include/internal/catch_matchers_string.h
Normal file
67
include/internal/catch_matchers_string.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Created by Phil Nash on 08/02/2017.
|
||||
* Copyright (c) 2017 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)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace StdString {
|
||||
|
||||
struct CasedString
|
||||
{
|
||||
CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
|
||||
std::string adjustString( std::string const& str ) const;
|
||||
std::string caseSensitivitySuffix() const;
|
||||
|
||||
CaseSensitive::Choice m_caseSensitivity;
|
||||
std::string m_str;
|
||||
};
|
||||
|
||||
struct StringMatcherBase : MatcherBase<std::string> {
|
||||
StringMatcherBase( std::string const& operation, CasedString const& comparator );
|
||||
virtual std::string describe() const CATCH_OVERRIDE;
|
||||
|
||||
CasedString m_comparator;
|
||||
std::string m_operation;
|
||||
};
|
||||
|
||||
struct EqualsMatcher : StringMatcherBase {
|
||||
EqualsMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct ContainsMatcher : StringMatcherBase {
|
||||
ContainsMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct StartsWithMatcher : StringMatcherBase {
|
||||
StartsWithMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct EndsWithMatcher : StringMatcherBase {
|
||||
EndsWithMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
|
||||
StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
93
include/internal/catch_matchers_string.hpp
Normal file
93
include/internal/catch_matchers_string.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Created by Phil Nash on 08/02/2017.
|
||||
* Copyright (c) 2017 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_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace StdString {
|
||||
|
||||
CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
|
||||
: m_caseSensitivity( caseSensitivity ),
|
||||
m_str( adjustString( str ) )
|
||||
{}
|
||||
std::string CasedString::adjustString( std::string const& str ) const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? toLower( str )
|
||||
: str;
|
||||
}
|
||||
std::string CasedString::caseSensitivitySuffix() const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? " (case insensitive)"
|
||||
: std::string();
|
||||
}
|
||||
|
||||
|
||||
StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
|
||||
: m_comparator( comparator ),
|
||||
m_operation( operation ) {
|
||||
}
|
||||
|
||||
std::string StringMatcherBase::describe() const {
|
||||
std::string description;
|
||||
description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
|
||||
m_comparator.caseSensitivitySuffix().size());
|
||||
description += m_operation;
|
||||
description += ": \"";
|
||||
description += m_comparator.m_str;
|
||||
description += "\"";
|
||||
description += m_comparator.caseSensitivitySuffix();
|
||||
return description;
|
||||
}
|
||||
|
||||
EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
|
||||
|
||||
bool EqualsMatcher::match( std::string const& source ) const {
|
||||
return m_comparator.adjustString( source ) == m_comparator.m_str;
|
||||
}
|
||||
|
||||
|
||||
ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
|
||||
|
||||
bool ContainsMatcher::match( std::string const& source ) const {
|
||||
return contains( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
|
||||
StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
|
||||
|
||||
bool StartsWithMatcher::match( std::string const& source ) const {
|
||||
return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
|
||||
EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
|
||||
|
||||
bool EndsWithMatcher::match( std::string const& source ) const {
|
||||
return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
101
include/internal/catch_matchers_vector.h
Normal file
101
include/internal/catch_matchers_vector.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Created by Phil Nash on 21/02/2017.
|
||||
* Copyright (c) 2017 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)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace Vector {
|
||||
|
||||
template<typename T>
|
||||
struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
|
||||
|
||||
ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
return std::find(v.begin(), v.end(), m_comparator) != v.end();
|
||||
}
|
||||
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Contains: " + Catch::toString( m_comparator );
|
||||
}
|
||||
|
||||
T const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
|
||||
|
||||
ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
// !TBD: see note in EqualsMatcher
|
||||
if (m_comparator.size() > v.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < m_comparator.size(); ++i)
|
||||
if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Contains: " + Catch::toString( m_comparator );
|
||||
}
|
||||
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
|
||||
|
||||
EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
// !TBD: This currently works if all elements can be compared using !=
|
||||
// - a more general approach would be via a compare template that defaults
|
||||
// to using !=. but could be specialised for, e.g. std::vector<T> etc
|
||||
// - then just call that directly
|
||||
if (m_comparator.size() != v.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < v.size(); ++i)
|
||||
if (m_comparator[i] != v[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Equals: " + Catch::toString( m_comparator );
|
||||
}
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
} // namespace Vector
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
|
||||
template<typename T>
|
||||
Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
|
||||
return Vector::ContainsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
|
||||
return Vector::ContainsElementMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
|
||||
return Vector::EqualsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
@ -38,7 +38,9 @@ namespace Catch {
|
||||
{}
|
||||
|
||||
ScopedMessage::~ScopedMessage() {
|
||||
getResultCapture().popScopedMessage( m_info );
|
||||
if ( !std::uncaught_exception() ){
|
||||
getResultCapture().popScopedMessage(m_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,64 +105,67 @@ namespace Catch {
|
||||
namespace Impl {
|
||||
namespace NSStringMatchers {
|
||||
|
||||
template<typename MatcherT>
|
||||
struct StringHolder : MatcherImpl<MatcherT, NSString*>{
|
||||
struct StringHolder : MatcherBase<NSString*>{
|
||||
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
||||
StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
|
||||
StringHolder() {
|
||||
arcSafeRelease( m_substr );
|
||||
}
|
||||
|
||||
virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
|
||||
return false;
|
||||
}
|
||||
|
||||
NSString* m_substr;
|
||||
};
|
||||
|
||||
struct Equals : StringHolder<Equals> {
|
||||
struct Equals : StringHolder {
|
||||
Equals( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const CATCH_OVERRIDE {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str isEqualToString:m_substr];
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "equals string: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
||||
struct Contains : StringHolder<Contains> {
|
||||
struct Contains : StringHolder {
|
||||
Contains( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location != NSNotFound;
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "contains string: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
||||
struct StartsWith : StringHolder<StartsWith> {
|
||||
struct StartsWith : StringHolder {
|
||||
StartsWith( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location == 0;
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "starts with: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
struct EndsWith : StringHolder<EndsWith> {
|
||||
struct EndsWith : StringHolder {
|
||||
EndsWith( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "ends with: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
@ -66,8 +66,18 @@ namespace Catch {
|
||||
}
|
||||
|
||||
private:
|
||||
T* nullableValue;
|
||||
char storage[sizeof(T)];
|
||||
T *nullableValue;
|
||||
union {
|
||||
char storage[sizeof(T)];
|
||||
|
||||
// These are here to force alignment for the storage
|
||||
long double dummy1;
|
||||
void (*dummy2)();
|
||||
long double dummy3;
|
||||
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
|
||||
long long dummy4;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "catch_test_case_registry_impl.hpp"
|
||||
#include "catch_reporter_registry.hpp"
|
||||
#include "catch_exception_translator_registry.hpp"
|
||||
#include "catch_tag_alias_registry.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -35,6 +36,10 @@ namespace Catch {
|
||||
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
|
||||
return m_exceptionTranslatorRegistry;
|
||||
}
|
||||
virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
|
||||
return m_tagAliasRegistry;
|
||||
}
|
||||
|
||||
|
||||
public: // IMutableRegistryHub
|
||||
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
|
||||
@ -49,11 +54,15 @@ namespace Catch {
|
||||
virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
|
||||
m_exceptionTranslatorRegistry.registerTranslator( translator );
|
||||
}
|
||||
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
|
||||
m_tagAliasRegistry.add( alias, tag, lineInfo );
|
||||
}
|
||||
|
||||
private:
|
||||
TestRegistry m_testCaseRegistry;
|
||||
ReporterRegistry m_reporterRegistry;
|
||||
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
|
||||
TagAliasRegistry m_tagAliasRegistry;
|
||||
};
|
||||
|
||||
// Single, global, instance
|
||||
|
@ -92,7 +92,11 @@ namespace Catch {
|
||||
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
|
||||
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
|
||||
|
||||
// Deprecated - use the form without INTERNAL_
|
||||
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
|
||||
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
|
||||
|
||||
#define CATCH_REGISTER_LISTENER( listenerType ) \
|
||||
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
|
||||
|
@ -39,6 +39,7 @@ namespace Catch {
|
||||
char const* capturedExpression,
|
||||
ResultDisposition::Flags resultDisposition,
|
||||
char const* secondArg = "" );
|
||||
~ResultBuilder();
|
||||
|
||||
template<typename T>
|
||||
ExpressionLhs<T const&> operator <= ( T const& operand );
|
||||
@ -64,7 +65,7 @@ namespace Catch {
|
||||
void captureResult( ResultWas::OfType resultType );
|
||||
void captureExpression();
|
||||
void captureExpectedException( std::string const& expectedMessage );
|
||||
void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
|
||||
void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
|
||||
void handleResult( AssertionResult const& result );
|
||||
void react();
|
||||
bool shouldDebugBreak() const;
|
||||
@ -73,6 +74,9 @@ namespace Catch {
|
||||
template<typename ArgT, typename MatcherT>
|
||||
void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
|
||||
|
||||
void setExceptionGuard();
|
||||
void unsetExceptionGuard();
|
||||
|
||||
private:
|
||||
AssertionInfo m_assertionInfo;
|
||||
AssertionResultData m_data;
|
||||
@ -80,6 +84,7 @@ namespace Catch {
|
||||
|
||||
bool m_shouldDebugBreak;
|
||||
bool m_shouldThrow;
|
||||
bool m_guardException;
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
@ -106,6 +111,7 @@ namespace Catch {
|
||||
endExpression( expr );
|
||||
}
|
||||
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
|
||||
|
@ -30,9 +30,20 @@ namespace Catch {
|
||||
char const* secondArg )
|
||||
: m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
|
||||
m_shouldDebugBreak( false ),
|
||||
m_shouldThrow( false )
|
||||
m_shouldThrow( false ),
|
||||
m_guardException( false )
|
||||
{}
|
||||
|
||||
ResultBuilder::~ResultBuilder() {
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
if ( m_guardException ) {
|
||||
m_stream.oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
|
||||
captureResult( ResultWas::ThrewException );
|
||||
getCurrentContext().getResultCapture()->exceptionEarlyReported();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
|
||||
m_data.resultType = result;
|
||||
return *this;
|
||||
@ -60,12 +71,13 @@ namespace Catch {
|
||||
|
||||
void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
|
||||
if( expectedMessage.empty() )
|
||||
captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
|
||||
captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() );
|
||||
else
|
||||
captureExpectedException( Matchers::Equals( expectedMessage ) );
|
||||
}
|
||||
|
||||
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
||||
|
||||
void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) {
|
||||
|
||||
assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
|
||||
AssertionResultData data = m_data;
|
||||
@ -99,6 +111,15 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void ResultBuilder::react() {
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
if (m_shouldDebugBreak) {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// To inspect the state during test, you need to go one level up the callstack
|
||||
// To go back to the test and change execution, jump over the throw statement
|
||||
///////////////////////////////////////////////////////////////////
|
||||
CATCH_BREAK_INTO_DEBUGGER();
|
||||
}
|
||||
#endif
|
||||
if( m_shouldThrow )
|
||||
throw Catch::TestFailureException();
|
||||
}
|
||||
@ -136,6 +157,13 @@ namespace Catch {
|
||||
dest = m_assertionInfo.capturedExpression;
|
||||
}
|
||||
|
||||
void ResultBuilder::setExceptionGuard() {
|
||||
m_guardException = true;
|
||||
}
|
||||
void ResultBuilder::unsetExceptionGuard() {
|
||||
m_guardException = false;
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
|
||||
|
@ -64,7 +64,8 @@ namespace Catch {
|
||||
m_context( getCurrentMutableContext() ),
|
||||
m_activeTestCase( CATCH_NULL ),
|
||||
m_config( _config ),
|
||||
m_reporter( reporter )
|
||||
m_reporter( reporter ),
|
||||
m_shouldReportUnexpected ( true )
|
||||
{
|
||||
m_context.setRunner( this );
|
||||
m_context.setConfig( m_config );
|
||||
@ -144,8 +145,9 @@ namespace Catch {
|
||||
m_totals.assertions.failed++;
|
||||
}
|
||||
|
||||
if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
|
||||
m_messages.clear();
|
||||
// We have no use for the return value (whether messages should be cleared), because messages were made scoped
|
||||
// and should be let to clear themselves out.
|
||||
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
|
||||
|
||||
// Reset working state
|
||||
m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
|
||||
@ -223,11 +225,19 @@ namespace Catch {
|
||||
return &m_lastResult;
|
||||
}
|
||||
|
||||
virtual void exceptionEarlyReported() {
|
||||
m_shouldReportUnexpected = false;
|
||||
}
|
||||
|
||||
virtual void handleFatalErrorCondition( std::string const& message ) {
|
||||
ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
|
||||
resultBuilder.setResultType( ResultWas::FatalErrorCondition );
|
||||
resultBuilder << message;
|
||||
resultBuilder.captureExpression();
|
||||
// Don't rebuild the result -- the stringification itself can cause more fatal errors
|
||||
// Instead, fake a result data.
|
||||
AssertionResultData tempResult;
|
||||
tempResult.resultType = ResultWas::FatalErrorCondition;
|
||||
tempResult.message = message;
|
||||
AssertionResult result(m_lastAssertionInfo, tempResult);
|
||||
|
||||
getResultCapture().assertionEnded(result);
|
||||
|
||||
handleUnfinishedSections();
|
||||
|
||||
@ -268,6 +278,7 @@ namespace Catch {
|
||||
m_reporter->sectionStarting( testCaseSection );
|
||||
Counts prevAssertions = m_totals.assertions;
|
||||
double duration = 0;
|
||||
m_shouldReportUnexpected = true;
|
||||
try {
|
||||
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal );
|
||||
|
||||
@ -289,7 +300,11 @@ namespace Catch {
|
||||
// This just means the test was aborted due to failure
|
||||
}
|
||||
catch(...) {
|
||||
makeUnexpectedResultBuilder().useActiveException();
|
||||
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
|
||||
// are reported without translation at the point of origin.
|
||||
if (m_shouldReportUnexpected) {
|
||||
makeUnexpectedResultBuilder().useActiveException();
|
||||
}
|
||||
}
|
||||
m_testCaseTracker->close();
|
||||
handleUnfinishedSections();
|
||||
@ -349,6 +364,7 @@ namespace Catch {
|
||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||
std::vector<ITracker*> m_activeSections;
|
||||
TrackerContext m_trackerContext;
|
||||
bool m_shouldReportUnexpected;
|
||||
};
|
||||
|
||||
IResultCapture& getResultCapture() {
|
||||
|
@ -30,6 +30,10 @@ namespace Catch {
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
|
||||
#endif
|
||||
Section::~Section() {
|
||||
if( m_sectionIncluded ) {
|
||||
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||
@ -39,6 +43,9 @@ namespace Catch {
|
||||
getResultCapture().sectionEnded( endInfo );
|
||||
}
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// This indicates whether the section should be executed or not
|
||||
Section::operator bool() const {
|
||||
|
@ -24,6 +24,8 @@
|
||||
#elif defined __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
# pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
# pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace Catch {
|
||||
|
||||
struct TagAlias {
|
||||
TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
|
||||
TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
|
||||
|
||||
std::string tag;
|
||||
SourceLineInfo lineInfo;
|
||||
|
@ -19,8 +19,7 @@ namespace Catch {
|
||||
virtual ~TagAliasRegistry();
|
||||
virtual Option<TagAlias> find( std::string const& alias ) const;
|
||||
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
|
||||
void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
|
||||
static TagAliasRegistry& get();
|
||||
void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
|
||||
|
||||
private:
|
||||
std::map<std::string, TagAlias> m_registry;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "catch_tag_alias_registry.h"
|
||||
#include "catch_console_colour.hpp"
|
||||
#include "catch_interfaces_registry_hub.h"
|
||||
#include "catch_stream.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -38,41 +40,36 @@ namespace Catch {
|
||||
return expandedTestSpec;
|
||||
}
|
||||
|
||||
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
|
||||
void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
|
||||
|
||||
if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
|
||||
std::ostringstream oss;
|
||||
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
|
||||
oss << Colour( Colour::Red )
|
||||
<< "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n"
|
||||
<< Colour( Colour::FileName )
|
||||
<< lineInfo << '\n';
|
||||
throw std::domain_error( oss.str().c_str() );
|
||||
}
|
||||
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
|
||||
std::ostringstream oss;
|
||||
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
|
||||
<< "\tFirst seen at " << find(alias)->lineInfo << '\n'
|
||||
<< "\tRedefined at " << lineInfo;
|
||||
oss << Colour( Colour::Red )
|
||||
<< "error: tag alias, \"" << alias << "\" already registered.\n"
|
||||
<< "\tFirst seen at "
|
||||
<< Colour( Colour::Red ) << find(alias)->lineInfo << '\n'
|
||||
<< Colour( Colour::Red ) << "\tRedefined at "
|
||||
<< Colour( Colour::FileName) << lineInfo << '\n';
|
||||
throw std::domain_error( oss.str().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
TagAliasRegistry& TagAliasRegistry::get() {
|
||||
static TagAliasRegistry instance;
|
||||
return instance;
|
||||
ITagAliasRegistry::~ITagAliasRegistry() {}
|
||||
|
||||
ITagAliasRegistry const& ITagAliasRegistry::get() {
|
||||
return getRegistryHub().getTagAliasRegistry();
|
||||
}
|
||||
|
||||
ITagAliasRegistry::~ITagAliasRegistry() {}
|
||||
ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
|
||||
|
||||
|
||||
RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
|
||||
try {
|
||||
TagAliasRegistry::get().add( alias, tag, lineInfo );
|
||||
}
|
||||
catch( std::exception& ex ) {
|
||||
Colour colourGuard( Colour::Red );
|
||||
Catch::cerr() << ex.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo );
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
@ -38,17 +38,13 @@ namespace Catch {
|
||||
}
|
||||
inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||
if( isReservedTag( tag ) ) {
|
||||
{
|
||||
Colour colourGuard( Colour::Red );
|
||||
Catch::cerr()
|
||||
<< "Tag name [" << tag << "] not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n";
|
||||
}
|
||||
{
|
||||
Colour colourGuard( Colour::FileName );
|
||||
Catch::cerr() << _lineInfo << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
std::ostringstream ss;
|
||||
ss << Colour(Colour::Red)
|
||||
<< "Tag name [" << tag << "] not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n"
|
||||
<< Colour(Colour::FileName)
|
||||
<< _lineInfo << '\n';
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,13 +11,14 @@
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_ptr.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
|
||||
|
||||
namespace Catch {
|
||||
namespace TestCaseTracking {
|
||||
|
||||
@ -290,12 +291,12 @@ namespace TestCaseTracking {
|
||||
if( !filters.empty() ) {
|
||||
m_filters.push_back(""); // Root - should never be consulted
|
||||
m_filters.push_back(""); // Test Case - not a section filter
|
||||
std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) );
|
||||
m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
|
||||
}
|
||||
}
|
||||
void addNextFilters( std::vector<std::string> const& filters ) {
|
||||
if( filters.size() > 1 )
|
||||
std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) );
|
||||
m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
|
||||
}
|
||||
};
|
||||
|
||||
@ -365,4 +366,6 @@ using TestCaseTracking::IndexTracker;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
||||
|
@ -87,59 +87,76 @@ void registerTestCaseFunction
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||
static void TestName(); \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||
static void TestName()
|
||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ \
|
||||
struct TestName : ClassName{ \
|
||||
void test(); \
|
||||
}; \
|
||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
|
||||
} \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||
void TestName::test()
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
||||
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
|
||||
static void TestName(); \
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||
static void TestName()
|
||||
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
namespace{ \
|
||||
struct TestCaseName : ClassName{ \
|
||||
void test(); \
|
||||
}; \
|
||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
|
||||
} \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||
void TestCaseName::test()
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
|
||||
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
|
||||
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
|
||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||
|
@ -97,7 +97,7 @@ namespace Catch {
|
||||
void addPattern() {
|
||||
std::string token = subString();
|
||||
for( size_t i = 0; i < m_escapeChars.size(); ++i )
|
||||
token = token.substr( 0, m_escapeChars[i]-i ) + token.substr( m_escapeChars[i]+1-i );
|
||||
token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
|
||||
m_escapeChars.clear();
|
||||
if( startsWith( token, "exclude:" ) ) {
|
||||
m_exclusion = true;
|
||||
|
@ -10,14 +10,20 @@
|
||||
|
||||
#include "catch_platform.h"
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
typedef unsigned long long uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
|
||||
namespace Catch {
|
||||
typedef unsigned long long UInt64;
|
||||
}
|
||||
#else
|
||||
#include <stdint.h>
|
||||
namespace Catch {
|
||||
typedef uint64_t UInt64;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace Catch {
|
||||
class Timer {
|
||||
public:
|
||||
Timer() : m_ticks( 0 ) {}
|
||||
@ -27,7 +33,7 @@ namespace Catch {
|
||||
double getElapsedSeconds() const;
|
||||
|
||||
private:
|
||||
uint64_t m_ticks;
|
||||
UInt64 m_ticks;
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
|
@ -15,30 +15,34 @@
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
# include "catch_windows_h_proxy.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
uint64_t getCurrentTicks() {
|
||||
static uint64_t hz=0, hzo=0;
|
||||
UInt64 getCurrentTicks() {
|
||||
static UInt64 hz=0, hzo=0;
|
||||
if (!hz) {
|
||||
QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
|
||||
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
|
||||
}
|
||||
uint64_t t;
|
||||
UInt64 t;
|
||||
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
|
||||
return ((t-hzo)*1000000)/hz;
|
||||
}
|
||||
#else
|
||||
uint64_t getCurrentTicks() {
|
||||
UInt64 getCurrentTicks() {
|
||||
timeval t;
|
||||
gettimeofday(&t,CATCH_NULL);
|
||||
return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
|
||||
return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ std::string toString( std::nullptr_t );
|
||||
|
||||
#ifdef __OBJC__
|
||||
std::string toString( NSString const * const& nsstring );
|
||||
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
|
||||
std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
|
||||
std::string toString( NSObject* const& nsObject );
|
||||
#endif
|
||||
|
||||
@ -72,6 +72,7 @@ namespace Detail {
|
||||
|
||||
extern const std::string unprintableString;
|
||||
|
||||
#if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
|
||||
struct BorgType {
|
||||
template<typename T> BorgType( T const& );
|
||||
};
|
||||
@ -90,6 +91,20 @@ namespace Detail {
|
||||
static T const&t;
|
||||
enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
|
||||
};
|
||||
#else
|
||||
template<typename T>
|
||||
class IsStreamInsertable {
|
||||
template<typename SS, typename TT>
|
||||
static auto test(int)
|
||||
-> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
|
||||
|
||||
template<typename, typename>
|
||||
static auto test(...) -> std::false_type;
|
||||
|
||||
public:
|
||||
static const bool value = decltype(test<std::ostream,const T&>(0))::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
|
||||
template<typename T,
|
||||
|
@ -198,7 +198,7 @@ std::string toString( std::nullptr_t ) {
|
||||
return "nil";
|
||||
return "@" + toString([nsstring UTF8String]);
|
||||
}
|
||||
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
|
||||
std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
|
||||
if( !nsstring )
|
||||
return "nil";
|
||||
return "@" + toString([nsstring UTF8String]);
|
||||
|
@ -25,7 +25,7 @@ namespace Catch {
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
struct add_const {
|
||||
struct add_const {
|
||||
typedef const T type;
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace Catch {
|
||||
Version( unsigned int _majorVersion,
|
||||
unsigned int _minorVersion,
|
||||
unsigned int _patchNumber,
|
||||
std::string const& _branchName,
|
||||
char const * const _branchName,
|
||||
unsigned int _buildNumber );
|
||||
|
||||
unsigned int const majorVersion;
|
||||
@ -23,7 +23,7 @@ namespace Catch {
|
||||
unsigned int const patchNumber;
|
||||
|
||||
// buildNumber is only used if branchName is not null
|
||||
std::string const branchName;
|
||||
char const * const branchName;
|
||||
unsigned int const buildNumber;
|
||||
|
||||
friend std::ostream& operator << ( std::ostream& os, Version const& version );
|
||||
@ -32,7 +32,7 @@ namespace Catch {
|
||||
void operator=( Version const& );
|
||||
};
|
||||
|
||||
extern Version libraryVersion;
|
||||
inline Version libraryVersion();
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
|
||||
|
@ -16,7 +16,7 @@ namespace Catch {
|
||||
( unsigned int _majorVersion,
|
||||
unsigned int _minorVersion,
|
||||
unsigned int _patchNumber,
|
||||
std::string const& _branchName,
|
||||
char const * const _branchName,
|
||||
unsigned int _buildNumber )
|
||||
: majorVersion( _majorVersion ),
|
||||
minorVersion( _minorVersion ),
|
||||
@ -29,15 +29,18 @@ namespace Catch {
|
||||
os << version.majorVersion << '.'
|
||||
<< version.minorVersion << '.'
|
||||
<< version.patchNumber;
|
||||
|
||||
if( !version.branchName.empty() ) {
|
||||
os << '-' << version.branchName
|
||||
<< '.' << version.buildNumber;
|
||||
// branchName is never null -> 0th char is \0 if it is empty
|
||||
if (version.branchName[0]) {
|
||||
os << '-' << version.branchName
|
||||
<< '.' << version.buildNumber;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 7, 2, "", 0 );
|
||||
inline Version libraryVersion() {
|
||||
static Version version( 1, 9, 5, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "catch_stream.h"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_suppress_warnings.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@ -241,6 +240,5 @@ namespace Catch {
|
||||
};
|
||||
|
||||
}
|
||||
#include "catch_reenable_warnings.h"
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
|
||||
|
62
include/reporters/catch_reporter_automake.hpp
Normal file
62
include/reporters/catch_reporter_automake.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Created by Justin R. Wilson on 2/19/2017.
|
||||
* Copyright 2017 Justin R. Wilson. 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)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct AutomakeReporter : StreamingReporterBase {
|
||||
AutomakeReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config )
|
||||
{}
|
||||
|
||||
virtual ~AutomakeReporter();
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in the format of Automake .trs files";
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) CATCH_OVERRIDE { return true; }
|
||||
|
||||
virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
|
||||
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
|
||||
stream << ":test-result: ";
|
||||
if (_testCaseStats.totals.assertions.allPassed()) {
|
||||
stream << "PASS";
|
||||
} else if (_testCaseStats.totals.assertions.allOk()) {
|
||||
stream << "XFAIL";
|
||||
} else {
|
||||
stream << "FAIL";
|
||||
}
|
||||
stream << ' ' << _testCaseStats.testInfo.name << '\n';
|
||||
StreamingReporterBase::testCaseEnded( _testCaseStats );
|
||||
}
|
||||
|
||||
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
stream << ":test-result: SKIP " << testInfo.name << '\n';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
AutomakeReporter::~AutomakeReporter() {}
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_REGISTER_REPORTER( "automake", AutomakeReporter)
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
@ -9,11 +9,38 @@
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
#include "../internal/catch_errno_guard.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
// Because formatting using c++ streams is stateful, drop down to C is required
|
||||
// Alternatively we could use stringstream, but its performance is... not good.
|
||||
std::string getFormattedDuration( double duration ) {
|
||||
// Max exponent + 1 is required to represent the whole part
|
||||
// + 1 for decimal point
|
||||
// + 3 for the 3 decimal places
|
||||
// + 1 for null terminator
|
||||
const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
|
||||
char buffer[maxDoubleSize];
|
||||
|
||||
// Save previous errno, to prevent sprintf from overwriting it
|
||||
ErrnoGuard guard;
|
||||
#ifdef _MSC_VER
|
||||
sprintf_s(buffer, "%.3f", duration);
|
||||
#else
|
||||
sprintf(buffer, "%.3f", duration);
|
||||
#endif
|
||||
return std::string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
|
||||
|
||||
StreamingReporterBase( ReporterConfig const& _config )
|
||||
|
@ -37,8 +37,7 @@ namespace Catch {
|
||||
stream << "No test cases matched '" << spec << '\'' << std::endl;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {
|
||||
}
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
|
||||
AssertionResult const& result = _assertionStats.assertionResult;
|
||||
@ -59,6 +58,12 @@ namespace Catch {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
|
||||
if (m_config->showDurations() == ShowDurations::Always) {
|
||||
stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
||||
printTotals( _testRunStats.totals );
|
||||
stream << '\n' << std::endl;
|
||||
@ -164,7 +169,7 @@ namespace Catch {
|
||||
stream << result.getSourceInfo() << ':';
|
||||
}
|
||||
|
||||
void printResultType( Colour::Code colour, std::string passOrFail ) const {
|
||||
void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
|
||||
if( !passOrFail.empty() ) {
|
||||
{
|
||||
Colour colourGuard( colour );
|
||||
@ -174,7 +179,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
void printIssue( std::string issue ) const {
|
||||
void printIssue( std::string const& issue ) const {
|
||||
stream << ' ' << issue;
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,12 @@
|
||||
#include "../internal/catch_reporter_registrars.hpp"
|
||||
#include "../internal/catch_console_colour.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
||||
struct ConsoleReporter : StreamingReporterBase {
|
||||
ConsoleReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config ),
|
||||
@ -36,18 +40,15 @@ namespace Catch {
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
|
||||
AssertionResult const& result = _assertionStats.assertionResult;
|
||||
|
||||
bool printInfoMessages = true;
|
||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||
|
||||
// Drop out if result was successful and we're not printing those
|
||||
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
|
||||
if( result.getResultType() != ResultWas::Warning )
|
||||
return false;
|
||||
printInfoMessages = false;
|
||||
}
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if( !includeResults && result.getResultType() != ResultWas::Warning )
|
||||
return false;
|
||||
|
||||
lazyPrint();
|
||||
|
||||
AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
|
||||
AssertionPrinter printer( stream, _assertionStats, includeResults );
|
||||
printer.print();
|
||||
stream << std::endl;
|
||||
return true;
|
||||
@ -67,14 +68,11 @@ namespace Catch {
|
||||
stream << "\nNo assertions in test case";
|
||||
stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
|
||||
}
|
||||
if( m_headerPrinted ) {
|
||||
if( m_config->showDurations() == ShowDurations::Always )
|
||||
stream << "Completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||
m_headerPrinted = false;
|
||||
if( m_config->showDurations() == ShowDurations::Always ) {
|
||||
stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
|
||||
}
|
||||
else {
|
||||
if( m_config->showDurations() == ShowDurations::Always )
|
||||
stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||
if( m_headerPrinted ) {
|
||||
m_headerPrinted = false;
|
||||
}
|
||||
StreamingReporterBase::sectionEnded( _sectionStats );
|
||||
}
|
||||
@ -140,7 +138,11 @@ namespace Catch {
|
||||
case ResultWas::ThrewException:
|
||||
colour = Colour::Error;
|
||||
passOrFail = "FAILED";
|
||||
messageLabel = "due to unexpected exception with message";
|
||||
messageLabel = "due to unexpected exception with ";
|
||||
if (_stats.infoMessages.size() == 1)
|
||||
messageLabel += "message";
|
||||
if (_stats.infoMessages.size() > 1)
|
||||
messageLabel += "messages";
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
colour = Colour::Error;
|
||||
@ -256,7 +258,7 @@ namespace Catch {
|
||||
stream << '\n' << getLineOfChars<'~'>() << '\n';
|
||||
Colour colour( Colour::SecondaryText );
|
||||
stream << currentTestRunInfo->name
|
||||
<< " is a Catch v" << libraryVersion << " host application.\n"
|
||||
<< " is a Catch v" << libraryVersion() << " host application.\n"
|
||||
<< "Run with -? for options\n\n";
|
||||
|
||||
if( m_config->rngSeed() != 0 )
|
||||
|
@ -51,7 +51,8 @@ namespace Catch {
|
||||
public:
|
||||
JunitReporter( ReporterConfig const& _config )
|
||||
: CumulativeReporterBase( _config ),
|
||||
xml( _config.stream() )
|
||||
xml( _config.stream() ),
|
||||
m_okToFail( false )
|
||||
{
|
||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||
}
|
||||
@ -77,8 +78,11 @@ namespace Catch {
|
||||
CumulativeReporterBase::testGroupStarting( groupInfo );
|
||||
}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE {
|
||||
m_okToFail = testCaseInfo.okToFail();
|
||||
}
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
|
||||
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
|
||||
unexpectedExceptions++;
|
||||
return CumulativeReporterBase::assertionEnded( assertionStats );
|
||||
}
|
||||
@ -243,6 +247,7 @@ namespace Catch {
|
||||
std::ostringstream stdOutForSuite;
|
||||
std::ostringstream stdErrForSuite;
|
||||
unsigned int unexpectedExceptions;
|
||||
bool m_okToFail;
|
||||
};
|
||||
|
||||
INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
|
||||
|
259
include/reporters/catch_reporter_tap.hpp
Normal file
259
include/reporters/catch_reporter_tap.hpp
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Created by Colton Wolkins on 2015-08-15.
|
||||
* Copyright 2015 Martin Moene. 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)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct TAPReporter : StreamingReporterBase {
|
||||
|
||||
TAPReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config ),
|
||||
counter(0)
|
||||
{}
|
||||
|
||||
virtual ~TAPReporter();
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in TAP format, suitable for test harneses";
|
||||
}
|
||||
|
||||
virtual ReporterPreferences getPreferences() const {
|
||||
ReporterPreferences prefs;
|
||||
prefs.shouldRedirectStdOut = false;
|
||||
return prefs;
|
||||
}
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& spec ) {
|
||||
stream << "# No test cases matched '" << spec << "'" << std::endl;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
|
||||
++counter;
|
||||
|
||||
AssertionPrinter printer( stream, _assertionStats, counter );
|
||||
printer.print();
|
||||
stream << " # " << currentTestCaseInfo->name ;
|
||||
|
||||
stream << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
||||
printTotals( _testRunStats.totals );
|
||||
stream << "\n" << std::endl;
|
||||
StreamingReporterBase::testRunEnded( _testRunStats );
|
||||
}
|
||||
|
||||
private:
|
||||
size_t counter;
|
||||
class AssertionPrinter {
|
||||
void operator= ( AssertionPrinter const& );
|
||||
public:
|
||||
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, size_t counter )
|
||||
: stream( _stream )
|
||||
, stats( _stats )
|
||||
, result( _stats.assertionResult )
|
||||
, messages( _stats.infoMessages )
|
||||
, itMessage( _stats.infoMessages.begin() )
|
||||
, printInfoMessages( true )
|
||||
, counter(counter)
|
||||
{}
|
||||
|
||||
void print() {
|
||||
itMessage = messages.begin();
|
||||
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::Ok:
|
||||
printResultType( passedString() );
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if ( ! result.hasExpression() )
|
||||
printRemainingMessages( Colour::None );
|
||||
else
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
if (result.isOk()) {
|
||||
printResultType(passedString());
|
||||
} else {
|
||||
printResultType(failedString());
|
||||
}
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if (result.isOk()) {
|
||||
printIssue(" # TODO");
|
||||
}
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ThrewException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "unexpected exception with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
printResultType( failedString() );
|
||||
printIssue( "fatal error condition with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "expected exception, got none" );
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
printResultType( "info" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
printResultType( "warning" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
printResultType( failedString() );
|
||||
printIssue( "explicitly" );
|
||||
printRemainingMessages( Colour::None );
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
case ResultWas::Exception:
|
||||
printResultType( "** internal error **" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Colour::Code dimColour() { return Colour::FileName; }
|
||||
|
||||
static const char* failedString() { return "not ok"; }
|
||||
static const char* passedString() { return "ok"; }
|
||||
|
||||
void printSourceInfo() const {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << result.getSourceInfo() << ":";
|
||||
}
|
||||
|
||||
void printResultType( std::string const& passOrFail ) const {
|
||||
if( !passOrFail.empty() ) {
|
||||
stream << passOrFail << ' ' << counter << " -";
|
||||
}
|
||||
}
|
||||
|
||||
void printIssue( std::string const& issue ) const {
|
||||
stream << " " << issue;
|
||||
}
|
||||
|
||||
void printExpressionWas() {
|
||||
if( result.hasExpression() ) {
|
||||
stream << ";";
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " expression was:";
|
||||
}
|
||||
printOriginalExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printOriginalExpression() const {
|
||||
if( result.hasExpression() ) {
|
||||
stream << " " << result.getExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printReconstructedExpression() const {
|
||||
if( result.hasExpandedExpression() ) {
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " for: ";
|
||||
}
|
||||
std::string expr = result.getExpandedExpression();
|
||||
std::replace( expr.begin(), expr.end(), '\n', ' ');
|
||||
stream << expr;
|
||||
}
|
||||
}
|
||||
|
||||
void printMessage() {
|
||||
if ( itMessage != messages.end() ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
++itMessage;
|
||||
}
|
||||
}
|
||||
|
||||
void printRemainingMessages( Colour::Code colour = dimColour() ) {
|
||||
if (itMessage == messages.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// using messages.end() directly yields compilation error:
|
||||
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
|
||||
const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
|
||||
|
||||
{
|
||||
Colour colourGuard( colour );
|
||||
stream << " with " << pluralise( N, "message" ) << ":";
|
||||
}
|
||||
|
||||
for(; itMessage != itEnd; ) {
|
||||
// If this assertion is a warning ignore any INFO messages
|
||||
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
if ( ++itMessage != itEnd ) {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << " and";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& stream;
|
||||
AssertionStats const& stats;
|
||||
AssertionResult const& result;
|
||||
std::vector<MessageInfo> messages;
|
||||
std::vector<MessageInfo>::const_iterator itMessage;
|
||||
bool printInfoMessages;
|
||||
size_t counter;
|
||||
};
|
||||
|
||||
void printTotals( const Totals& totals ) const {
|
||||
if( totals.testCases.total() == 0 ) {
|
||||
stream << "1..0 # Skipped: No tests ran.";
|
||||
} else {
|
||||
stream << "1.." << counter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
TAPReporter::~TAPReporter() {}
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_REGISTER_REPORTER( "tap", TAPReporter )
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
@ -49,14 +49,7 @@ namespace Catch {
|
||||
return "Reports test results as TeamCity service messages";
|
||||
}
|
||||
|
||||
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
stream << "##teamcity[testIgnored name='"
|
||||
<< escape( testInfo.name ) << "'";
|
||||
if( testInfo.isHidden() )
|
||||
stream << " message='hidden test'";
|
||||
else
|
||||
stream << " message='test skipped because it didn|'t match the test spec'";
|
||||
stream << "]\n";
|
||||
virtual void skipTest( TestCaseInfo const& /* testInfo */ ) CATCH_OVERRIDE {
|
||||
}
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {}
|
||||
@ -134,10 +127,19 @@ namespace Catch {
|
||||
" " << result.getExpandedExpression() << "\n";
|
||||
}
|
||||
|
||||
stream << "##teamcity[testFailed"
|
||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||
<< " message='" << escape( msg.str() ) << "'"
|
||||
<< "]\n";
|
||||
if( currentTestCaseInfo->okToFail() ) {
|
||||
msg << "- failure ignore as test marked as 'ok to fail'\n";
|
||||
stream << "##teamcity[testIgnored"
|
||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||
<< " message='" << escape( msg.str() ) << "'"
|
||||
<< "]\n";
|
||||
}
|
||||
else {
|
||||
stream << "##teamcity[testFailed"
|
||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||
<< " message='" << escape( msg.str() ) << "'"
|
||||
<< "]\n";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -148,6 +150,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
m_testTimer.start();
|
||||
StreamingReporterBase::testCaseStarting( testInfo );
|
||||
stream << "##teamcity[testStarted name='"
|
||||
<< escape( testInfo.name ) << "']\n";
|
||||
@ -164,7 +167,8 @@ namespace Catch {
|
||||
<< escape( testCaseStats.testInfo.name )
|
||||
<< "' out='" << escape( testCaseStats.stdErr ) << "']\n";
|
||||
stream << "##teamcity[testFinished name='"
|
||||
<< escape( testCaseStats.testInfo.name ) << "']\n";
|
||||
<< escape( testCaseStats.testInfo.name ) << "' duration='"
|
||||
<< m_testTimer.getElapsedMilliseconds() << "']\n";
|
||||
}
|
||||
|
||||
private:
|
||||
@ -203,7 +207,7 @@ namespace Catch {
|
||||
}
|
||||
private:
|
||||
bool m_headerPrintedForThisSection;
|
||||
|
||||
Timer m_testTimer;
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
|
@ -36,6 +36,12 @@ namespace Catch {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
|
||||
m_xml
|
||||
.writeAttribute( "filename", sourceInfo.file )
|
||||
.writeAttribute( "line", sourceInfo.line );
|
||||
}
|
||||
|
||||
public: // StreamingReporterBase
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
|
||||
@ -65,6 +71,8 @@ namespace Catch {
|
||||
.writeAttribute( "description", testInfo.description )
|
||||
.writeAttribute( "tags", testInfo.tagsAsString );
|
||||
|
||||
writeSourceInfo( testInfo.lineInfo );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
m_testCaseTimer.start();
|
||||
m_xml.ensureTagClosed();
|
||||
@ -76,6 +84,7 @@ namespace Catch {
|
||||
m_xml.startElement( "Section" )
|
||||
.writeAttribute( "name", trim( sectionInfo.name ) )
|
||||
.writeAttribute( "description", sectionInfo.description );
|
||||
writeSourceInfo( sectionInfo.lineInfo );
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
}
|
||||
@ -83,71 +92,77 @@ namespace Catch {
|
||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||
const AssertionResult& assertionResult = assertionStats.assertionResult;
|
||||
|
||||
// Print any info messages in <Info> tags.
|
||||
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
|
||||
AssertionResult const& result = assertionStats.assertionResult;
|
||||
|
||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||
|
||||
if( includeResults ) {
|
||||
// Print any info messages in <Info> tags.
|
||||
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
if( it->type == ResultWas::Info ) {
|
||||
m_xml.scopedElement( "Info" )
|
||||
.writeText( it->message );
|
||||
.writeText( it->message );
|
||||
} else if ( it->type == ResultWas::Warning ) {
|
||||
m_xml.scopedElement( "Warning" )
|
||||
.writeText( it->message );
|
||||
.writeText( it->message );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
|
||||
if( !includeResults && result.getResultType() != ResultWas::Warning )
|
||||
return true;
|
||||
|
||||
|
||||
// Print the expression if there is one.
|
||||
if( assertionResult.hasExpression() ) {
|
||||
if( result.hasExpression() ) {
|
||||
m_xml.startElement( "Expression" )
|
||||
.writeAttribute( "success", assertionResult.succeeded() )
|
||||
.writeAttribute( "type", assertionResult.getTestMacroName() )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line );
|
||||
.writeAttribute( "success", result.succeeded() )
|
||||
.writeAttribute( "type", result.getTestMacroName() );
|
||||
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
|
||||
m_xml.scopedElement( "Original" )
|
||||
.writeText( assertionResult.getExpression() );
|
||||
.writeText( result.getExpression() );
|
||||
m_xml.scopedElement( "Expanded" )
|
||||
.writeText( assertionResult.getExpandedExpression() );
|
||||
.writeText( result.getExpandedExpression() );
|
||||
}
|
||||
|
||||
// And... Print a result applicable to each result type.
|
||||
switch( assertionResult.getResultType() ) {
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::ThrewException:
|
||||
m_xml.scopedElement( "Exception" )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "Exception" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
m_xml.scopedElement( "FatalErrorCondition" )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "FatalErrorCondition" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
m_xml.scopedElement( "Info" )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
.writeText( result.getMessage() );
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
// Warning will already have been written
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
m_xml.scopedElement( "Failure" )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "Failure" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( assertionResult.hasExpression() )
|
||||
if( result.hasExpression() )
|
||||
m_xml.endElement();
|
||||
|
||||
return true;
|
||||
|
@ -141,6 +141,16 @@ TEST_CASE( "Approximate PI", "[Approx][PI]" )
|
||||
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE( "Absolute margin", "[Approx]" ) {
|
||||
REQUIRE( 104.0 != Approx(100.0) );
|
||||
REQUIRE( 104.0 == Approx(100.0).margin(5) );
|
||||
REQUIRE( 104.0 != Approx(100.0).margin(3) );
|
||||
REQUIRE( 100.3 != Approx(100.0) );
|
||||
REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
|
168
projects/SelfTest/Baselines/automake.std.approved.txt
Normal file
168
projects/SelfTest/Baselines/automake.std.approved.txt
Normal file
@ -0,0 +1,168 @@
|
||||
:test-result: PASS # A test name that starts with a #
|
||||
:test-result: PASS #542
|
||||
:test-result: PASS #809
|
||||
:test-result: FAIL 'Not' checks that should fail
|
||||
:test-result: PASS 'Not' checks that should succeed
|
||||
:test-result: PASS (unimplemented) static bools can be evaluated
|
||||
:test-result: FAIL A METHOD_AS_TEST_CASE based test run that fails
|
||||
:test-result: PASS A METHOD_AS_TEST_CASE based test run that succeeds
|
||||
:test-result: FAIL A TEST_CASE_METHOD based test run that fails
|
||||
:test-result: PASS A TEST_CASE_METHOD based test run that succeeds
|
||||
:test-result: FAIL A couple of nested sections followed by a failure
|
||||
:test-result: FAIL A failing expression with a non streamable type is still captured
|
||||
:test-result: PASS AllOf matcher
|
||||
:test-result: PASS An empty test with no assertions
|
||||
:test-result: PASS An expression with side-effects should only be evaluated once
|
||||
:test-result: FAIL An unchecked exception reports the line of the last assertion
|
||||
:test-result: PASS Anonymous test case 1
|
||||
:test-result: PASS AnyOf matcher
|
||||
:test-result: PASS Approximate PI
|
||||
:test-result: PASS Approximate comparisons with different epsilons
|
||||
:test-result: PASS Approximate comparisons with floats
|
||||
:test-result: PASS Approximate comparisons with ints
|
||||
:test-result: PASS Approximate comparisons with mixed numeric types
|
||||
:test-result: PASS Assertions then sections
|
||||
:test-result: PASS Character pretty printing
|
||||
:test-result: PASS Comparing function pointers
|
||||
:test-result: PASS Comparing member function pointers
|
||||
:test-result: PASS Comparisons between ints where one side is computed
|
||||
:test-result: PASS Comparisons between unsigned ints and negative signed ints match c++ standard behaviour
|
||||
:test-result: PASS Comparisons with int literals don't warn when mixing signed/ unsigned
|
||||
:test-result: FAIL Contains string matcher
|
||||
:test-result: FAIL Custom exceptions can be translated when testing for nothrow
|
||||
:test-result: FAIL Custom exceptions can be translated when testing for throwing as something else
|
||||
:test-result: FAIL Custom std-exceptions can be custom translated
|
||||
:test-result: PASS Demonstrate that a non-const == is not used
|
||||
:test-result: FAIL EndsWith string matcher
|
||||
:test-result: XFAIL Equality checks that should fail
|
||||
:test-result: PASS Equality checks that should succeed
|
||||
:test-result: PASS Equals
|
||||
:test-result: FAIL Equals string matcher
|
||||
:test-result: PASS Exception messages can be tested for
|
||||
:test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||
:test-result: FAIL FAIL aborts the test
|
||||
:test-result: FAIL FAIL does not require an argument
|
||||
:test-result: PASS Factorials are computed
|
||||
:test-result: PASS Generator over a range of pairs
|
||||
:test-result: PASS Generators over two ranges
|
||||
:test-result: PASS Greater-than inequalities with different epsilons
|
||||
:test-result: PASS INFO and WARN do not abort tests
|
||||
:test-result: FAIL INFO gets logged on failure
|
||||
:test-result: FAIL INFO gets logged on failure, even if captured before successful assertions
|
||||
:test-result: XFAIL Inequality checks that should fail
|
||||
:test-result: PASS Inequality checks that should succeed
|
||||
:test-result: PASS Less-than inequalities with different epsilons
|
||||
:test-result: PASS Long strings can be wrapped
|
||||
:test-result: PASS Long text is truncted
|
||||
:test-result: PASS ManuallyRegistered
|
||||
:test-result: PASS Matchers can be (AllOf) composed with the && operator
|
||||
:test-result: PASS Matchers can be (AnyOf) composed with the || operator
|
||||
:test-result: PASS Matchers can be composed with both && and ||
|
||||
:test-result: FAIL Matchers can be composed with both && and || - failing
|
||||
:test-result: PASS Matchers can be negated (Not) with the ! operator
|
||||
:test-result: FAIL Matchers can be negated (Not) with the ! operator - failing
|
||||
:test-result: FAIL Mismatching exception messages failing the test
|
||||
:test-result: PASS Nice descriptive name
|
||||
:test-result: FAIL Non-std exceptions can be translated
|
||||
:test-result: PASS NotImplemented exception
|
||||
:test-result: PASS Objects that evaluated in boolean contexts can be checked
|
||||
:test-result: PASS Operators at different namespace levels not hijacked by Koenig lookup
|
||||
:test-result: FAIL Ordering comparison checks that should fail
|
||||
:test-result: PASS Ordering comparison checks that should succeed
|
||||
:test-result: FAIL Output from all sections is reported
|
||||
:test-result: PASS Parse test names and tags
|
||||
:test-result: PASS Parsing a std::pair
|
||||
:test-result: PASS Pointers can be compared to null
|
||||
:test-result: PASS Pointers can be converted to strings
|
||||
:test-result: PASS Process can be configured on command line
|
||||
:test-result: FAIL SCOPED_INFO is reset for each loop
|
||||
:test-result: PASS SUCCEED counts as a test pass
|
||||
:test-result: PASS SUCCESS does not require an argument
|
||||
:test-result: PASS Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods
|
||||
:test-result: PASS Scenario: Do that thing with the thing
|
||||
:test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping
|
||||
:test-result: PASS Scenario: Vector resizing affects size and capacity
|
||||
A string sent directly to stdout
|
||||
A string sent directly to stderr
|
||||
:test-result: PASS Sends stuff to stdout and stderr
|
||||
:test-result: PASS Some simple comparisons between doubles
|
||||
Message from section one
|
||||
Message from section two
|
||||
:test-result: PASS Standard output from all sections is reported
|
||||
:test-result: FAIL StartsWith string matcher
|
||||
:test-result: PASS String matchers
|
||||
hello
|
||||
hello
|
||||
:test-result: PASS Strings can be rendered with colour
|
||||
:test-result: FAIL Tabs and newlines show in output
|
||||
:test-result: PASS Tag alias can be registered against tag patterns
|
||||
:test-result: PASS Test case with one argument
|
||||
:test-result: PASS Test enum bit values
|
||||
:test-result: PASS Text can be formatted using the Text class
|
||||
:test-result: PASS The NO_FAIL macro reports a failure but does not fail the test
|
||||
:test-result: FAIL This test 'should' fail but doesn't
|
||||
:test-result: PASS Tracker
|
||||
:test-result: FAIL Unexpected exceptions can be translated
|
||||
:test-result: PASS Use a custom approx
|
||||
:test-result: PASS Variadic macros
|
||||
:test-result: PASS When checked exceptions are thrown they can be expected or unexpected
|
||||
:test-result: FAIL When unchecked exceptions are thrown directly they are always failures
|
||||
:test-result: FAIL When unchecked exceptions are thrown during a CHECK the test should continue
|
||||
:test-result: FAIL When unchecked exceptions are thrown during a REQUIRE the test should abort fail
|
||||
:test-result: FAIL When unchecked exceptions are thrown from functions they are always failures
|
||||
:test-result: FAIL When unchecked exceptions are thrown from sections they are always failures
|
||||
:test-result: PASS When unchecked exceptions are thrown, but caught, they do not affect the test
|
||||
:test-result: PASS Where the LHS is not a simple value
|
||||
:test-result: PASS Where there is more to the expression after the RHS
|
||||
:test-result: PASS X/level/0/a
|
||||
:test-result: PASS X/level/0/b
|
||||
:test-result: PASS X/level/1/a
|
||||
:test-result: PASS X/level/1/b
|
||||
:test-result: PASS XmlEncode
|
||||
:test-result: PASS atomic if
|
||||
:test-result: PASS boolean member
|
||||
:test-result: PASS checkedElse
|
||||
:test-result: FAIL checkedElse, failing
|
||||
:test-result: PASS checkedIf
|
||||
:test-result: FAIL checkedIf, failing
|
||||
:test-result: PASS comparisons between const int variables
|
||||
:test-result: PASS comparisons between int variables
|
||||
:test-result: PASS even more nested SECTION tests
|
||||
:test-result: PASS first tag
|
||||
spanner:test-result: PASS has printf
|
||||
:test-result: FAIL just failure
|
||||
:test-result: PASS just info
|
||||
:test-result: FAIL looped SECTION tests
|
||||
:test-result: FAIL looped tests
|
||||
:test-result: FAIL more nested SECTION tests
|
||||
:test-result: PASS nested SECTION tests
|
||||
:test-result: PASS non streamable - with conv. op
|
||||
:test-result: PASS not allowed
|
||||
:test-result: PASS null strings
|
||||
:test-result: PASS pair<pair<int,const char *,pair<std::string,int> > -> toString
|
||||
:test-result: PASS pointer to class
|
||||
:test-result: PASS random SECTION tests
|
||||
:test-result: PASS replaceInPlace
|
||||
:test-result: PASS second tag
|
||||
:test-result: FAIL send a single char to INFO
|
||||
:test-result: FAIL sends information to INFO
|
||||
:test-result: PASS std::pair<int,const std::string> -> toString
|
||||
:test-result: PASS std::pair<int,std::string> -> toString
|
||||
:test-result: PASS std::vector<std::pair<std::string,int> > -> toString
|
||||
:test-result: FAIL string literals of different sizes can be compared
|
||||
:test-result: PASS toString on const wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on const wchar_t pointer returns the string contents
|
||||
:test-result: PASS toString on wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on wchar_t returns the string contents
|
||||
:test-result: PASS toString( has_maker )
|
||||
:test-result: PASS toString( has_maker_and_toString )
|
||||
:test-result: PASS toString( has_toString )
|
||||
:test-result: PASS toString( vectors<has_maker )
|
||||
:test-result: SKIP toString( vectors<has_maker_and_toString )
|
||||
:test-result: SKIP toString( vectors<has_toString )
|
||||
:test-result: PASS toString(enum w/operator<<)
|
||||
:test-result: PASS toString(enum)
|
||||
:test-result: PASS vector<int> -> toString
|
||||
:test-result: PASS vector<string> -> toString
|
||||
:test-result: PASS vectors can be sized and resized
|
||||
:test-result: PASS xmlentitycheck
|
@ -3,6 +3,42 @@
|
||||
<exe-name> is a <version> host application.
|
||||
Run with -? for options
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
inside REQUIRE_NOTHROW
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
REQUIRE_NOTHROW( thisThrows() )
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -105,10 +141,10 @@ due to unexpected exception with message:
|
||||
-------------------------------------------------------------------------------
|
||||
Contains string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "not there"
|
||||
@ -148,10 +184,10 @@ due to unexpected exception with message:
|
||||
-------------------------------------------------------------------------------
|
||||
EndsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ends with: "this"
|
||||
@ -230,10 +266,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" equals: "something else"
|
||||
@ -276,6 +312,20 @@ MessageTests.cpp:<line number>
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
FAIL_CHECK does not abort the test
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
This is a failure
|
||||
|
||||
MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
This message appears in the output
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
INFO and WARN do not abort tests
|
||||
-------------------------------------------------------------------------------
|
||||
@ -318,7 +368,9 @@ MessageTests.cpp:<line number>: FAILED:
|
||||
CHECK( a == 0 )
|
||||
with expansion:
|
||||
2 == 0
|
||||
with message:
|
||||
with messages:
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
and this, but later
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -355,10 +407,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and || - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( ( contains: "string" or
|
||||
@ -367,10 +419,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" not contains: "substring"
|
||||
@ -543,6 +595,17 @@ MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
toString(p): 0x<hex digits>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Reconstruction should be based on stringification: #914
|
||||
-------------------------------------------------------------------------------
|
||||
DecompositionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
DecompositionTests.cpp:<line number>: FAILED:
|
||||
CHECK( truthy(false) )
|
||||
with expansion:
|
||||
Hey, its truthy!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
SCOPED_INFO is reset for each loop
|
||||
-------------------------------------------------------------------------------
|
||||
@ -564,10 +627,10 @@ Message from section two
|
||||
-------------------------------------------------------------------------------
|
||||
StartsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "string"
|
||||
@ -602,6 +665,67 @@ ExceptionTests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
3.14
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, VectorContains( -1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: -1
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ } Contains: 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Contains( v) )
|
||||
with expansion:
|
||||
{ } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v2, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Equals( v ) )
|
||||
with expansion:
|
||||
{ } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( empty ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
When unchecked exceptions are thrown directly they are always failures
|
||||
-------------------------------------------------------------------------------
|
||||
@ -829,6 +953,6 @@ with expansion:
|
||||
"first" == "second"
|
||||
|
||||
===============================================================================
|
||||
test cases: 161 | 117 passed | 42 failed | 2 failed as expected
|
||||
assertions: 932 | 836 passed | 78 failed | 18 failed as expected
|
||||
test cases: 168 | 119 passed | 45 failed | 4 failed as expected
|
||||
assertions: 968 | 859 passed | 88 failed | 21 failed as expected
|
||||
|
||||
|
@ -15,26 +15,42 @@ with message:
|
||||
yay
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#542
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int )
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int& )
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
inside REQUIRE_NOTHROW
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int )
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
REQUIRE_NOTHROW( thisThrows() )
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
inside REQUIRE_THROWS
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
REQUIRE_THROWS( thisThrows() )
|
||||
with message:
|
||||
answer := 42
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#809
|
||||
@ -48,6 +64,65 @@ PASSED:
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#833
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( a == t )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( a == t )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THROWS( throws_int(true) )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_NOTHROW( throws_int(false) )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
|
||||
with expansion:
|
||||
"aaa" ends with: "aaa"
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( templated_tests<int>(3) )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( errno == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -305,12 +380,48 @@ with expansion:
|
||||
{?} == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
AllOf matcher
|
||||
Absolute margin
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
ApproxTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 != Approx(100.0) )
|
||||
with expansion:
|
||||
104.0 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 == Approx(100.0).margin(5) )
|
||||
with expansion:
|
||||
104.0 == Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 != Approx(100.0).margin(3) )
|
||||
with expansion:
|
||||
104.0 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 100.3 != Approx(100.0) )
|
||||
with expansion:
|
||||
100.3 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
|
||||
with expansion:
|
||||
100.3 == Approx( 100.0 )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
AllOf matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) )
|
||||
with expansion:
|
||||
@ -364,17 +475,17 @@ with message:
|
||||
-------------------------------------------------------------------------------
|
||||
AnyOf matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( contains: "string" or contains:
|
||||
"not there" )
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) )
|
||||
with expansion:
|
||||
@ -567,6 +678,32 @@ PASSED:
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Capture and info messages
|
||||
Capture should stringify like assertions
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( true )
|
||||
with message:
|
||||
i := 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Capture and info messages
|
||||
Info should NOT stringify the way assertions do
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( true )
|
||||
with message:
|
||||
3
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
Specifically escaped
|
||||
@ -682,7 +819,7 @@ TrickyTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( a )
|
||||
with expansion:
|
||||
true
|
||||
0x<hex digits>
|
||||
|
||||
TrickyTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@ -848,10 +985,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Contains string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "not there"
|
||||
@ -903,10 +1040,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
EndsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ends with: "this"
|
||||
@ -1033,10 +1170,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) )
|
||||
with expansion:
|
||||
@ -1046,26 +1183,14 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" equals: "something else"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher, with NULL
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( "", Equals(0) )
|
||||
with expansion:
|
||||
"" equals: ""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception messages can be tested for
|
||||
exact match
|
||||
@ -1149,6 +1274,20 @@ MessageTests.cpp:<line number>
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
FAIL_CHECK does not abort the test
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
This is a failure
|
||||
|
||||
MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
This message appears in the output
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Factorials are computed
|
||||
-------------------------------------------------------------------------------
|
||||
@ -2578,14 +2717,17 @@ MessageTests.cpp:<line number>: FAILED:
|
||||
CHECK( a == 1 )
|
||||
with expansion:
|
||||
2 == 1
|
||||
with message:
|
||||
with messages:
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
CHECK( a == 0 )
|
||||
with expansion:
|
||||
2 == 0
|
||||
with message:
|
||||
with messages:
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
and this, but later
|
||||
|
||||
MessageTests.cpp:<line number>:
|
||||
@ -2593,7 +2735,10 @@ PASSED:
|
||||
CHECK( a == 2 )
|
||||
with expansion:
|
||||
2 == 2
|
||||
with message:
|
||||
with messages:
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
and this, but later
|
||||
but not this
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -3268,7 +3413,7 @@ with expansion:
|
||||
re>"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Long text is truncted
|
||||
Long text is truncated
|
||||
-------------------------------------------------------------------------------
|
||||
TestMain.cpp:<line number>
|
||||
...............................................................................
|
||||
@ -4293,10 +4438,10 @@ with message:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be (AllOf) composed with the && operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) )
|
||||
with expansion:
|
||||
@ -4306,17 +4451,17 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be (AnyOf) composed with the || operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( contains: "string" or contains:
|
||||
"different" or contains: "random" )
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
|
||||
with expansion:
|
||||
@ -4326,10 +4471,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and ||
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) )
|
||||
with expansion:
|
||||
@ -4339,10 +4484,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and || - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( ( contains: "string" or
|
||||
@ -4351,10 +4496,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) )
|
||||
with expansion:
|
||||
@ -4363,10 +4508,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" not contains: "substring"
|
||||
@ -4426,7 +4571,7 @@ TrickyTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( True )
|
||||
with expansion:
|
||||
true
|
||||
1
|
||||
|
||||
TrickyTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@ -4438,7 +4583,7 @@ TrickyTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_FALSE( False )
|
||||
with expansion:
|
||||
!false
|
||||
!0
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Operators at different namespace levels not hijacked by Koenig lookup
|
||||
@ -5790,6 +5935,23 @@ MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
toString(p): 0x<hex digits>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
empty args don't cause a crash
|
||||
-------------------------------------------------------------------------------
|
||||
TestMain.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) )
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.processName == "" )
|
||||
with expansion:
|
||||
"" == ""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
default - no arguments
|
||||
@ -5801,6 +5963,12 @@ TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) )
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.processName == "test" )
|
||||
with expansion:
|
||||
"test" == "test"
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.shouldDebugBreak == false )
|
||||
@ -6269,6 +6437,17 @@ TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Reconstruction should be based on stringification: #914
|
||||
-------------------------------------------------------------------------------
|
||||
DecompositionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
DecompositionTests.cpp:<line number>: FAILED:
|
||||
CHECK( truthy(false) )
|
||||
with expansion:
|
||||
Hey, its truthy!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
SCOPED_INFO is reset for each loop
|
||||
-------------------------------------------------------------------------------
|
||||
@ -6632,10 +6811,10 @@ No assertions in section 'two'
|
||||
-------------------------------------------------------------------------------
|
||||
StartsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "string"
|
||||
@ -6643,28 +6822,28 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
String matchers
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "string"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "abc"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "this"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) )
|
||||
with expansion:
|
||||
@ -6703,7 +6882,8 @@ PASSED:
|
||||
with expansion:
|
||||
"error: tag alias, "[@zzz]" already registered.
|
||||
First seen at file:2
|
||||
Redefined at file:10" contains: "[@zzz]"
|
||||
Redefined at file:10
|
||||
" contains: "[@zzz]"
|
||||
|
||||
TagAliasTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@ -6711,7 +6891,8 @@ PASSED:
|
||||
with expansion:
|
||||
"error: tag alias, "[@zzz]" already registered.
|
||||
First seen at file:2
|
||||
Redefined at file:10" contains: "file"
|
||||
Redefined at file:10
|
||||
" contains: "file"
|
||||
|
||||
TagAliasTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@ -6719,7 +6900,8 @@ PASSED:
|
||||
with expansion:
|
||||
"error: tag alias, "[@zzz]" already registered.
|
||||
First seen at file:2
|
||||
Redefined at file:10" contains: "2"
|
||||
Redefined at file:10
|
||||
" contains: "2"
|
||||
|
||||
TagAliasTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@ -6727,7 +6909,8 @@ PASSED:
|
||||
with expansion:
|
||||
"error: tag alias, "[@zzz]" already registered.
|
||||
First seen at file:2
|
||||
Redefined at file:10" contains: "10"
|
||||
Redefined at file:10
|
||||
" contains: "10"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Tag alias can be registered against tag patterns
|
||||
@ -7892,6 +8075,142 @@ PASSED:
|
||||
with message:
|
||||
no assertions
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: 1
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, VectorContains( 2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( empty) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( empty, Contains( empty) )
|
||||
with expansion:
|
||||
{ } Contains: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( empty, Equals( empty ) )
|
||||
with expansion:
|
||||
{ } Equals: { }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, VectorContains( -1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: -1
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ } Contains: 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Contains( v) )
|
||||
with expansion:
|
||||
{ } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v2, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Equals( v ) )
|
||||
with expansion:
|
||||
{ } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( empty ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
When checked exceptions are thrown they can be expected or unexpected
|
||||
-------------------------------------------------------------------------------
|
||||
@ -9164,6 +9483,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 161 | 116 passed | 43 failed | 2 failed as expected
|
||||
assertions: 934 | 836 passed | 80 failed | 18 failed as expected
|
||||
test cases: 168 | 118 passed | 46 failed | 4 failed as expected
|
||||
assertions: 970 | 859 passed | 90 failed | 21 failed as expected
|
||||
|
||||
|
@ -15,26 +15,42 @@ with message:
|
||||
yay
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#542
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int )
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int& )
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
inside REQUIRE_NOTHROW
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int )
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
REQUIRE_NOTHROW( thisThrows() )
|
||||
due to unexpected exception with messages:
|
||||
answer := 42
|
||||
expected exception
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
inside REQUIRE_THROWS
|
||||
-------------------------------------------------------------------------------
|
||||
ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
REQUIRE_THROWS( thisThrows() )
|
||||
with message:
|
||||
answer := 42
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#809
|
||||
@ -48,6 +64,65 @@ PASSED:
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#833
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( a == t )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( a == t )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THROWS( throws_int(true) )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_NOTHROW( throws_int(false) )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
|
||||
with expansion:
|
||||
"aaa" ends with: "aaa"
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( templated_tests<int>(3) )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( errno == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -69,6 +144,6 @@ ConditionTests.cpp:<line number>: FAILED:
|
||||
CHECK_FALSE( true )
|
||||
|
||||
===============================================================================
|
||||
test cases: 4 | 3 passed | 1 failed
|
||||
assertions: 10 | 6 passed | 4 failed
|
||||
test cases: 6 | 3 passed | 1 failed | 2 failed as expected
|
||||
assertions: 18 | 11 passed | 4 failed | 3 failed as expected
|
||||
|
||||
|
@ -1,9 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesspanner>
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="935" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="13" failures="78" tests="971" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
||||
<testcase classname="global" name="#542" time="{duration}"/>
|
||||
<testcase classname="#748 - captures with unexpected exceptions" name="outside assertions" time="{duration}">
|
||||
<error type="TEST_CASE">
|
||||
expected exception
|
||||
answer := 42
|
||||
ExceptionTests.cpp:<line number>
|
||||
</error>
|
||||
</testcase>
|
||||
<testcase classname="#748 - captures with unexpected exceptions" name="inside REQUIRE_NOTHROW" time="{duration}">
|
||||
<error message="thisThrows()" type="REQUIRE_NOTHROW">
|
||||
expected exception
|
||||
answer := 42
|
||||
ExceptionTests.cpp:<line number>
|
||||
</error>
|
||||
</testcase>
|
||||
<testcase classname="#748 - captures with unexpected exceptions" name="inside REQUIRE_THROWS" time="{duration}"/>
|
||||
<testcase classname="global" name="#809" time="{duration}"/>
|
||||
<testcase classname="global" name="#833" time="{duration}"/>
|
||||
<testcase classname="global" name="#835 -- errno should not be touched by Catch" time="{duration}">
|
||||
<failure message="1 == 0" type="CHECK">
|
||||
MiscTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
||||
<failure message="false != false" type="CHECK">
|
||||
ConditionTests.cpp:<line number>
|
||||
@ -63,6 +83,7 @@ TrickyTests.cpp:<line number>
|
||||
TrickyTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Absolute margin" time="{duration}"/>
|
||||
<testcase classname="global" name="AllOf matcher" time="{duration}"/>
|
||||
<testcase classname="global" name="An expression with side-effects should only be evaluated once" time="{duration}"/>
|
||||
<testcase classname="global" name="An unchecked exception reports the line of the last assertion" time="{duration}">
|
||||
@ -82,6 +103,8 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="Assertions then sections" name="A section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another other section" time="{duration}"/>
|
||||
<testcase classname="Capture and info messages" name="Capture should stringify like assertions" time="{duration}"/>
|
||||
<testcase classname="Capture and info messages" name="Info should NOT stringify the way assertions do" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Specifically escaped" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="General chars" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Low ASCII" time="{duration}"/>
|
||||
@ -92,7 +115,7 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Comparisons with int literals don't warn when mixing signed/ unsigned" time="{duration}"/>
|
||||
<testcase classname="global" name="Contains string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" contains: "not there"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
|
||||
@ -116,7 +139,7 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Demonstrate that a non-const == is not used" time="{duration}"/>
|
||||
<testcase classname="global" name="EndsWith string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" ends with: "this"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Equality checks that should fail" time="{duration}">
|
||||
@ -164,10 +187,9 @@ ConditionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Equals" time="{duration}"/>
|
||||
<testcase classname="global" name="Equals string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" equals: "something else"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Equals string matcher, with NULL" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="exact match" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="different case" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="wildcarded" time="{duration}"/>
|
||||
@ -192,6 +214,12 @@ MessageTests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="global" name="FAIL does not require an argument" time="{duration}">
|
||||
<failure type="FAIL">
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="FAIL_CHECK does not abort the test" time="{duration}">
|
||||
<failure type="FAIL_CHECK">
|
||||
This is a failure
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
@ -209,10 +237,13 @@ MessageTests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}">
|
||||
<failure message="2 == 1" type="CHECK">
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="2 == 0" type="CHECK">
|
||||
this message may be logged later
|
||||
this message should be logged
|
||||
and this, but later
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
@ -250,20 +281,20 @@ ConditionTests.cpp:<line number>
|
||||
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/No wrapping" time="{duration}"/>
|
||||
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap before" time="{duration}"/>
|
||||
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap after" time="{duration}"/>
|
||||
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
|
||||
<testcase classname="global" name="Long text is truncated" time="{duration}"/>
|
||||
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be (AllOf) composed with the && operator" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be (AnyOf) composed with the || operator" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be composed with both && and ||" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be composed with both && and || - failing" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator - failing" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" not contains: "substring"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Mismatching exception messages failing the test" time="{duration}">
|
||||
@ -387,6 +418,7 @@ MessageTests.cpp:<line number>
|
||||
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
|
||||
<testcase classname="global" name="Pointers can be compared to null" time="{duration}"/>
|
||||
<testcase classname="global" name="Pointers can be converted to strings" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="empty args don't cause a crash" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
|
||||
@ -411,6 +443,11 @@ MessageTests.cpp:<line number>
|
||||
<testcase classname="Process can be configured on command line" name="use-colour/yes" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="use-colour/no" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="use-colour/error" time="{duration}"/>
|
||||
<testcase classname="global" name="Reconstruction should be based on stringification: #914" time="{duration}">
|
||||
<failure message="Hey, its truthy!" type="CHECK">
|
||||
DecompositionTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="SCOPED_INFO is reset for each loop" time="{duration}">
|
||||
<failure message="10 < 10" type="REQUIRE">
|
||||
current counter 10
|
||||
@ -446,7 +483,7 @@ Message from section two
|
||||
</testcase>
|
||||
<testcase classname="global" name="StartsWith string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" starts with: "string"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="String matchers" time="{duration}"/>
|
||||
@ -500,6 +537,39 @@ ExceptionTests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Use a custom approx" time="{duration}"/>
|
||||
<testcase classname="Variadic macros" name="Section with one argument" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Contains (element)" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Contains (vector)" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Equals" time="{duration}"/>
|
||||
<testcase classname="Vector matchers that fail" name="Contains (element)" time="{duration}">
|
||||
<failure message="{ 1, 2, 3 } Contains: -1" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ } Contains: 1" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="Vector matchers that fail" name="Contains (vector)" time="{duration}">
|
||||
<failure message="{ } Contains: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2, 3 } Contains: { 1, 2, 4 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="Vector matchers that fail" name="Equals" time="{duration}">
|
||||
<failure message="{ 1, 2, 3 } Equals: { 1, 2 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2 } Equals: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ } Equals: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2, 3 } Equals: { }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="When checked exceptions are thrown they can be expected or unexpected" time="{duration}"/>
|
||||
<testcase classname="global" name="When unchecked exceptions are thrown directly they are always failures" time="{duration}">
|
||||
<error type="TEST_CASE">
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,20 +23,50 @@ TEST_CASE("#809") {
|
||||
REQUIRE(42 == f);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// REQUIRE_THROWS_AS was changed to catch exceptions by const&
|
||||
// using type traits. This means that this should compile cleanly
|
||||
|
||||
// Provides indirection to prevent unreachable-code warnings
|
||||
// ------------------------------------------------------------------
|
||||
// Changes to REQUIRE_THROWS_AS made it stop working in a template in
|
||||
// an unfixable way (as long as C++03 compatibility is being kept).
|
||||
// To prevent these from happening in the future, this needs to compile
|
||||
|
||||
void throws_int(bool b) {
|
||||
if (b) {
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("#542") {
|
||||
CHECK_THROWS_AS(throws_int(true), int);
|
||||
CHECK_THROWS_AS(throws_int(true), int&);
|
||||
CHECK_THROWS_AS(throws_int(true), const int);
|
||||
template <typename T>
|
||||
bool templated_tests(T t) {
|
||||
int a = 3;
|
||||
REQUIRE(a == t);
|
||||
CHECK(a == t);
|
||||
REQUIRE_THROWS(throws_int(true));
|
||||
CHECK_THROWS_AS(throws_int(true), const int&);
|
||||
REQUIRE_NOTHROW(throws_int(false));
|
||||
REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("#833") {
|
||||
REQUIRE(templated_tests<int>(3));
|
||||
}
|
||||
|
||||
// Test containing example where original stream insertable check breaks compilation
|
||||
#if defined (CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
|
||||
namespace {
|
||||
struct A {};
|
||||
std::ostream& operator<< (std::ostream &o, const A &) { return o << 0; }
|
||||
|
||||
struct B : private A {
|
||||
bool operator== (int) const { return true; }
|
||||
};
|
||||
|
||||
B f ();
|
||||
std::ostream g ();
|
||||
}
|
||||
|
||||
TEST_CASE( "#872" ) {
|
||||
B x;
|
||||
REQUIRE (x == 4);
|
||||
}
|
||||
#endif
|
||||
|
@ -248,15 +248,6 @@ TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++
|
||||
CHECK( minInt > 2u );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct Ex
|
||||
{
|
||||
Ex( T ){}
|
||||
|
||||
bool operator == ( const T& ) const { return true; }
|
||||
T operator * ( const T& ) const { return T(); }
|
||||
};
|
||||
|
||||
TEST_CASE( "Comparisons between ints where one side is computed", "" )
|
||||
{
|
||||
CHECK( 54 == 6*9 );
|
||||
|
28
projects/SelfTest/DecompositionTests.cpp
Normal file
28
projects/SelfTest/DecompositionTests.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Created by Martin on 27/5/2017.
|
||||
* Copyright 2017 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 <iostream>
|
||||
|
||||
struct truthy {
|
||||
truthy(bool b):m_value(b){}
|
||||
operator bool() const {
|
||||
return false;
|
||||
}
|
||||
bool m_value;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, truthy) {
|
||||
o << "Hey, its truthy!";
|
||||
return o;
|
||||
}
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE( "Reconstruction should be based on stringification: #914" , "[Decomposition][failing][.]") {
|
||||
CHECK(truthy(false));
|
||||
}
|
@ -11,6 +11,10 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
inline int thisThrows()
|
||||
@ -205,3 +209,18 @@ TEST_CASE( "Mismatching exception messages failing the test", "[.][failing][!thr
|
||||
REQUIRE_THROWS_WITH( thisThrows(), "should fail" );
|
||||
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
||||
}
|
||||
|
||||
TEST_CASE( "#748 - captures with unexpected exceptions", "[!shouldfail][!throws]" ) {
|
||||
int answer = 42;
|
||||
CAPTURE( answer );
|
||||
// the message should be printed on the first two sections but not on the third
|
||||
SECTION( "outside assertions" ) {
|
||||
thisThrows();
|
||||
}
|
||||
SECTION( "inside REQUIRE_NOTHROW" ) {
|
||||
REQUIRE_NOTHROW( thisThrows() );
|
||||
}
|
||||
SECTION( "inside REQUIRE_THROWS" ) {
|
||||
REQUIRE_THROWS( thisThrows() );
|
||||
}
|
||||
}
|
||||
|
168
projects/SelfTest/MatchersTests.cpp
Normal file
168
projects/SelfTest/MatchersTests.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Created by Phil on 21/02/2017.
|
||||
* Copyright 2017 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.hpp"
|
||||
|
||||
inline const char* testStringForMatching()
|
||||
{
|
||||
return "this string contains 'abc' as a substring";
|
||||
}
|
||||
inline const char* testStringForMatching2()
|
||||
{
|
||||
return "some completely different text that contains one common word";
|
||||
}
|
||||
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
TEST_CASE("String matchers", "[matchers]" )
|
||||
{
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("AllOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) );
|
||||
}
|
||||
TEST_CASE("AnyOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) );
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(),
|
||||
Contains( "string" ) &&
|
||||
Contains( "abc" ) &&
|
||||
Contains( "substring" ) &&
|
||||
Contains( "contains" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE( "Vector matchers", "[matchers][vector]" ) {
|
||||
std::vector<int> v;
|
||||
v.push_back( 1 );
|
||||
v.push_back( 2 );
|
||||
v.push_back( 3 );
|
||||
|
||||
std::vector<int> v2;
|
||||
v2.push_back( 1 );
|
||||
v2.push_back( 2 );
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION( "Contains (element)" ) {
|
||||
CHECK_THAT( v, VectorContains( 1 ) );
|
||||
CHECK_THAT( v, VectorContains( 2 ) );
|
||||
}
|
||||
SECTION( "Contains (vector)" ) {
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
v2.push_back( 3 ); // now exactly matches
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
|
||||
CHECK_THAT( v, Contains( empty) );
|
||||
CHECK_THAT( empty, Contains( empty) );
|
||||
}
|
||||
|
||||
SECTION( "Equals" ) {
|
||||
|
||||
// Same vector
|
||||
CHECK_THAT( v, Equals( v ) );
|
||||
|
||||
CHECK_THAT( empty, Equals( empty ) );
|
||||
|
||||
// Different vector with same elements
|
||||
v2.push_back( 3 );
|
||||
CHECK_THAT( v, Equals( v2 ) );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) {
|
||||
std::vector<int> v;
|
||||
v.push_back( 1 );
|
||||
v.push_back( 2 );
|
||||
v.push_back( 3 );
|
||||
|
||||
std::vector<int> v2;
|
||||
v2.push_back( 1 );
|
||||
v2.push_back( 2 );
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION( "Contains (element)" ) {
|
||||
CHECK_THAT( v, VectorContains( -1 ) );
|
||||
CHECK_THAT( empty, VectorContains( 1 ) );
|
||||
}
|
||||
SECTION( "Contains (vector)" ) {
|
||||
CHECK_THAT( empty, Contains( v) );
|
||||
v2.push_back( 4 );
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
}
|
||||
|
||||
SECTION( "Equals" ) {
|
||||
|
||||
CHECK_THAT( v, Equals( v2 ) );
|
||||
CHECK_THAT( v2, Equals( v ) );
|
||||
CHECK_THAT( empty, Equals( v ) );
|
||||
CHECK_THAT( v, Equals( empty ) );
|
||||
}
|
||||
}
|
@ -53,6 +53,13 @@ TEST_CASE( "INFO gets logged on failure, even if captured before successful asse
|
||||
TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" )
|
||||
{
|
||||
FAIL( "This is a " << "failure" ); // This should output the message and abort
|
||||
WARN( "We should never see this");
|
||||
}
|
||||
|
||||
TEST_CASE( "FAIL_CHECK does not abort the test", "[failing][messages][.]" )
|
||||
{
|
||||
FAIL_CHECK( "This is a " << "failure" ); // This should output the message then continue
|
||||
WARN( "This message appears in the output");
|
||||
}
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../include/internal/catch_xmlwriter.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
|
||||
TEST_CASE( "random SECTION tests", "[.][sections][failing]" )
|
||||
{
|
||||
@ -204,100 +205,6 @@ TEST_CASE( "atomic if", "[failing][0]")
|
||||
REQUIRE(x == 0);
|
||||
}
|
||||
|
||||
inline const char* testStringForMatching()
|
||||
{
|
||||
return "this string contains 'abc' as a substring";
|
||||
}
|
||||
inline const char* testStringForMatching2()
|
||||
{
|
||||
return "some completely different text that contains one common word";
|
||||
}
|
||||
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
TEST_CASE("String matchers", "[matchers]" )
|
||||
{
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) );
|
||||
}
|
||||
TEST_CASE("Equals string matcher, with NULL", "[matchers]")
|
||||
{
|
||||
REQUIRE_THAT("", Equals(CATCH_NULL));
|
||||
}
|
||||
TEST_CASE("AllOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) );
|
||||
}
|
||||
TEST_CASE("AnyOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) );
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(),
|
||||
Contains( "string" ) &&
|
||||
Contains( "abc" ) &&
|
||||
Contains( "substring" ) &&
|
||||
Contains( "contains" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int Factorial( unsigned int number )
|
||||
{
|
||||
// return number <= 1 ? number : Factorial(number-1)*number;
|
||||
@ -487,3 +394,14 @@ TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" )
|
||||
TEST_CASE( "# A test name that starts with a #" ) {
|
||||
SUCCEED( "yay" );
|
||||
}
|
||||
|
||||
|
||||
static int f() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST_CASE( "#835 -- errno should not be touched by Catch", "[!shouldfail]" ) {
|
||||
errno = 1;
|
||||
CHECK(f() == 0);
|
||||
REQUIRE(errno == 1); // Check that f() doesn't touch errno.
|
||||
}
|
||||
|
@ -9,6 +9,9 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
#include "../include/reporters/catch_reporter_teamcity.hpp"
|
||||
#include "../include/reporters/catch_reporter_tap.hpp"
|
||||
#include "../include/reporters/catch_reporter_automake.hpp"
|
||||
|
||||
|
||||
// Some example tag aliases
|
||||
CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
|
||||
@ -48,10 +51,18 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
||||
|
||||
Catch::ConfigData config;
|
||||
|
||||
SECTION( "empty args don't cause a crash" ) {
|
||||
Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
||||
CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) );
|
||||
|
||||
CHECK( config.processName == "" );
|
||||
}
|
||||
|
||||
SECTION( "default - no arguments", "" ) {
|
||||
const char* argv[] = { "test" };
|
||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||
|
||||
CHECK( config.processName == "test" );
|
||||
CHECK( config.shouldDebugBreak == false );
|
||||
CHECK( config.abortAfter == -1 );
|
||||
CHECK( config.noThrow == false );
|
||||
@ -468,7 +479,7 @@ TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
||||
CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
||||
TEST_CASE( "Long text is truncated", "[Text][Truncated]" ) {
|
||||
|
||||
std::string longLine( 90, '*' );
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
|
||||
TEST_CASE( "Character pretty printing" ){
|
||||
//
|
||||
SECTION("Specifically escaped"){
|
||||
char tab = '\t';
|
||||
char newline = '\n';
|
||||
@ -36,5 +35,19 @@ TEST_CASE( "Character pretty printing" ){
|
||||
char c = static_cast<char>(i);
|
||||
REQUIRE(c == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE( "Capture and info messages" ) {
|
||||
SECTION("Capture should stringify like assertions") {
|
||||
int i = 2;
|
||||
CAPTURE(i);
|
||||
REQUIRE(true);
|
||||
}
|
||||
SECTION("Info should NOT stringify the way assertions do") {
|
||||
int i = 3;
|
||||
INFO(i);
|
||||
REQUIRE(true);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user