Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/extras
diff options
context:
space:
mode:
authorLeitwolf2026-10-25 10:31:36 +0300
committerGitHub2026-10-25 10:31:36 +0300
commitd2e3e074bb2e1b8ffd9fc990d0b87667ea602f58 (patch)
tree0bce4462b2e190c39b3e1c5f697e3e4abd1a5e2a /extras
parent13f81a480a93807c14dddb5abdb97355ced4d4c5 (diff)
parent126dc333564cb72b5115d9a9242d66694694b6d0 (diff)
downloadcatch3-d2e3e074bb2e1b8ffd9fc990d0b87667ea602f58.tar.gz
Merge pull request #18 from Progmasoft/build/catch3-identity
Give Catch3 its own build names and headers
Diffstat (limited to 'extras')
-rw-r--r--extras/Catch3.cmake (renamed from extras/Catch.cmake)46
-rw-r--r--extras/Catch3AddTests.cmake (renamed from extras/CatchAddTests.cmake)50
-rw-r--r--extras/Catch3ShardTests.cmake (renamed from extras/CatchShardTests.cmake)10
-rw-r--r--extras/Catch3ShardTestsImpl.cmake (renamed from extras/CatchShardTestsImpl.cmake)0
-rw-r--r--extras/ParseAndAddCatchTests.cmake250
-rw-r--r--extras/catch_amalgamated.cpp2739
-rw-r--r--extras/catch_amalgamated.hpp8575
7 files changed, 5473 insertions, 6197 deletions
diff --git a/extras/Catch.cmake b/extras/Catch3.cmake
index 1b068de6..064d44b6 100644
--- a/extras/Catch.cmake
+++ b/extras/Catch3.cmake
@@ -2,12 +2,12 @@
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
-Catch
------
+Catch3
+------
-This module defines a function to help use the Catch test framework.
+This module defines a function to help use the Catch3 test framework.
-The :command:`catch_discover_tests` discovers tests by asking the compiled test
+The :command:`catch3_discover_tests` discovers tests by asking the compiled test
executable to enumerate its tests. This does not require CMake to be re-run
when tests change. However, it may not work in a cross-compiling environment,
and setting test properties is less convenient.
@@ -20,12 +20,12 @@ However, it provides more fine-grained pass/fail information to CTest, which is
usually considered as more beneficial. By default, the CTest test name is the
same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
-.. command:: catch_discover_tests
+.. command:: catch3_discover_tests
Automatically add tests with CTest by querying the compiled test executable
for available tests::
- catch_discover_tests(target
+ catch3_discover_tests(target
[TEST_SPEC arg1...]
[EXTRA_ARGS arg1...]
[WORKING_DIRECTORY dir]
@@ -42,7 +42,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
[ADD_TAGS_AS_LABELS]
)
- ``catch_discover_tests`` sets up a post-build command on the test executable
+ ``catch3_discover_tests`` sets up a post-build command on the test executable
that generates the list of tests by parsing the output from running the test
with the ``--list=json`` argument, the discovery protocol of the Catch3 runner
(``"format": "catch3-tests"``, version 1). This ensures that the full
@@ -85,7 +85,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
``TEST_PREFIX prefix``
Specifies a ``prefix`` to be prepended to the name of each discovered test
case. This can be useful when the same test executable is being used in
- multiple calls to ``catch_discover_tests()`` but with different
+ multiple calls to ``catch3_discover_tests()`` but with different
``TEST_SPEC`` or ``EXTRA_ARGS``.
``TEST_SUFFIX suffix``
@@ -95,12 +95,12 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
``PROPERTIES name1 value1...``
Specifies additional properties to be set on all tests discovered by this
- invocation of ``catch_discover_tests``.
+ invocation of ``catch3_discover_tests``.
``TEST_LIST var``
Make the list of tests available in the variable ``var``, rather than the
default ``<target>_TESTS``. This can be useful when the same test
- executable is being used in multiple calls to ``catch_discover_tests()``.
+ executable is being used in multiple calls to ``catch3_discover_tests()``.
Note that this variable is only available in CTest.
``REPORTER reporter``
@@ -139,7 +139,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
This requires cmake/ctest >= 3.22.
``DISCOVERY_MODE mode``
- Provides control over when ``catch_discover_tests`` performs test discovery.
+ Provides control over when ``catch3_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
@@ -147,8 +147,8 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
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
+ ``CMAKE_CATCH3_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when
+ calling ``catch3_discover_tests``. This provides a mechanism for globally selecting
a preferred test discovery behavior without having to modify each call site.
On Apple Silicon with the Xcode generator you must use ``PRE_TEST``. With the
@@ -166,7 +166,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
#]=======================================================================]
#------------------------------------------------------------------------------
-function(catch_discover_tests TARGET)
+function(catch3_discover_tests TARGET)
cmake_parse_arguments(
""
@@ -193,10 +193,10 @@ function(catch_discover_tests TARGET)
message(FATAL_ERROR "The DL_FRAMEWORK_PATHS option requires at least cmake 3.22")
endif()
if(NOT _DISCOVERY_MODE)
- if(NOT CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE)
- set(CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
+ if(NOT CMAKE_CATCH3_DISCOVER_TESTS_DISCOVERY_MODE)
+ set(CMAKE_CATCH3_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
endif()
- set(_DISCOVERY_MODE ${CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE})
+ set(_DISCOVERY_MODE ${CMAKE_CATCH3_DISCOVER_TESTS_DISCOVERY_MODE})
endif()
if(NOT _DISCOVERY_MODE MATCHES "^(POST_BUILD|PRE_TEST)$")
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
@@ -242,7 +242,7 @@ function(catch_discover_tests TARGET)
-D "TEST_DL_FRAMEWORK_PATHS=${_DL_FRAMEWORK_PATHS}"
-D "CTEST_FILE=${ctest_tests_file}"
-D "ADD_TAGS_AS_LABELS=${_ADD_TAGS_AS_LABELS}"
- -P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
+ -P "${_CATCH3_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
@@ -269,8 +269,8 @@ function(catch_discover_tests TARGET)
" 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"
+ " include(\"${_CATCH3_DISCOVER_TESTS_SCRIPT}\")" "\n"
+ " catch3_discover_tests_impl(" "\n"
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
@@ -323,7 +323,7 @@ endfunction()
###############################################################################
-set(_CATCH_DISCOVER_TESTS_SCRIPT
- ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
- CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file"
+set(_CATCH3_DISCOVER_TESTS_SCRIPT
+ ${CMAKE_CURRENT_LIST_DIR}/Catch3AddTests.cmake
+ CACHE INTERNAL "Full path to the Catch3AddTests.cmake helper file"
)
diff --git a/extras/CatchAddTests.cmake b/extras/Catch3AddTests.cmake
index ef2fb439..cbe431d4 100644
--- a/extras/CatchAddTests.cmake
+++ b/extras/Catch3AddTests.cmake
@@ -39,7 +39,7 @@ string(ASCII 3 _CloseBracketListingEscape)
# Placeholder bytes in the listing would break our parsing hack, so
# we check they don't exist. They shouldn't exist in valid JSON, but
# the reporter might not be escaping them properly.
-function(validate_input_noescapes listing_var)
+function(catch3_validate_input_noescapes listing_var)
foreach(byte "${_SemicolonEscape}" "${_BoundaryEscape}" "${_OpenBracketEscape}" "${_CloseBracketEscape}")
string(FIND "${${listing_var}}" "${byte}" found)
if(NOT found EQUAL -1)
@@ -54,7 +54,7 @@ endfunction()
# Replaces relevant characters with their placeholders, see the top of this file.
# Modifies argument `var` in place.
-function(magic_escape_chars var)
+function(catch3_magic_escape_chars var)
set(value "${${var}}")
string(REPLACE ";" "${_SemicolonEscape}" value "${value}")
string(REPLACE "[" "${_OpenBracketEscape}" value "${value}")
@@ -65,7 +65,7 @@ endfunction()
# Turns placeholders back into original characters, see the top of this file.
# Modifies argument `var` in place.
-function(magic_unescape_chars var)
+function(catch3_magic_unescape_chars var)
set(value "${${var}}")
string(REPLACE "${_SemicolonEscape}" ";" value "${value}")
string(REPLACE "${_OpenBracketEscape}" "[" value "${value}")
@@ -95,7 +95,7 @@ endfunction()
# Note that to support passing the object strings back from the function,
# they will still contain the placeholders and need to be unescaped before
# further processing (e.g. sending them into CMake's JSON parsing API).
-function(split_json_array json_array_var out_var)
+function(catch3_split_json_array json_array_var out_var)
# We have to pass the input by var name to avoid CMake processing
# the input as an arg.
set(json_in "${${json_array_var}}")
@@ -106,7 +106,7 @@ function(split_json_array json_array_var out_var)
string(REGEX REPLACE "^[ \t\r\n]*\\[" "" json_in "${json_in}")
string(REGEX REPLACE "\\][ \t\r\n]*$" "" json_in "${json_in}")
- magic_escape_chars(json_in)
+ catch3_magic_escape_chars(json_in)
# We need to keep the whitespace around comma around, so that if we
# split inside the test object, we can reconstruct it losslessly.
@@ -129,7 +129,7 @@ function(split_json_array json_array_var out_var)
# Because the fragments (might) contain invalid JSON characters due
# to escaping, we have to unescape it before checking if we can parse it.
set(maybe_json "${accumulator}")
- magic_unescape_chars(maybe_json)
+ catch3_magic_unescape_chars(maybe_json)
string(JSON unused ERROR_VARIABLE err GET "${maybe_json}" "name")
if(err STREQUAL "NOTFOUND")
list(APPEND array_elements "${accumulator}")
@@ -145,7 +145,7 @@ endfunction()
#
# This allows the registration script to escape parts of the test script
# only once, instead of escaping the unchanged arguments over and over again.
-function(prepare_command_fragment out_var)
+function(catch3_prepare_command_fragment out_var)
set(_args "")
math(EXPR _last_arg ${ARGC}-1)
if(_last_arg GREATER_EQUAL 1)
@@ -164,7 +164,7 @@ endfunction()
# Generates random filename in the temp folder.
# Temp folder is retrieved by checking env vars from various platforms.
-function(make_temp_file_path OUT_VARIABLE FALLBACK_PATH)
+function(catch3_make_temp_file_path OUT_VARIABLE FALLBACK_PATH)
set(TEMP_DIR "")
set(ENV_VARS
# From XDG base dir specification
@@ -192,7 +192,7 @@ function(make_temp_file_path OUT_VARIABLE FALLBACK_PATH)
# Generate the random file name
string(RANDOM LENGTH 8 RAND_ID)
- set(FINAL_TEMP_PATH "${TEMP_DIR}/Catch2-test-listing.${RAND_ID}.json")
+ set(FINAL_TEMP_PATH "${TEMP_DIR}/Catch3-test-listing.${RAND_ID}.json")
set(${OUT_VARIABLE} "${FINAL_TEMP_PATH}" PARENT_SCOPE)
endfunction()
@@ -205,7 +205,7 @@ endfunction()
#
# <base>_tests.cmake -> <base>_test-list.cmake
# <base>_tests-Debug.cmake -> <base>_test-list-Debug.cmake
-function(make_test_list_file_path CTEST_FILE OUT_VARIABLE)
+function(catch3_make_test_list_file_path CTEST_FILE OUT_VARIABLE)
if("${CTEST_FILE}" MATCHES "_tests(.*)\\.cmake$")
string(REGEX REPLACE "_tests(.*)\\.cmake$" "_test-list\\1.cmake" list_file "${CTEST_FILE}")
else()
@@ -214,7 +214,7 @@ function(make_test_list_file_path CTEST_FILE OUT_VARIABLE)
set(${OUT_VARIABLE} "${list_file}" PARENT_SCOPE)
endfunction()
-function(catch_discover_tests_impl)
+function(catch3_discover_tests_impl)
cmake_parse_arguments(
""
""
@@ -224,7 +224,7 @@ function(catch_discover_tests_impl)
)
# We write the list of all discovered tests into a separate file
- make_test_list_file_path("${_CTEST_FILE}" _CTEST_LIST_FILE)
+ catch3_make_test_list_file_path("${_CTEST_FILE}" _CTEST_LIST_FILE)
# We periodically append to the output files below, so we have to ensure
# that it is empty at the start, or we get duplicated test scripts.
@@ -306,7 +306,7 @@ function(catch_discover_tests_impl)
if(listing_start GREATER 0)
string(SUBSTRING "${listing_output}" ${listing_start} -1 listing_output)
endif()
- validate_input_noescapes(listing_output)
+ catch3_validate_input_noescapes(listing_output)
# The runner writes reports itself: REPORTER chooses which, OUTPUT_DIR where.
set(report_option "")
@@ -360,7 +360,7 @@ function(catch_discover_tests_impl)
# Extract just the JSON array with tests and then split them into
# individual objects.
string(JSON test_listing GET "${listing_output}" "tests")
- split_json_array(test_listing tests)
+ catch3_split_json_array(test_listing tests)
# Exit early if no tests are detected
if(NOT tests)
@@ -378,7 +378,7 @@ function(catch_discover_tests_impl)
set(test_names "set(${_TEST_LIST}")
# Most of the commands/arguments in the CTest script are identical
- # for every test registered with one `catch_discover_tests` call.
+ # for every test registered with one `catch3_discover_tests` call.
# To avoid repeating the work in escaping them, we escape them before
# the per-test loop and reuse the escaped fragments.
#
@@ -386,11 +386,11 @@ function(catch_discover_tests_impl)
# add_test(<name><exec><exe><escaped_name><extra_args><reporter><out_dir>)
# Of these, <exec>,<exe>,<extra_args>, and <reporter> are the same between
# all tests.
- prepare_command_fragment(_exec_exe_fragment
+ catch3_prepare_command_fragment(_exec_exe_fragment
${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}"
)
- prepare_command_fragment(_args_reporter_fragment
+ catch3_prepare_command_fragment(_args_reporter_fragment
"${extra_args}"
)
@@ -398,14 +398,14 @@ function(catch_discover_tests_impl)
# set_tests_properties(<name> PROPERTIES WORKING_DIRECTORY <dir> <properties>)
# set_tests_properties(<name> PROPERTIES ENVIRONMENT_MODIFICATION <env_mod>)
# Of these, only the <name> changes between tests.
- prepare_command_fragment(_properties_fragment
+ catch3_prepare_command_fragment(_properties_fragment
PROPERTIES
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
${properties}
)
# Env modification is optional, so we prepare it in a separate command
if(environment_modifications)
- prepare_command_fragment(_env_modification_fragment
+ catch3_prepare_command_fragment(_env_modification_fragment
PROPERTIES
ENVIRONMENT_MODIFICATION "${environment_modifications}"
)
@@ -429,7 +429,7 @@ function(catch_discover_tests_impl)
# The elements are still escaped and contain JSON-invalid characters,
# they have to be unescaped before parsing them as JSON.
- magic_unescape_chars(single_test)
+ catch3_magic_unescape_chars(single_test)
if(add_tags)
string(JSON test_tags GET "${single_test}" "tags")
endif()
@@ -450,9 +450,9 @@ function(catch_discover_tests_impl)
endif()
set(full_name "${prefix}${plain_name}${suffix}")
- prepare_command_fragment(_full_name_fragment "${full_name}")
- prepare_command_fragment(_escaped_name_fragment "${escaped_name}")
- prepare_command_fragment(_outdir_fragment "${output_dir_arg}")
+ catch3_prepare_command_fragment(_full_name_fragment "${full_name}")
+ catch3_prepare_command_fragment(_escaped_name_fragment "${escaped_name}")
+ catch3_prepare_command_fragment(_outdir_fragment "${output_dir_arg}")
string(APPEND script
"add_test(${_full_name_fragment}${_exec_exe_fragment}${_escaped_name_fragment}${_args_reporter_fragment}${_outdir_fragment})\n")
@@ -477,7 +477,7 @@ function(catch_discover_tests_impl)
list(APPEND tag_list "${a_tag}")
endforeach()
- prepare_command_fragment(_labels_fragment
+ catch3_prepare_command_fragment(_labels_fragment
PROPERTIES
LABELS "${tag_list}"
)
@@ -515,7 +515,7 @@ endfunction()
# To enable `include`ing this file in the unit test scripts, we only run
# the impl if an actual `TEST_EXECUTABLE` is provided.
if(CMAKE_SCRIPT_MODE_FILE AND DEFINED TEST_EXECUTABLE)
- catch_discover_tests_impl(
+ catch3_discover_tests_impl(
TEST_EXECUTABLE ${TEST_EXECUTABLE}
TEST_EXECUTOR ${TEST_EXECUTOR}
TEST_WORKING_DIR ${TEST_WORKING_DIR}
diff --git a/extras/CatchShardTests.cmake b/extras/Catch3ShardTests.cmake
index 27f7c9f7..a7d651ef 100644
--- a/extras/CatchShardTests.cmake
+++ b/extras/Catch3ShardTests.cmake
@@ -10,7 +10,7 @@
# * SHARD_COUNT - number of shards to split target's tests into
# * REPORTER - report options for the shards, such as --junit=FILE
# * TEST_SPEC - test spec used for filtering tests
-function(catch_add_sharded_tests TARGET)
+function(catch3_add_sharded_tests TARGET)
if(${CMAKE_VERSION} VERSION_LESS "3.10.0")
message(FATAL_ERROR "add_sharded_catch_tests only supports CMake versions 3.10.0 and up")
endif()
@@ -46,7 +46,7 @@ function(catch_add_sharded_tests TARGET)
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
- set(shard_impl_script_file "${_CATCH_DISCOVER_SHARD_TESTS_IMPL_SCRIPT}")
+ set(shard_impl_script_file "${_CATCH3_DISCOVER_SHARD_TESTS_IMPL_SCRIPT}")
add_custom_command(
TARGET ${TARGET} POST_BUILD
@@ -66,7 +66,7 @@ endfunction()
###############################################################################
-set(_CATCH_DISCOVER_SHARD_TESTS_IMPL_SCRIPT
- ${CMAKE_CURRENT_LIST_DIR}/CatchShardTestsImpl.cmake
- CACHE INTERNAL "Catch2 full path to CatchShardTestsImpl.cmake helper file"
+set(_CATCH3_DISCOVER_SHARD_TESTS_IMPL_SCRIPT
+ ${CMAKE_CURRENT_LIST_DIR}/Catch3ShardTestsImpl.cmake
+ CACHE INTERNAL "Full path to the Catch3ShardTestsImpl.cmake helper file"
)
diff --git a/extras/CatchShardTestsImpl.cmake b/extras/Catch3ShardTestsImpl.cmake
index 99fd900a..99fd900a 100644
--- a/extras/CatchShardTestsImpl.cmake
+++ b/extras/Catch3ShardTestsImpl.cmake
diff --git a/extras/ParseAndAddCatchTests.cmake b/extras/ParseAndAddCatchTests.cmake
deleted file mode 100644
index d7c17ace..00000000
--- a/extras/ParseAndAddCatchTests.cmake
+++ /dev/null
@@ -1,250 +0,0 @@
-#==================================================================================================#
-# supported macros #
-# - TEST_CASE, #
-# - TEMPLATE_TEST_CASE #
-# - SCENARIO, #
-# - TEST_CASE_METHOD, #
-# - CATCH_TEST_CASE, #
-# - CATCH_TEMPLATE_TEST_CASE #
-# - CATCH_SCENARIO, #
-# - CATCH_TEST_CASE_METHOD. #
-# #
-# Usage #
-# 1. make sure this module is in the path or add this otherwise: #
-# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
-# 2. make sure that you've enabled testing option for the project by the call: #
-# enable_testing() #
-# 3. add the lines to the script for testing target (sample CMakeLists.txt): #
-# project(testing_target) #
-# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
-# enable_testing() #
-# #
-# find_path(CATCH_INCLUDE_DIR "catch.hpp") #
-# include_directories(${INCLUDE_DIRECTORIES} ${CATCH_INCLUDE_DIR}) #
-# #
-# file(GLOB SOURCE_FILES "*.cpp") #
-# add_executable(${PROJECT_NAME} ${SOURCE_FILES}) #
-# #
-# include(ParseAndAddCatchTests) #
-# ParseAndAddCatchTests(${PROJECT_NAME}) #
-# #
-# The following variables affect the behavior of the script: #
-# #
-# PARSE_CATCH_TESTS_VERBOSE (Default OFF) #
-# -- enables debug messages #
-# PARSE_CATCH_TESTS_NO_HIDDEN_TESTS (Default OFF) #
-# -- excludes tests marked with [!hide], [.] or [.foo] tags #
-# PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME (Default ON) #
-# -- adds fixture class name to the test name #
-# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) #
-# -- adds cmake target name to the test name #
-# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) #
-# -- causes CMake to rerun when file with tests changes so that new tests will be discovered #
-# #
-# One can also set (locally) the optional variable OptionalCatchTestLauncher to precise the way #
-# a test should be run. For instance to use test MPI, one can write #
-# set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC}) #
-# just before calling this ParseAndAddCatchTests function #
-# #
-# The AdditionalCatchParameters optional variable can be used to pass extra argument to the test #
-# command. For example, to include successful tests in the output, one can write #
-# set(AdditionalCatchParameters --success) #
-# #
-# After the script, the ParseAndAddCatchTests_TESTS property for the target, and for each source #
-# file in the target is set, and contains the list of the tests extracted from that target, or #
-# from that file. This is useful, for example to add further labels or properties to the tests. #
-# #
-#==================================================================================================#
-
-if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.8)
- message(FATAL_ERROR "ParseAndAddCatchTests requires CMake 2.8.8 or newer")
-endif()
-
-option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF)
-option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
-option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON)
-option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON)
-option(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS "Add test file to CMAKE_CONFIGURE_DEPENDS property" OFF)
-
-function(ParseAndAddCatchTests_PrintDebugMessage)
- if(PARSE_CATCH_TESTS_VERBOSE)
- message(STATUS "ParseAndAddCatchTests: ${ARGV}")
- endif()
-endfunction()
-
-# This removes the contents between
-# - block comments (i.e. /* ... */)
-# - full line comments (i.e. // ... )
-# contents have been read into '${CppCode}'.
-# !keep partial line comments
-function(ParseAndAddCatchTests_RemoveComments CppCode)
- string(ASCII 2 CMakeBeginBlockComment)
- string(ASCII 3 CMakeEndBlockComment)
- string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}")
- string(REGEX REPLACE "\\*/" "${CMakeEndBlockComment}" ${CppCode} "${${CppCode}}")
- string(REGEX REPLACE "${CMakeBeginBlockComment}[^${CMakeEndBlockComment}]*${CMakeEndBlockComment}" "" ${CppCode} "${${CppCode}}")
- string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" ${CppCode} "${${CppCode}}")
-
- set(${CppCode} "${${CppCode}}" PARENT_SCOPE)
-endfunction()
-
-# Worker function
-function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
- # If SourceFile is an object library, do not scan it (as it is not a file). Exit without giving a warning about a missing file.
- if(SourceFile MATCHES "\\\$<TARGET_OBJECTS:.+>")
- ParseAndAddCatchTests_PrintDebugMessage("Detected OBJECT library: ${SourceFile} this will not be scanned for tests.")
- return()
- endif()
- # According to CMake docs EXISTS behavior is well-defined only for full paths.
- get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
- if(NOT EXISTS ${SourceFile})
- message(WARNING "Cannot find source file: ${SourceFile}")
- return()
- endif()
- ParseAndAddCatchTests_PrintDebugMessage("parsing ${SourceFile}")
- file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
-
- # Remove block and fullline comments
- ParseAndAddCatchTests_RemoveComments(Contents)
-
- # Find definition of test names
- # https://regex101.com/r/JygOND/1
- string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([ \t\n]*\"[^\"]*\"[ \t\n]*(,[ \t\n]*\"[^\"]*\")?(,[ \t\n]*[^\,\)]*)*\\)[ \t\n]*\{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
-
- if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
- ParseAndAddCatchTests_PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
- set_property(
- DIRECTORY
- APPEND
- PROPERTY CMAKE_CONFIGURE_DEPENDS ${SourceFile}
- )
- endif()
-
- # check CMP0110 policy for new add_test() behavior
- if(POLICY CMP0110)
- cmake_policy(GET CMP0110 _cmp0110_value) # new add_test() behavior
- else()
- # just to be thorough explicitly set the variable
- set(_cmp0110_value)
- endif()
-
- foreach(TestName ${Tests})
- # Strip newlines
- string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
-
- # Get test type and fixture if applicable
- string(REGEX MATCH "(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
- string(REGEX MATCH "(CATCH_)?(TEMPLATE_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
- string(REGEX REPLACE "${TestType}\\([ \t]*" "" TestFixture "${TestTypeAndFixture}")
-
- # Get string parts of test definition
- string(REGEX MATCHALL "\"+([^\\^\"]|\\\\\")+\"+" TestStrings "${TestName}")
-
- # Strip wrapping quotation marks
- string(REGEX REPLACE "^\"(.*)\"$" "\\1" TestStrings "${TestStrings}")
- string(REPLACE "\";\"" ";" TestStrings "${TestStrings}")
-
- # Validate that a test name and tags have been provided
- list(LENGTH TestStrings TestStringsLength)
- if(TestStringsLength GREATER 2 OR TestStringsLength LESS 1)
- message(FATAL_ERROR "You must provide a valid test name and tags for all tests in ${SourceFile}")
- endif()
-
- # Assign name and tags
- list(GET TestStrings 0 Name)
- if("${TestType}" STREQUAL "SCENARIO")
- set(Name "Scenario: ${Name}")
- endif()
- if(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME AND "${TestType}" MATCHES "(CATCH_)?TEST_CASE_METHOD" AND TestFixture)
- set(CTestName "${TestFixture}:${Name}")
- else()
- set(CTestName "${Name}")
- endif()
- if(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME)
- set(CTestName "${TestTarget}:${CTestName}")
- endif()
- # add target to labels to enable running all tests added from this target
- set(Labels ${TestTarget})
- if(TestStringsLength EQUAL 2)
- list(GET TestStrings 1 Tags)
- string(TOLOWER "${Tags}" Tags)
- # remove target from labels if the test is hidden
- if("${Tags}" MATCHES ".*\\[!?(hide|\\.)\\].*")
- list(REMOVE_ITEM Labels ${TestTarget})
- endif()
- string(REPLACE "]" ";" Tags "${Tags}")
- string(REPLACE "[" "" Tags "${Tags}")
- else()
- # unset tags variable from previous loop
- unset(Tags)
- endif()
-
- list(APPEND Labels ${Tags})
-
- set(HiddenTagFound OFF)
- foreach(label ${Labels})
- string(REGEX MATCH "^!hide|^\\." result ${label})
- if(result)
- set(HiddenTagFound ON)
- break()
- endif()
- endforeach(label)
- if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_LESS "3.9")
- ParseAndAddCatchTests_PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label")
- else()
- ParseAndAddCatchTests_PrintDebugMessage("Adding test \"${CTestName}\"")
- if(Labels)
- ParseAndAddCatchTests_PrintDebugMessage("Setting labels to ${Labels}")
- endif()
-
- # Escape commas in the test spec
- string(REPLACE "," "\\," Name ${Name})
-
- # Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were necessary,
- # only with CMake 3.18.0 the escaped double quotes confuse the call. This change is reverted in 3.18.1
- # And properly introduced in 3.19 with the CMP0110 policy
- if(_cmp0110_value STREQUAL "NEW" OR ${CMAKE_VERSION} VERSION_EQUAL "3.18")
- ParseAndAddCatchTests_PrintDebugMessage("CMP0110 set to NEW, no need for add_test(\"\") workaround")
- else()
- ParseAndAddCatchTests_PrintDebugMessage("CMP0110 set to OLD adding \"\" for add_test() workaround")
- set(CTestName "\"${CTestName}\"")
- endif()
-
- # Handle template test cases
- if("${TestTypeAndFixture}" MATCHES ".*TEMPLATE_.*")
- set(Name "${Name} - *")
- endif()
-
- # Add the test and set its properties
- add_test(NAME "${CTestName}" COMMAND ${OptionalCatchTestLauncher} $<TARGET_FILE:${TestTarget}> ${Name} ${AdditionalCatchParameters})
- # Old CMake versions do not document VERSION_GREATER_EQUAL, so we use VERSION_GREATER with 3.8 instead
- if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_GREATER "3.8")
- ParseAndAddCatchTests_PrintDebugMessage("Setting DISABLED test property")
- set_tests_properties("${CTestName}" PROPERTIES DISABLED ON)
- else()
- set_tests_properties("${CTestName}" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
- LABELS "${Labels}")
- endif()
- set_property(
- TARGET ${TestTarget}
- APPEND
- PROPERTY ParseAndAddCatchTests_TESTS "${CTestName}")
- set_property(
- SOURCE ${SourceFile}
- APPEND
- PROPERTY ParseAndAddCatchTests_TESTS "${CTestName}")
- endif()
- endforeach()
-endfunction()
-
-# entry point
-function(ParseAndAddCatchTests TestTarget)
- message(DEPRECATION "ParseAndAddCatchTest: function deprecated because of possibility of missed test cases. Consider using 'catch_discover_tests' from 'Catch.cmake'")
- ParseAndAddCatchTests_PrintDebugMessage("Started parsing ${TestTarget}")
- get_target_property(SourceFiles ${TestTarget} SOURCES)
- ParseAndAddCatchTests_PrintDebugMessage("Found the following sources: ${SourceFiles}")
- foreach(SourceFile ${SourceFiles})
- ParseAndAddCatchTests_ParseFile(${SourceFile} ${TestTarget})
- endforeach()
- ParseAndAddCatchTests_PrintDebugMessage("Finished parsing ${TestTarget}")
-endfunction()
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index f5a8b781..0f336b53 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -7,7 +7,7 @@
// SPDX-License-Identifier: BSL-1.0
// Catch3 v0.3.0, on the Catch2 v3.16.1 engine
-// Generated: 2026-10-24 19:06:40.031209
+// Generated: 2026-10-25 02:37:10.065190
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -20,8 +20,6 @@
#include "catch_amalgamated.hpp"
-#ifndef CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
-#define CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
#if defined(CATCH_PLATFORM_WINDOWS)
@@ -39,7 +37,6 @@
#endif // defined(CATCH_PLATFORM_WINDOWS)
-#endif // CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
// Copyright (c) 2026 Progmasoft.
// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1
@@ -2160,6 +2157,180 @@ namespace Progmasoft::Catch3
+#include <cmath>
+#include <limits>
+
+namespace {
+
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+ return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+}
+
+namespace Catch {
+
+ Approx::Approx ( double value )
+ : m_epsilon( static_cast<double>(std::numeric_limits<float>::epsilon())*100. ),
+ m_margin( 0.0 ),
+ m_scale( 0.0 ),
+ m_value( value )
+ {}
+
+ Approx Approx::custom() {
+ return Approx( 0 );
+ }
+
+ Approx Approx::operator-() const {
+ auto temp(*this);
+ temp.m_value = -temp.m_value;
+ return temp;
+ }
+
+
+ std::string Approx::toString() const {
+ ReusableStringStream rss;
+ rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
+ return rss.str();
+ }
+
+ bool Approx::equalityComparisonImpl(const double other) const {
+ // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
+ // Thanks to Richard Harris for his help refining the scaled margin value
+ return marginComparison(m_value, other, m_margin)
+ || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
+ }
+
+ void Approx::setMargin(double newMargin) {
+ CATCH_ENFORCE(newMargin >= 0,
+ "Invalid Approx::margin: " << newMargin << '.'
+ << " Approx::Margin has to be non-negative.");
+ m_margin = newMargin;
+ }</