Merge branch 'catchorg:devel' into devel

This commit is contained in:
ניר 2023-05-29 09:32:57 +03:00 committed by GitHub
commit d25f5ecaf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 999 additions and 640 deletions

View File

@ -68,7 +68,11 @@ set(_OtherConfigOptions
foreach(OptionName ${_OtherConfigOptions})
AddConfigOption(${OptionName})
endforeach()
set(CATCH_CONFIG_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
if(DEFINED BUILD_SHARED_LIBS)
set(CATCH_CONFIG_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
else()
set(CATCH_CONFIG_SHARED_LIBRARY "")
endif()
set(CATCH_CONFIG_DEFAULT_REPORTER "console" CACHE STRING "Read docs/configuration.md for details. The name of the reporter should be without quotes.")
set(CATCH_CONFIG_CONSOLE_WIDTH "80" CACHE STRING "Read docs/configuration.md for details. Must form a valid integer literal.")

View File

@ -74,6 +74,7 @@ function(add_warnings_to_targets targets)
"-Woverloaded-virtual"
"-Wparentheses"
"-Wpedantic"
"-Wredundant-decls"
"-Wreorder"
"-Wreturn-std-move"
"-Wshadow"
@ -83,7 +84,7 @@ function(add_warnings_to_targets targets)
"-Wundef"
"-Wuninitialized"
"-Wunneeded-internal-declaration"
"-Wunreachable-code"
"-Wunreachable-code-aggressive"
"-Wunused"
"-Wunused-function"
"-Wunused-parameter"

View File

@ -126,6 +126,7 @@ catch_discover_tests(target
[OUTPUT_DIR dir]
[OUTPUT_PREFIX prefix]
[OUTPUT_SUFFIX suffix]
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
)
```
@ -198,6 +199,16 @@ If specified, `suffix` is added to each output file name, like so
`--out dir/<test_name>suffix`. This can be used to add a file extension to
the output file name e.g. ".xml".
* `DISCOVERY_MODE mode`
If specified allows control over when test discovery is performed.
For a value of `POST_BUILD` (default) test discovery is performed at build time.
For a a value of `PRE_TEST` test discovery is delayed until just prior to test
execution (useful e.g. in cross-compilation environments).
``DISCOVERY_MODE`` defaults to the value of the
``CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when
calling ``catch_discover_tests``. This provides a mechanism for globally
selecting a preferred test discovery behavior.
### `ParseAndAddCatchTests.cmake`

View File

@ -28,7 +28,7 @@ depending on how often the cleanup needs to happen.
## Why cannot I derive from the built-in reporters?
They are not made to be overridden, in that we do not attempt to maintain
a consistent internal state if a member function is overriden, and by
a consistent internal state if a member function is overridden, and by
forbidding users from using them as a base class, we can refactor them
as needed later.

View File

@ -134,7 +134,7 @@ type, making their usage much nicer. These are
* `map<T>(func, GeneratorWrapper<U>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`)
* `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>`
* `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
* `range(Arithemtic start, Arithmetic end)` for `RangeGenerator<Arithmetic>` with a step size of `1`
* `range(Arithmetic start, Arithmetic end)` for `RangeGenerator<Arithmetic>` with a step size of `1`
* `range(Arithmetic start, Arithmetic end, Arithmetic step)` for `RangeGenerator<Arithmetic>` with a custom step size
* `from_range(InputIterator from, InputIterator to)` for `IteratorGenerator<T>`
* `from_range(Container const&)` for `IteratorGenerator<T>`

View File

@ -95,6 +95,9 @@ A C++ client library for Consul. Consul is a distributed tool for discovering an
### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp)
A library of algorithms for values-distributed-in-time.
### [SFML](https://github.com/SFML/SFML)
Simple and Fast Multimedia Library.
### [SOCI](https://github.com/SOCI/soci)
The C++ Database Access Library.
@ -143,7 +146,7 @@ Newsbeuter is an open-source RSS/Atom feed reader for text terminals.
A 2D, Zombie, RPG game which is being made on our own engine.
### [raspigcd](https://github.com/pantadeusz/raspigcd)
Low level CLI app and library for execution of GCODE on Raspberry Pi without any additional microcontrolers (just RPi + Stepsticks).
Low level CLI app and library for execution of GCODE on Raspberry Pi without any additional microcontrollers (just RPi + Stepsticks).
### [SpECTRE](https://github.com/sxs-collaboration/spectre)
SpECTRE is a code for multi-scale, multi-physics problems in astrophysics and gravitational physics.

View File

@ -149,7 +149,7 @@
### Fixes
* Cleaned out some warnings and static analysis issues
* Suppressed `-Wcomma` warning rarely occuring in templated test cases (#2543)
* Suppressed `-Wcomma` warning rarely occurring in templated test cases (#2543)
* Constified implementation details in `INFO` (#2564)
* Made `MatcherGenericBase` copy constructor const (#2566)
* Fixed serialization of test filters so the output roundtrips
@ -517,7 +517,7 @@ v3 releases.
* The `SECTION`(s) before the `GENERATE` will not be run multiple times, the following ones will.
* Added `-D`/`--min-duration` command line flag (#1910)
* If a test takes longer to finish than the provided value, its name and duration will be printed.
* This flag is overriden by setting `-d`/`--duration`.
* This flag is overridden by setting `-d`/`--duration`.
### Fixes
* `TAPReporter` no longer skips successful assertions (#1983)
@ -585,7 +585,7 @@ v3 releases.
### Fixes
* Fixed computation of benchmarking column widths in ConsoleReporter (#1885, #1886)
* Suppressed clang-tidy's `cppcoreguidelines-pro-type-vararg` in assertions (#1901)
* It was a false positive trigered by the new warning support workaround
* It was a false positive triggered by the new warning support workaround
* Fixed bug in test specification parser handling of OR'd patterns using escaping (#1905)
### Miscellaneous
@ -922,7 +922,7 @@ v3 releases.
### Contrib
* `ParseAndAddCatchTests` has learned how to use `DISABLED` CTest property (#1452)
* `ParseAndAddCatchTests` now works when there is a whitspace before the test name (#1493)
* `ParseAndAddCatchTests` now works when there is a whitespace before the test name (#1493)
### Miscellaneous

View File

@ -96,12 +96,12 @@ void assertionStarting( AssertionInfo const& assertionInfo );
void assertionEnded( AssertionStats const& assertionStats );
```
`assertionStarting` is called after the expression is captured, but before
the assertion expression is evaluated. This might seem like a minor
distinction, but what it means is that if you have assertion like
`REQUIRE( a + b == c + d )`, then what happens is that `a + b` and `c + d`
are evaluated before `assertionStarting` is emitted, while the `==` is
evaluated after the event.
The `assertionStarting` event is emitted before the expression in the
assertion is captured or evaluated and `assertionEnded` is emitted
afterwards. This means that given assertion like `REQUIRE(a + b == c + d)`,
Catch2 first emits `assertionStarting` event, then `a + b` and `c + d`
are evaluated, then their results are captured, the comparison is evaluated,
and then `assertionEnded` event is emitted.
## Benchmarking events

View File

@ -44,11 +44,11 @@ TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][genera
/* Possible simplifications where less legacy toolchain support is needed:
*
* - With libstdc++6 or newer, the make_tuple() calls can be ommitted
* - With libstdc++6 or newer, the make_tuple() calls can be omitted
* (technically C++17 but does not require -std in GCC/Clang). See
* https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list
*
* - In C++17 mode std::tie() and the preceding variable delcarations can be
* - In C++17 mode std::tie() and the preceding variable declarations can be
* replaced by structured bindings: auto [test_input, expected] = GENERATE(
* table<std::string, size_t>({ ...
*/

View File

@ -37,6 +37,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
[OUTPUT_DIR dir]
[OUTPUT_PREFIX prefix]
[OUTPUT_SUFFIX suffix]
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
)
``catch_discover_tests`` sets up a post-build command on the test executable
@ -123,14 +124,28 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
test executable and when the tests are executed themselves. This requires
cmake/ctest >= 3.22.
`DISCOVERY_MODE mode``
Provides control over when ``catch_discover_tests`` performs test discovery.
By default, ``POST_BUILD`` sets up a post-build command to perform test discovery
at build time. In certain scenarios, like cross-compiling, this ``POST_BUILD``
behavior is not desirable. By contrast, ``PRE_TEST`` delays test discovery until
just prior to test execution. This way test discovery occurs in the target environment
where the test has a better chance at finding appropriate runtime dependencies.
``DISCOVERY_MODE`` defaults to the value of the
``CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when
calling ``catch_discover_tests``. This provides a mechanism for globally selecting
a preferred test discovery behavior without having to modify each call site.
#]=======================================================================]
#------------------------------------------------------------------------------
function(catch_discover_tests TARGET)
cmake_parse_arguments(
""
""
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX"
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX;DISCOVERY_MODE"
"TEST_SPEC;EXTRA_ARGS;PROPERTIES;DL_PATHS"
${ARGN}
)
@ -141,12 +156,20 @@ function(catch_discover_tests TARGET)
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
if (_DL_PATHS)
if(${CMAKE_VERSION} VERSION_LESS "3.22.0")
message(FATAL_ERROR "The DL_PATHS option requires at least cmake 3.22")
endif()
endif()
if(NOT _DISCOVERY_MODE)
if(NOT CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE)
set(CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
endif()
set(_DISCOVERY_MODE ${CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE})
endif()
if (NOT _DISCOVERY_MODE MATCHES "^(POST_BUILD|PRE_TEST)$")
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
endif()
## Generate a unique name based on the extra arguments
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}")
@ -159,39 +182,77 @@ function(catch_discover_tests TARGET)
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 "TEST_REPORTER=${_REPORTER}"
-D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
-D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
-D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
-D "TEST_DL_PATHS=${_DL_PATHS}"
-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(_DISCOVERY_MODE STREQUAL "POST_BUILD")
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 "TEST_REPORTER=${_REPORTER}"
-D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
-D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
-D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
-D "TEST_DL_PATHS=${_DL_PATHS}"
-D "CTEST_FILE=${ctest_tests_file}"
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
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"
)
elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
string(CONCAT ctest_include_content
"if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
" if(NOT EXISTS \"${ctest_tests_file}\" OR" "\n"
" NOT \"${ctest_tests_file}\" IS_NEWER_THAN \"$<TARGET_FILE:${TARGET}>\" OR\n"
" NOT \"${ctest_tests_file}\" IS_NEWER_THAN \"\${CMAKE_CURRENT_LIST_FILE}\")\n"
" include(\"${_CATCH_DISCOVER_TESTS_SCRIPT}\")" "\n"
" catch_discover_tests_impl(" "\n"
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
" TEST_SPEC" " [==[" "${_TEST_SPEC}" "]==]" "\n"
" TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
" TEST_REPORTER" " [==[" "${_REPORTER}" "]==]" "\n"
" TEST_OUTPUT_DIR" " [==[" "${_OUTPUT_DIR}" "]==]" "\n"
" TEST_OUTPUT_PREFIX" " [==[" "${_OUTPUT_PREFIX}" "]==]" "\n"
" TEST_OUTPUT_SUFFIX" " [==[" "${_OUTPUT_SUFFIX}" "]==]" "\n"
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
" TEST_DL_PATHS" " [==[" "${_DL_PATHS}" "]==]" "\n"
" CTEST_FILE" " [==[" "${CTEST_FILE}" "]==]" "\n"
" )" "\n"
" endif()" "\n"
" include(\"${ctest_tests_file}\")" "\n"
"else()" "\n"
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
"endif()" "\n"
)
file(GENERATE OUTPUT "${ctest_include_file}" CONTENT "${ctest_include_content}")
endif()
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}"
@ -204,9 +265,7 @@ function(catch_discover_tests TARGET)
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
)
else()
message(FATAL_ERROR
"Cannot set more than one TEST_INCLUDE_FILE"
)
message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE")
endif()
endif()

View File

@ -1,28 +1,6 @@
# 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(reporter ${TEST_REPORTER})
set(output_dir ${TEST_OUTPUT_DIR})
set(output_prefix ${TEST_OUTPUT_PREFIX})
set(output_suffix ${TEST_OUTPUT_SUFFIX})
set(dl_paths ${TEST_DL_PATHS})
set(script)
set(suite)
set(tests)
if(WIN32)
set(dl_paths_variable_name PATH)
elseif(APPLE)
set(dl_paths_variable_name DYLD_LIBRARY_PATH)
else()
set(dl_paths_variable_name LD_LIBRARY_PATH)
endif()
function(add_command NAME)
set(_args "")
# use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments
@ -38,119 +16,172 @@ function(add_command NAME)
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"
function(catch_discover_tests_impl)
cmake_parse_arguments(
""
""
"TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_DL_PATHS;TEST_OUTPUT_DIR;TEST_OUTPUT_PREFIX;TEST_OUTPUT_SUFFIX;TEST_PREFIX;TEST_REPORTER;TEST_SPEC;TEST_SUFFIX;TEST_LIST;CTEST_FILE"
"TEST_EXTRA_ARGS;TEST_PROPERTIES;TEST_EXECUTOR"
${ARGN}
)
endif()
if(dl_paths)
cmake_path(CONVERT "${dl_paths}" TO_NATIVE_PATH_LIST paths)
set(ENV{${dl_paths_variable_name}} "${paths}")
endif()
set(prefix "${_TEST_PREFIX}")
set(suffix "${_TEST_SUFFIX}")
set(spec ${_TEST_SPEC})
set(extra_args ${_TEST_EXTRA_ARGS})
set(properties ${_TEST_PROPERTIES})
set(reporter ${_TEST_REPORTER})
set(output_dir ${_TEST_OUTPUT_DIR})
set(output_prefix ${_TEST_OUTPUT_PREFIX})
set(output_suffix ${_TEST_OUTPUT_SUFFIX})
set(dl_paths ${_TEST_DL_PATHS})
set(script)
set(suite)
set(tests)
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
OUTPUT_VARIABLE output
RESULT_VARIABLE result
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
)
if(NOT ${result} EQUAL 0)
message(FATAL_ERROR
"Error running test executable '${TEST_EXECUTABLE}':\n"
" Result: ${result}\n"
" Output: ${output}\n"
)
endif()
if(WIN32)
set(dl_paths_variable_name PATH)
elseif(APPLE)
set(dl_paths_variable_name DYLD_LIBRARY_PATH)
else()
set(dl_paths_variable_name LD_LIBRARY_PATH)
endif()
string(REPLACE "\n" ";" output "${output}")
# 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()
# Prepare reporter
if(reporter)
set(reporter_arg "--reporter ${reporter}")
if(dl_paths)
cmake_path(CONVERT "${dl_paths}" TO_NATIVE_PATH_LIST paths)
set(ENV{${dl_paths_variable_name}} "${paths}")
endif()
# Run test executable to check whether reporter is available
# note that the use of --list-reporters is not the important part,
# we only want to check whether the execution succeeds with ${reporter_arg}
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} ${reporter_arg} --list-reporters
OUTPUT_VARIABLE reporter_check_output
RESULT_VARIABLE reporter_check_result
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
OUTPUT_VARIABLE output
RESULT_VARIABLE result
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
)
if(${reporter_check_result} EQUAL 255)
if(NOT ${result} EQUAL 0)
message(FATAL_ERROR
"\"${reporter}\" is not a valid reporter!\n"
)
elseif(NOT ${reporter_check_result} EQUAL 0)
message(FATAL_ERROR
"Error running test executable '${TEST_EXECUTABLE}':\n"
" Result: ${reporter_check_result}\n"
" Output: ${reporter_check_output}\n"
"Error running test executable '${_TEST_EXECUTABLE}':\n"
" Result: ${result}\n"
" Output: ${output}\n"
)
endif()
endif()
# Prepare output dir
if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
set(output_dir "${TEST_WORKING_DIR}/${output_dir}")
if(NOT EXISTS ${output_dir})
file(MAKE_DIRECTORY ${output_dir})
string(REPLACE "\n" ";" output "${output}")
# Prepare reporter
if(reporter)
set(reporter_arg "--reporter ${reporter}")
# Run test executable to check whether reporter is available
# note that the use of --list-reporters is not the important part,
# we only want to check whether the execution succeeds with ${reporter_arg}
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} ${reporter_arg} --list-reporters
OUTPUT_VARIABLE reporter_check_output
RESULT_VARIABLE reporter_check_result
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
)
if(${reporter_check_result} EQUAL 255)
message(FATAL_ERROR
"\"${reporter}\" is not a valid reporter!\n"
)
elseif(NOT ${reporter_check_result} EQUAL 0)
message(FATAL_ERROR
"Error running test executable '${TEST_EXECUTABLE}':\n"
" Result: ${reporter_check_result}\n"
" Output: ${reporter_check_output}\n"
)
endif()
endif()
endif()
if(dl_paths)
foreach(path ${dl_paths})
cmake_path(NATIVE_PATH path native_path)
list(APPEND environment_modifications "${dl_paths_variable_name}=path_list_prepend:${native_path}")
# Prepare output dir
if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
set(output_dir "${_TEST_WORKING_DIR}/${output_dir}")
if(NOT EXISTS ${output_dir})
file(MAKE_DIRECTORY ${output_dir})
endif()
endif()
if(dl_paths)
foreach(path ${dl_paths})
cmake_path(NATIVE_PATH path native_path)
list(APPEND environment_modifications "${dl_paths_variable_name}=path_list_prepend:${native_path}")
endforeach()
endif()
# Parse output
foreach(line ${output})
set(test ${line})
# Escape characters in test case names that would be parsed by Catch2
set(test_name ${test})
foreach(char , [ ])
string(REPLACE ${char} "\\${char}" test_name ${test_name})
endforeach(char)
# ...add output dir
if(output_dir)
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
endif()
# ...and add to script
add_command(add_test
"${prefix}${test}${suffix}"
${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}"
"${test_name}"
${extra_args}
"${reporter_arg}"
"${output_dir_arg}"
)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
${properties}
)
if(environment_modifications)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
ENVIRONMENT_MODIFICATION "${environment_modifications}")
endif()
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}")
endfunction()
if(CMAKE_SCRIPT_MODE_FILE)
catch_discover_tests_impl(
TEST_EXECUTABLE ${TEST_EXECUTABLE}
TEST_EXECUTOR ${TEST_EXECUTOR}
TEST_WORKING_DIR ${TEST_WORKING_DIR}
TEST_SPEC ${TEST_SPEC}
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
TEST_PROPERTIES ${TEST_PROPERTIES}
TEST_PREFIX ${TEST_PREFIX}
TEST_SUFFIX ${TEST_SUFFIX}
TEST_LIST ${TEST_LIST}
TEST_REPORTER ${TEST_REPORTER}
TEST_OUTPUT_DIR ${TEST_OUTPUT_DIR}
TEST_OUTPUT_PREFIX ${TEST_OUTPUT_PREFIX}
TEST_OUTPUT_SUFFIX ${TEST_OUTPUT_SUFFIX}
TEST_DL_PATHS ${TEST_DL_PATHS}
CTEST_FILE ${CTEST_FILE}
)
endif()
# Parse output
foreach(line ${output})
set(test ${line})
# Escape characters in test case names that would be parsed by Catch2
set(test_name ${test})
foreach(char , [ ])
string(REPLACE ${char} "\\${char}" test_name ${test_name})
endforeach(char)
# ...add output dir
if(output_dir)
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
endif()
# ...and add to script
add_command(add_test
"${prefix}${test}${suffix}"
${TEST_EXECUTOR}
"${TEST_EXECUTABLE}"
"${test_name}"
${extra_args}
"${reporter_arg}"
"${output_dir_arg}"
)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
${properties}
)
if(environment_modifications)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
ENVIRONMENT_MODIFICATION "${environment_modifications}")
endif()
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}")

View File

@ -10,8 +10,10 @@ project(
'cpp',
version: '3.3.2', # CML version placeholder, don't delete
license: 'BSL-1.0',
meson_version: '>=0.50.0',
meson_version: '>=0.54.1',
)
subdir('src/catch2')
subdir('tests')
if get_option('tests')
subdir('tests')
endif

1
meson_options.txt Normal file
View File

@ -0,0 +1 @@
option('tests', type: 'boolean', value: true, description: 'Build the unit tests')

View File

@ -30,6 +30,7 @@
#include <algorithm>
#include <chrono>
#include <exception>
#include <functional>
#include <string>
#include <vector>

View File

@ -17,8 +17,7 @@
#include <catch2/benchmark/detail/catch_repeat.hpp>
#include <catch2/benchmark/detail/catch_run_for_at_least.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
namespace Catch {
namespace Benchmark {
@ -41,14 +40,17 @@ namespace Catch {
Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
std::vector<FloatDuration<Clock>> times;
times.reserve(cfg.benchmarkSamples());
std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
const auto num_samples = cfg.benchmarkSamples();
times.reserve( num_samples );
for ( size_t i = 0; i < num_samples; ++i ) {
Detail::ChronometerModel<Clock> model;
this->benchmark(Chronometer(model, iterations_per_sample));
this->benchmark( Chronometer( model, iterations_per_sample ) );
auto sample_time = model.elapsed() - env.clock_cost.mean;
if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
return sample_time / iterations_per_sample;
});
if ( sample_time < FloatDuration<Clock>::zero() ) {
sample_time = FloatDuration<Clock>::zero();
}
times.push_back(sample_time / iterations_per_sample);
}
return times;
}
};

View File

@ -10,14 +10,11 @@
#ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
#define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
#include <catch2/benchmark/catch_clock.hpp>
#include <catch2/benchmark/catch_estimate.hpp>
#include <catch2/benchmark/catch_outlier_classification.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <algorithm>
#include <vector>
#include <iterator>
namespace Catch {
namespace Benchmark {
@ -33,7 +30,9 @@ namespace Catch {
operator SampleAnalysis<Duration2>() const {
std::vector<Duration2> samples2;
samples2.reserve(samples.size());
std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
for (auto const& d : samples) {
samples2.push_back(Duration2(d));
}
return {
CATCH_MOVE(samples2),
mean,

View File

@ -16,8 +16,6 @@
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
namespace Catch {
@ -28,7 +26,9 @@ namespace Catch {
if (!cfg.benchmarkNoAnalysis()) {
std::vector<double> samples;
samples.reserve(static_cast<size_t>(last - first));
std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
for (auto current = first; current != last; ++current) {
samples.push_back( current->count() );
}
auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
@ -43,7 +43,10 @@ namespace Catch {
};
std::vector<Duration> samples2;
samples2.reserve(samples.size());
std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
for (auto s : samples) {
samples2.push_back( Duration( s ) );
}
return {
CATCH_MOVE(samples2),
wrap_estimate(analysis.mean),

View File

@ -19,7 +19,6 @@
#include <catch2/internal/catch_unique_ptr.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
#include <cmath>
@ -30,26 +29,29 @@ namespace Catch {
std::vector<double> resolution(int k) {
std::vector<TimePoint<Clock>> times;
times.reserve(static_cast<size_t>(k + 1));
std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
for ( int i = 0; i < k + 1; ++i ) {
times.push_back( Clock::now() );
}
std::vector<double> deltas;
deltas.reserve(static_cast<size_t>(k));
std::transform(std::next(times.begin()), times.end(), times.begin(),
std::back_inserter(deltas),
[](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
for ( size_t idx = 1; idx < times.size(); ++idx ) {
deltas.push_back( static_cast<double>(
( times[idx] - times[idx - 1] ).count() ) );
}
return deltas;
}
const auto warmup_iterations = 10000;
const auto warmup_time = std::chrono::milliseconds(100);
const auto minimum_ticks = 1000;
const auto warmup_seed = 10000;
const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
const auto clock_cost_estimation_tick_limit = 100000;
const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
const auto clock_cost_estimation_iterations = 10000;
constexpr auto warmup_iterations = 10000;
constexpr auto warmup_time = std::chrono::milliseconds(100);
constexpr auto minimum_ticks = 1000;
constexpr auto warmup_seed = 10000;
constexpr auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
constexpr auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
constexpr auto clock_cost_estimation_tick_limit = 100000;
constexpr auto clock_cost_estimation_time = std::chrono::milliseconds(10);
constexpr auto clock_cost_estimation_iterations = 10000;
template <typename Clock>
int warmup() {
@ -84,9 +86,11 @@ namespace Catch {
std::vector<double> times;
int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
times.reserve(static_cast<size_t>(nsamples));
std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
});
for ( int s = 0; s < nsamples; ++s ) {
times.push_back( static_cast<double>(
( time_clock( r.iterations ) / r.iterations )
.count() ) );
}
return {
FloatDuration<Clock>(mean(times.begin(), times.end())),
classify_outliers(times.begin(), times.end()),

View File

@ -13,7 +13,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
#include <numeric>
#include <random>
@ -21,117 +21,172 @@
#include <future>
#endif
namespace {
namespace Catch {
namespace Benchmark {
namespace Detail {
namespace {
using Catch::Benchmark::Detail::sample;
template <typename URng, typename Estimator>
static sample
resample( URng& rng,
unsigned int resamples,
std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last,
Estimator& estimator ) {
auto n = static_cast<size_t>( last - first );
std::uniform_int_distribution<decltype( n )> dist( 0,
n - 1 );
template <typename URng, typename Estimator>
sample resample(URng& rng, unsigned int resamples, std::vector<double>::iterator first, std::vector<double>::iterator last, Estimator& estimator) {
auto n = static_cast<size_t>(last - first);
std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
sample out;
out.reserve( resamples );
// We allocate the vector outside the loop to avoid realloc
// per resample
std::vector<double> resampled;
resampled.reserve( n );
for ( size_t i = 0; i < resamples; ++i ) {
resampled.clear();
for ( size_t s = 0; s < n; ++s ) {
resampled.push_back(
first[static_cast<std::ptrdiff_t>(
dist( rng ) )] );
}
const auto estimate =
estimator( resampled.begin(), resampled.end() );
out.push_back( estimate );
}
std::sort( out.begin(), out.end() );
return out;
}
sample out;
out.reserve(resamples);
std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
std::vector<double> resampled;
resampled.reserve(n);
std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[static_cast<std::ptrdiff_t>(dist(rng))]; });
return estimator(resampled.begin(), resampled.end());
});
std::sort(out.begin(), out.end());
return out;
}
static double outlier_variance( Estimate<double> mean,
Estimate<double> stddev,
int n ) {
double sb = stddev.point;
double mn = mean.point / n;
double mg_min = mn / 2.;
double sg = (std::min)( mg_min / 4., sb / std::sqrt( n ) );
double sg2 = sg * sg;
double sb2 = sb * sb;
auto c_max = [n, mn, sb2, sg2]( double x ) -> double {
double k = mn - x;
double d = k * k;
double nd = n * d;
double k0 = -n * nd;
double k1 = sb2 - n * sg2 + nd;
double det = k1 * k1 - 4 * sg2 * k0;
return static_cast<int>( -2. * k0 /
( k1 + std::sqrt( det ) ) );
};
double erf_inv(double x) {
// Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
double w, p;
auto var_out = [n, sb2, sg2]( double c ) {
double nc = n - c;
return ( nc / n ) * ( sb2 - nc * sg2 );
};
w = -log((1.0 - x) * (1.0 + x));
return (std::min)( var_out( 1 ),
var_out(
(std::min)( c_max( 0. ),
c_max( mg_min ) ) ) ) /
sb2;
}
if (w < 6.250000) {
w = w - 3.125000;
p = -3.6444120640178196996e-21;
p = -1.685059138182016589e-19 + p * w;
p = 1.2858480715256400167e-18 + p * w;
p = 1.115787767802518096e-17 + p * w;
p = -1.333171662854620906e-16 + p * w;
p = 2.0972767875968561637e-17 + p * w;
p = 6.6376381343583238325e-15 + p * w;
p = -4.0545662729752068639e-14 + p * w;
p = -8.1519341976054721522e-14 + p * w;
p = 2.6335093153082322977e-12 + p * w;
p = -1.2975133253453532498e-11 + p * w;
p = -5.4154120542946279317e-11 + p * w;
p = 1.051212273321532285e-09 + p * w;
p = -4.1126339803469836976e-09 + p * w;
p = -2.9070369957882005086e-08 + p * w;
p = 4.2347877827932403518e-07 + p * w;
p = -1.3654692000834678645e-06 + p * w;
p = -1.3882523362786468719e-05 + p * w;
p = 0.0001867342080340571352 + p * w;
p = -0.00074070253416626697512 + p * w;
p = -0.0060336708714301490533 + p * w;
p = 0.24015818242558961693 + p * w;
p = 1.6536545626831027356 + p * w;
} else if (w < 16.000000) {
w = sqrt(w) - 3.250000;
p = 2.2137376921775787049e-09;
p = 9.0756561938885390979e-08 + p * w;
p = -2.7517406297064545428e-07 + p * w;
p = 1.8239629214389227755e-08 + p * w;
p = 1.5027403968909827627e-06 + p * w;
p = -4.013867526981545969e-06 + p * w;
p = 2.9234449089955446044e-06 + p * w;
p = 1.2475304481671778723e-05 + p * w;
p = -4.7318229009055733981e-05 + p * w;
p = 6.8284851459573175448e-05 + p * w;
p = 2.4031110387097893999e-05 + p * w;
p = -0.0003550375203628474796 + p * w;
p = 0.00095328937973738049703 + p * w;
p = -0.0016882755560235047313 + p * w;
p = 0.0024914420961078508066 + p * w;
p = -0.0037512085075692412107 + p * w;
p = 0.005370914553590063617 + p * w;
p = 1.0052589676941592334 + p * w;
p = 3.0838856104922207635 + p * w;
} else {
w = sqrt(w) - 5.000000;
p = -2.7109920616438573243e-11;
p = -2.5556418169965252055e-10 + p * w;
p = 1.5076572693500548083e-09 + p * w;
p = -3.7894654401267369937e-09 + p * w;
p = 7.6157012080783393804e-09 + p * w;
p = -1.4960026627149240478e-08 + p * w;
p = 2.9147953450901080826e-08 + p * w;
p = -6.7711997758452339498e-08 + p * w;
p = 2.2900482228026654717e-07 + p * w;
p = -9.9298272942317002539e-07 + p * w;
p = 4.5260625972231537039e-06 + p * w;
p = -1.9681778105531670567e-05 + p * w;
p = 7.5995277030017761139e-05 + p * w;
p = -0.00021503011930044477347 + p * w;
p = -0.00013871931833623122026 + p * w;
p = 1.0103004648645343977 + p * w;
p = 4.8499064014085844221 + p * w;
}
return p * x;
}
static double erf_inv( double x ) {
// Code accompanying the article "Approximating the erfinv
// function" in GPU Computing Gems, Volume 2
double w, p;
double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
auto m = Catch::Benchmark::Detail::mean(first, last);
double variance = std::accumulate( first,
last,
0.,
[m]( double a, double b ) {
double diff = b - m;
return a + diff * diff;
} ) /
( last - first );
return std::sqrt( variance );
}
w = -log( ( 1.0 - x ) * ( 1.0 + x ) );
}
if ( w < 6.250000 ) {
w = w - 3.125000;
p = -3.6444120640178196996e-21;
p = -1.685059138182016589e-19 + p * w;
p = 1.2858480715256400167e-18 + p * w;
p = 1.115787767802518096e-17 + p * w;
p = -1.333171662854620906e-16 + p * w;
p = 2.0972767875968561637e-17 + p * w;
p = 6.6376381343583238325e-15 + p * w;
p = -4.0545662729752068639e-14 + p * w;
p = -8.1519341976054721522e-14 + p * w;
p = 2.6335093153082322977e-12 + p * w;
p = -1.2975133253453532498e-11 + p * w;
p = -5.4154120542946279317e-11 + p * w;
p = 1.051212273321532285e-09 + p * w;
p = -4.1126339803469836976e-09 + p * w;
p = -2.9070369957882005086e-08 + p * w;
p = 4.2347877827932403518e-07 + p * w;
p = -1.3654692000834678645e-06 + p * w;
p = -1.3882523362786468719e-05 + p * w;
p = 0.0001867342080340571352 + p * w;
p = -0.00074070253416626697512 + p * w;
p = -0.0060336708714301490533 + p * w;
p = 0.24015818242558961693 + p * w;
p = 1.6536545626831027356 + p * w;
} else if ( w < 16.000000 ) {
w = sqrt( w ) - 3.250000;
p = 2.2137376921775787049e-09;
p = 9.0756561938885390979e-08 + p * w;
p = -2.7517406297064545428e-07 + p * w;
p = 1.8239629214389227755e-08 + p * w;
p = 1.5027403968909827627e-06 + p * w;
p = -4.013867526981545969e-06 + p * w;
p = 2.9234449089955446044e-06 + p * w;
p = 1.2475304481671778723e-05 + p * w;
p = -4.7318229009055733981e-05 + p * w;
p = 6.8284851459573175448e-05 + p * w;
p = 2.4031110387097893999e-05 + p * w;
p = -0.0003550375203628474796 + p * w;
p = 0.00095328937973738049703 + p * w;
p = -0.0016882755560235047313 + p * w;
p = 0.0024914420961078508066 + p * w;
p = -0.0037512085075692412107 + p * w;
p = 0.005370914553590063617 + p * w;
p = 1.0052589676941592334 + p * w;
p = 3.0838856104922207635 + p * w;
} else {
w = sqrt( w ) - 5.000000;
p = -2.7109920616438573243e-11;
p = -2.5556418169965252055e-10 + p * w;
p = 1.5076572693500548083e-09 + p * w;
p = -3.7894654401267369937e-09 + p * w;
p = 7.6157012080783393804e-09 + p * w;
p = -1.4960026627149240478e-08 + p * w;
p = 2.9147953450901080826e-08 + p * w;
p = -6.7711997758452339498e-08 + p * w;
p = 2.2900482228026654717e-07 + p * w;
p = -9.9298272942317002539e-07 + p * w;
p = 4.5260625972231537039e-06 + p * w;
p = -1.9681778105531670567e-05 + p * w;
p = 7.5995277030017761139e-05 + p * w;
p = -0.00021503011930044477347 + p * w;
p = -0.00013871931833623122026 + p * w;
p = 1.0103004648645343977 + p * w;
p = 4.8499064014085844221 + p * w;
}
return p * x;
}
static double
standard_deviation( std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last ) {
auto m = Catch::Benchmark::Detail::mean( first, last );
double variance =
std::accumulate( first,
last,
0.,
[m]( double a, double b ) {
double diff = b - m;
return a + diff * diff;
} ) /
( last - first );
return std::sqrt( variance );
}
} // namespace
} // namespace Detail
} // namespace Benchmark
} // namespace Catch
namespace Catch {
namespace Benchmark {
@ -161,6 +216,47 @@ namespace Catch {
return xj + g * (xj1 - xj);
}
OutlierClassification
classify_outliers( std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last ) {
std::vector<double> copy( first, last );
auto q1 = weighted_average_quantile( 1, 4, copy.begin(), copy.end() );
auto q3 = weighted_average_quantile( 3, 4, copy.begin(), copy.end() );
auto iqr = q3 - q1;
auto los = q1 - ( iqr * 3. );
auto lom = q1 - ( iqr * 1.5 );
auto him = q3 + ( iqr * 1.5 );
auto his = q3 + ( iqr * 3. );
OutlierClassification o;
for ( ; first != last; ++first ) {
const double t = *first;
if ( t < los ) {
++o.low_severe;
} else if ( t < lom ) {
++o.low_mild;
} else if ( t > his ) {
++o.high_severe;
} else if ( t > him ) {
++o.high_mild;
}
++o.samples_seen;
}
return o;
}
double mean( std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last ) {
auto count = last - first;
double sum = 0.;
while (first != last) {
sum += *first;
++first;
}
return sum / static_cast<double>(count);
}
double erfc_inv(double x) {
return erf_inv(1.0 - x);
@ -182,35 +278,10 @@ namespace Catch {
return result;
}
double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
double sb = stddev.point;
double mn = mean.point / n;
double mg_min = mn / 2.;
double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
double sg2 = sg * sg;
double sb2 = sb * sb;
auto c_max = [n, mn, sb2, sg2](double x) -> double {
double k = mn - x;
double d = k * k;
double nd = n * d;
double k0 = -n * nd;
double k1 = sb2 - n * sg2 + nd;
double det = k1 * k1 - 4 * sg2 * k0;
return static_cast<int>(-2. * k0 / (k1 + std::sqrt(det)));
};
auto var_out = [n, sb2, sg2](double c) {
double nc = n - c;
return (nc / n) * (sb2 - nc * sg2);
};
return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
}
bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
bootstrap_analysis analyse_samples(double confidence_level,
unsigned int n_resamples,
std::vector<double>::iterator first,
std::vector<double>::iterator last) {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy;
@ -218,11 +289,12 @@ namespace Catch {
auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
auto mean = &Detail::mean<std::vector<double>::iterator>;
auto mean = &Detail::mean;
auto stddev = &standard_deviation;
#if defined(CATCH_CONFIG_USE_ASYNC)
auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
std::vector<double>::const_iterator)) {
auto seed = entropy();
return std::async(std::launch::async, [=] {
std::mt19937 rng(seed);
@ -237,7 +309,8 @@ namespace Catch {
auto mean_estimate = mean_future.get();
auto stddev_estimate = stddev_future.get();
#else
auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
std::vector<double>::const_iterator)) {
auto seed = entropy();
std::mt19937 rng(seed);
auto resampled = resample(rng, n_resamples, first, last, f);

View File

@ -15,8 +15,6 @@
#include <algorithm>
#include <vector>
#include <numeric>
#include <tuple>
#include <cmath>
namespace Catch {
@ -30,39 +28,17 @@ namespace Catch {
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
template <typename Iterator>
OutlierClassification classify_outliers(Iterator first, Iterator last) {
std::vector<double> copy(first, last);
OutlierClassification
classify_outliers( std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last );
auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
auto iqr = q3 - q1;
auto los = q1 - (iqr * 3.);
auto lom = q1 - (iqr * 1.5);
auto him = q3 + (iqr * 1.5);
auto his = q3 + (iqr * 3.);
double mean( std::vector<double>::const_iterator first,
std::vector<double>::const_iterator last );
OutlierClassification o;
for (; first != last; ++first) {
auto&& t = *first;
if (t < los) ++o.low_severe;
else if (t < lom) ++o.low_mild;
else if (t > his) ++o.high_severe;
else if (t > him) ++o.high_mild;
++o.samples_seen;
}
return o;
}
template <typename Iterator>
double mean(Iterator first, Iterator last) {
auto count = last - first;
double sum = std::accumulate(first, last, 0.);
return sum / static_cast<double>(count);
}
template <typename Estimator, typename Iterator>
sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
template <typename Estimator>
sample jackknife(Estimator&& estimator,
std::vector<double>::iterator first,
std::vector<double>::iterator last) {
auto n = static_cast<size_t>(last - first);
auto second = first;
++second;
@ -85,8 +61,12 @@ namespace Catch {
double normal_quantile(double p);
template <typename Iterator, typename Estimator>
Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
template <typename Estimator>
Estimate<double> bootstrap( double confidence_level,
std::vector<double>::iterator first,
std::vector<double>::iterator last,
sample const& resample,
Estimator&& estimator ) {
auto n_samples = last - first;
double point = estimator(first, last);
@ -95,13 +75,13 @@ namespace Catch {
sample jack = jackknife(estimator, first, last);
double jack_mean = mean(jack.begin(), jack.end());
double sum_squares, sum_cubes;
std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
auto d = jack_mean - x;
auto d2 = d * d;
auto d3 = d2 * d;
return { sqcb.first + d2, sqcb.second + d3 };
});
double sum_squares = 0, sum_cubes = 0;
for (double x : jack) {
auto difference = jack_mean - x;
auto square = difference * difference;
auto cube = square * difference;
sum_squares += square; sum_cubes += cube;
}
double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
long n = static_cast<long>(resample.size());
@ -128,15 +108,16 @@ namespace Catch {
return { point, resample[lo], resample[hi], confidence_level };
}
double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
struct bootstrap_analysis {
Estimate<double> mean;
Estimate<double> standard_deviation;
double outlier_variance;
};
bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
bootstrap_analysis analyse_samples(double confidence_level,
unsigned int n_resamples,
std::vector<double>::iterator first,
std::vector<double>::iterator last);
} // namespace Detail
} // namespace Benchmark
} // namespace Catch

View File

@ -86,6 +86,7 @@
#include <catch2/internal/catch_platform.hpp>
#include <catch2/internal/catch_polyfills.hpp>
#include <catch2/internal/catch_preprocessor.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/internal/catch_preprocessor_remove_parens.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>

View File

@ -105,7 +105,7 @@ namespace Catch {
elem = trim(elem);
}
// Insert the default reporter if user hasn't asked for a specfic one
// Insert the default reporter if user hasn't asked for a specific one
if ( m_data.reporterSpecifications.empty() ) {
m_data.reporterSpecifications.push_back( {
#if defined( CATCH_CONFIG_DEFAULT_REPORTER )

View File

@ -22,6 +22,8 @@
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <exception>
namespace Catch {
namespace {

View File

@ -13,9 +13,9 @@
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/catch_test_spec.hpp>
#include <catch2/catch_version.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/internal/catch_startup_exception_registry.hpp>
#include <catch2/internal/catch_sharding.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_textflow.hpp>
#include <catch2/internal/catch_windows_h_proxy.hpp>
#include <catch2/reporters/catch_reporter_multi.hpp>
@ -27,6 +27,7 @@
#include <algorithm>
#include <cassert>
#include <exception>
#include <iomanip>
#include <set>

View File

@ -139,12 +139,20 @@ namespace Catch {
for (size_t idx = 0; idx < originalTags.size(); ++idx) {
auto c = originalTags[idx];
if (c == '[') {
assert(!inTag);
CATCH_ENFORCE(
!inTag,
"Found '[' inside a tag while registering test case '"
<< _nameAndTags.name << "' at " << _lineInfo );
inTag = true;
tagStart = idx;
}
if (c == ']') {
assert(inTag);
CATCH_ENFORCE(
inTag,
"Found unmatched ']' while registering test case '"
<< _nameAndTags.name << "' at " << _lineInfo );
inTag = false;
tagEnd = idx;
assert(tagStart < tagEnd);
@ -153,7 +161,11 @@ namespace Catch {
// it over to backing storage and actually reference the
// backing storage in the saved tags
StringRef tagStr = originalTags.substr(tagStart+1, tagEnd - tagStart - 1);
CATCH_ENFORCE(!tagStr.empty(), "Empty tags are not allowed");
CATCH_ENFORCE( !tagStr.empty(),
"Found an empty tag while registering test case '"
<< _nameAndTags.name << "' at "
<< _lineInfo );
enforceNotReservedTag(tagStr, lineInfo);
properties |= parseSpecialTag(tagStr);
// When copying a tag to the backing storage, we need to
@ -167,8 +179,12 @@ namespace Catch {
// the tags.
internalAppendTag(tagStr);
}
(void)inTag; // Silence "set-but-unused" warning in release mode.
}
CATCH_ENFORCE( !inTag,
"Found an unclosed tag while registering test case '"
<< _nameAndTags.name << "' at " << _lineInfo );
// Add [.] if relevant
if (isHidden()) {
internalAppendTag("."_sr);

View File

@ -7,6 +7,7 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_test_spec.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/catch_test_case_info.hpp>
@ -107,16 +108,18 @@ namespace Catch {
return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
}
TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const
{
Matches matches( m_filters.size() );
std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const {
Matches matches;
matches.reserve( m_filters.size() );
for ( auto const& filter : m_filters ) {
std::vector<TestCaseHandle const*> currentMatches;
for( auto const& test : testCases )
if( isThrowSafe( test, config ) && filter.matches( test.getTestCaseInfo() ) )
for ( auto const& test : testCases )
if ( isThrowSafe( test, config ) &&
filter.matches( test.getTestCaseInfo() ) )
currentMatches.emplace_back( &test );
return FilterMatch{ extractFilterName(filter), currentMatches };
} );
matches.push_back(
FilterMatch{ extractFilterName( filter ), currentMatches } );
}
return matches;
}

View File

@ -171,7 +171,7 @@
// ------
// Simple toggle defines
// their value is never used and they cannot be overriden
// their value is never used and they cannot be overridden
// ------

View File

@ -43,6 +43,7 @@ namespace Catch {
public:
virtual ~IResultCapture();
virtual void notifyAssertionStarted( AssertionInfo const& info ) = 0;
virtual bool sectionStarted( StringRef sectionName,
SourceLineInfo const& sectionLineInfo,
Counts& assertions ) = 0;

View File

@ -205,7 +205,7 @@ namespace Catch {
*/
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
//! Called if a fatal error (signal/structured exception) occured
//! Called if a fatal error (signal/structured exception) occurred
virtual void fatalErrorEncountered( StringRef error ) = 0;
//! Writes out information about provided reporters using reporter-specific format

View File

@ -12,7 +12,6 @@
namespace Catch {
class TestSpec;
struct TestCaseInfo;
class TestCaseHandle;
class IConfig;
@ -26,11 +25,6 @@ namespace Catch {
virtual std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const = 0;
};
bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
}
#endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED

View File

@ -23,7 +23,9 @@ namespace Catch {
ResultDisposition::Flags resultDisposition )
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
m_resultCapture( getResultCapture() )
{}
{
m_resultCapture.notifyAssertionStarted( m_assertionInfo );
}
void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );

View File

@ -50,12 +50,18 @@
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
_Pragma( "GCC diagnostic ignored \"-Wunused-result\"" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
_Pragma( "GCC diagnostic ignored \"-Wunused-variable\"" )
# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
_Pragma( "GCC diagnostic ignored \"-Wuseless-cast\"" )
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
_Pragma( "GCC diagnostic ignored \"-Wshadow\"" )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
#endif
@ -128,6 +134,9 @@
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wcomma\"" )
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wshadow\"" )
#endif // __clang__
@ -365,6 +374,9 @@
#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT)
# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
#endif
@ -374,6 +386,16 @@
#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
#endif
#if !defined( CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if !defined( CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS )
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS
#endif
#if !defined( CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS )
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS
#endif
// The goal of this macro is to avoid evaluation of the arguments, but
// still have the compiler warn on problems inside...
@ -387,13 +409,6 @@
# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS
#endif
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
#define CATCH_TRY if ((true))

View File

@ -18,6 +18,8 @@
#ifndef CATCH_CONFIG_COUNTER_HPP_INCLUDED
#define CATCH_CONFIG_COUNTER_HPP_INCLUDED
#include <catch2/catch_user_config.hpp>
#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif

View File

@ -17,6 +17,8 @@
#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
#include <catch2/catch_user_config.hpp>
#if defined(_MSC_VER)
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS

View File

@ -17,6 +17,8 @@
#ifndef CATCH_CONFIG_WCHAR_HPP_INCLUDED
#define CATCH_CONFIG_WCHAR_HPP_INCLUDED
#include <catch2/catch_user_config.hpp>
// We assume that WCHAR should be enabled by default, and only disabled
// for a shortlist (so far only DJGPP) of compilers.

View File

@ -11,6 +11,8 @@
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <exception>
namespace Catch {
namespace {

View File

@ -9,8 +9,8 @@
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>

View File

@ -8,6 +8,8 @@
#ifndef CATCH_OPTIONAL_HPP_INCLUDED
#define CATCH_OPTIONAL_HPP_INCLUDED
#include <catch2/internal/catch_move_and_forward.hpp>
#include <cassert>
namespace Catch {
@ -16,35 +18,50 @@ namespace Catch {
template<typename T>
class Optional {
public:
Optional() : nullableValue( nullptr ) {}
Optional( T const& _value )
: nullableValue( new( storage ) T( _value ) )
{}
Optional( Optional const& _other )
: nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
{}
Optional(): nullableValue( nullptr ) {}
~Optional() { reset(); }
~Optional() {
Optional( T const& _value ):
nullableValue( new ( storage ) T( _value ) ) {}
Optional( T&& _value ):
nullableValue( new ( storage ) T( CATCH_MOVE( _value ) ) ) {}
Optional& operator=( T const& _value ) {
reset();
nullableValue = new ( storage ) T( _value );
return *this;
}
Optional& operator=( T&& _value ) {
reset();
nullableValue = new ( storage ) T( CATCH_MOVE( _value ) );
return *this;
}
Optional& operator= ( Optional const& _other ) {
if( &_other != this ) {
Optional( Optional const& _other ):
nullableValue( _other ? new ( storage ) T( *_other ) : nullptr ) {}
Optional( Optional&& _other ):
nullableValue( _other ? new ( storage ) T( CATCH_MOVE( *_other ) )
: nullptr ) {}
Optional& operator=( Optional const& _other ) {
if ( &_other != this ) {
reset();
if( _other )
nullableValue = new( storage ) T( *_other );
if ( _other ) { nullableValue = new ( storage ) T( *_other ); }
}
return *this;
}
Optional& operator = ( T const& _value ) {
reset();
nullableValue = new( storage ) T( _value );
Optional& operator=( Optional&& _other ) {
if ( &_other != this ) {
reset();
if ( _other ) {
nullableValue = new ( storage ) T( CATCH_MOVE( *_other ) );
}
}
return *this;
}
void reset() {
if( nullableValue )
nullableValue->~T();
if ( nullableValue ) { nullableValue->~T(); }
nullableValue = nullptr;
}
@ -91,7 +108,7 @@ namespace Catch {
}
private:
T *nullableValue;
T* nullableValue;
alignas(alignof(T)) char storage[sizeof(T)];
};

View File

@ -0,0 +1,19 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#ifndef CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
#define CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
#include <catch2/catch_user_config.hpp>
#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__##_catch_sr
#else
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"_catch_sr
#endif
#endif // CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED

View File

@ -57,8 +57,6 @@ namespace Catch {
auto it = m_impl->factories.find( name );
if ( it == m_impl->factories.end() ) return nullptr;
return it->second->create( CATCH_MOVE( config ) );
return IEventListenerPtr();
}
void ReporterRegistry::registerReporter( std::string const& name,

View File

@ -21,9 +21,9 @@ namespace Catch {
};
kvPair splitKVPair(StringRef kvString) {
auto splitPos = static_cast<size_t>( std::distance(
kvString.begin(),
std::find( kvString.begin(), kvString.end(), '=' ) ) );
auto splitPos = static_cast<size_t>(
std::find( kvString.begin(), kvString.end(), '=' ) -
kvString.begin() );
return { kvString.substr( 0, splitPos ),
kvString.substr( splitPos + 1, kvString.size() ) };

View File

@ -267,7 +267,7 @@ namespace Catch {
}
void RunContext::assertionEnded(AssertionResult const & result) {
void RunContext::assertionEnded(AssertionResult&& result) {
if (result.getResultType() == ResultWas::Ok) {
m_totals.assertions.passed++;
m_lastAssertionPassed = true;
@ -289,19 +289,26 @@ namespace Catch {
m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals));
if (result.getResultType() != ResultWas::Warning)
if ( result.getResultType() != ResultWas::Warning ) {
m_messageScopes.clear();
}
// Reset working state
resetAssertionInfo();
m_lastResult = result;
m_lastResult = CATCH_MOVE( result );
}
void RunContext::resetAssertionInfo() {
m_lastAssertionInfo.macroName = StringRef();
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
}
bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) {
void RunContext::notifyAssertionStarted( AssertionInfo const& info ) {
m_reporter->assertionStarting( info );
}
bool RunContext::sectionStarted( StringRef sectionName,
SourceLineInfo const& sectionLineInfo,
Counts& assertions ) {
ITracker& sectionTracker =
SectionTracker::acquire( m_trackerContext,
TestCaseTracking::NameAndLocationRef(
@ -439,7 +446,7 @@ namespace Catch {
tempResult.message = static_cast<std::string>(message);
AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult));
assertionEnded(result);
assertionEnded(CATCH_MOVE(result) );
handleUnfinishedSections();
@ -561,8 +568,6 @@ namespace Catch {
ITransientExpression const& expr,
AssertionReaction& reaction
) {
m_reporter->assertionStarting( info );
bool negated = isFalseTest( info.resultDisposition );
bool result = expr.getResult() != negated;
@ -591,7 +596,7 @@ namespace Catch {
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
assertionEnded( assertionResult );
assertionEnded( CATCH_MOVE(assertionResult) );
}
void RunContext::handleMessage(
@ -600,16 +605,16 @@ namespace Catch {
StringRef message,
AssertionReaction& reaction
) {
m_reporter->assertionStarting( info );
m_lastAssertionInfo = info;
AssertionResultData data( resultType, LazyExpression( false ) );
data.message = static_cast<std::string>(message);
AssertionResult assertionResult{ m_lastAssertionInfo,
CATCH_MOVE( data ) };
assertionEnded( assertionResult );
if ( !assertionResult.isOk() ) {
const auto isOk = assertionResult.isOk();
assertionEnded( CATCH_MOVE(assertionResult) );
if ( !isOk ) {
populateReaction( reaction );
} else if ( resultType == ResultWas::ExplicitSkip ) {
// TODO: Need to handle this explicitly, as ExplicitSkip is
@ -634,7 +639,7 @@ namespace Catch {
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
data.message = CATCH_MOVE(message);
AssertionResult assertionResult{ info, CATCH_MOVE(data) };
assertionEnded( assertionResult );
assertionEnded( CATCH_MOVE(assertionResult) );
populateReaction( reaction );
}
@ -652,7 +657,7 @@ namespace Catch {
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"s;
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionEnded( assertionResult );
assertionEnded( CATCH_MOVE(assertionResult) );
}
void RunContext::handleNonExpr(
AssertionInfo const &info,
@ -663,10 +668,10 @@ namespace Catch {
AssertionResultData data( resultType, LazyExpression( false ) );
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionEnded( assertionResult );
if( !assertionResult.isOk() )
populateReaction( reaction );
const auto isOk = assertionResult.isOk();
assertionEnded( CATCH_MOVE(assertionResult) );
if ( !isOk ) { populateReaction( reaction ); }
}

View File

@ -70,6 +70,7 @@ namespace Catch {
ResultWas::OfType resultType,
AssertionReaction &reaction ) override;
void notifyAssertionStarted( AssertionInfo const& info ) override;
bool sectionStarted( StringRef sectionName,
SourceLineInfo const& sectionLineInfo,
Counts& assertions ) override;
@ -120,7 +121,7 @@ namespace Catch {
void resetAssertionInfo();
bool testForMissingAssertions( Counts& assertions );
void assertionEnded( AssertionResult const& result );
void assertionEnded( AssertionResult&& result );
void reportExpr
( AssertionInfo const &info,
ResultWas::OfType resultType,

View File

@ -8,7 +8,6 @@
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <algorithm>
#include <ostream>
#include <cstring>
#include <cctype>
@ -32,9 +31,9 @@ namespace Catch {
return s.find( infix ) != std::string::npos;
}
void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), []( char c ) {
return toLower( c );
} );
for ( char& c : s ) {
c = toLower( c );
}
}
std::string toLower( std::string const& s ) {
std::string lc = s;

View File

@ -24,6 +24,38 @@
namespace Catch {
namespace {
static void enforceNoDuplicateTestCases(
std::vector<TestCaseHandle> const& tests ) {
auto testInfoCmp = []( TestCaseInfo const* lhs,
TestCaseInfo const* rhs ) {
return *lhs < *rhs;
};
std::set<TestCaseInfo const*, decltype( testInfoCmp )&> seenTests(
testInfoCmp );
for ( auto const& test : tests ) {
const auto infoPtr = &test.getTestCaseInfo();
const auto prev = seenTests.insert( infoPtr );
CATCH_ENFORCE( prev.second,
"error: test case \""
<< infoPtr->name << "\", with tags \""
<< infoPtr->tagsAsString()
<< "\" already defined.\n"
<< "\tFirst seen at "
<< ( *prev.first )->lineInfo << "\n"
<< "\tRedefined at " << infoPtr->lineInfo );
}
}
static bool matchTest( TestCaseHandle const& testCase,
TestSpec const& testSpec,
IConfig const& config ) {
return testSpec.matches( testCase.getTestCaseInfo() ) &&
isThrowSafe( testCase, config );
}
} // end unnamed namespace
std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases ) {
switch (config.runOrder()) {
case TestRunOrder::Declared:
@ -80,29 +112,6 @@ namespace Catch {
return !testCase.getTestCaseInfo().throws() || config.allowThrows();
}
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config ) {
return testSpec.matches( testCase.getTestCaseInfo() ) && isThrowSafe( testCase, config );
}
void
enforceNoDuplicateTestCases( std::vector<TestCaseHandle> const& tests ) {
auto testInfoCmp = []( TestCaseInfo const* lhs,
TestCaseInfo const* rhs ) {
return *lhs < *rhs;
};
std::set<TestCaseInfo const*, decltype(testInfoCmp) &> seenTests(testInfoCmp);
for ( auto const& test : tests ) {
const auto infoPtr = &test.getTestCaseInfo();
const auto prev = seenTests.insert( infoPtr );
CATCH_ENFORCE(
prev.second,
"error: test case \"" << infoPtr->name << "\", with tags \""
<< infoPtr->tagsAsString() << "\" already defined.\n"
<< "\tFirst seen at " << ( *prev.first )->lineInfo << "\n"
<< "\tRedefined at " << infoPtr->lineInfo );
}
}
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
std::vector<TestCaseHandle> filtered;
filtered.reserve( testCases.size() );

View File

@ -24,9 +24,6 @@ namespace Catch {
std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases );
bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
void enforceNoDuplicateTestCases( std::vector<TestCaseHandle> const& functions );
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );

View File

@ -113,7 +113,7 @@ namespace TestCaseTracking {
//! Returns true if tracker run to completion (successfully or not)
virtual bool isComplete() const = 0;
//! Returns true if tracker run to completion succesfully
//! Returns true if tracker run to completion successfully
bool isSuccessfullyCompleted() const {
return m_runState == CompletedSuccessfully;
}

View File

@ -10,6 +10,7 @@
#include <catch2/catch_user_config.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
@ -22,12 +23,6 @@
#if !defined(CATCH_CONFIG_DISABLE)
#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__##_catch_sr
#else
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"_catch_sr
#endif
#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
///////////////////////////////////////////////////////////////////////////////
@ -95,6 +90,7 @@
if( catchAssertionHandler.allowThrows() ) \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(__VA_ARGS__); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
@ -115,6 +111,7 @@
if( catchAssertionHandler.allowThrows() ) \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(expr); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
@ -141,6 +138,7 @@
if( catchAssertionHandler.allowThrows() ) \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(__VA_ARGS__); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \

View File

@ -59,7 +59,7 @@ namespace Catch {
// Calculates the length of the current line
void calcLength();
// Returns current indention width
// Returns current indentation width
size_t indentSize() const;
// Creates an indented and (optionally) suffixed string from

View File

@ -129,7 +129,7 @@ namespace Catch {
/**
* Creates a matcher that checks if all elements in a range are equal
* to all elements in another range, in some permuation.
* to all elements in another range, in some permutation.
*
* Uses to provided predicate `predicate` to do the comparisons
*/

View File

@ -8,9 +8,14 @@
#ifndef CATCH_MATCHERS_IMPL_HPP_INCLUDED
#define CATCH_MATCHERS_IMPL_HPP_INCLUDED
#include <catch2/internal/catch_test_macro_impl.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
#include <catch2/internal/catch_decomposer.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <string>
namespace Catch {
template<typename ArgT, typename MatcherT>

View File

@ -110,6 +110,7 @@ internal_headers = [
'internal/catch_platform.hpp',
'internal/catch_polyfills.hpp',
'internal/catch_preprocessor.hpp',
'internal/catch_preprocessor_internal_stringify.hpp',
'internal/catch_preprocessor_remove_parens.hpp',
'internal/catch_random_number_generator.hpp',
'internal/catch_random_seed_generation.hpp',

View File

@ -171,7 +171,7 @@ private:
return;
const auto itEnd = messages.cend();
const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
const auto N = static_cast<std::size_t>(itEnd - itMessage);
stream << colourImpl->guardColour( colour ) << " with "
<< pluralise( N, "message"_sr ) << ':';

View File

@ -124,7 +124,7 @@ namespace Catch {
void skipTest(TestCaseInfo const&) override {}
protected:
//! Should the cumulative base store the assertion expansion for succesful assertions?
//! Should the cumulative base store the assertion expansion for successful assertions?
bool m_shouldStoreSuccesfulAssertions = true;
//! Should the cumulative base store the assertion expansion for failed assertions?
bool m_shouldStoreFailedAssertions = true;

View File

@ -14,7 +14,6 @@
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <algorithm>
#include <iterator>
#include <ostream>
namespace Catch {
@ -165,7 +164,7 @@ namespace Catch {
// using messages.end() directly (or auto) yields compilation error:
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
const std::size_t N = static_cast<std::size_t>(itEnd - itMessage);
stream << colourImpl->guardColour( colour ) << " with "
<< pluralise( N, "message"_sr ) << ':';

View File

@ -468,6 +468,17 @@ set_tests_properties(
)
add_executable(AssertionStartingEventGoesBeforeAssertionIsEvaluated
X20-AssertionStartingEventGoesBeforeAssertionIsEvaluated.cpp
)
target_link_libraries(AssertionStartingEventGoesBeforeAssertionIsEvaluated
PRIVATE Catch2::Catch2WithMain
)
add_test(
NAME ReporterEvents::AssertionStartingHappensBeforeAssertionIsEvaluated
COMMAND $<TARGET_FILE:AssertionStartingEventGoesBeforeAssertionIsEvaluated>
)
#add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
#target_link_libraries(DebugBreakMacros Catch2)
#add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)

View File

@ -0,0 +1,81 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/**\file
* TODO: FIXES Registers custom reporter that reports testCase* events
*
* The resulting executable can then be used by an external Python script
* to verify that testCase{Starting,Ended} and testCasePartial{Starting,Ended}
* events are properly nested.
*/
#include <catch2/catch_test_macros.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/matchers/catch_matchers_predicate.hpp>
namespace {
static size_t assertion_starting_events_seen = 0;
// TODO: custom matcher to check that "assertion_starting_events_seen" has
// the right number of checks
class AssertionStartingListener : public Catch::EventListenerBase {
public:
AssertionStartingListener( Catch::IConfig const* config ):
EventListenerBase( config ) {}
void assertionStarting( Catch::AssertionInfo const& ) override {
++assertion_starting_events_seen;
}
};
static bool f1() {
return assertion_starting_events_seen == 1;
}
static void f2() {
if ( assertion_starting_events_seen != 2 ) { throw 1; }
}
static void f3() {
if ( assertion_starting_events_seen == 3 ) { throw 1; }
}
static bool f4() { return assertion_starting_events_seen == 4; }
static void f5() { throw assertion_starting_events_seen; }
} // anonymous namespace
CATCH_REGISTER_LISTENER( AssertionStartingListener )
TEST_CASE() {
// **IMPORTANT**
// The order of assertions below matters.
REQUIRE( f1() );
REQUIRE_NOTHROW( f2() );
REQUIRE_THROWS( f3() );
REQUIRE_THAT( f4(),
Catch::Matchers::Predicate<bool>( []( bool b ) { return b; } ) );
REQUIRE_THROWS_MATCHES(
f5(), size_t, Catch::Matchers::Predicate<size_t>( []( size_t i ) {
return i == 5;
} ) );
CAPTURE( assertion_starting_events_seen ); // **not** an assertion
INFO( "some info msg" ); // **not** an assertion
WARN( "warning! warning!" ); // assertion-like message
SUCCEED(); // assertion-like message
// We skip FAIL/SKIP and so on, which fail the test.
// This require will also increment the count once
REQUIRE( assertion_starting_events_seen == 8 );
}

View File

@ -131,7 +131,6 @@ Nor would this
:test-result: PASS Default scale is invisible to comparison
:test-result: PASS Directly creating an EnumInfo
:test-result: PASS Empty stream name opens cout stream
:test-result: PASS Empty tag is not allowed
:test-result: FAIL EndsWith string matcher
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
:test-result: PASS Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM

View File

@ -129,7 +129,6 @@
:test-result: PASS Default scale is invisible to comparison
:test-result: PASS Directly creating an EnumInfo
:test-result: PASS Empty stream name opens cout stream
:test-result: PASS Empty tag is not allowed
:test-result: FAIL EndsWith string matcher
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
:test-result: PASS Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM

View File

@ -521,7 +521,6 @@ ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected
==
"{** unexpected enum value **}"
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "" )->isConsole() for: true
Tag.tests.cpp:<line number>: passed: Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive)
EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value1 ) == "Value1" for: "Value1" == "Value1"
@ -2538,7 +2537,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected

View File

@ -519,7 +519,6 @@ ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected
==
"{** unexpected enum value **}"
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "" )->isConsole() for: true
Tag.tests.cpp:<line number>: passed: Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive)
EnumToString.tests.cpp:<line number>: passed: stringify( EnumClass3::Value1 ) == "Value1" for: "Value1" == "Value1"
@ -2527,7 +2526,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected

View File

@ -1533,6 +1533,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 409 | 323 passed | 69 failed | 6 skipped | 11 failed as expected
assertions: 2209 | 2049 passed | 128 failed | 32 failed as expected
test cases: 408 | 322 passed | 69 failed | 6 skipped | 11 failed as expected
assertions: 2208 | 2048 passed | 128 failed | 32 failed as expected

View File

@ -3967,15 +3967,6 @@ Stream.tests.cpp:<line number>: PASSED:
with expansion:
true
-------------------------------------------------------------------------------
Empty tag is not allowed
-------------------------------------------------------------------------------
Tag.tests.cpp:<line number>
...............................................................................
Tag.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo ) )
-------------------------------------------------------------------------------
EndsWith string matcher
-------------------------------------------------------------------------------
@ -13460,7 +13451,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AllTrue range matcher
Basic usage
One false evalutes to false
One false evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13499,7 +13490,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AllTrue range matcher
Contained type is convertible to bool
One false evalutes to false
One false evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13735,7 +13726,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AnyTrue range matcher
Basic usage
One true evalutes to true
One true evaluates to true
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13774,7 +13765,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AnyTrue range matcher
Contained type is convertible to bool
One true evalutes to true
One true evaluates to true
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -14010,7 +14001,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of NoneTrue range matcher
Basic usage
One true evalutes to false
One true evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -14049,7 +14040,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of NoneTrue range matcher
Contained type is convertible to bool
One true evalutes to false
One true evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -18231,6 +18222,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected

View File

@ -3965,15 +3965,6 @@ Stream.tests.cpp:<line number>: PASSED:
with expansion:
true
-------------------------------------------------------------------------------
Empty tag is not allowed
-------------------------------------------------------------------------------
Tag.tests.cpp:<line number>
...............................................................................
Tag.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo ) )
-------------------------------------------------------------------------------
EndsWith string matcher
-------------------------------------------------------------------------------
@ -13453,7 +13444,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AllTrue range matcher
Basic usage
One false evalutes to false
One false evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13492,7 +13483,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AllTrue range matcher
Contained type is convertible to bool
One false evalutes to false
One false evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13728,7 +13719,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AnyTrue range matcher
Basic usage
One true evalutes to true
One true evaluates to true
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -13767,7 +13758,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of AnyTrue range matcher
Contained type is convertible to bool
One true evalutes to true
One true evaluates to true
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -14003,7 +13994,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of NoneTrue range matcher
Basic usage
One true evalutes to false
One true evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -14042,7 +14033,7 @@ with expansion:
-------------------------------------------------------------------------------
Usage of NoneTrue range matcher
Contained type is convertible to bool
One true evalutes to false
One true evaluates to false
-------------------------------------------------------------------------------
MatchersRanges.tests.cpp:<line number>
...............................................................................
@ -18220,6 +18211,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2237" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2236" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@ -463,7 +463,6 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Empty stream name opens cout stream" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Empty tag is not allowed" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}" status="run">
<failure message="testStringForMatching(), EndsWith( &quot;Substring&quot; )" type="CHECK_THAT">
FAILED:
@ -1401,10 +1400,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of AllMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/Empty evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/One false evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/One false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
@ -1414,10 +1413,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of AnyMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/Empty evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/One true evalutes to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/One true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evalutes to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
@ -1427,10 +1426,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of NoneMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/All true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/Empty evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/One true evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/One true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/All false evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All false evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2237" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2236" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@ -462,7 +462,6 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Empty stream name opens cout stream" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Empty tag is not allowed" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}" status="run">
<failure message="testStringForMatching(), EndsWith( &quot;Substring&quot; )" type="CHECK_THAT">
FAILED:
@ -1400,10 +1399,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of AllMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/Empty evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/One false evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/One false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Basic usage/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Contained type is convertible to bool/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AllTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
@ -1413,10 +1412,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of AnyMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/Empty evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/One true evalutes to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/One true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Basic usage/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evalutes to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All false evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of AnyTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
@ -1426,10 +1425,10 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Usage of NoneMatch range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/All true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/Empty evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/One true evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/One true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Basic usage/All false evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evalutes to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evaluates to false" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All false evaluates to true" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Shortcircuiting/All are read" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Usage of NoneTrue range matcher/Shortcircuiting/Short-circuited" time="{duration}" status="run"/>

View File

@ -233,7 +233,6 @@
<testCase name="startsWith" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp">
<testCase name="Empty tag is not allowed" duration="{duration}"/>
<testCase name="Tag alias can be registered against tag patterns/The same tag alias can only be registered once" duration="{duration}"/>
<testCase name="Tag alias can be registered against tag patterns/Tag aliases must be of the form [@name]" duration="{duration}"/>
<testCase name="Tags with spaces and non-alphanumerical characters are accepted" duration="{duration}"/>
@ -1389,10 +1388,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of AllMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/Empty evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/One false evalutes to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/One false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evalutes to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
@ -1402,10 +1401,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of AnyMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/Empty evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/One true evalutes to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/One true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evalutes to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
@ -1415,10 +1414,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of NoneMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/All true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/Empty evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/One true evalutes to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/One true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/All false evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evalutes to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All false evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>

View File

@ -232,7 +232,6 @@
<testCase name="startsWith" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp">
<testCase name="Empty tag is not allowed" duration="{duration}"/>
<testCase name="Tag alias can be registered against tag patterns/The same tag alias can only be registered once" duration="{duration}"/>
<testCase name="Tag alias can be registered against tag patterns/Tag aliases must be of the form [@name]" duration="{duration}"/>
<testCase name="Tags with spaces and non-alphanumerical characters are accepted" duration="{duration}"/>
@ -1388,10 +1387,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of AllMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/Empty evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/One false evalutes to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/One false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Basic usage/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evalutes to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/One false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Contained type is convertible to bool/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of AllTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
@ -1401,10 +1400,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of AnyMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/Empty evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/One true evalutes to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/One true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Basic usage/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evalutes to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/One true evaluates to true" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Contained type is convertible to bool/All false evaluates to false" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of AnyTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
@ -1414,10 +1413,10 @@ at Matchers.tests.cpp:<line number>
<testCase name="Usage of NoneMatch range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/All true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/Empty evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/One true evalutes to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/One true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Basic usage/All false evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evalutes to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/One true evaluates to false" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Contained type is convertible to bool/All false evaluates to true" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Shortcircuiting/All are read" duration="{duration}"/>
<testCase name="Usage of NoneTrue range matcher/Shortcircuiting/Short-circuited" duration="{duration}"/>

View File

@ -986,8 +986,6 @@ ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
# Empty stream name opens cout stream
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
# Empty tag is not allowed
ok {test-number} - Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
# EndsWith string matcher
not ok {test-number} - testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
# EndsWith string matcher
@ -4477,5 +4475,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2237
1..2236

View File

@ -984,8 +984,6 @@ ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
# Empty stream name opens cout stream
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
# Empty tag is not allowed
ok {test-number} - Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
# EndsWith string matcher
not ok {test-number} - testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
# EndsWith string matcher
@ -4466,5 +4464,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2237
1..2236

View File

@ -301,8 +301,6 @@
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
##teamcity[testStarted name='Empty stream name opens cout stream']
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
##teamcity[testStarted name='Empty tag is not allowed']
##teamcity[testFinished name='Empty tag is not allowed' duration="{duration}"]
##teamcity[testStarted name='EndsWith string matcher']
##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:<line number>|n...............................................................................|n|nMatchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "Substring"|n']
##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "this" (case insensitive)|n']

View File

@ -301,8 +301,6 @@
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
##teamcity[testStarted name='Empty stream name opens cout stream']
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
##teamcity[testStarted name='Empty tag is not allowed']
##teamcity[testFinished name='Empty tag is not allowed' duration="{duration}"]
##teamcity[testStarted name='EndsWith string matcher']
##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:<line number>|n...............................................................................|n|nMatchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "Substring"|n']
##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "this" (case insensitive)|n']

View File

@ -4375,17 +4375,6 @@ C
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Empty tag is not allowed" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original>
Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
</Original>
<Expanded>
Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="EndsWith string matcher" tags="[.][failing][matchers]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original>
@ -15670,7 +15659,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !AllTrue()
@ -15712,7 +15701,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !AllTrue()
@ -16020,7 +16009,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, AnyTrue()
@ -16062,7 +16051,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, AnyTrue()
@ -16370,7 +16359,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !NoneTrue()
@ -16412,7 +16401,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !NoneTrue()
@ -21203,6 +21192,6 @@ b1!
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2049" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="309" failures="84" expectedFailures="11" skips="5"/>
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
</Catch2TestRun>

View File

@ -4375,17 +4375,6 @@ C
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Empty tag is not allowed" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original>
Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
</Original>
<Expanded>
Catch::TestCaseInfo( "", { "fake test name", "[]" }, dummySourceLineInfo )
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="EndsWith string matcher" tags="[.][failing][matchers]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original>
@ -15670,7 +15659,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !AllTrue()
@ -15712,7 +15701,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One false evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !AllTrue()
@ -16020,7 +16009,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, AnyTrue()
@ -16062,7 +16051,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to true" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, AnyTrue()
@ -16370,7 +16359,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Basic usage" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !NoneTrue()
@ -16412,7 +16401,7 @@ There is no extra whitespace here
<OverallResults successes="1" failures="0" expectedFailures="0" skipped="false"/>
</Section>
<Section name="Contained type is convertible to bool" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evalutes to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Section name="One true evaluates to false" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/MatchersRanges.tests.cpp" >
<Original>
data, !NoneTrue()
@ -21202,6 +21191,6 @@ b1!
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2049" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="309" failures="84" expectedFailures="11" skips="5"/>
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
</Catch2TestRun>

View File

@ -89,6 +89,47 @@ TEST_CASE("Optional comparison ops", "[optional][approvals]") {
}
}
namespace {
struct MoveChecker {
bool has_moved = false;
MoveChecker() = default;
MoveChecker( MoveChecker const& rhs ) = default;
MoveChecker& operator=( MoveChecker const& rhs ) = default;
MoveChecker( MoveChecker&& rhs ) { rhs.has_moved = true; }
MoveChecker& operator=( MoveChecker&& rhs ) {
rhs.has_moved = true;
return *this;
}
};
}
TEST_CASE( "Optional supports move ops", "[optional][approvals]" ) {
using Catch::Optional;
MoveChecker a;
Optional<MoveChecker> opt_A( a );
REQUIRE_FALSE( a.has_moved );
REQUIRE_FALSE( opt_A->has_moved );
SECTION( "Move construction from element" ) {
Optional<MoveChecker> opt_B( CATCH_MOVE( a ) );
REQUIRE( a.has_moved );
}
SECTION( "Move assignment from element" ) {
opt_A = CATCH_MOVE( a );
REQUIRE( a.has_moved );
}
SECTION( "Move construction from optional" ) {
Optional<MoveChecker> opt_B( CATCH_MOVE( opt_A ) );
REQUIRE( opt_A->has_moved );
}
SECTION( "Move assignment from optional" ) {
Optional<MoveChecker> opt_B( opt_A );
REQUIRE_FALSE( opt_A->has_moved );
opt_B = CATCH_MOVE( opt_A );
REQUIRE( opt_A->has_moved );
}
}
TEST_CASE( "Decomposer checks that the argument is 0 when handling "
"only-0-comparable types",
"[decomposition][approvals]" ) {

View File

@ -412,6 +412,7 @@ TEST_CASE("GENERATE handles function (pointers)", "[generators][compilation][app
TEST_CASE("GENERATE decays arrays", "[generators][compilation][approvals]") {
auto str = GENERATE("abc", "def", "gh");
(void)str;
STATIC_REQUIRE(std::is_same<decltype(str), const char*>::value);
}

View File

@ -22,6 +22,8 @@
#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
#include <catch2/benchmark/detail/catch_estimate_clock.hpp>
#include <numeric>
namespace {
struct manual_clock {
public:
@ -442,6 +444,6 @@ TEST_CASE("Failing benchmarks", "[!benchmark][.approvals]") {
}
TEST_CASE( "Failing benchmark respects should-fail",
"[!shouldfail][!benchmark][.approvals]" ) {
"[!shouldfail][!benchmark][approvals]" ) {
BENCHMARK( "Asserting benchmark" ) { REQUIRE( 1 == 2 ); };
}

View File

@ -98,7 +98,20 @@ TEST_CASE( "Test case with identical tags keeps just one", "[tags]" ) {
REQUIRE( testCase.tags[0] == Tag( "tag1" ) );
}
TEST_CASE( "Empty tag is not allowed" ) {
REQUIRE_THROWS( Catch::TestCaseInfo(
"", { "fake test name", "[]" }, dummySourceLineInfo ) );
TEST_CASE("Mismatched square brackets in tags are caught and reported",
"[tags][approvals]") {
using Catch::TestCaseInfo;
using Catch::Matchers::ContainsSubstring;
REQUIRE_THROWS_WITH( TestCaseInfo( "",
{ "test with unclosed tag", "[abc" },
dummySourceLineInfo ),
ContainsSubstring("registering test case 'test with unclosed tag'") );
REQUIRE_THROWS_WITH( TestCaseInfo( "",
{ "test with nested tags", "[abc[def]]" },
dummySourceLineInfo ),
ContainsSubstring("registering test case 'test with nested tags'") );
REQUIRE_THROWS_WITH( TestCaseInfo( "",
{ "test with superfluous close tags", "[abc][def]]" },
dummySourceLineInfo ),
ContainsSubstring("registering test case 'test with superfluous close tags'") );
}

View File

@ -20,7 +20,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif
namespace {

View File

@ -381,7 +381,7 @@ TEST_CASE("Usage of AllTrue range matcher", "[matchers][templated][quantifiers]"
std::array<bool, 0> const data{};
REQUIRE_THAT( data, AllTrue() );
}
SECTION( "One false evalutes to false" ) {
SECTION( "One false evaluates to false" ) {
std::array<bool, 5> const data{ { true, true, false, true, true } };
REQUIRE_THAT( data, !AllTrue() );
}
@ -398,7 +398,7 @@ TEST_CASE("Usage of AllTrue range matcher", "[matchers][templated][quantifiers]"
{ { true }, { true }, { true }, { true }, { true } } };
REQUIRE_THAT( data, AllTrue() );
}
SECTION( "One false evalutes to false" ) {
SECTION( "One false evaluates to false" ) {
std::array<ConvertibleToBool, 5> const data{
{ { true }, { true }, { false }, { true }, { true } } };
REQUIRE_THAT( data, !AllTrue() );
@ -446,7 +446,7 @@ TEST_CASE( "Usage of NoneTrue range matcher", "[matchers][templated][quantifiers
std::array<bool, 0> const data{};
REQUIRE_THAT( data, NoneTrue() );
}
SECTION( "One true evalutes to false" ) {
SECTION( "One true evaluates to false" ) {
std::array<bool, 5> const data{
{ false, false, true, false, false } };
REQUIRE_THAT( data, !NoneTrue() );
@ -464,7 +464,7 @@ TEST_CASE( "Usage of NoneTrue range matcher", "[matchers][templated][quantifiers
{ { true }, { true }, { true }, { true }, { true } } };
REQUIRE_THAT( data, !NoneTrue() );
}
SECTION( "One true evalutes to false" ) {
SECTION( "One true evaluates to false" ) {
std::array<ConvertibleToBool, 5> const data{
{ { false }, { false }, { true }, { false }, { false } } };
REQUIRE_THAT( data, !NoneTrue() );
@ -512,7 +512,7 @@ TEST_CASE( "Usage of AnyTrue range matcher", "[matchers][templated][quantifiers]
std::array<bool, 0> const data{};
REQUIRE_THAT( data, !AnyTrue() );
}
SECTION( "One true evalutes to true" ) {
SECTION( "One true evaluates to true" ) {
std::array<bool, 5> const data{
{ false, false, true, false, false } };
REQUIRE_THAT( data, AnyTrue() );
@ -530,7 +530,7 @@ TEST_CASE( "Usage of AnyTrue range matcher", "[matchers][templated][quantifiers]
{ { true }, { true }, { true }, { true }, { true } } };
REQUIRE_THAT( data, AnyTrue() );
}
SECTION( "One true evalutes to true" ) {
SECTION( "One true evaluates to true" ) {
std::array<ConvertibleToBool, 5> const data{
{ { false }, { false }, { true }, { false }, { false } } };
REQUIRE_THAT( data, AnyTrue() );

View File

@ -287,7 +287,7 @@ def markdownToclify(
Path to the markdown output file.
min_toc_len: int (default: 2)
Miniumum number of entries to create a table of contents for.
Minimum number of entries to create a table of contents for.
github: bool (default: False)
Uses GitHub TOC syntax if True.