mirror of
https://github.com/catchorg/Catch2.git
synced 2025-10-06 12:01:07 +02:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7cbd0b587a | ||
|
2f15ccd4d3 | ||
|
8f3fc15b73 | ||
|
e13d9cab02 | ||
|
414e2fa946 | ||
|
b5ef68b044 | ||
|
681f5daa13 | ||
|
3b6fda3c1b | ||
|
1b2fa601c6 | ||
|
39bfc6e82b | ||
|
ba6d33fb8c | ||
|
4be81d3588 | ||
|
5201e92564 | ||
|
5e484862f2 | ||
|
5713381d06 | ||
|
1ab6be30a2 | ||
|
126850e76b | ||
|
5e8df1c384 | ||
|
44dbda9f01 | ||
|
ca2455e6e6 | ||
|
42213d4c31 | ||
|
62dae592c3 | ||
|
9a5705411a | ||
|
a1aefce6e4 | ||
|
d5959907f5 | ||
|
31e6499e64 | ||
|
b0f4f16ee0 | ||
|
1e3ddbb496 | ||
|
15ad95c8db | ||
|
00a10d5a5e | ||
|
0d687a15d3 | ||
|
bdf431c400 | ||
|
a0359980f0 | ||
|
8d4074aad9 | ||
|
f0f40a0dbf | ||
|
fa4fd7f296 | ||
|
07c84adfba | ||
|
8d854c689b | ||
|
f0909dfe02 | ||
|
de36b2ada6 | ||
|
9700ee4fc0 | ||
|
bbda8cd77c | ||
|
4575594bbf | ||
|
c053dca26e | ||
|
3d7104c124 | ||
|
6441c20a2c | ||
|
5774c4f9c2 | ||
|
2bc33dd04d |
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -9,3 +9,14 @@
|
|||||||
|
|
||||||
# Windows specific files should retain windows line-endings
|
# Windows specific files should retain windows line-endings
|
||||||
*.sln text eol=crlf
|
*.sln text eol=crlf
|
||||||
|
|
||||||
|
# Keep executable scripts with LFs so they can be run after being
|
||||||
|
# checked out on Windows
|
||||||
|
*.py text eol=lf
|
||||||
|
|
||||||
|
|
||||||
|
# Keep the single include header with LFs to make sure it is uploaded,
|
||||||
|
# hashed etc with LF
|
||||||
|
single_include/*.hpp eol=lf
|
||||||
|
# Also keep the LICENCE file with LFs for the same reason
|
||||||
|
LICENCE.txt eol=lf
|
||||||
|
@@ -204,7 +204,7 @@ before_script:
|
|||||||
|
|
||||||
- |
|
- |
|
||||||
# Use Debug builds for running Valgrind and building examples
|
# Use Debug builds for running Valgrind and building examples
|
||||||
cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DUSE_VALGRIND=${VALGRIND} -DBUILD_EXAMPLES=ON -DENABLE_COVERAGE=ON
|
cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_COVERAGE=ON
|
||||||
# Don't bother with release build for coverage build
|
# Don't bother with release build for coverage build
|
||||||
cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
|
cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
|
||||||
|
|
||||||
|
100
CMakeLists.txt
100
CMakeLists.txt
@@ -1,10 +1,19 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
project(CatchSelfTest)
|
# detect if Catch is being bundled,
|
||||||
|
# disable testsuite in that case
|
||||||
|
if(NOT DEFINED PROJECT_NAME)
|
||||||
|
set(NOT_SUBPROJECT ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
|
project(Catch2 LANGUAGES CXX VERSION 2.1.2)
|
||||||
option(BUILD_EXAMPLES "Build documentation examples" OFF)
|
|
||||||
option(ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
|
||||||
|
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
|
||||||
|
option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
|
||||||
|
option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
@@ -13,7 +22,6 @@ set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|||||||
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
||||||
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
|
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
|
||||||
set(HEADER_DIR ${CATCH_DIR}/include)
|
set(HEADER_DIR ${CATCH_DIR}/include)
|
||||||
set(CATCH_VERSION_NUMBER 2.1.0)
|
|
||||||
|
|
||||||
if(USE_WMAIN)
|
if(USE_WMAIN)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
||||||
@@ -179,6 +187,7 @@ set(INTERNAL_HEADERS
|
|||||||
${HEADER_DIR}/internal/catch_timer.h
|
${HEADER_DIR}/internal/catch_timer.h
|
||||||
${HEADER_DIR}/internal/catch_tostring.h
|
${HEADER_DIR}/internal/catch_tostring.h
|
||||||
${HEADER_DIR}/internal/catch_totals.h
|
${HEADER_DIR}/internal/catch_totals.h
|
||||||
|
${HEADER_DIR}/internal/catch_uncaught_exceptions.h
|
||||||
${HEADER_DIR}/internal/catch_user_interfaces.h
|
${HEADER_DIR}/internal/catch_user_interfaces.h
|
||||||
${HEADER_DIR}/internal/catch_version.h
|
${HEADER_DIR}/internal/catch_version.h
|
||||||
${HEADER_DIR}/internal/catch_wildcard_pattern.h
|
${HEADER_DIR}/internal/catch_wildcard_pattern.h
|
||||||
@@ -239,6 +248,7 @@ set(IMPL_SOURCES
|
|||||||
${HEADER_DIR}/internal/catch_timer.cpp
|
${HEADER_DIR}/internal/catch_timer.cpp
|
||||||
${HEADER_DIR}/internal/catch_tostring.cpp
|
${HEADER_DIR}/internal/catch_tostring.cpp
|
||||||
${HEADER_DIR}/internal/catch_totals.cpp
|
${HEADER_DIR}/internal/catch_totals.cpp
|
||||||
|
${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
|
||||||
${HEADER_DIR}/internal/catch_version.cpp
|
${HEADER_DIR}/internal/catch_version.cpp
|
||||||
${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
|
${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
|
||||||
${HEADER_DIR}/internal/catch_xmlwriter.cpp
|
${HEADER_DIR}/internal/catch_xmlwriter.cpp
|
||||||
@@ -284,7 +294,19 @@ SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
|
|||||||
|
|
||||||
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
||||||
# without building all of our selftests.
|
# without building all of our selftests.
|
||||||
if (NOT NO_SELFTEST)
|
|
||||||
|
if(DEFINED NO_SELFTEST)
|
||||||
|
message(DEPRECATION "*** CMake option NO_SELFTEST is deprecated; use BUILD_TESTING instead")
|
||||||
|
if (NO_SELFTEST)
|
||||||
|
set(BUILD_TESTING OFF CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
|
||||||
|
else()
|
||||||
|
set(BUILD_TESTING ON CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
if (BUILD_TESTING AND NOT_SUBPROJECT)
|
||||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
||||||
target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
|
target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
|
||||||
|
|
||||||
@@ -299,7 +321,8 @@ if (NOT NO_SELFTEST)
|
|||||||
set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
|
set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||||
set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
|
set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
if (ENABLE_COVERAGE)
|
if (CATCH_ENABLE_COVERAGE)
|
||||||
|
set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
find_package(codecov)
|
find_package(codecov)
|
||||||
add_coverage(SelfTest)
|
add_coverage(SelfTest)
|
||||||
@@ -307,18 +330,25 @@ if (NOT NO_SELFTEST)
|
|||||||
coverage_evaluate()
|
coverage_evaluate()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add desired warnings
|
# Add per compiler options
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Werror )
|
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic)
|
||||||
|
if (CATCH_ENABLE_WERROR)
|
||||||
|
target_compile_options( SelfTest PRIVATE -Werror)
|
||||||
endif()
|
endif()
|
||||||
# Clang specific warning go here
|
endif()
|
||||||
|
# Clang specific options go here
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
# Actually keep these
|
|
||||||
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
||||||
endif()
|
endif()
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||||
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
|
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
|
||||||
target_compile_options( SelfTest PRIVATE /w44265 /WX /w44061 /w44062 )
|
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
|
||||||
|
if (CATCH_ENABLE_WERROR)
|
||||||
|
target_compile_options( SelfTest PRIVATE /WX)
|
||||||
|
endif()
|
||||||
|
# Force MSVC to consider everything as encoded in utf-8
|
||||||
|
target_compile_options( SelfTest PRIVATE /utf-8 )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
@@ -344,7 +374,7 @@ if (NOT NO_SELFTEST)
|
|||||||
add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
||||||
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
||||||
|
|
||||||
if (USE_VALGRIND)
|
if (CATCH_USE_VALGRIND)
|
||||||
add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
|
add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
|
||||||
add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
||||||
set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
|
||||||
@@ -355,18 +385,20 @@ if (NOT NO_SELFTEST)
|
|||||||
endif() # !NO_SELFTEST
|
endif() # !NO_SELFTEST
|
||||||
|
|
||||||
|
|
||||||
if(BUILD_EXAMPLES)
|
if(CATCH_BUILD_EXAMPLES)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(DIRECTORY "single_include/" DESTINATION "include/catch")
|
install(DIRECTORY "single_include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/catch")
|
||||||
|
|
||||||
|
install(DIRECTORY docs/ DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||||
|
|
||||||
## Provide some pkg-config integration
|
## Provide some pkg-config integration
|
||||||
# Don't bother on Windows
|
# Don't bother on Windows
|
||||||
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
||||||
|
|
||||||
set(PKGCONFIG_INSTALL_DIR
|
set(PKGCONFIG_INSTALL_DIR
|
||||||
"${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
|
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
|
||||||
CACHE PATH "Path where catch.pc is installed"
|
CACHE PATH "Path where catch.pc is installed"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -374,3 +406,37 @@ if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
|||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# add catch as a 'linkable' target
|
||||||
|
add_library(Catch INTERFACE)
|
||||||
|
|
||||||
|
# depend on some obvious c++11 features so the dependency is transitively added dependants
|
||||||
|
target_compile_features(Catch INTERFACE cxx_auto_type cxx_constexpr cxx_noexcept)
|
||||||
|
|
||||||
|
target_include_directories(Catch
|
||||||
|
INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
|
||||||
|
$<INSTALL_INTERFACE:include/catch>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
|
||||||
|
add_library(Catch2::Catch ALIAS Catch)
|
||||||
|
|
||||||
|
set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
|
||||||
|
|
||||||
|
# create and install an export set for catch target as Catch2::Catch
|
||||||
|
install(TARGETS Catch EXPORT Catch2Config DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
|
install(EXPORT Catch2Config
|
||||||
|
NAMESPACE Catch2::
|
||||||
|
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
|
||||||
|
|
||||||
|
# install Catch2ConfigVersion.cmake file to handle versions in find_package
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
write_basic_package_version_file(Catch2ConfigVersion.cmake
|
||||||
|
COMPATIBILITY SameMajorVersion)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
||||||
|
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
[](https://travis-ci.org/catchorg/Catch2)
|
[](https://travis-ci.org/catchorg/Catch2)
|
||||||
[](https://ci.appveyor.com/project/catchorg/catch2)
|
[](https://ci.appveyor.com/project/catchorg/catch2)
|
||||||
[](https://codecov.io/gh/catchorg/Catch2)
|
[](https://codecov.io/gh/catchorg/Catch2)
|
||||||
[](https://wandbox.org/permlink/nerce2MiN6sVmfCi)
|
[](https://wandbox.org/permlink/6O2wo5BOvVeUeKQe)
|
||||||
|
|
||||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.0.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
<a href="https://github.com/catchorg/Catch2/releases/download/v2.1.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||||
|
|
||||||
## Catch2 is released!
|
## Catch2 is released!
|
||||||
|
|
||||||
|
@@ -54,7 +54,7 @@ before_build:
|
|||||||
|
|
||||||
# build with MSBuild
|
# build with MSBuild
|
||||||
build:
|
build:
|
||||||
project: Build\CatchSelfTest.sln # path to Visual Studio solution or project
|
project: Build\Catch2.sln # path to Visual Studio solution or project
|
||||||
parallel: true # enable MSBuild parallel builds
|
parallel: true # enable MSBuild parallel builds
|
||||||
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
|
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
|
||||||
|
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
exec_prefix=${prefix}
|
|
||||||
|
|
||||||
Name: Catch
|
Name: Catch
|
||||||
Description: Testing library for C++
|
Description: Testing library for C++
|
||||||
Requires:
|
Version: @Catch2_VERSION@
|
||||||
Version: @CATCH_VERSION_NUMBER@
|
Cflags: -I${includedir}
|
||||||
Libs:
|
|
||||||
Cflags: -I${prefix}/@INCLUDE_INSTALL_DIR@/include
|
|
||||||
|
12
codecov.yml
12
codecov.yml
@@ -1,6 +1,18 @@
|
|||||||
|
coverage:
|
||||||
|
precision: 2
|
||||||
|
round: nearest
|
||||||
|
range: "60...90"
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
threshold: 2%
|
||||||
|
|
||||||
codecov:
|
codecov:
|
||||||
branch: master
|
branch: master
|
||||||
|
|
||||||
|
comment:
|
||||||
|
layout: "diff"
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
ignore:
|
ignore:
|
||||||
- "projects/SelfTest"
|
- "projects/SelfTest"
|
||||||
|
@@ -4,7 +4,7 @@ from conans import ConanFile
|
|||||||
|
|
||||||
class CatchConan(ConanFile):
|
class CatchConan(ConanFile):
|
||||||
name = "Catch"
|
name = "Catch"
|
||||||
version = "2.1.0"
|
version = "2.1.2"
|
||||||
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
||||||
author = "philsquared"
|
author = "philsquared"
|
||||||
generators = "cmake"
|
generators = "cmake"
|
||||||
|
175
contrib/Catch.cmake
Normal file
175
contrib/Catch.cmake
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
#[=======================================================================[.rst:
|
||||||
|
Catch
|
||||||
|
-----
|
||||||
|
|
||||||
|
This module defines a function to help use the Catch test framework.
|
||||||
|
|
||||||
|
The :command:`catch_discover_tests` discovers tests by asking the compiled test
|
||||||
|
executable to enumerate its tests. This does not require CMake to be re-run
|
||||||
|
when tests change. However, it may not work in a cross-compiling environment,
|
||||||
|
and setting test properties is less convenient.
|
||||||
|
|
||||||
|
This command is intended to replace use of :command:`add_test` to register
|
||||||
|
tests, and will create a separate CTest test for each Catch test case. Note
|
||||||
|
that this is in some cases less efficient, as common set-up and tear-down logic
|
||||||
|
cannot be shared by multiple test cases executing in the same instance.
|
||||||
|
However, it provides more fine-grained pass/fail information to CTest, which is
|
||||||
|
usually considered as more beneficial. By default, the CTest test name is the
|
||||||
|
same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
||||||
|
|
||||||
|
.. command:: catch_discover_tests
|
||||||
|
|
||||||
|
Automatically add tests with CTest by querying the compiled test executable
|
||||||
|
for available tests::
|
||||||
|
|
||||||
|
catch_discover_tests(target
|
||||||
|
[TEST_SPEC arg1...]
|
||||||
|
[EXTRA_ARGS arg1...]
|
||||||
|
[WORKING_DIRECTORY dir]
|
||||||
|
[TEST_PREFIX prefix]
|
||||||
|
[TEST_SUFFIX suffix]
|
||||||
|
[PROPERTIES name1 value1...]
|
||||||
|
[TEST_LIST var]
|
||||||
|
)
|
||||||
|
|
||||||
|
``catch_discover_tests`` sets up a post-build command on the test executable
|
||||||
|
that generates the list of tests by parsing the output from running the test
|
||||||
|
with the ``--list-test-names-only`` argument. This ensures that the full
|
||||||
|
list of tests is obtained. Since test discovery occurs at build time, it is
|
||||||
|
not necessary to re-run CMake when the list of tests changes.
|
||||||
|
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
|
||||||
|
in order to function in a cross-compiling environment.
|
||||||
|
|
||||||
|
Additionally, setting properties on tests is somewhat less convenient, since
|
||||||
|
the tests are not available at CMake time. Additional test properties may be
|
||||||
|
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
|
||||||
|
more fine-grained test control is needed, custom content may be provided
|
||||||
|
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
|
||||||
|
directory property. The set of discovered tests is made accessible to such a
|
||||||
|
script via the ``<target>_TESTS`` variable.
|
||||||
|
|
||||||
|
The options are:
|
||||||
|
|
||||||
|
``target``
|
||||||
|
Specifies the Catch executable, which must be a known CMake executable
|
||||||
|
target. CMake will substitute the location of the built executable when
|
||||||
|
running the test.
|
||||||
|
|
||||||
|
``TEST_SPEC arg1...``
|
||||||
|
Specifies test cases, wildcarded test cases, tags and tag expressions to
|
||||||
|
pass to the Catch executable with the ``--list-test-names-only`` argument.
|
||||||
|
|
||||||
|
``EXTRA_ARGS arg1...``
|
||||||
|
Any extra arguments to pass on the command line to each test case.
|
||||||
|
|
||||||
|
``WORKING_DIRECTORY dir``
|
||||||
|
Specifies the directory in which to run the discovered test cases. If this
|
||||||
|
option is not provided, the current binary directory is used.
|
||||||
|
|
||||||
|
``TEST_PREFIX prefix``
|
||||||
|
Specifies a ``prefix`` to be prepended to the name of each discovered test
|
||||||
|
case. This can be useful when the same test executable is being used in
|
||||||
|
multiple calls to ``catch_discover_tests()`` but with different
|
||||||
|
``TEST_SPEC`` or ``EXTRA_ARGS``.
|
||||||
|
|
||||||
|
``TEST_SUFFIX suffix``
|
||||||
|
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||||
|
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
|
||||||
|
be specified.
|
||||||
|
|
||||||
|
``PROPERTIES name1 value1...``
|
||||||
|
Specifies additional properties to be set on all tests discovered by this
|
||||||
|
invocation of ``catch_discover_tests``.
|
||||||
|
|
||||||
|
``TEST_LIST var``
|
||||||
|
Make the list of tests available in the variable ``var``, rather than the
|
||||||
|
default ``<target>_TESTS``. This can be useful when the same test
|
||||||
|
executable is being used in multiple calls to ``catch_discover_tests()``.
|
||||||
|
Note that this variable is only available in CTest.
|
||||||
|
|
||||||
|
#]=======================================================================]
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
function(catch_discover_tests TARGET)
|
||||||
|
cmake_parse_arguments(
|
||||||
|
""
|
||||||
|
""
|
||||||
|
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST"
|
||||||
|
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT _WORKING_DIRECTORY)
|
||||||
|
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
endif()
|
||||||
|
if(NOT _TEST_LIST)
|
||||||
|
set(_TEST_LIST ${TARGET}_TESTS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## Generate a unique name based on the extra arguments
|
||||||
|
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
|
||||||
|
string(SUBSTRING ${args_hash} 0 7 args_hash)
|
||||||
|
|
||||||
|
# Define rule to generate test list for aforementioned test executable
|
||||||
|
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
|
||||||
|
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
|
||||||
|
get_property(crosscompiling_emulator
|
||||||
|
TARGET ${TARGET}
|
||||||
|
PROPERTY CROSSCOMPILING_EMULATOR
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET} POST_BUILD
|
||||||
|
BYPRODUCTS "${ctest_tests_file}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "TEST_TARGET=${TARGET}"
|
||||||
|
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
|
||||||
|
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
|
||||||
|
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
|
||||||
|
-D "TEST_SPEC=${_TEST_SPEC}"
|
||||||
|
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
|
||||||
|
-D "TEST_PROPERTIES=${_PROPERTIES}"
|
||||||
|
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||||
|
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||||
|
-D "TEST_LIST=${_TEST_LIST}"
|
||||||
|
-D "CTEST_FILE=${ctest_tests_file}"
|
||||||
|
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
file(WRITE "${ctest_include_file}"
|
||||||
|
"if(EXISTS \"${ctest_tests_file}\")\n"
|
||||||
|
" include(\"${ctest_tests_file}\")\n"
|
||||||
|
"else()\n"
|
||||||
|
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
|
||||||
|
"endif()\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
|
||||||
|
# Add discovered tests to directory TEST_INCLUDE_FILES
|
||||||
|
set_property(DIRECTORY
|
||||||
|
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
|
||||||
|
get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
|
||||||
|
if (NOT ${test_include_file_set})
|
||||||
|
set_property(DIRECTORY
|
||||||
|
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Cannot set more than one TEST_INCLUDE_FILE"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set(_CATCH_DISCOVER_TESTS_SCRIPT
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
|
||||||
|
)
|
77
contrib/CatchAddTests.cmake
Normal file
77
contrib/CatchAddTests.cmake
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
set(prefix "${TEST_PREFIX}")
|
||||||
|
set(suffix "${TEST_SUFFIX}")
|
||||||
|
set(spec ${TEST_SPEC})
|
||||||
|
set(extra_args ${TEST_EXTRA_ARGS})
|
||||||
|
set(properties ${TEST_PROPERTIES})
|
||||||
|
set(script)
|
||||||
|
set(suite)
|
||||||
|
set(tests)
|
||||||
|
|
||||||
|
function(add_command NAME)
|
||||||
|
set(_args "")
|
||||||
|
foreach(_arg ${ARGN})
|
||||||
|
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||||
|
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
|
||||||
|
else()
|
||||||
|
set(_args "${_args} ${_arg}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Run test executable to get list of available tests
|
||||||
|
if(NOT EXISTS "${TEST_EXECUTABLE}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
|
||||||
|
if(${result} EQUAL 0)
|
||||||
|
message(WARNING
|
||||||
|
"Test executable '${TEST_EXECUTABLE}' contains no tests!\n"
|
||||||
|
)
|
||||||
|
elseif(${result} LESS 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Error running test executable '${TEST_EXECUTABLE}':\n"
|
||||||
|
" Result: ${result}\n"
|
||||||
|
" Output: ${output}\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REPLACE "\n" ";" output "${output}")
|
||||||
|
|
||||||
|
# Parse output
|
||||||
|
foreach(line ${output})
|
||||||
|
# Test name; strip spaces to get just the name...
|
||||||
|
string(REGEX REPLACE " +" "" test "${line}")
|
||||||
|
# ...and add to script
|
||||||
|
add_command(add_test
|
||||||
|
"${prefix}${test}${suffix}"
|
||||||
|
${TEST_EXECUTOR}
|
||||||
|
"${TEST_EXECUTABLE}"
|
||||||
|
"${test}"
|
||||||
|
${extra_args}
|
||||||
|
)
|
||||||
|
add_command(set_tests_properties
|
||||||
|
"${prefix}${test}${suffix}"
|
||||||
|
PROPERTIES
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
|
${properties}
|
||||||
|
)
|
||||||
|
list(APPEND tests "${prefix}${test}${suffix}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Create a list of all discovered tests, which users may use to e.g. set
|
||||||
|
# properties on the tests
|
||||||
|
add_command(set ${TEST_LIST} ${tests})
|
||||||
|
|
||||||
|
# Write CTest script
|
||||||
|
file(WRITE "${CTEST_FILE}" "${script}")
|
@@ -28,9 +28,14 @@ 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.
|
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.
|
||||||
|
|
||||||
## Other reporters
|
## 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.
|
Other reporters are not part of the single-header distribution and need
|
||||||
|
to be downloaded and included separately. All reporters are stored in
|
||||||
|
`single_include` directory in the git repository, and are named
|
||||||
|
`catch_reporter_*.hpp`. For example, to use the TeamCity reporter you
|
||||||
|
need to download `single_include/catch_reporter_teamcity.hpp` and include
|
||||||
|
it after Catch itself.
|
||||||
|
|
||||||
```
|
```cpp
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "catch_reporter_teamcity.hpp"
|
#include "catch_reporter_teamcity.hpp"
|
||||||
@@ -124,7 +129,15 @@ The advantage of this approach is that you can always automatically update Catch
|
|||||||
|
|
||||||
|
|
||||||
### Automatic test registration
|
### 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
|
We provide 2 CMake scripts that can automatically register Catch-based
|
||||||
|
tests with CTest,
|
||||||
|
* `contrib/ParseAndAddCatchTests.cmake`
|
||||||
|
* `contrib/CatchAddTests.cmake`
|
||||||
|
|
||||||
|
The first is based on parsing the test implementation files, and attempts
|
||||||
|
to register all `TEST_CASE`s using their tags as labels. This means that
|
||||||
|
these:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
TEST_CASE("Test1", "[unit]") {
|
TEST_CASE("Test1", "[unit]") {
|
||||||
int a = 1;
|
int a = 1;
|
||||||
@@ -144,7 +157,14 @@ TEST_CASE("Test3", "[a][b][c]") {
|
|||||||
REQUIRE(a == b);
|
REQUIRE(a == b);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
would be registered as 3 tests, `Test1`, `Test2` and `Test3`, and 4 ctest labels would be created, `a`, `b`, `c` and `unit`.
|
would be registered as 3 tests, `Test1`, `Test2` and `Test3`,
|
||||||
|
and 4 CTest labels would be created, `a`, `b`, `c` and `unit`.
|
||||||
|
|
||||||
|
|
||||||
|
The second is based on parsing the output of a Catch binary given
|
||||||
|
`--list-test-names-only`. This means that it deals with inactive
|
||||||
|
(e.g. commented-out) tests better, but requires CMake 3.10 for full
|
||||||
|
functionality.
|
||||||
|
|
||||||
### CodeCoverage module (GCOV, LCOV...)
|
### CodeCoverage module (GCOV, LCOV...)
|
||||||
|
|
||||||
|
@@ -35,6 +35,9 @@ The next-generation core storage and query engine for Couchbase Lite
|
|||||||
### [DtCraft](https://github.com/twhuang-uiuc/DtCraft)
|
### [DtCraft](https://github.com/twhuang-uiuc/DtCraft)
|
||||||
A High-performance Cluster Computing Engine
|
A High-performance Cluster Computing Engine
|
||||||
|
|
||||||
|
### [forest](https://github.com/xorz57/forest)
|
||||||
|
Forest is an open-source, template library of tree data structures written in C++11.
|
||||||
|
|
||||||
### [Fuxedo](https://github.com/fuxedo/fuxedo)
|
### [Fuxedo](https://github.com/fuxedo/fuxedo)
|
||||||
Open source Oracle Tuxedo-like XATMI middleware for C and C++.
|
Open source Oracle Tuxedo-like XATMI middleware for C and C++.
|
||||||
|
|
||||||
|
@@ -81,6 +81,7 @@ int main( int argc, char* argv[] )
|
|||||||
int height = 0; // Some user variable you want to be able to set
|
int height = 0; // Some user variable you want to be able to set
|
||||||
|
|
||||||
// Build a new parser on top of Catch's
|
// Build a new parser on top of Catch's
|
||||||
|
using namespace Catch::clara;
|
||||||
auto cli
|
auto cli
|
||||||
= session.cli() // Get Catch's composite command line parser
|
= session.cli() // Get Catch's composite command line parser
|
||||||
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
||||||
@@ -105,6 +106,20 @@ int main( int argc, char* argv[] )
|
|||||||
|
|
||||||
See the [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) for more details.
|
See the [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) for more details.
|
||||||
|
|
||||||
|
|
||||||
|
## Version detection
|
||||||
|
|
||||||
|
Catch provides a triplet of macros providing the header's version,
|
||||||
|
|
||||||
|
* `CATCH_VERSION_MAJOR`
|
||||||
|
* `CATCH_VERSION_MINOR`
|
||||||
|
* `CATCH_VERSION_PATCH`
|
||||||
|
|
||||||
|
these macros expand into a single number, that corresponds to the appropriate
|
||||||
|
part of the version. As an example, given single header version v2.3.4,
|
||||||
|
the macros would expand into `2`, `3`, and `4` respectively.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md#top)
|
[Home](Readme.md#top)
|
||||||
|
@@ -1,5 +1,44 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
|
|
||||||
|
# 2.1.2
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
* Fixed compilation error with `-fno-rtti` (#1165)
|
||||||
|
* Fixed NoAssertion warnings
|
||||||
|
* `operator<<` is used before range-based stringification (#1172)
|
||||||
|
* Fixed `-Wpedantic` warnings (extra semicolons and binary literals) (#1173)
|
||||||
|
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* Added `CATCH_VERSION_{MAJOR,MINOR,PATCH}` macros (#1131)
|
||||||
|
* Added `BrightYellow` colour for use in reporters (#979)
|
||||||
|
* It is also used by ConsoleReporter for reconstructed expressions
|
||||||
|
|
||||||
|
## Other changes
|
||||||
|
* Catch is now exported as a CMake package and linkable target (#1170)
|
||||||
|
|
||||||
|
# 2.1.1
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* Static arrays are now properly stringified like ranges across MSVC/GCC/Clang
|
||||||
|
* Embedded newer version of Clara -- v1.1.1
|
||||||
|
* This should fix some warnings dragged in from Clara
|
||||||
|
* MSVC's CLR exceptions are supported
|
||||||
|
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
* Fixed compilation when comparison operators do not return bool (#1147)
|
||||||
|
* Fixed CLR exceptions blowing up the executable during translation (#1138)
|
||||||
|
|
||||||
|
|
||||||
|
## Other changes
|
||||||
|
* Many CMake changes
|
||||||
|
* `NO_SELFTEST` option is deprecated, use `BUILD_TESTING` instead.
|
||||||
|
* Catch specific CMake options were prefixed with `CATCH_` for namespacing purposes
|
||||||
|
* Other changes to simplify Catch2's packaging
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 2.1.0
|
# 2.1.0
|
||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
|
@@ -21,10 +21,8 @@ Catch uses a variant of [semantic versioning](http://semver.org/), with breaking
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
This will take care of generating the single include header, updating
|
||||||
### Generate updated single-include header
|
version numbers everywhere and pushing the new version to Wandbox.
|
||||||
|
|
||||||
After updating version number, regenerate single-include header using `generateSingleHeader.py`.
|
|
||||||
|
|
||||||
|
|
||||||
### Release notes
|
### Release notes
|
||||||
@@ -39,11 +37,19 @@ After version number is incremented, single-include header is regenerated and re
|
|||||||
|
|
||||||
### Release on 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.
|
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. All non-bundled reporters (Automake,
|
||||||
|
TAP, TeamCity) should also be attached as binaries, as they are dependent
|
||||||
|
on a specific version of the single-include header.
|
||||||
|
|
||||||
|
|
||||||
## Optional steps
|
## Optional steps
|
||||||
|
|
||||||
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they are *should* happen, but they can happen the next day without losing anything significant.
|
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they *should* happen, but they can happen the next day without losing anything significant.
|
||||||
|
|
||||||
|
|
||||||
### vcpkg update
|
### vcpkg update
|
||||||
@@ -57,8 +63,3 @@ GitHub
|
|||||||
vcpkg
|
vcpkg
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Wandbox update
|
|
||||||
|
|
||||||
Recently we also included a link to wandbox with preloaded Catch on the main page. Strictly speaking it is unneccessary to update this after every release, Catch usually does not change that much between versions, but it should be kept up to date anyway.
|
|
||||||
|
|
||||||
|
@@ -33,6 +33,23 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Catch::is_range<T> specialisation
|
||||||
|
As a fallback, Catch attempts to detect if the type can be iterated
|
||||||
|
(`begin(T)` and `end(T)` are valid) and if it can be, it is stringified
|
||||||
|
as a range. For certain types this can lead to infinite recursion, so
|
||||||
|
it can be disabled by specializing `Catch::is_range` like so:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace Catch {
|
||||||
|
template<>
|
||||||
|
struct is_range<T> {
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
|
By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Build examples.
|
# Build examples.
|
||||||
#
|
#
|
||||||
# Requires BUILD_EXAMPLES to be defined 'true', see ../CMakeLists.txt.
|
# Requires CATCH_BUILD_EXAMPLES to be defined 'true', see ../CMakeLists.txt.
|
||||||
#
|
#
|
||||||
|
|
||||||
cmake_minimum_required( VERSION 3.0 )
|
cmake_minimum_required( VERSION 3.0 )
|
||||||
|
@@ -9,6 +9,9 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
|
||||||
|
|
||||||
|
#define CATCH_VERSION_MAJOR 2
|
||||||
|
#define CATCH_VERSION_MINOR 1
|
||||||
|
#define CATCH_VERSION_PATCH 2
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang system_header
|
# pragma clang system_header
|
||||||
|
106
include/external/clara.hpp
vendored
106
include/external/clara.hpp
vendored
@@ -1,5 +1,11 @@
|
|||||||
// v1.0-develop.2
|
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
// See https://github.com/philsquared/Clara
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// See https://github.com/philsquared/Clara for more details
|
||||||
|
|
||||||
|
// Clara v1.1.2
|
||||||
|
|
||||||
#ifndef CATCH_CLARA_HPP_INCLUDED
|
#ifndef CATCH_CLARA_HPP_INCLUDED
|
||||||
#define CATCH_CLARA_HPP_INCLUDED
|
#define CATCH_CLARA_HPP_INCLUDED
|
||||||
@@ -370,7 +376,7 @@ namespace detail {
|
|||||||
template<typename ClassT, typename ReturnT, typename ArgT>
|
template<typename ClassT, typename ReturnT, typename ArgT>
|
||||||
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
||||||
static const bool isValid = true;
|
static const bool isValid = true;
|
||||||
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
|
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
|
||||||
using ReturnType = ReturnT;
|
using ReturnType = ReturnT;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -535,7 +541,7 @@ namespace detail {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResultValueBase() {
|
~ResultValueBase() override {
|
||||||
if( m_type == Ok )
|
if( m_type == Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
}
|
}
|
||||||
@@ -573,7 +579,7 @@ namespace detail {
|
|||||||
auto errorMessage() const -> std::string { return m_errorMessage; }
|
auto errorMessage() const -> std::string { return m_errorMessage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void enforceOk() const {
|
void enforceOk() const override {
|
||||||
// !TBD: If no exceptions, std::terminate here or something
|
// !TBD: If no exceptions, std::terminate here or something
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ResultBase::LogicError:
|
case ResultBase::LogicError:
|
||||||
@@ -653,46 +659,32 @@ namespace detail {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BoundRefBase {
|
struct NonCopyable {
|
||||||
BoundRefBase() = default;
|
NonCopyable() = default;
|
||||||
BoundRefBase( BoundRefBase const & ) = delete;
|
NonCopyable( NonCopyable const & ) = delete;
|
||||||
BoundRefBase( BoundRefBase && ) = delete;
|
NonCopyable( NonCopyable && ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase const & ) = delete;
|
NonCopyable &operator=( NonCopyable const & ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase && ) = delete;
|
NonCopyable &operator=( NonCopyable && ) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~BoundRefBase() = default;
|
struct BoundRef : NonCopyable {
|
||||||
|
virtual ~BoundRef() = default;
|
||||||
virtual auto isFlag() const -> bool = 0;
|
|
||||||
virtual auto isContainer() const -> bool { return false; }
|
virtual auto isContainer() const -> bool { return false; }
|
||||||
|
virtual auto isFlag() const -> bool { return false; }
|
||||||
|
};
|
||||||
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
||||||
|
};
|
||||||
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
||||||
};
|
virtual auto isFlag() const -> bool { return true; }
|
||||||
|
|
||||||
struct BoundValueRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return false; }
|
|
||||||
|
|
||||||
auto setFlag( bool ) -> ParserResult override {
|
|
||||||
return ParserResult::logicError( "Flags can only be set on boolean fields" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundFlagRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return true; }
|
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
|
||||||
bool flag;
|
|
||||||
auto result = convertInto( arg, flag );
|
|
||||||
if( result )
|
|
||||||
setFlag( flag );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( T &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
auto setValue( std::string const &arg ) -> ParserResult override {
|
||||||
return convertInto( arg, m_ref );
|
return convertInto( arg, m_ref );
|
||||||
@@ -700,10 +692,10 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T> &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
@@ -748,12 +740,12 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename ArgType, typename L>
|
template<typename ArgType, typename L>
|
||||||
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
||||||
ArgType temp;
|
ArgType temp{};
|
||||||
auto result = convertInto( arg, temp );
|
auto result = convertInto( arg, temp );
|
||||||
return !result
|
return !result
|
||||||
? result
|
? result
|
||||||
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
@@ -803,6 +795,9 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator|( T const &other ) const -> Parser;
|
auto operator|( T const &other ) const -> Parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@@ -810,16 +805,16 @@ namespace detail {
|
|||||||
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ParserRefImpl( T &ref, std::string const &hint )
|
ParserRefImpl( T &ref, std::string const &hint )
|
||||||
: m_ref( std::make_shared<BoundRef<T>>( ref ) ),
|
: m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint )
|
m_hint( hint )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -860,10 +855,10 @@ namespace detail {
|
|||||||
|
|
||||||
class ExeName : public ComposableParserImpl<ExeName> {
|
class ExeName : public ComposableParserImpl<ExeName> {
|
||||||
std::shared_ptr<std::string> m_name;
|
std::shared_ptr<std::string> m_name;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
|
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,7 +866,7 @@ namespace detail {
|
|||||||
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
||||||
|
|
||||||
explicit ExeName( std::string &ref ) : ExeName() {
|
explicit ExeName( std::string &ref ) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundRef<std::string>>( ref );
|
m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
@@ -914,7 +909,10 @@ namespace detail {
|
|||||||
if( token.type != TokenType::Argument )
|
if( token.type != TokenType::Argument )
|
||||||
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
||||||
|
|
||||||
auto result = m_ref->setValue( remainingTokens->token );
|
assert( !m_ref->isFlag() );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
|
|
||||||
|
auto result = valueRef->setValue( remainingTokens->token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
else
|
else
|
||||||
@@ -988,19 +986,21 @@ namespace detail {
|
|||||||
auto const &token = *remainingTokens;
|
auto const &token = *remainingTokens;
|
||||||
if( isMatch(token.token ) ) {
|
if( isMatch(token.token ) ) {
|
||||||
if( m_ref->isFlag() ) {
|
if( m_ref->isFlag() ) {
|
||||||
auto result = m_ref->setFlag( true );
|
auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
|
||||||
|
auto result = flagRef->setFlag( true );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
||||||
} else {
|
} else {
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if( !remainingTokens )
|
if( !remainingTokens )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto const &argToken = *remainingTokens;
|
auto const &argToken = *remainingTokens;
|
||||||
if( argToken.type != TokenType::Argument )
|
if( argToken.type != TokenType::Argument )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto result = m_ref->setValue( argToken.token );
|
auto result = valueRef->setValue( argToken.token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
@@ -1077,6 +1077,12 @@ namespace detail {
|
|||||||
return Parser( *this ) |= other;
|
return Parser( *this ) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
|
template<typename T>
|
||||||
|
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser { return operator|( other ); }
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const &o : m_options) {
|
||||||
@@ -1116,6 +1122,8 @@ namespace detail {
|
|||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
|
optWidth = (std::min)(optWidth, consoleWidth/2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
||||||
|
@@ -31,6 +31,14 @@
|
|||||||
# define CATCH_CPP14_OR_GREATER
|
# define CATCH_CPP14_OR_GREATER
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if __cplusplus >= 201703L
|
||||||
|
# define CATCH_CPP17_OR_GREATER
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_CPP17_OR_GREATER)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
@@ -80,6 +88,11 @@
|
|||||||
// Visual C++
|
// Visual C++
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
|
||||||
|
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
# endif
|
||||||
|
|
||||||
// Universal Windows platform does not support SEH
|
// Universal Windows platform does not support SEH
|
||||||
// Or console colours (or console at all...)
|
// Or console colours (or console at all...)
|
||||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
@@ -112,6 +125,11 @@
|
|||||||
# define CATCH_CONFIG_POSIX_SIGNALS
|
# define CATCH_CONFIG_POSIX_SIGNALS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_INTERNAL_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
||||||
|
@@ -84,8 +84,12 @@ namespace {
|
|||||||
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
|
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
|
||||||
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
|
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
|
||||||
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
||||||
|
case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
|
||||||
|
|
||||||
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
||||||
|
|
||||||
|
default:
|
||||||
|
CATCH_ERROR( "Unknown colour requested" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +147,10 @@ namespace {
|
|||||||
case Colour::BrightRed: return setColour( "[1;31m" );
|
case Colour::BrightRed: return setColour( "[1;31m" );
|
||||||
case Colour::BrightGreen: return setColour( "[1;32m" );
|
case Colour::BrightGreen: return setColour( "[1;32m" );
|
||||||
case Colour::BrightWhite: return setColour( "[1;37m" );
|
case Colour::BrightWhite: return setColour( "[1;37m" );
|
||||||
|
case Colour::BrightYellow: return setColour( "[1;33m" );
|
||||||
|
|
||||||
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
||||||
|
default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static IColourImpl* instance() {
|
static IColourImpl* instance() {
|
||||||
|
@@ -30,10 +30,11 @@ namespace Catch {
|
|||||||
BrightGreen = Bright | Green,
|
BrightGreen = Bright | Green,
|
||||||
LightGrey = Bright | Grey,
|
LightGrey = Bright | Grey,
|
||||||
BrightWhite = Bright | White,
|
BrightWhite = Bright | White,
|
||||||
|
BrightYellow = Bright | Yellow,
|
||||||
|
|
||||||
// By intention
|
// By intention
|
||||||
FileName = LightGrey,
|
FileName = LightGrey,
|
||||||
Warning = Yellow,
|
Warning = BrightYellow,
|
||||||
ResultError = BrightRed,
|
ResultError = BrightRed,
|
||||||
ResultSuccess = BrightGreen,
|
ResultSuccess = BrightGreen,
|
||||||
ResultExpectedFailure = Warning,
|
ResultExpectedFailure = Warning,
|
||||||
@@ -42,7 +43,7 @@ namespace Catch {
|
|||||||
Success = Green,
|
Success = Green,
|
||||||
|
|
||||||
OriginalExpression = Cyan,
|
OriginalExpression = Cyan,
|
||||||
ReconstructedExpression = Yellow,
|
ReconstructedExpression = BrightYellow,
|
||||||
|
|
||||||
SecondaryText = LightGrey,
|
SecondaryText = LightGrey,
|
||||||
Headers = White
|
Headers = White
|
||||||
|
@@ -40,7 +40,10 @@ namespace Catch {
|
|||||||
#ifdef CATCH_TRAP
|
#ifdef CATCH_TRAP
|
||||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
||||||
#else
|
#else
|
||||||
#define CATCH_BREAK_INTO_DEBUGGER() (void)0, 0
|
namespace Catch {
|
||||||
|
inline void doNothing() {}
|
||||||
|
}
|
||||||
|
#define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
||||||
|
@@ -82,7 +82,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; };
|
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -93,7 +93,7 @@ namespace Catch {
|
|||||||
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
||||||
|
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs != rhs; };
|
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -128,19 +128,19 @@ namespace Catch {
|
|||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs > rhs, m_lhs, ">", rhs };
|
return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs < rhs, m_lhs, "<", rhs };
|
return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs >= rhs, m_lhs, ">=", rhs };
|
return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs <= rhs, m_lhs, "<=", rhs };
|
return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||||
|
@@ -33,6 +33,17 @@ namespace Catch {
|
|||||||
return Catch::Detail::stringify( [exception description] );
|
return Catch::Detail::stringify( [exception description] );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
// Compiling a mixed mode project with MSVC means that CLR
|
||||||
|
// exceptions will be caught in (...) as well. However, these
|
||||||
|
// do not fill-in std::current_exception and thus lead to crash
|
||||||
|
// when attempting rethrow.
|
||||||
|
// /EHa switch also causes structured exceptions to be caught
|
||||||
|
// here, but they fill-in current_exception properly, so
|
||||||
|
// at worst the output should be a little weird, instead of
|
||||||
|
// causing a crash.
|
||||||
|
if (std::current_exception() == nullptr) {
|
||||||
|
return "Non C++ exception. Possibly a CLR exception.";
|
||||||
|
}
|
||||||
return tryTranslators();
|
return tryTranslators();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -17,12 +17,14 @@
|
|||||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(CATCH_PLATFORM_WINDOWS) && defined(CATCH_CONFIG_WINDOWS_SEH)) || defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||||
namespace {
|
namespace {
|
||||||
// Report the error condition
|
// Report the error condition
|
||||||
void reportFatal( char const * const message ) {
|
void reportFatal( char const * const message ) {
|
||||||
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
|
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "catch_message.h"
|
#include "catch_message.h"
|
||||||
#include "catch_interfaces_capture.h"
|
#include "catch_interfaces_capture.h"
|
||||||
|
#include "catch_uncaught_exceptions.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@@ -49,18 +50,9 @@ namespace Catch {
|
|||||||
getResultCapture().pushScopedMessage( m_info );
|
getResultCapture().pushScopedMessage( m_info );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
|
|
||||||
#endif
|
|
||||||
ScopedMessage::~ScopedMessage() {
|
ScopedMessage::~ScopedMessage() {
|
||||||
if ( !std::uncaught_exception() ){
|
if ( !uncaught_exceptions() ){
|
||||||
getResultCapture().popScopedMessage(m_info);
|
getResultCapture().popScopedMessage(m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -321,12 +321,13 @@ namespace Catch {
|
|||||||
handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
|
handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Counts assertions = m_totals.assertions - prevAssertions;
|
||||||
|
bool missingAssertions = testForMissingAssertions(assertions);
|
||||||
|
|
||||||
m_testCaseTracker->close();
|
m_testCaseTracker->close();
|
||||||
handleUnfinishedSections();
|
handleUnfinishedSections();
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
|
||||||
Counts assertions = m_totals.assertions - prevAssertions;
|
|
||||||
bool missingAssertions = testForMissingAssertions(assertions);
|
|
||||||
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
||||||
m_reporter->sectionEnded(testCaseSectionStats);
|
m_reporter->sectionEnded(testCaseSectionStats);
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "catch_section.h"
|
#include "catch_section.h"
|
||||||
#include "catch_capture.hpp"
|
#include "catch_capture.hpp"
|
||||||
|
#include "catch_uncaught_exceptions.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@@ -18,22 +19,15 @@ namespace Catch {
|
|||||||
m_timer.start();
|
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() {
|
Section::~Section() {
|
||||||
if( m_sectionIncluded ) {
|
if( m_sectionIncluded ) {
|
||||||
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||||
if( std::uncaught_exception() )
|
if( uncaught_exceptions() )
|
||||||
getResultCapture().sectionEndedEarly( endInfo );
|
getResultCapture().sectionEndedEarly( endInfo );
|
||||||
else
|
else
|
||||||
getResultCapture().sectionEnded( endInfo );
|
getResultCapture().sectionEnded( endInfo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This indicates whether the section should be executed or not
|
// This indicates whether the section should be executed or not
|
||||||
Section::operator bool() const {
|
Section::operator bool() const {
|
||||||
|
@@ -259,6 +259,9 @@ namespace Catch {
|
|||||||
if( Option<std::size_t> listed = list( config() ) )
|
if( Option<std::size_t> listed = list( config() ) )
|
||||||
return static_cast<int>( *listed );
|
return static_cast<int>( *listed );
|
||||||
|
|
||||||
|
// Note that on unices only the lower 8 bits are usually used, clamping
|
||||||
|
// the return value to 255 prevents false negative when some multiple
|
||||||
|
// of 256 tests has failed
|
||||||
return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
|
return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
|
||||||
}
|
}
|
||||||
catch( std::exception& ex ) {
|
catch( std::exception& ex ) {
|
||||||
|
@@ -15,6 +15,13 @@
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const uint32_t byte_2_lead = 0xC0;
|
||||||
|
const uint32_t byte_3_lead = 0xE0;
|
||||||
|
const uint32_t byte_4_lead = 0xF0;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
StringRef::StringRef( char const* rawChars ) noexcept
|
StringRef::StringRef( char const* rawChars ) noexcept
|
||||||
@@ -79,13 +86,12 @@ namespace Catch {
|
|||||||
// Make adjustments for uft encodings
|
// Make adjustments for uft encodings
|
||||||
for( size_type i=0; i < m_size; ++i ) {
|
for( size_type i=0; i < m_size; ++i ) {
|
||||||
char c = m_start[i];
|
char c = m_start[i];
|
||||||
if( ( c & 0b11000000 ) == 0b11000000 ) {
|
if( ( c & byte_2_lead ) == byte_2_lead ) {
|
||||||
if( ( c & 0b11100000 ) == 0b11000000 )
|
noChars--;
|
||||||
|
if (( c & byte_3_lead ) == byte_3_lead )
|
||||||
|
noChars--;
|
||||||
|
if( ( c & byte_4_lead ) == byte_4_lead )
|
||||||
noChars--;
|
noChars--;
|
||||||
else if( ( c & 0b11110000 ) == 0b11100000 )
|
|
||||||
noChars-=2;
|
|
||||||
else if( ( c & 0b11111000 ) == 0b11110000 )
|
|
||||||
noChars-=3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noChars;
|
return noChars;
|
||||||
|
@@ -63,11 +63,11 @@ namespace Catch {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& ) {
|
typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& ) {
|
||||||
return Detail::unprintableString;
|
return Detail::unprintableString;
|
||||||
};
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
||||||
return convertUnknownEnumToString( value );
|
return convertUnknownEnumToString( value );
|
||||||
};
|
}
|
||||||
|
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
@@ -136,18 +136,6 @@ namespace Catch {
|
|||||||
static std::string convert(wchar_t * str);
|
static std::string convert(wchar_t * str);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_string_array : std::false_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<signed char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<unsigned char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<int SZ>
|
template<int SZ>
|
||||||
struct StringMaker<char[SZ]> {
|
struct StringMaker<char[SZ]> {
|
||||||
static std::string convert(const char* str) {
|
static std::string convert(const char* str) {
|
||||||
@@ -399,12 +387,20 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
struct StringMaker<R, typename std::enable_if<is_range<R>::value && !is_string_array<R>::value>::type> {
|
struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
|
||||||
static std::string convert( R const& range ) {
|
static std::string convert( R const& range ) {
|
||||||
return rangeToString( range );
|
return rangeToString( range );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, int SZ>
|
||||||
|
struct StringMaker<T[SZ]> {
|
||||||
|
static std::string convert(T const(&arr)[SZ]) {
|
||||||
|
return rangeToString(arr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
// Separate std::chrono::duration specialization
|
// Separate std::chrono::duration specialization
|
||||||
|
21
include/internal/catch_uncaught_exceptions.cpp
Normal file
21
include/internal/catch_uncaught_exceptions.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Created by Josh on 1/2/2018.
|
||||||
|
* Copyright 2018 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_compiler_capabilities.h"
|
||||||
|
#include "catch_uncaught_exceptions.h"
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
bool uncaught_exceptions() {
|
||||||
|
#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
return std::uncaught_exceptions() > 0;
|
||||||
|
#else
|
||||||
|
return std::uncaught_exception();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // end namespace Catch
|
15
include/internal/catch_uncaught_exceptions.h
Normal file
15
include/internal/catch_uncaught_exceptions.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Created by Josh on 1/2/2018.
|
||||||
|
* Copyright 2018 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_UNCAUGHT_EXCEPTIONS_H_INCLUDED
|
||||||
|
#define TWOBLUECUBES_CATCH_UNCAUGHT_EXCEPTIONS_H_INCLUDED
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
bool uncaught_exceptions();
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // TWOBLUECUBES_CATCH_UNCAUGHT_EXCEPTIONS_H_INCLUDED
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 1, 0, "", 0 );
|
static Version version( 2, 1, 2, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,7 +64,7 @@ namespace Catch {
|
|||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JunitReporter::~JunitReporter() {};
|
JunitReporter::~JunitReporter() {}
|
||||||
|
|
||||||
std::string JunitReporter::getDescription() {
|
std::string JunitReporter::getDescription() {
|
||||||
return "Reports test results in an XML format that looks like Ant's junitreport target";
|
return "Reports test results in an XML format that looks like Ant's junitreport target";
|
||||||
|
@@ -6,7 +6,7 @@ if "%CONFIGURATION%"=="Debug" (
|
|||||||
python scripts\generateSingleHeader.py
|
python scripts\generateSingleHeader.py
|
||||||
cmake -Hmisc -Bbuild-misc -A%PLATFORM%
|
cmake -Hmisc -Bbuild-misc -A%PLATFORM%
|
||||||
cmake --build build-misc
|
cmake --build build-misc
|
||||||
cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DBUILD_EXAMPLES=ON -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind
|
cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=ON -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind
|
||||||
)
|
)
|
||||||
if "%CONFIGURATION%"=="Release" (
|
if "%CONFIGURATION%"=="Release" (
|
||||||
cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
|
cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
|
||||||
|
@@ -96,5 +96,10 @@ int main(int argc, char** argv) {
|
|||||||
return lhs + ' ' + rhs;
|
return lhs + ' ' + rhs;
|
||||||
});
|
});
|
||||||
|
|
||||||
exec_cmd(cmdline, num, windowsify_path(catch_path(args[0])));
|
try {
|
||||||
|
return exec_cmd(cmdline, num, windowsify_path(catch_path(args[0])));
|
||||||
|
} catch (std::exception const& ex) {
|
||||||
|
std::cerr << "Helper failed with: '" << ex.what() << "'\n";
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,12 @@ Decomposition.tests.cpp:<line number>: passed: fptr == 0 for: 0 == 0
|
|||||||
Decomposition.tests.cpp:<line number>: passed: fptr == 0l for: 0 == 0
|
Decomposition.tests.cpp:<line number>: passed: fptr == 0l for: 0 == 0
|
||||||
Compilation.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
|
Compilation.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
|
||||||
Compilation.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
|
Compilation.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 == t2 for: {?} == {?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 != t2 for: {?} != {?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 < t2 for: {?} < {?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 > t2 for: {?} > {?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 <= t2 for: {?} <= {?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: t1 >= t2 for: {?} >= {?}
|
||||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
||||||
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
||||||
@@ -592,6 +598,11 @@ Message from section one
|
|||||||
Message from section two
|
Message from section two
|
||||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("This String") for: "this string contains 'abc' as a substring" starts with: "This String"
|
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("This String") for: "this string contains 'abc' as a substring" starts with: "This String"
|
||||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" starts with: "string" (case insensitive)
|
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" starts with: "string" (case insensitive)
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(singular) == "{ 1 }" for: "{ 1 }" == "{ 1 }"
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(arr) == "{ 3, 2, 1 }" for: "{ 3, 2, 1 }" == "{ 3, 2, 1 }"
|
||||||
|
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })" for: "{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
|
==
|
||||||
|
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string") for: "this string contains 'abc' as a substring" contains: "string"
|
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string") for: "this string contains 'abc' as a substring" contains: "string"
|
||||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "string" (case insensitive)
|
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "string" (case insensitive)
|
||||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("abc") for: "this string contains 'abc' as a substring" contains: "abc"
|
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("abc") for: "this string contains 'abc' as a substring" contains: "abc"
|
||||||
@@ -641,6 +652,9 @@ String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringre
|
|||||||
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
||||||
String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
|
String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
|
||||||
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
||||||
|
String.tests.cpp:<line number>: passed: ascii.numberOfCharacters() == ascii.size() for: 39 == 39
|
||||||
|
String.tests.cpp:<line number>: passed: simpleu8.numberOfCharacters() == 30 for: 30 == 30
|
||||||
|
String.tests.cpp:<line number>: passed: emojis.numberOfCharacters() == 9 for: 9 == 9
|
||||||
ToStringChrono.tests.cpp:<line number>: passed: minute == seconds for: 1 m == 60 s
|
ToStringChrono.tests.cpp:<line number>: passed: minute == seconds for: 1 m == 60 s
|
||||||
ToStringChrono.tests.cpp:<line number>: passed: hour != seconds for: 1 h != 60 s
|
ToStringChrono.tests.cpp:<line number>: passed: hour != seconds for: 1 h != 60 s
|
||||||
ToStringChrono.tests.cpp:<line number>: passed: micro != milli for: 1 us != 1 ms
|
ToStringChrono.tests.cpp:<line number>: passed: micro != milli for: 1 us != 1 ms
|
||||||
@@ -976,6 +990,14 @@ Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load
|
|||||||
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
||||||
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
||||||
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
|
||||||
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(streamable_range{}) == "op<<(streamable_range)" for: "op<<(streamable_range)"
|
||||||
|
==
|
||||||
|
"op<<(streamable_range)"
|
||||||
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(stringmaker_range{}) == "stringmaker(streamable_range)" for: "stringmaker(streamable_range)"
|
||||||
|
==
|
||||||
|
"stringmaker(streamable_range)"
|
||||||
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(just_range{}) == "{ 1, 2, 3, 4 }" for: "{ 1, 2, 3, 4 }" == "{ 1, 2, 3, 4 }"
|
||||||
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(disabled_range{}) == "{?}" for: "{?}" == "{?}"
|
||||||
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }" for: "{ StringMaker<has_maker> }"
|
ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }" for: "{ StringMaker<has_maker> }"
|
||||||
==
|
==
|
||||||
"{ StringMaker<has_maker> }"
|
"{ StringMaker<has_maker> }"
|
||||||
@@ -1047,5 +1069,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
|
|||||||
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
||||||
Misc.tests.cpp:<line number>: passed:
|
Misc.tests.cpp:<line number>: passed:
|
||||||
Misc.tests.cpp:<line number>: passed:
|
Misc.tests.cpp:<line number>: passed:
|
||||||
Failed 49 test cases, failed 108 assertions.
|
Failed 61 test cases, failed 120 assertions.
|
||||||
|
|
||||||
|
@@ -1064,6 +1064,6 @@ with expansion:
|
|||||||
"first" == "second"
|
"first" == "second"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 195 | 144 passed | 47 failed | 4 failed as expected
|
test cases: 198 | 147 passed | 47 failed | 4 failed as expected
|
||||||
assertions: 983 | 857 passed | 105 failed | 21 failed as expected
|
assertions: 999 | 873 passed | 105 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@@ -51,6 +51,48 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0 == 0
|
0 == 0
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
#1147
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Compilation.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 == t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} == {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 != t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} != {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 < t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} < {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 > t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} > {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 <= t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} <= {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 >= t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} >= {?}
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
#748 - captures with unexpected exceptions
|
#748 - captures with unexpected exceptions
|
||||||
outside assertions
|
outside assertions
|
||||||
@@ -532,6 +574,15 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
100.3 == Approx( 100.0 )
|
100.3 == Approx( 100.0 )
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
An empty test with no assertions
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Misc.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'An empty test with no assertions'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
An expression with side-effects should only be evaluated once
|
An expression with side-effects should only be evaluated once
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -2076,6 +2127,9 @@ warning:
|
|||||||
this is a message
|
this is a message
|
||||||
this is a warning
|
this is a warning
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'INFO and WARN do not abort tests'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
INFO gets logged on failure
|
INFO gets logged on failure
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -2488,6 +2542,9 @@ Misc.tests.cpp:<line number>:
|
|||||||
warning:
|
warning:
|
||||||
This one ran
|
This one ran
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'Nice descriptive name'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Non-std exceptions can be translated
|
Non-std exceptions can be translated
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -4620,6 +4677,15 @@ with expansion:
|
|||||||
A string sent directly to stdout
|
A string sent directly to stdout
|
||||||
A string sent directly to stderr
|
A string sent directly to stderr
|
||||||
A string sent to stderr via clog
|
A string sent to stderr via clog
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Sends stuff to stdout and stderr
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Misc.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'Sends stuff to stdout and stderr'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Some simple comparisons between doubles
|
Some simple comparisons between doubles
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -4707,6 +4773,47 @@ with expansion:
|
|||||||
"this string contains 'abc' as a substring" starts with: "string" (case
|
"this string contains 'abc' as a substring" starts with: "string" (case
|
||||||
insensitive)
|
insensitive)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Static arrays are convertible to string
|
||||||
|
Single item
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ToStringGeneral.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ToStringGeneral.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( Catch::Detail::stringify(singular) == "{ 1 }" )
|
||||||
|
with expansion:
|
||||||
|
"{ 1 }" == "{ 1 }"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Static arrays are convertible to string
|
||||||
|
Multiple
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ToStringGeneral.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ToStringGeneral.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( Catch::Detail::stringify(arr) == "{ 3, 2, 1 }" )
|
||||||
|
with expansion:
|
||||||
|
"{ 3, 2, 1 }" == "{ 3, 2, 1 }"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Static arrays are convertible to string
|
||||||
|
Non-trivial inner items
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ToStringGeneral.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ToStringGeneral.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })" )
|
||||||
|
with expansion:
|
||||||
|
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
|
==
|
||||||
|
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
String matchers
|
String matchers
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -5132,6 +5239,31 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
11 == 11
|
11 == 11
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
StringRef
|
||||||
|
Counting utf-8 codepoints
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
String.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( ascii.numberOfCharacters() == ascii.size() )
|
||||||
|
with expansion:
|
||||||
|
39 == 39
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( simpleu8.numberOfCharacters() == 30 )
|
||||||
|
with expansion:
|
||||||
|
30 == 30
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( emojis.numberOfCharacters() == 9 )
|
||||||
|
with expansion:
|
||||||
|
9 == 9
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Stringifying std::chrono::duration helpers
|
Stringifying std::chrono::duration helpers
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -5307,6 +5439,9 @@ Message.tests.cpp:<line number>:
|
|||||||
FAILED - but was ok:
|
FAILED - but was ok:
|
||||||
CHECK_NOFAIL( 1 == 2 )
|
CHECK_NOFAIL( 1 == 2 )
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'The NO_FAIL macro reports a failure but does not fail the test'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
This test 'should' fail but doesn't
|
This test 'should' fail but doesn't
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -6672,6 +6807,15 @@ Exception.tests.cpp:<line number>: FAILED:
|
|||||||
due to unexpected exception with message:
|
due to unexpected exception with message:
|
||||||
unexpected exception
|
unexpected exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
When unchecked exceptions are thrown, but caught, they do not affect the test
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Exception.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'When unchecked exceptions are thrown, but caught, they do not affect the test'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Where the LHS is not a simple value
|
Where the LHS is not a simple value
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -6683,6 +6827,9 @@ warning:
|
|||||||
Uncomment the code in this test to check that it gives a sensible compiler
|
Uncomment the code in this test to check that it gives a sensible compiler
|
||||||
error
|
error
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'Where the LHS is not a simple value'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Where there is more to the expression after the RHS
|
Where there is more to the expression after the RHS
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -6694,6 +6841,9 @@ warning:
|
|||||||
Uncomment the code in this test to check that it gives a sensible compiler
|
Uncomment the code in this test to check that it gives a sensible compiler
|
||||||
error
|
error
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'Where there is more to the expression after the RHS'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
X/level/0/a
|
X/level/0/a
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -7060,7 +7210,25 @@ Misc.tests.cpp:<line number>
|
|||||||
Misc.tests.cpp:<line number>:
|
Misc.tests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
first tag
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Misc.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'first tag'
|
||||||
|
|
||||||
loose text artifact
|
loose text artifact
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
has printf
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Tricky.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'has printf'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
just failure
|
just failure
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -7071,6 +7239,15 @@ Message.tests.cpp:<line number>: FAILED:
|
|||||||
explicitly with message:
|
explicitly with message:
|
||||||
Previous info should not be seen
|
Previous info should not be seen
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
just info
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Message.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'just info'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
long long
|
long long
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -7489,6 +7666,15 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
"didn|'t" == "didn|'t"
|
"didn|'t" == "didn|'t"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
second tag
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Misc.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in test case 'second tag'
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
send a single char to INFO
|
send a single char to INFO
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -7733,6 +7919,40 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
""wide load"" == ""wide load""
|
""wide load"" == ""wide load""
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
toString streamable range
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ToStringWhich.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ToStringWhich.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( ::Catch::Detail::stringify(streamable_range{}) == "op<<(streamable_range)" )
|
||||||
|
with expansion:
|
||||||
|
"op<<(streamable_range)"
|
||||||
|
==
|
||||||
|
"op<<(streamable_range)"
|
||||||
|
|
||||||
|
ToStringWhich.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( ::Catch::Detail::stringify(stringmaker_range{}) == "stringmaker(streamable_range)" )
|
||||||
|
with expansion:
|
||||||
|
"stringmaker(streamable_range)"
|
||||||
|
==
|
||||||
|
"stringmaker(streamable_range)"
|
||||||
|
|
||||||
|
ToStringWhich.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( ::Catch::Detail::stringify(just_range{}) == "{ 1, 2, 3, 4 }" )
|
||||||
|
with expansion:
|
||||||
|
"{ 1, 2, 3, 4 }" == "{ 1, 2, 3, 4 }"
|
||||||
|
|
||||||
|
ToStringWhich.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( ::Catch::Detail::stringify(disabled_range{}) == "{?}" )
|
||||||
|
with expansion:
|
||||||
|
"{?}" == "{?}"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
toString( vectors<has_maker> )
|
toString( vectors<has_maker> )
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -8246,6 +8466,6 @@ Misc.tests.cpp:<line number>:
|
|||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 195 | 142 passed | 49 failed | 4 failed as expected
|
test cases: 198 | 133 passed | 61 failed | 4 failed as expected
|
||||||
assertions: 982 | 853 passed | 108 failed | 21 failed as expected
|
assertions: 1010 | 869 passed | 120 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@@ -51,6 +51,48 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0 == 0
|
0 == 0
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
#1147
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Compilation.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 == t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} == {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 != t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} != {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 < t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} < {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 > t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} > {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 <= t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} <= {?}
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( t1 >= t2 )
|
||||||
|
with expansion:
|
||||||
|
{?} >= {?}
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
#748 - captures with unexpected exceptions
|
#748 - captures with unexpected exceptions
|
||||||
outside assertions
|
outside assertions
|
||||||
@@ -257,6 +299,6 @@ with expansion:
|
|||||||
!true
|
!true
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 10 | 7 passed | 1 failed | 2 failed as expected
|
test cases: 11 | 8 passed | 1 failed | 2 failed as expected
|
||||||
assertions: 28 | 21 passed | 4 failed | 3 failed as expected
|
assertions: 34 | 27 passed | 4 failed | 3 failed as expected
|
||||||
|
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<testsuitesloose text artifact
|
||||||
>
|
>
|
||||||
<testsuite name="<exe-name>" errors="15" failures="94" tests="983" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="15" failures="106" tests="1011" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="#1147" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
||||||
<error type="TEST_CASE">
|
<error type="TEST_CASE">
|
||||||
expected exception
|
expected exception
|
||||||
@@ -537,6 +538,9 @@ Matchers.tests.cpp:<line number>
|
|||||||
Matchers.tests.cpp:<line number>
|
Matchers.tests.cpp:<line number>
|
||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Single item" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Multiple" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Non-trivial inner items" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="String matchers" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="String matchers" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/Empty string" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/Empty string" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/From string literal" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/From string literal" time="{duration}"/>
|
||||||
@@ -558,6 +562,7 @@ String.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/implicitly constructed" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/to std::string/implicitly constructed" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/explicitly constructed" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/to std::string/explicitly constructed" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/assigned" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/to std::string/assigned" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="StringRef/Counting utf-8 codepoints" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration helpers" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration helpers" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration with weird ratios" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration with weird ratios" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point<system_clock>" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point<system_clock>" time="{duration}"/>
|
||||||
@@ -821,6 +826,7 @@ Tricky.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="toString on const wchar_t pointer returns the string contents" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString on const wchar_t pointer returns the string contents" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="toString on wchar_t const pointer returns the string contents" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString on wchar_t const pointer returns the string contents" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="toString on wchar_t returns the string contents" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString on wchar_t returns the string contents" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="toString streamable range" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="toString( vectors<has_maker> )" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString( vectors<has_maker> )" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="toString( vectors<has_maker_and_operator> )" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString( vectors<has_maker_and_operator> )" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="toString( vectors<has_operator> )" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="toString( vectors<has_operator> )" time="{duration}"/>
|
||||||
|
@@ -42,6 +42,57 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="#1147" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 == t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} == {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 != t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} != {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 < t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} < {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 > t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} > {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 <= t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} <= {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
t1 >= t2
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
{?} >= {?}
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<Section name="outside assertions" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<Section name="outside assertions" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<Info>
|
<Info>
|
||||||
@@ -549,7 +600,7 @@
|
|||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
@@ -2396,7 +2447,7 @@
|
|||||||
<Warning>
|
<Warning>
|
||||||
this is a warning
|
this is a warning
|
||||||
</Warning>
|
</Warning>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="INFO gets logged on failure" tags="[.][failing][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
<TestCase name="INFO gets logged on failure" tags="[.][failing][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||||
<Info>
|
<Info>
|
||||||
@@ -2906,7 +2957,7 @@
|
|||||||
<Warning>
|
<Warning>
|
||||||
This one ran
|
This one ran
|
||||||
</Warning>
|
</Warning>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Non-std exceptions can be translated" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<TestCase name="Non-std exceptions can be translated" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
@@ -5324,7 +5375,7 @@
|
|||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Sends stuff to stdout and stderr" tags="[.]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="Sends stuff to stdout and stderr" tags="[.]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<OverallResult success="true">
|
<OverallResult success="false">
|
||||||
<StdOut>
|
<StdOut>
|
||||||
A string sent directly to stdout
|
A string sent directly to stdout
|
||||||
</StdOut>
|
</StdOut>
|
||||||
@@ -5426,6 +5477,44 @@ Message from section two
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Static arrays are convertible to string" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Section name="Single item" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Catch::Detail::stringify(singular) == "{ 1 }"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"{ 1 }" == "{ 1 }"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="Multiple" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Catch::Detail::stringify(arr) == "{ 3, 2, 1 }"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"{ 3, 2, 1 }" == "{ 3, 2, 1 }"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="Non-trivial inner items" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
|
==
|
||||||
|
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="String matchers" tags="[matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
<TestCase name="String matchers" tags="[matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -5493,7 +5582,7 @@ Message from section two
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="StringRef" tags="[Strings]" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<TestCase name="StringRef" tags="[StringRef][Strings]" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Section name="Empty string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Section name="Empty string" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -5903,6 +5992,33 @@ Message from section two
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
<Section name="Counting utf-8 codepoints" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
ascii.numberOfCharacters() == ascii.size()
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
39 == 39
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
simpleu8.numberOfCharacters() == 30
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
30 == 30
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
emojis.numberOfCharacters() == 9
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
9 == 9
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Stringifying std::chrono::duration helpers" tags="[chrono][toString]" filename="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp" >
|
<TestCase name="Stringifying std::chrono::duration helpers" tags="[chrono][toString]" filename="projects/<exe-name>/UsageTests/ToStringChrono.tests.cpp" >
|
||||||
@@ -6094,7 +6210,7 @@ Message from section two
|
|||||||
1 == 2
|
1 == 2
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="This test 'should' fail but doesn't" tags="[!shouldfail][.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="This test 'should' fail but doesn't" tags="[!shouldfail][.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
@@ -7610,19 +7726,19 @@ Message from section two
|
|||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test" tags="[!throws]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
<TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test" tags="[!throws]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Where the LHS is not a simple value" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<TestCase name="Where the LHS is not a simple value" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
<Warning>
|
<Warning>
|
||||||
Uncomment the code in this test to check that it gives a sensible compiler error
|
Uncomment the code in this test to check that it gives a sensible compiler error
|
||||||
</Warning>
|
</Warning>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Where there is more to the expression after the RHS" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<TestCase name="Where there is more to the expression after the RHS" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
<Warning>
|
<Warning>
|
||||||
Uncomment the code in this test to check that it gives a sensible compiler error
|
Uncomment the code in this test to check that it gives a sensible compiler error
|
||||||
</Warning>
|
</Warning>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="X/level/0/a" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<TestCase name="X/level/0/a" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
@@ -7963,11 +8079,11 @@ Message from section two
|
|||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="first tag" tags="[tag1]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="first tag" tags="[tag1]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="has printf" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
<TestCase name="has printf" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||||
loose text artifact
|
loose text artifact
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="just failure" tags="[.][fail][isolated info][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
<TestCase name="just failure" tags="[.][fail][isolated info][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||||
<Failure filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
<Failure filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||||
@@ -7976,7 +8092,7 @@ loose text artifact
|
|||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="just info" tags="[info][isolated info][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
<TestCase name="just info" tags="[info][isolated info][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="long long" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="long long" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
@@ -8286,7 +8402,7 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="replaceInPlace" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<TestCase name="replaceInPlace" tags="[StringManip][Strings]" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Section name="replace single char" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Section name="replace single char" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -8423,7 +8539,7 @@ loose text artifact
|
|||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="second tag" tags="[tag2]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="second tag" tags="[tag2]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="send a single char to INFO" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
<TestCase name="send a single char to INFO" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||||
<Info>
|
<Info>
|
||||||
@@ -8661,6 +8777,45 @@ loose text artifact
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="toString streamable range" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
::Catch::Detail::stringify(streamable_range{}) == "op<<(streamable_range)"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"op<<(streamable_range)"
|
||||||
|
==
|
||||||
|
"op<<(streamable_range)"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
::Catch::Detail::stringify(stringmaker_range{}) == "stringmaker(streamable_range)"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"stringmaker(streamable_range)"
|
||||||
|
==
|
||||||
|
"stringmaker(streamable_range)"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
::Catch::Detail::stringify(just_range{}) == "{ 1, 2, 3, 4 }"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"{ 1, 2, 3, 4 }" == "{ 1, 2, 3, 4 }"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
::Catch::Detail::stringify(disabled_range{}) == "{?}"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"{?}" == "{?}"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="toString( vectors<has_maker> )" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
<TestCase name="toString( vectors<has_maker> )" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringWhich.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -9168,7 +9323,7 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="853" failures="109" expectedFailures="21"/>
|
<OverallResults successes="869" failures="121" expectedFailures="21"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="853" failures="108" expectedFailures="21"/>
|
<OverallResults successes="869" failures="120" expectedFailures="21"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@@ -36,7 +36,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
TEST_CASE( "StringRef", "[Strings]" ) {
|
TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
||||||
|
|
||||||
using Catch::StringRef;
|
using Catch::StringRef;
|
||||||
|
|
||||||
@@ -164,9 +164,21 @@ TEST_CASE( "StringRef", "[Strings]" ) {
|
|||||||
REQUIRE( stdStr.size() == sr.size() );
|
REQUIRE( stdStr.size() == sr.size() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION( "Counting utf-8 codepoints" ) {
|
||||||
|
StringRef ascii = "just a plain old boring ascii string...";
|
||||||
|
REQUIRE(ascii.numberOfCharacters() == ascii.size());
|
||||||
|
|
||||||
|
StringRef simpleu8 = u8"Trocha češtiny nikoho nezabila";
|
||||||
|
REQUIRE(simpleu8.numberOfCharacters() == 30);
|
||||||
|
|
||||||
|
StringRef emojis = u8"Here be 👾";
|
||||||
|
REQUIRE(emojis.numberOfCharacters() == 9);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "replaceInPlace" ) {
|
TEST_CASE( "replaceInPlace", "[Strings][StringManip]" ) {
|
||||||
std::string letters = "abcdefcg";
|
std::string letters = "abcdefcg";
|
||||||
SECTION( "replace single char" ) {
|
SECTION( "replace single char" ) {
|
||||||
CHECK( Catch::replaceInPlace( letters, "b", "z" ) );
|
CHECK( Catch::replaceInPlace( letters, "b", "z" ) );
|
||||||
|
@@ -29,5 +29,5 @@ CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" )
|
|||||||
struct TestListener : Catch::TestEventListenerBase {
|
struct TestListener : Catch::TestEventListenerBase {
|
||||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||||
};
|
};
|
||||||
CATCH_REGISTER_LISTENER( TestListener );
|
CATCH_REGISTER_LISTENER( TestListener )
|
||||||
|
|
||||||
|
@@ -12,6 +12,19 @@ namespace { namespace CompilationTests {
|
|||||||
#ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
#ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
#define COMPILATION_TEST_HELPERS_INCLUDED
|
#define COMPILATION_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
|
// Comparison operators can return non-booleans.
|
||||||
|
// This is unusual, but should be supported.
|
||||||
|
struct logic_t {
|
||||||
|
logic_t operator< (logic_t) const { return {}; }
|
||||||
|
logic_t operator<=(logic_t) const { return {}; }
|
||||||
|
logic_t operator> (logic_t) const { return {}; }
|
||||||
|
logic_t operator>=(logic_t) const { return {}; }
|
||||||
|
logic_t operator==(logic_t) const { return {}; }
|
||||||
|
logic_t operator!=(logic_t) const { return {}; }
|
||||||
|
explicit operator bool() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// This is a minimal example for an issue we have found in 1.7.0
|
// This is a minimal example for an issue we have found in 1.7.0
|
||||||
struct foo {
|
struct foo {
|
||||||
int i;
|
int i;
|
||||||
@@ -109,4 +122,16 @@ namespace { namespace CompilationTests {
|
|||||||
REQUIRE(0 == y.v);
|
REQUIRE(0 == y.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Comparison operators can return non-booleans.
|
||||||
|
// This is unusual, but should be supported.
|
||||||
|
TEST_CASE("#1147") {
|
||||||
|
logic_t t1, t2;
|
||||||
|
REQUIRE(t1 == t2);
|
||||||
|
REQUIRE(t1 != t2);
|
||||||
|
REQUIRE(t1 < t2);
|
||||||
|
REQUIRE(t1 > t2);
|
||||||
|
REQUIRE(t1 <= t2);
|
||||||
|
REQUIRE(t1 >= t2);
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace CompilationTests
|
}} // namespace CompilationTests
|
||||||
|
@@ -100,3 +100,18 @@ TEST_CASE( "std::set is convertible string", "[toString]" ) {
|
|||||||
REQUIRE( Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }" );
|
REQUIRE( Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Static arrays are convertible to string", "[toString]") {
|
||||||
|
SECTION("Single item") {
|
||||||
|
int singular[1] = { 1 };
|
||||||
|
REQUIRE(Catch::Detail::stringify(singular) == "{ 1 }");
|
||||||
|
}
|
||||||
|
SECTION("Multiple") {
|
||||||
|
int arr[3] = { 3, 2, 1 };
|
||||||
|
REQUIRE(Catch::Detail::stringify(arr) == "{ 3, 2, 1 }");
|
||||||
|
}
|
||||||
|
SECTION("Non-trivial inner items") {
|
||||||
|
std::vector<std::string> arr[2] = { {"1:1", "1:2", "1:3"}, {"2:1", "2:2"} };
|
||||||
|
REQUIRE(Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -71,3 +71,76 @@ TEST_CASE( "toString( vectors<has_maker_and_operator> )", "[toString]" ) {
|
|||||||
std::vector<has_maker_and_operator> v(1);
|
std::vector<has_maker_and_operator> v(1);
|
||||||
REQUIRE( ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker_and_operator> }" );
|
REQUIRE( ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker_and_operator> }" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conversion should go
|
||||||
|
// StringMaker specialization, operator<<, range/enum detection, unprintable
|
||||||
|
struct int_iterator {
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = int;
|
||||||
|
using reference = int&;
|
||||||
|
using pointer = int*;
|
||||||
|
|
||||||
|
int_iterator() = default;
|
||||||
|
int_iterator(int i) :val(i) {}
|
||||||
|
|
||||||
|
value_type operator*() const { return val; }
|
||||||
|
bool operator==(int_iterator rhs) const { return val == rhs.val; }
|
||||||
|
bool operator!=(int_iterator rhs) const { return val != rhs.val; }
|
||||||
|
int_iterator operator++() { ++val; return *this; }
|
||||||
|
int_iterator operator++(int) {
|
||||||
|
auto temp(*this);
|
||||||
|
++val;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int val = 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct streamable_range {
|
||||||
|
int_iterator begin() const { return int_iterator{ 1 }; }
|
||||||
|
int_iterator end() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const streamable_range&) {
|
||||||
|
os << "op<<(streamable_range)";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stringmaker_range {
|
||||||
|
int_iterator begin() const { return int_iterator{ 1 }; }
|
||||||
|
int_iterator end() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
template <>
|
||||||
|
struct StringMaker<stringmaker_range> {
|
||||||
|
static std::string convert(stringmaker_range const&) {
|
||||||
|
return "stringmaker(streamable_range)";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct just_range {
|
||||||
|
int_iterator begin() const { return int_iterator{ 1 }; }
|
||||||
|
int_iterator end() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct disabled_range {
|
||||||
|
int_iterator begin() const { return int_iterator{ 1 }; }
|
||||||
|
int_iterator end() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
template <>
|
||||||
|
struct is_range<disabled_range> {
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("toString streamable range", "[toString]") {
|
||||||
|
REQUIRE(::Catch::Detail::stringify(streamable_range{}) == "op<<(streamable_range)");
|
||||||
|
REQUIRE(::Catch::Detail::stringify(stringmaker_range{}) == "stringmaker(streamable_range)");
|
||||||
|
REQUIRE(::Catch::Detail::stringify(just_range{}) == "{ 1, 2, 3, 4 }");
|
||||||
|
REQUIRE(::Catch::Detail::stringify(disabled_range{}) == "{?}");
|
||||||
|
}
|
||||||
|
@@ -50,6 +50,8 @@ infParser = re.compile(r'''
|
|||||||
|
|
|
|
||||||
\(__builtin_inff\(\)\) # Linux (ubuntu) INFINITY macro
|
\(__builtin_inff\(\)\) # Linux (ubuntu) INFINITY macro
|
||||||
|
|
|
|
||||||
|
\(__builtin_inff\ \(\)\) # Fedora INFINITY macro
|
||||||
|
|
|
||||||
__builtin_huge_valf\(\) # OSX macro
|
__builtin_huge_valf\(\) # OSX macro
|
||||||
''', re.VERBOSE)
|
''', re.VERBOSE)
|
||||||
nanParser = re.compile(r'''
|
nanParser = re.compile(r'''
|
||||||
|
2
scripts/embedClara.py
Normal file → Executable file
2
scripts/embedClara.py
Normal file → Executable file
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Execute this script any time you import a new copy of Clara into the third_party area
|
# Execute this script any time you import a new copy of Clara into the third_party area
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import io
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
@@ -46,11 +47,11 @@ def generate(v):
|
|||||||
outDir = os.path.dirname(outputPath)
|
outDir = os.path.dirname(outputPath)
|
||||||
if not os.path.exists(outDir):
|
if not os.path.exists(outDir):
|
||||||
os.makedirs(outDir)
|
os.makedirs(outDir)
|
||||||
out = open( outputPath, 'w' )
|
out = io.open( outputPath, 'w', newline='\n')
|
||||||
|
|
||||||
def write( line ):
|
def write( line ):
|
||||||
if globals['includeImpl'] or globals['implIfDefs'] == -1:
|
if globals['includeImpl'] or globals['implIfDefs'] == -1:
|
||||||
out.write( line )
|
out.write( line.decode('utf-8') )
|
||||||
|
|
||||||
def insertCpps():
|
def insertCpps():
|
||||||
dirs = [os.path.join( rootPath, s) for s in ['', 'internal', 'reporters']]
|
dirs = [os.path.join( rootPath, s) for s in ['', 'internal', 'reporters']]
|
||||||
@@ -104,22 +105,22 @@ def generate(v):
|
|||||||
write( '// end {}\n'.format(filename) )
|
write( '// end {}\n'.format(filename) )
|
||||||
|
|
||||||
|
|
||||||
out.write( "/*\n" )
|
write( "/*\n" )
|
||||||
out.write( " * Catch v{0}\n".format( v.getVersionString() ) )
|
write( " * Catch v{0}\n".format( v.getVersionString() ) )
|
||||||
out.write( " * Generated: {0}\n".format( datetime.datetime.now() ) )
|
write( " * Generated: {0}\n".format( datetime.datetime.now() ) )
|
||||||
out.write( " * ----------------------------------------------------------\n" )
|
write( " * ----------------------------------------------------------\n" )
|
||||||
out.write( " * This file has been merged from multiple headers. Please don't edit it directly\n" )
|
write( " * This file has been merged from multiple headers. Please don't edit it directly\n" )
|
||||||
out.write( " * Copyright (c) {} Two Blue Cubes Ltd. All rights reserved.\n".format( datetime.date.today().year ) )
|
write( " * Copyright (c) {} Two Blue Cubes Ltd. All rights reserved.\n".format( datetime.date.today().year ) )
|
||||||
out.write( " *\n" )
|
write( " *\n" )
|
||||||
out.write( " * Distributed under the Boost Software License, Version 1.0. (See accompanying\n" )
|
write( " * Distributed under the Boost Software License, Version 1.0. (See accompanying\n" )
|
||||||
out.write( " * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" )
|
write( " * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" )
|
||||||
out.write( " */\n" )
|
write( " */\n" )
|
||||||
out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
|
write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
|
||||||
out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
|
write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
|
||||||
|
|
||||||
parseFile( rootPath, 'catch.hpp' )
|
parseFile( rootPath, 'catch.hpp' )
|
||||||
|
|
||||||
out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
|
write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
|
||||||
out.close()
|
out.close()
|
||||||
print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
|
print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ from scriptCommon import catchPath
|
|||||||
versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
|
versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
|
||||||
rootPath = os.path.join( catchPath, 'include/' )
|
rootPath = os.path.join( catchPath, 'include/' )
|
||||||
versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
|
versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
|
||||||
|
definePath = os.path.join(rootPath, 'catch.hpp')
|
||||||
readmePath = os.path.join( catchPath, "README.md" )
|
readmePath = os.path.join( catchPath, "README.md" )
|
||||||
conanPath = os.path.join(catchPath, 'conanfile.py')
|
conanPath = os.path.join(catchPath, 'conanfile.py')
|
||||||
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
|
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
|
||||||
@@ -80,7 +81,7 @@ class Version:
|
|||||||
def updateReadmeFile(version):
|
def updateReadmeFile(version):
|
||||||
import updateWandbox
|
import updateWandbox
|
||||||
|
|
||||||
downloadParser = re.compile( r'<a href=\"https://github.com/philsquared/Catch/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
downloadParser = re.compile( r'<a href=\"https://github.com/catchorg/Catch2/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
||||||
success, wandboxLink = updateWandbox.uploadFiles()
|
success, wandboxLink = updateWandbox.uploadFiles()
|
||||||
if not success:
|
if not success:
|
||||||
print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
||||||
@@ -92,7 +93,7 @@ def updateReadmeFile(version):
|
|||||||
f.close()
|
f.close()
|
||||||
f = open( readmePath, 'w' )
|
f = open( readmePath, 'w' )
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = downloadParser.sub( r'<a href="https://github.com/philsquared/Catch/releases/download/v{0}/catch.hpp">'.format(version.getVersionString()) , line)
|
line = downloadParser.sub( r'<a href="https://github.com/catchorg/Catch2/releases/download/v{0}/catch.hpp">'.format(version.getVersionString()) , line)
|
||||||
if '[]' in line:
|
if '[]' in line:
|
||||||
line = '[]({0})'.format(wandboxLink)
|
line = '[]({0})'.format(wandboxLink)
|
||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
@@ -128,20 +129,36 @@ def updateConanTestFile(version):
|
|||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
def updateCmakeFile(version):
|
def updateCmakeFile(version):
|
||||||
cmakeParser = re.compile(r'set(CATCH_VERSION_NUMBER \d+\.\d+\.\d+)')
|
|
||||||
with open(cmakePath, 'r') as file:
|
with open(cmakePath, 'r') as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
with open(cmakePath, 'w') as file:
|
with open(cmakePath, 'w') as file:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if 'set(CATCH_VERSION_NUMBER ' in line:
|
if 'project(Catch2 LANGUAGES CXX VERSION ' in line:
|
||||||
file.write('set(CATCH_VERSION_NUMBER {0})\n'.format(version.getVersionString()))
|
file.write('project(Catch2 LANGUAGES CXX VERSION {0})\n'.format(version.getVersionString()))
|
||||||
else:
|
else:
|
||||||
file.write(line)
|
file.write(line)
|
||||||
|
|
||||||
|
|
||||||
|
def updateVersionDefine(version):
|
||||||
|
with open(definePath, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
with open(definePath, 'w') as file:
|
||||||
|
for line in lines:
|
||||||
|
if '#define CATCH_VERSION_MAJOR' in line:
|
||||||
|
file.write('#define CATCH_VERSION_MAJOR {}\n'.format(version.majorVersion))
|
||||||
|
elif '#define CATCH_VERSION_MINOR' in line:
|
||||||
|
file.write('#define CATCH_VERSION_MINOR {}\n'.format(version.minorVersion))
|
||||||
|
elif '#define CATCH_VERSION_PATCH' in line:
|
||||||
|
file.write('#define CATCH_VERSION_PATCH {}\n'.format(version.patchNumber))
|
||||||
|
else:
|
||||||
|
file.write(line)
|
||||||
|
|
||||||
|
|
||||||
def performUpdates(version):
|
def performUpdates(version):
|
||||||
# First update version file, so we can regenerate single header and
|
# First update version file, so we can regenerate single header and
|
||||||
# have it ready for upload to wandbox, when updating readme
|
# have it ready for upload to wandbox, when updating readme
|
||||||
version.updateVersionFile()
|
version.updateVersionFile()
|
||||||
|
updateVersionDefine(version)
|
||||||
|
|
||||||
import generateSingleHeader
|
import generateSingleHeader
|
||||||
generateSingleHeader.generate(version)
|
generateSingleHeader.generate(version)
|
||||||
|
@@ -8,7 +8,7 @@ from releaseCommon import Version
|
|||||||
|
|
||||||
print(catchPath)
|
print(catchPath)
|
||||||
|
|
||||||
default_path = '../vcpkg/ports/catch/'
|
default_path = '../vcpkg/ports/catch2/'
|
||||||
|
|
||||||
def adjusted_path(path):
|
def adjusted_path(path):
|
||||||
return os.path.join(catchPath, path)
|
return os.path.join(catchPath, path)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Catch v2.1.0
|
* Catch v2.1.2
|
||||||
* Generated: 2018-01-10 13:51:15.378034
|
* Generated: 2018-02-09 17:05:21.506253
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* This file has been merged from multiple headers. Please don't edit it directly
|
* This file has been merged from multiple headers. Please don't edit it directly
|
||||||
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
|
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
// start catch.hpp
|
// start catch.hpp
|
||||||
|
|
||||||
|
|
||||||
|
#define CATCH_VERSION_MAJOR 2
|
||||||
|
#define CATCH_VERSION_MINOR 1
|
||||||
|
#define CATCH_VERSION_PATCH 2
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang system_header
|
# pragma clang system_header
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
@@ -116,6 +120,14 @@ namespace Catch {
|
|||||||
# define CATCH_CPP14_OR_GREATER
|
# define CATCH_CPP14_OR_GREATER
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if __cplusplus >= 201703L
|
||||||
|
# define CATCH_CPP17_OR_GREATER
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_CPP17_OR_GREATER)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
@@ -164,6 +176,10 @@ namespace Catch {
|
|||||||
// Visual C++
|
// Visual C++
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
# endif
|
||||||
|
|
||||||
// Universal Windows platform does not support SEH
|
// Universal Windows platform does not support SEH
|
||||||
// Or console colours (or console at all...)
|
// Or console colours (or console at all...)
|
||||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
@@ -196,6 +212,10 @@ namespace Catch {
|
|||||||
# define CATCH_CONFIG_POSIX_SIGNALS
|
# define CATCH_CONFIG_POSIX_SIGNALS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_INTERNAL_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
||||||
@@ -735,11 +755,11 @@ namespace Catch {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& ) {
|
typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& ) {
|
||||||
return Detail::unprintableString;
|
return Detail::unprintableString;
|
||||||
};
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
|
||||||
return convertUnknownEnumToString( value );
|
return convertUnknownEnumToString( value );
|
||||||
};
|
}
|
||||||
|
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
@@ -807,18 +827,6 @@ namespace Catch {
|
|||||||
static std::string convert(wchar_t * str);
|
static std::string convert(wchar_t * str);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_string_array : std::false_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<signed char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<std::size_t N>
|
|
||||||
struct is_string_array<unsigned char[N]> : std::true_type {};
|
|
||||||
|
|
||||||
template<int SZ>
|
template<int SZ>
|
||||||
struct StringMaker<char[SZ]> {
|
struct StringMaker<char[SZ]> {
|
||||||
static std::string convert(const char* str) {
|
static std::string convert(const char* str) {
|
||||||
@@ -1069,12 +1077,19 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
struct StringMaker<R, typename std::enable_if<is_range<R>::value && !is_string_array<R>::value>::type> {
|
struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
|
||||||
static std::string convert( R const& range ) {
|
static std::string convert( R const& range ) {
|
||||||
return rangeToString( range );
|
return rangeToString( range );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, int SZ>
|
||||||
|
struct StringMaker<T[SZ]> {
|
||||||
|
static std::string convert(T const(&arr)[SZ]) {
|
||||||
|
return rangeToString(arr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
// Separate std::chrono::duration specialization
|
// Separate std::chrono::duration specialization
|
||||||
@@ -1269,7 +1284,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; };
|
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -1280,7 +1295,7 @@ namespace Catch {
|
|||||||
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
||||||
|
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs != rhs; };
|
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -1314,19 +1329,19 @@ namespace Catch {
|
|||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs > rhs, m_lhs, ">", rhs };
|
return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs < rhs, m_lhs, "<", rhs };
|
return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs >= rhs, m_lhs, ">=", rhs };
|
return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return { m_lhs <= rhs, m_lhs, "<=", rhs };
|
return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||||
@@ -3886,10 +3901,11 @@ namespace Catch {
|
|||||||
BrightGreen = Bright | Green,
|
BrightGreen = Bright | Green,
|
||||||
LightGrey = Bright | Grey,
|
LightGrey = Bright | Grey,
|
||||||
BrightWhite = Bright | White,
|
BrightWhite = Bright | White,
|
||||||
|
BrightYellow = Bright | Yellow,
|
||||||
|
|
||||||
// By intention
|
// By intention
|
||||||
FileName = LightGrey,
|
FileName = LightGrey,
|
||||||
Warning = Yellow,
|
Warning = BrightYellow,
|
||||||
ResultError = BrightRed,
|
ResultError = BrightRed,
|
||||||
ResultSuccess = BrightGreen,
|
ResultSuccess = BrightGreen,
|
||||||
ResultExpectedFailure = Warning,
|
ResultExpectedFailure = Warning,
|
||||||
@@ -3898,7 +3914,7 @@ namespace Catch {
|
|||||||
Success = Green,
|
Success = Green,
|
||||||
|
|
||||||
OriginalExpression = Cyan,
|
OriginalExpression = Cyan,
|
||||||
ReconstructedExpression = Yellow,
|
ReconstructedExpression = BrightYellow,
|
||||||
|
|
||||||
SecondaryText = LightGrey,
|
SecondaryText = LightGrey,
|
||||||
Headers = White
|
Headers = White
|
||||||
@@ -4611,7 +4627,10 @@ namespace Catch {
|
|||||||
#ifdef CATCH_TRAP
|
#ifdef CATCH_TRAP
|
||||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
||||||
#else
|
#else
|
||||||
#define CATCH_BREAK_INTO_DEBUGGER() (void)0, 0
|
namespace Catch {
|
||||||
|
inline void doNothing() {}
|
||||||
|
}
|
||||||
|
#define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// end catch_debugger.h
|
// end catch_debugger.h
|
||||||
@@ -5093,8 +5112,14 @@ namespace Catch {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start clara.hpp
|
// start clara.hpp
|
||||||
// v1.0-develop.2
|
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
// See https://github.com/philsquared/Clara
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// See https://github.com/philsquared/Clara for more details
|
||||||
|
|
||||||
|
// Clara v1.1.2
|
||||||
|
|
||||||
|
|
||||||
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
|
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
@@ -5457,7 +5482,7 @@ namespace detail {
|
|||||||
template<typename ClassT, typename ReturnT, typename ArgT>
|
template<typename ClassT, typename ReturnT, typename ArgT>
|
||||||
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
||||||
static const bool isValid = true;
|
static const bool isValid = true;
|
||||||
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
|
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
|
||||||
using ReturnType = ReturnT;
|
using ReturnType = ReturnT;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5621,7 +5646,7 @@ namespace detail {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResultValueBase() {
|
~ResultValueBase() override {
|
||||||
if( m_type == Ok )
|
if( m_type == Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
}
|
}
|
||||||
@@ -5659,7 +5684,7 @@ namespace detail {
|
|||||||
auto errorMessage() const -> std::string { return m_errorMessage; }
|
auto errorMessage() const -> std::string { return m_errorMessage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void enforceOk() const {
|
void enforceOk() const override {
|
||||||
// !TBD: If no exceptions, std::terminate here or something
|
// !TBD: If no exceptions, std::terminate here or something
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ResultBase::LogicError:
|
case ResultBase::LogicError:
|
||||||
@@ -5739,46 +5764,32 @@ namespace detail {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BoundRefBase {
|
struct NonCopyable {
|
||||||
BoundRefBase() = default;
|
NonCopyable() = default;
|
||||||
BoundRefBase( BoundRefBase const & ) = delete;
|
NonCopyable( NonCopyable const & ) = delete;
|
||||||
BoundRefBase( BoundRefBase && ) = delete;
|
NonCopyable( NonCopyable && ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase const & ) = delete;
|
NonCopyable &operator=( NonCopyable const & ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase && ) = delete;
|
NonCopyable &operator=( NonCopyable && ) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~BoundRefBase() = default;
|
struct BoundRef : NonCopyable {
|
||||||
|
virtual ~BoundRef() = default;
|
||||||
virtual auto isFlag() const -> bool = 0;
|
|
||||||
virtual auto isContainer() const -> bool { return false; }
|
virtual auto isContainer() const -> bool { return false; }
|
||||||
|
virtual auto isFlag() const -> bool { return false; }
|
||||||
|
};
|
||||||
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
||||||
|
};
|
||||||
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
||||||
};
|
virtual auto isFlag() const -> bool { return true; }
|
||||||
|
|
||||||
struct BoundValueRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return false; }
|
|
||||||
|
|
||||||
auto setFlag( bool ) -> ParserResult override {
|
|
||||||
return ParserResult::logicError( "Flags can only be set on boolean fields" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundFlagRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return true; }
|
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
|
||||||
bool flag;
|
|
||||||
auto result = convertInto( arg, flag );
|
|
||||||
if( result )
|
|
||||||
setFlag( flag );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( T &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
auto setValue( std::string const &arg ) -> ParserResult override {
|
||||||
return convertInto( arg, m_ref );
|
return convertInto( arg, m_ref );
|
||||||
@@ -5786,10 +5797,10 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T> &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
@@ -5834,12 +5845,12 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename ArgType, typename L>
|
template<typename ArgType, typename L>
|
||||||
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
||||||
ArgType temp;
|
ArgType temp{};
|
||||||
auto result = convertInto( arg, temp );
|
auto result = convertInto( arg, temp );
|
||||||
return !result
|
return !result
|
||||||
? result
|
? result
|
||||||
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
||||||
};
|
}
|
||||||
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
struct BoundLambda : BoundValueRefBase {
|
struct BoundLambda : BoundValueRefBase {
|
||||||
@@ -5888,6 +5899,9 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator|( T const &other ) const -> Parser;
|
auto operator|( T const &other ) const -> Parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@@ -5895,16 +5909,16 @@ namespace detail {
|
|||||||
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ParserRefImpl( T &ref, std::string const &hint )
|
ParserRefImpl( T &ref, std::string const &hint )
|
||||||
: m_ref( std::make_shared<BoundRef<T>>( ref ) ),
|
: m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint )
|
m_hint( hint )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -5945,10 +5959,10 @@ namespace detail {
|
|||||||
|
|
||||||
class ExeName : public ComposableParserImpl<ExeName> {
|
class ExeName : public ComposableParserImpl<ExeName> {
|
||||||
std::shared_ptr<std::string> m_name;
|
std::shared_ptr<std::string> m_name;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
|
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5956,7 +5970,7 @@ namespace detail {
|
|||||||
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
||||||
|
|
||||||
explicit ExeName( std::string &ref ) : ExeName() {
|
explicit ExeName( std::string &ref ) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundRef<std::string>>( ref );
|
m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
@@ -5999,7 +6013,10 @@ namespace detail {
|
|||||||
if( token.type != TokenType::Argument )
|
if( token.type != TokenType::Argument )
|
||||||
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
||||||
|
|
||||||
auto result = m_ref->setValue( remainingTokens->token );
|
assert( !m_ref->isFlag() );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
|
|
||||||
|
auto result = valueRef->setValue( remainingTokens->token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
else
|
else
|
||||||
@@ -6073,19 +6090,21 @@ namespace detail {
|
|||||||
auto const &token = *remainingTokens;
|
auto const &token = *remainingTokens;
|
||||||
if( isMatch(token.token ) ) {
|
if( isMatch(token.token ) ) {
|
||||||
if( m_ref->isFlag() ) {
|
if( m_ref->isFlag() ) {
|
||||||
auto result = m_ref->setFlag( true );
|
auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
|
||||||
|
auto result = flagRef->setFlag( true );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
||||||
} else {
|
} else {
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if( !remainingTokens )
|
if( !remainingTokens )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto const &argToken = *remainingTokens;
|
auto const &argToken = *remainingTokens;
|
||||||
if( argToken.type != TokenType::Argument )
|
if( argToken.type != TokenType::Argument )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto result = m_ref->setValue( argToken.token );
|
auto result = valueRef->setValue( argToken.token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
@@ -6161,6 +6180,12 @@ namespace detail {
|
|||||||
return Parser( *this ) |= other;
|
return Parser( *this ) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
|
template<typename T>
|
||||||
|
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser { return operator|( other ); }
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const &o : m_options) {
|
||||||
@@ -6200,6 +6225,8 @@ namespace detail {
|
|||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
|
optWidth = (std::min)(optWidth, consoleWidth/2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
||||||
@@ -6690,8 +6717,12 @@ namespace {
|
|||||||
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
|
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
|
||||||
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
|
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
|
||||||
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
||||||
|
case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
|
||||||
|
|
||||||
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
||||||
|
|
||||||
|
default:
|
||||||
|
CATCH_ERROR( "Unknown colour requested" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6749,8 +6780,10 @@ namespace {
|
|||||||
case Colour::BrightRed: return setColour( "[1;31m" );
|
case Colour::BrightRed: return setColour( "[1;31m" );
|
||||||
case Colour::BrightGreen: return setColour( "[1;32m" );
|
case Colour::BrightGreen: return setColour( "[1;32m" );
|
||||||
case Colour::BrightWhite: return setColour( "[1;37m" );
|
case Colour::BrightWhite: return setColour( "[1;37m" );
|
||||||
|
case Colour::BrightYellow: return setColour( "[1;33m" );
|
||||||
|
|
||||||
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
|
||||||
|
default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static IColourImpl* instance() {
|
static IColourImpl* instance() {
|
||||||
@@ -7086,6 +7119,17 @@ namespace Catch {
|
|||||||
return Catch::Detail::stringify( [exception description] );
|
return Catch::Detail::stringify( [exception description] );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
// Compiling a mixed mode project with MSVC means that CLR
|
||||||
|
// exceptions will be caught in (...) as well. However, these
|
||||||
|
// do not fill-in std::current_exception and thus lead to crash
|
||||||
|
// when attempting rethrow.
|
||||||
|
// /EHa switch also causes structured exceptions to be caught
|
||||||
|
// here, but they fill-in current_exception properly, so
|
||||||
|
// at worst the output should be a little weird, instead of
|
||||||
|
// causing a crash.
|
||||||
|
if (std::current_exception() == nullptr) {
|
||||||
|
return "Non C++ exception. Possibly a CLR exception.";
|
||||||
|
}
|
||||||
return tryTranslators();
|
return tryTranslators();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -7121,12 +7165,14 @@ namespace Catch {
|
|||||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(CATCH_PLATFORM_WINDOWS) && defined(CATCH_CONFIG_WINDOWS_SEH)) || defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||||
namespace {
|
namespace {
|
||||||
// Report the error condition
|
// Report the error condition
|
||||||
void reportFatal( char const * const message ) {
|
void reportFatal( char const * const message ) {
|
||||||
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
|
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||||
|
|
||||||
@@ -7950,6 +7996,13 @@ namespace Matchers {
|
|||||||
// end catch_matchers_string.cpp
|
// end catch_matchers_string.cpp
|
||||||
// start catch_message.cpp
|
// start catch_message.cpp
|
||||||
|
|
||||||
|
// start catch_uncaught_exceptions.h
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
bool uncaught_exceptions();
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
// end catch_uncaught_exceptions.h
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
MessageInfo::MessageInfo( std::string const& _macroName,
|
MessageInfo::MessageInfo( std::string const& _macroName,
|
||||||
@@ -7988,19 +8041,11 @@ namespace Catch {
|
|||||||
getResultCapture().pushScopedMessage( m_info );
|
getResultCapture().pushScopedMessage( m_info );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
|
|
||||||
#endif
|
|
||||||
ScopedMessage::~ScopedMessage() {
|
ScopedMessage::~ScopedMessage() {
|
||||||
if ( !std::uncaught_exception() ){
|
if ( !uncaught_exceptions() ){
|
||||||
getResultCapture().popScopedMessage(m_info);
|
getResultCapture().popScopedMessage(m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
// end catch_message.cpp
|
// end catch_message.cpp
|
||||||
// start catch_random_number_generator.cpp
|
// start catch_random_number_generator.cpp
|
||||||
@@ -8640,12 +8685,13 @@ namespace Catch {
|
|||||||
handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
|
handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Counts assertions = m_totals.assertions - prevAssertions;
|
||||||
|
bool missingAssertions = testForMissingAssertions(assertions);
|
||||||
|
|
||||||
m_testCaseTracker->close();
|
m_testCaseTracker->close();
|
||||||
handleUnfinishedSections();
|
handleUnfinishedSections();
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
|
||||||
Counts assertions = m_totals.assertions - prevAssertions;
|
|
||||||
bool missingAssertions = testForMissingAssertions(assertions);
|
|
||||||
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
||||||
m_reporter->sectionEnded(testCaseSectionStats);
|
m_reporter->sectionEnded(testCaseSectionStats);
|
||||||
}
|
}
|
||||||
@@ -8792,22 +8838,15 @@ namespace Catch {
|
|||||||
m_timer.start();
|
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() {
|
Section::~Section() {
|
||||||
if( m_sectionIncluded ) {
|
if( m_sectionIncluded ) {
|
||||||
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||||
if( std::uncaught_exception() )
|
if( uncaught_exceptions() )
|
||||||
getResultCapture().sectionEndedEarly( endInfo );
|
getResultCapture().sectionEndedEarly( endInfo );
|
||||||
else
|
else
|
||||||
getResultCapture().sectionEnded( endInfo );
|
getResultCapture().sectionEnded( endInfo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This indicates whether the section should be executed or not
|
// This indicates whether the section should be executed or not
|
||||||
Section::operator bool() const {
|
Section::operator bool() const {
|
||||||
@@ -9148,6 +9187,9 @@ namespace Catch {
|
|||||||
if( Option<std::size_t> listed = list( config() ) )
|
if( Option<std::size_t> listed = list( config() ) )
|
||||||
return static_cast<int>( *listed );
|
return static_cast<int>( *listed );
|
||||||
|
|
||||||
|
// Note that on unices only the lower 8 bits are usually used, clamping
|
||||||
|
// the return value to 255 prevents false negative when some multiple
|
||||||
|
// of 256 tests has failed
|
||||||
return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
|
return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
|
||||||
}
|
}
|
||||||
catch( std::exception& ex ) {
|
catch( std::exception& ex ) {
|
||||||
@@ -9455,6 +9497,13 @@ namespace Catch {
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const uint32_t byte_2_lead = 0xC0;
|
||||||
|
const uint32_t byte_3_lead = 0xE0;
|
||||||
|
const uint32_t byte_4_lead = 0xF0;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
StringRef::StringRef( char const* rawChars ) noexcept
|
StringRef::StringRef( char const* rawChars ) noexcept
|
||||||
@@ -9519,13 +9568,12 @@ namespace Catch {
|
|||||||
// Make adjustments for uft encodings
|
// Make adjustments for uft encodings
|
||||||
for( size_type i=0; i < m_size; ++i ) {
|
for( size_type i=0; i < m_size; ++i ) {
|
||||||
char c = m_start[i];
|
char c = m_start[i];
|
||||||
if( ( c & 0b11000000 ) == 0b11000000 ) {
|
if( ( c & byte_2_lead ) == byte_2_lead ) {
|
||||||
if( ( c & 0b11100000 ) == 0b11000000 )
|
noChars--;
|
||||||
|
if (( c & byte_3_lead ) == byte_3_lead )
|
||||||
|
noChars--;
|
||||||
|
if( ( c & byte_4_lead ) == byte_4_lead )
|
||||||
noChars--;
|
noChars--;
|
||||||
else if( ( c & 0b11110000 ) == 0b11100000 )
|
|
||||||
noChars-=2;
|
|
||||||
else if( ( c & 0b11111000 ) == 0b11110000 )
|
|
||||||
noChars-=3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noChars;
|
return noChars;
|
||||||
@@ -10657,6 +10705,20 @@ namespace Catch {
|
|||||||
|
|
||||||
}
|
}
|
||||||
// end catch_totals.cpp
|
// end catch_totals.cpp
|
||||||
|
// start catch_uncaught_exceptions.cpp
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
bool uncaught_exceptions() {
|
||||||
|
#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
|
||||||
|
return std::uncaught_exceptions() > 0;
|
||||||
|
#else
|
||||||
|
return std::uncaught_exception();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // end namespace Catch
|
||||||
|
// end catch_uncaught_exceptions.cpp
|
||||||
// start catch_version.cpp
|
// start catch_version.cpp
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@@ -10689,7 +10751,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 1, 0, "", 0 );
|
static Version version( 2, 1, 2, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11918,7 +11980,7 @@ namespace Catch {
|
|||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JunitReporter::~JunitReporter() {};
|
JunitReporter::~JunitReporter() {}
|
||||||
|
|
||||||
std::string JunitReporter::getDescription() {
|
std::string JunitReporter::getDescription() {
|
||||||
return "Reports test results in an XML format that looks like Ant's junitreport target";
|
return "Reports test results in an XML format that looks like Ant's junitreport target";
|
||||||
|
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
|
|||||||
settings = "os", "compiler", "arch", "build_type"
|
settings = "os", "compiler", "arch", "build_type"
|
||||||
username = getenv("CONAN_USERNAME", "philsquared")
|
username = getenv("CONAN_USERNAME", "philsquared")
|
||||||
channel = getenv("CONAN_CHANNEL", "testing")
|
channel = getenv("CONAN_CHANNEL", "testing")
|
||||||
requires = "Catch/2.1.0@%s/%s" % (username, channel)
|
requires = "Catch/2.1.2@%s/%s" % (username, channel)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
cmake = CMake(self)
|
cmake = CMake(self)
|
||||||
|
106
third_party/clara.hpp
vendored
106
third_party/clara.hpp
vendored
@@ -1,5 +1,11 @@
|
|||||||
// v1.0-develop.2
|
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
// See https://github.com/philsquared/Clara
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// See https://github.com/philsquared/Clara for more details
|
||||||
|
|
||||||
|
// Clara v1.1.2
|
||||||
|
|
||||||
#ifndef CLARA_HPP_INCLUDED
|
#ifndef CLARA_HPP_INCLUDED
|
||||||
#define CLARA_HPP_INCLUDED
|
#define CLARA_HPP_INCLUDED
|
||||||
@@ -370,7 +376,7 @@ namespace detail {
|
|||||||
template<typename ClassT, typename ReturnT, typename ArgT>
|
template<typename ClassT, typename ReturnT, typename ArgT>
|
||||||
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
|
||||||
static const bool isValid = true;
|
static const bool isValid = true;
|
||||||
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
|
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
|
||||||
using ReturnType = ReturnT;
|
using ReturnType = ReturnT;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -535,7 +541,7 @@ namespace detail {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResultValueBase() {
|
~ResultValueBase() override {
|
||||||
if( m_type == Ok )
|
if( m_type == Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
}
|
}
|
||||||
@@ -573,7 +579,7 @@ namespace detail {
|
|||||||
auto errorMessage() const -> std::string { return m_errorMessage; }
|
auto errorMessage() const -> std::string { return m_errorMessage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void enforceOk() const {
|
void enforceOk() const override {
|
||||||
// !TBD: If no exceptions, std::terminate here or something
|
// !TBD: If no exceptions, std::terminate here or something
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ResultBase::LogicError:
|
case ResultBase::LogicError:
|
||||||
@@ -653,46 +659,32 @@ namespace detail {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BoundRefBase {
|
struct NonCopyable {
|
||||||
BoundRefBase() = default;
|
NonCopyable() = default;
|
||||||
BoundRefBase( BoundRefBase const & ) = delete;
|
NonCopyable( NonCopyable const & ) = delete;
|
||||||
BoundRefBase( BoundRefBase && ) = delete;
|
NonCopyable( NonCopyable && ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase const & ) = delete;
|
NonCopyable &operator=( NonCopyable const & ) = delete;
|
||||||
BoundRefBase &operator=( BoundRefBase && ) = delete;
|
NonCopyable &operator=( NonCopyable && ) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~BoundRefBase() = default;
|
struct BoundRef : NonCopyable {
|
||||||
|
virtual ~BoundRef() = default;
|
||||||
virtual auto isFlag() const -> bool = 0;
|
|
||||||
virtual auto isContainer() const -> bool { return false; }
|
virtual auto isContainer() const -> bool { return false; }
|
||||||
|
virtual auto isFlag() const -> bool { return false; }
|
||||||
|
};
|
||||||
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
|
||||||
|
};
|
||||||
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
virtual auto setFlag( bool flag ) -> ParserResult = 0;
|
||||||
};
|
virtual auto isFlag() const -> bool { return true; }
|
||||||
|
|
||||||
struct BoundValueRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return false; }
|
|
||||||
|
|
||||||
auto setFlag( bool ) -> ParserResult override {
|
|
||||||
return ParserResult::logicError( "Flags can only be set on boolean fields" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundFlagRefBase : BoundRefBase {
|
|
||||||
auto isFlag() const -> bool override { return true; }
|
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
|
||||||
bool flag;
|
|
||||||
auto result = convertInto( arg, flag );
|
|
||||||
if( result )
|
|
||||||
setFlag( flag );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( T &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto setValue( std::string const &arg ) -> ParserResult override {
|
auto setValue( std::string const &arg ) -> ParserResult override {
|
||||||
return convertInto( arg, m_ref );
|
return convertInto( arg, m_ref );
|
||||||
@@ -700,10 +692,10 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BoundRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T> &m_ref;
|
||||||
|
|
||||||
explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
@@ -748,12 +740,12 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename ArgType, typename L>
|
template<typename ArgType, typename L>
|
||||||
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
|
||||||
ArgType temp;
|
ArgType temp{};
|
||||||
auto result = convertInto( arg, temp );
|
auto result = convertInto( arg, temp );
|
||||||
return !result
|
return !result
|
||||||
? result
|
? result
|
||||||
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
@@ -803,6 +795,9 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator|( T const &other ) const -> Parser;
|
auto operator|( T const &other ) const -> Parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@@ -810,16 +805,16 @@ namespace detail {
|
|||||||
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ParserRefImpl( T &ref, std::string const &hint )
|
ParserRefImpl( T &ref, std::string const &hint )
|
||||||
: m_ref( std::make_shared<BoundRef<T>>( ref ) ),
|
: m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint )
|
m_hint( hint )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -860,10 +855,10 @@ namespace detail {
|
|||||||
|
|
||||||
class ExeName : public ComposableParserImpl<ExeName> {
|
class ExeName : public ComposableParserImpl<ExeName> {
|
||||||
std::shared_ptr<std::string> m_name;
|
std::shared_ptr<std::string> m_name;
|
||||||
std::shared_ptr<BoundRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
|
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,7 +866,7 @@ namespace detail {
|
|||||||
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
|
||||||
|
|
||||||
explicit ExeName( std::string &ref ) : ExeName() {
|
explicit ExeName( std::string &ref ) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundRef<std::string>>( ref );
|
m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LambdaT>
|
template<typename LambdaT>
|
||||||
@@ -914,7 +909,10 @@ namespace detail {
|
|||||||
if( token.type != TokenType::Argument )
|
if( token.type != TokenType::Argument )
|
||||||
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
|
||||||
|
|
||||||
auto result = m_ref->setValue( remainingTokens->token );
|
assert( !m_ref->isFlag() );
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
|
|
||||||
|
auto result = valueRef->setValue( remainingTokens->token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
else
|
else
|
||||||
@@ -988,19 +986,21 @@ namespace detail {
|
|||||||
auto const &token = *remainingTokens;
|
auto const &token = *remainingTokens;
|
||||||
if( isMatch(token.token ) ) {
|
if( isMatch(token.token ) ) {
|
||||||
if( m_ref->isFlag() ) {
|
if( m_ref->isFlag() ) {
|
||||||
auto result = m_ref->setFlag( true );
|
auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
|
||||||
|
auto result = flagRef->setFlag( true );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
|
||||||
} else {
|
} else {
|
||||||
|
auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if( !remainingTokens )
|
if( !remainingTokens )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto const &argToken = *remainingTokens;
|
auto const &argToken = *remainingTokens;
|
||||||
if( argToken.type != TokenType::Argument )
|
if( argToken.type != TokenType::Argument )
|
||||||
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
|
||||||
auto result = m_ref->setValue( argToken.token );
|
auto result = valueRef->setValue( argToken.token );
|
||||||
if( !result )
|
if( !result )
|
||||||
return InternalParseResult( result );
|
return InternalParseResult( result );
|
||||||
if( result.value() == ParseResultType::ShortCircuitAll )
|
if( result.value() == ParseResultType::ShortCircuitAll )
|
||||||
@@ -1077,6 +1077,12 @@ namespace detail {
|
|||||||
return Parser( *this ) |= other;
|
return Parser( *this ) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
|
template<typename T>
|
||||||
|
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
|
||||||
|
template<typename T>
|
||||||
|
auto operator+( T const &other ) const -> Parser { return operator|( other ); }
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const &o : m_options) {
|
||||||
@@ -1116,6 +1122,8 @@ namespace detail {
|
|||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
|
optWidth = (std::min)(optWidth, consoleWidth/2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
|
||||||
|
Reference in New Issue
Block a user