Compare commits

..

1 Commits

Author SHA1 Message Date
Martin Hořeňovský
6146a104b8 WIP: unreachable? 2024-12-27 23:46:25 +01:00
27 changed files with 237 additions and 376 deletions

View File

@@ -1,6 +1,3 @@
# Enable Bzlmod for every Bazel command
common --enable_bzlmod
build --enable_platform_specific_config build --enable_platform_specific_config
build:gcc9 --cxxopt=-std=c++2a build:gcc9 --cxxopt=-std=c++2a

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.15)
project(PackageTest CXX) project(PackageTest CXX)
find_package(Catch2 CONFIG REQUIRED) find_package(Catch2 CONFIG REQUIRED)

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.10)
# detect if Catch is being bundled, # detect if Catch is being bundled,
# disable testsuite in that case # disable testsuite in that case
@@ -35,9 +35,11 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif() endif()
project(Catch2 project(Catch2
VERSION 3.8.1 # CML version placeholder, don't delete VERSION 3.7.1 # CML version placeholder, don't delete
LANGUAGES CXX LANGUAGES CXX
HOMEPAGE_URL "https://github.com/catchorg/Catch2" # HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet.
# HOMEPAGE_URL "https://github.com/catchorg/Catch2"
DESCRIPTION "A modern, C++-native, unit test framework." DESCRIPTION "A modern, C++-native, unit test framework."
) )
@@ -190,6 +192,12 @@ if (NOT_SUBPROJECT)
${PKGCONFIG_INSTALL_DIR} ${PKGCONFIG_INSTALL_DIR}
) )
# CPack/CMake started taking the package version from project version 3.12
# So we need to set the version manually for older CMake versions
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
endif()
set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/") set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/")

View File

@@ -1,4 +1,3 @@
module(name = "catch2") module(name = "catch2")
bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "rules_cc", version = "0.0.17")

16
WORKSPACE.bazel Normal file
View File

@@ -0,0 +1,16 @@
workspace(name = "catch2")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
],
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()

View File

@@ -81,11 +81,12 @@ to your CMake module path.
`Catch.cmake` provides function `catch_discover_tests` to get tests from `Catch.cmake` provides function `catch_discover_tests` to get tests from
a target. This function works by running the resulting executable with a target. This function works by running the resulting executable with
`--list-test` flag, and then parsing the output to find all existing tests. `--list-test-names-only` flag, and then parsing the output to find all
existing tests.
#### Usage #### Usage
```cmake ```cmake
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.5)
project(baz LANGUAGES CXX VERSION 0.0.1) project(baz LANGUAGES CXX VERSION 0.0.1)
@@ -127,8 +128,6 @@ catch_discover_tests(target
[OUTPUT_PREFIX prefix] [OUTPUT_PREFIX prefix]
[OUTPUT_SUFFIX suffix] [OUTPUT_SUFFIX suffix]
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>] [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
[SKIP_IS_FAILURE]
[ADD_TAGS_AS_LABELS]
) )
``` ```
@@ -212,15 +211,6 @@ execution (useful e.g. in cross-compilation environments).
calling ``catch_discover_tests``. This provides a mechanism for globally calling ``catch_discover_tests``. This provides a mechanism for globally
selecting a preferred test discovery behavior. selecting a preferred test discovery behavior.
* `SKIP_IS_FAILURE`
Skipped tests will be marked as failed instead.
* `ADD_TAGS_AS_LABELS`
Add the tags from tests as labels to CTest.
### `ParseAndAddCatchTests.cmake` ### `ParseAndAddCatchTests.cmake`
⚠ This script is [deprecated](https://github.com/catchorg/Catch2/pull/2120) ⚠ This script is [deprecated](https://github.com/catchorg/Catch2/pull/2120)
@@ -239,7 +229,7 @@ parsed are *silently ignored*.
#### Usage #### Usage
```cmake ```cmake
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.5)
project(baz LANGUAGES CXX VERSION 0.0.1) project(baz LANGUAGES CXX VERSION 0.0.1)

View File

@@ -2,8 +2,6 @@
# Release notes # Release notes
**Contents**<br> **Contents**<br>
[3.8.1](#381)<br>
[3.8.0](#380)<br>
[3.7.1](#371)<br> [3.7.1](#371)<br>
[3.7.0](#370)<br> [3.7.0](#370)<br>
[3.6.0](#360)<br> [3.6.0](#360)<br>
@@ -67,38 +65,6 @@
[Even Older versions](#even-older-versions)<br> [Even Older versions](#even-older-versions)<br>
## 3.8.1
### Fixes
* Fixed bug where catch_discover_tests fails when no TEST_CASEs are present (#2962)
* Fixed Clang 19 -Wc++20-extensions warning (#2968)
## 3.8.0
### Improvements
* Added `std::initializer_list` overloads for `(Unordered)RangeEquals` matcher (#2915, #2919)
* Added explicit casts to silence GCC's `Wconversion` (#2875)
* Made the use of `builtin_constant_p` tricks in assertion macros configurable (#2925)
* It is used to prod GCC-like compilers into providing warnings for the asserted expressions, but the compilers miscompile it annoyingly often.
* Cleaned out Clang-Tidy's `performance-enum-size` warnings
* Added support for using `from_range` generator with iterators with `value_type = const T` (#2926)
* This is not correct `value_type` typedef, but it is used in the wild and the change does not make the code meaningfully worse.
### Fixes
* Fixed crash when stringifying pre-1970 (epoch) dates on Windows (#2944)
### Miscellaneous
* Fixes and improvements for `catch_discover_tests` CMake helper
* Removed redundant `CTEST_FILE` param when creating the indirection file for `PRE_TEST` discovery mode (#2936)
* Rewrote the test discovery logic to use output from the JSON reporter
* This means that `catch_discover_tests` now requires CMake 3.19 or newer
* Added `ADD_TAGS_AS_LABELS` option. If specified, each CTest test will be labeled with corrensponding Catch2's test tag
* Bumped up the minimum required CMake version to build Catch2 to 3.16
* Meson build now provides option to avoid installing Catch2
* Bazel build is moved to Bzlmod.
## 3.7.1 ## 3.7.1
### Improvements ### Improvements

View File

@@ -1,4 +1,4 @@
cmake_minimum_required( VERSION 3.16 ) cmake_minimum_required( VERSION 3.10 )
project( Catch2Examples LANGUAGES CXX ) project( Catch2Examples LANGUAGES CXX )

View File

@@ -39,7 +39,6 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
[OUTPUT_SUFFIX suffix] [OUTPUT_SUFFIX suffix]
[DISCOVERY_MODE <POST_BUILD|PRE_TEST>] [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
[SKIP_IS_FAILURE] [SKIP_IS_FAILURE]
[ADD_TAGS_AS_LABELS]
) )
``catch_discover_tests`` sets up a post-build command on the test executable ``catch_discover_tests`` sets up a post-build command on the test executable
@@ -145,13 +144,10 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
``CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when ``CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when
calling ``catch_discover_tests``. This provides a mechanism for globally selecting calling ``catch_discover_tests``. This provides a mechanism for globally selecting
a preferred test discovery behavior without having to modify each call site. a preferred test discovery behavior without having to modify each call site.
``SKIP_IS_FAILURE`` ``SKIP_IS_FAILURE``
Disables skipped test detection. Disables skipped test detection.
``ADD_TAGS_AS_LABELS``
Adds all test tags as CTest labels.
#]=======================================================================] #]=======================================================================]
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@@ -159,16 +155,12 @@ function(catch_discover_tests TARGET)
cmake_parse_arguments( cmake_parse_arguments(
"" ""
"SKIP_IS_FAILURE;ADD_TAGS_AS_LABELS" "SKIP_IS_FAILURE"
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX;DISCOVERY_MODE" "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX;DISCOVERY_MODE"
"TEST_SPEC;EXTRA_ARGS;PROPERTIES;DL_PATHS;DL_FRAMEWORK_PATHS" "TEST_SPEC;EXTRA_ARGS;PROPERTIES;DL_PATHS;DL_FRAMEWORK_PATHS"
${ARGN} ${ARGN}
) )
if (${CMAKE_VERSION} VERSION_LESS "3.19")
message(FATAL_ERROR "This script requires JSON support from CMake version 3.19 or greater.")
endif()
if(NOT _WORKING_DIRECTORY) if(NOT _WORKING_DIRECTORY)
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif() endif()
@@ -230,7 +222,6 @@ function(catch_discover_tests TARGET)
-D "TEST_DL_PATHS=${_DL_PATHS}" -D "TEST_DL_PATHS=${_DL_PATHS}"
-D "TEST_DL_FRAMEWORK_PATHS=${_DL_FRAMEWORK_PATHS}" -D "TEST_DL_FRAMEWORK_PATHS=${_DL_FRAMEWORK_PATHS}"
-D "CTEST_FILE=${ctest_tests_file}" -D "CTEST_FILE=${ctest_tests_file}"
-D "ADD_TAGS_AS_LABELS=${_ADD_TAGS_AS_LABELS}"
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}" -P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
VERBATIM VERBATIM
) )
@@ -276,7 +267,7 @@ function(catch_discover_tests TARGET)
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n" " CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
" TEST_DL_PATHS" " [==[" "${_DL_PATHS}" "]==]" "\n" " TEST_DL_PATHS" " [==[" "${_DL_PATHS}" "]==]" "\n"
" TEST_DL_FRAMEWORK_PATHS" " [==[" "${_DL_FRAMEWORK_PATHS}" "]==]" "\n" " TEST_DL_FRAMEWORK_PATHS" " [==[" "${_DL_FRAMEWORK_PATHS}" "]==]" "\n"
" ADD_TAGS_AS_LABELS" " [==[" "${_ADD_TAGS_AS_LABELS}" "]==]" "\n" " CTEST_FILE" " [==[" "${CTEST_FILE}" "]==]" "\n"
" )" "\n" " )" "\n"
" endif()" "\n" " endif()" "\n"
" include(\"${ctest_tests_file}\")" "\n" " include(\"${ctest_tests_file}\")" "\n"
@@ -303,10 +294,22 @@ function(catch_discover_tests TARGET)
endif() endif()
endif() endif()
# Add discovered tests to directory TEST_INCLUDE_FILES if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
set_property(DIRECTORY # Add discovered tests to directory TEST_INCLUDE_FILES
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" set_property(DIRECTORY
) APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
else()
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
if (NOT ${test_include_file_set})
set_property(DIRECTORY
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
)
else()
message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE")
endif()
endif()
endfunction() endfunction()

View File

@@ -22,11 +22,10 @@ function(catch_discover_tests_impl)
"" ""
"" ""
"TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_OUTPUT_DIR;TEST_OUTPUT_PREFIX;TEST_OUTPUT_SUFFIX;TEST_PREFIX;TEST_REPORTER;TEST_SPEC;TEST_SUFFIX;TEST_LIST;CTEST_FILE" "TEST_EXECUTABLE;TEST_WORKING_DIR;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;TEST_DL_PATHS;TEST_DL_FRAMEWORK_PATHS;ADD_TAGS_AS_LABELS" "TEST_EXTRA_ARGS;TEST_PROPERTIES;TEST_EXECUTOR;TEST_DL_PATHS;TEST_DL_FRAMEWORK_PATHS"
${ARGN} ${ARGN}
) )
set(add_tags "${_ADD_TAGS_AS_LABELS}")
set(prefix "${_TEST_PREFIX}") set(prefix "${_TEST_PREFIX}")
set(suffix "${_TEST_SUFFIX}") set(suffix "${_TEST_SUFFIX}")
set(spec ${_TEST_SPEC}) set(spec ${_TEST_SPEC})
@@ -73,19 +72,25 @@ function(catch_discover_tests_impl)
endif() endif()
execute_process( execute_process(
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" ${spec} --list-tests --reporter json COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
OUTPUT_VARIABLE listing_output OUTPUT_VARIABLE output
RESULT_VARIABLE result RESULT_VARIABLE result
WORKING_DIRECTORY "${_TEST_WORKING_DIR}" WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
) )
if(NOT ${result} EQUAL 0) if(NOT ${result} EQUAL 0)
message(FATAL_ERROR message(FATAL_ERROR
"Error listing tests from executable '${_TEST_EXECUTABLE}':\n" "Error running test executable '${_TEST_EXECUTABLE}':\n"
" Result: ${result}\n" " Result: ${result}\n"
" Output: ${listing_output}\n" " Output: ${output}\n"
) )
endif() endif()
# Make sure to escape ; (semicolons) in test names first, because
# that'd break the foreach loop for "Parse output" later and create
# wrongly splitted and thus failing test cases (false positives)
string(REPLACE ";" "\;" output "${output}")
string(REPLACE "\n" ";" output "${output}")
# Prepare reporter # Prepare reporter
if(reporter) if(reporter)
set(reporter_arg "--reporter ${reporter}") set(reporter_arg "--reporter ${reporter}")
@@ -105,7 +110,7 @@ function(catch_discover_tests_impl)
) )
elseif(NOT ${reporter_check_result} EQUAL 0) elseif(NOT ${reporter_check_result} EQUAL 0)
message(FATAL_ERROR message(FATAL_ERROR
"Error checking for reporter in test executable '${_TEST_EXECUTABLE}':\n" "Error running test executable '${_TEST_EXECUTABLE}':\n"
" Result: ${reporter_check_result}\n" " Result: ${reporter_check_result}\n"
" Output: ${reporter_check_output}\n" " Output: ${reporter_check_output}\n"
) )
@@ -134,92 +139,46 @@ function(catch_discover_tests_impl)
endforeach() endforeach()
endif() endif()
# Parse JSON output for list of tests/class names/tags # Parse output
string(JSON version GET "${listing_output}" "version") foreach(line ${output})
if (NOT version STREQUAL "1") set(test "${line}")
message(FATAL_ERROR "Unsupported catch output version: '${version}'")
endif()
# Speed-up reparsing by cutting away unneeded parts of JSON.
string(JSON test_listing GET "${listing_output}" "listings" "tests")
string(JSON num_tests LENGTH "${test_listing}")
# Exit early if no tests are detected
if(num_tests STREQUAL "0")
return()
endif()
# CMake's foreach-RANGE is inclusive, so we have to subtract 1
math(EXPR num_tests "${num_tests} - 1")
foreach(idx RANGE ${num_tests})
string(JSON single_test GET ${test_listing} ${idx})
string(JSON test_tags GET "${single_test}" "tags")
string(JSON plain_name GET "${single_test}" "name")
# Escape characters in test case names that would be parsed by Catch2 # Escape characters in test case names that would be parsed by Catch2
# Note that the \ escaping must happen FIRST! Do not change the order. # Note that the \ escaping must happen FIRST! Do not change the order.
set(escaped_name "${plain_name}") set(test_name "${test}")
foreach(char \\ , [ ] ;) foreach(char \\ , [ ])
string(REPLACE ${char} "\\${char}" escaped_name "${escaped_name}") string(REPLACE ${char} "\\${char}" test_name "${test_name}")
endforeach(char) endforeach(char)
# ...add output dir # ...add output dir
if(output_dir) if(output_dir)
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" escaped_name_clean "${escaped_name}") string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean "${test_name}")
set(output_dir_arg "--out ${output_dir}/${output_prefix}${escaped_name_clean}${output_suffix}") set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
endif() endif()
# ...and add to script # ...and add to script
add_command(add_test add_command(add_test
"${prefix}${plain_name}${suffix}" "${prefix}${test}${suffix}"
${_TEST_EXECUTOR} ${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}" "${_TEST_EXECUTABLE}"
"${escaped_name}" "${test_name}"
${extra_args} ${extra_args}
"${reporter_arg}" "${reporter_arg}"
"${output_dir_arg}" "${output_dir_arg}"
) )
add_command(set_tests_properties add_command(set_tests_properties
"${prefix}${plain_name}${suffix}" "${prefix}${test}${suffix}"
PROPERTIES PROPERTIES
WORKING_DIRECTORY "${_TEST_WORKING_DIR}" WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
${properties} ${properties}
) )
if (add_tags)
string(JSON num_tags LENGTH "${test_tags}")
math(EXPR num_tags "${num_tags} - 1")
set(tag_list "")
if (num_tags GREATER_EQUAL "0")
foreach(tag_idx RANGE ${num_tags})
string(JSON a_tag GET "${test_tags}" "${tag_idx}")
# Catch2's tags can contain semicolons, which are list element separators
# in CMake, so we have to escape them. Ideally we could use the [=[...]=]
# syntax for this, but CTest currently keeps the square quotes in the label
# name. So we add 2 backslashes to escape it instead.
# **IMPORTANT**: The number of backslashes depends on how many layers
# of CMake the tag goes. If this script is changed, the
# number of backslashes to escape may change as well.
string(REPLACE ";" "\\;" a_tag "${a_tag}")
list(APPEND tag_list "${a_tag}")
endforeach()
add_command(set_tests_properties
"${prefix}${plain_name}${suffix}"
PROPERTIES
LABELS "${tag_list}"
)
endif()
endif(add_tags)
if(environment_modifications) if(environment_modifications)
add_command(set_tests_properties add_command(set_tests_properties
"${prefix}${plain_name}${suffix}" "${prefix}${test}${suffix}"
PROPERTIES PROPERTIES
ENVIRONMENT_MODIFICATION "${environment_modifications}") ENVIRONMENT_MODIFICATION "${environment_modifications}")
endif() endif()
list(APPEND tests "${prefix}${plain_name}${suffix}") list(APPEND tests "${prefix}${test}${suffix}")
endforeach() endforeach()
# Create a list of all discovered tests, which users may use to e.g. set # Create a list of all discovered tests, which users may use to e.g. set
@@ -248,6 +207,5 @@ if(CMAKE_SCRIPT_MODE_FILE)
TEST_DL_PATHS ${TEST_DL_PATHS} TEST_DL_PATHS ${TEST_DL_PATHS}
TEST_DL_FRAMEWORK_PATHS ${TEST_DL_FRAMEWORK_PATHS} TEST_DL_FRAMEWORK_PATHS ${TEST_DL_FRAMEWORK_PATHS}
CTEST_FILE ${CTEST_FILE} CTEST_FILE ${CTEST_FILE}
ADD_TAGS_AS_LABELS ${ADD_TAGS_AS_LABELS}
) )
endif() endif()

View File

@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// Catch v3.8.1 // Catch v3.7.1
// Generated: 2025-04-08 12:33:19.863332 // Generated: 2024-09-17 10:36:45.608896
// ---------------------------------------------------------- // ----------------------------------------------------------
// This file is an amalgamation of multiple different files. // This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly. // You probably shouldn't edit it directly.
@@ -332,7 +332,7 @@ namespace Catch {
double diff = b - m; double diff = b - m;
return a + diff * diff; return a + diff * diff;
} ) / } ) /
static_cast<double>( last - first ); ( last - first );
return std::sqrt( variance ); return std::sqrt( variance );
} }
@@ -367,7 +367,7 @@ namespace Catch {
double* first, double* first,
double* last ) { double* last ) {
auto count = last - first; auto count = last - first;
double idx = static_cast<double>((count - 1) * k) / static_cast<double>(q); double idx = (count - 1) * k / static_cast<double>(q);
int j = static_cast<int>(idx); int j = static_cast<int>(idx);
double g = idx - j; double g = idx - j;
std::nth_element(first, first + j, last); std::nth_element(first, first + j, last);
@@ -470,10 +470,10 @@ namespace Catch {
double accel = sum_cubes / ( 6 * std::pow( sum_squares, 1.5 ) ); double accel = sum_cubes / ( 6 * std::pow( sum_squares, 1.5 ) );
long n = static_cast<long>( resample.size() ); long n = static_cast<long>( resample.size() );
double prob_n = static_cast<double>( double prob_n =
std::count_if( resample.begin(), std::count_if( resample.begin(),
resample.end(), resample.end(),
[point]( double x ) { return x < point; } )) / [point]( double x ) { return x < point; } ) /
static_cast<double>( n ); static_cast<double>( n );
// degenerate case with uniform samples // degenerate case with uniform samples
if ( Catch::Detail::directCompare( prob_n, 0. ) ) { if ( Catch::Detail::directCompare( prob_n, 0. ) ) {
@@ -1926,7 +1926,7 @@ namespace Catch {
return static_cast<unsigned int>(getElapsedMicroseconds()/1000); return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
} }
auto Timer::getElapsedSeconds() const -> double { auto Timer::getElapsedSeconds() const -> double {
return static_cast<double>(getElapsedMicroseconds())/1000000.0; return getElapsedMicroseconds()/1000000.0;
} }
@@ -1946,10 +1946,7 @@ namespace Detail {
const int hexThreshold = 255; const int hexThreshold = 255;
struct Endianness { struct Endianness {
enum Arch : uint8_t { enum Arch { Big, Little };
Big,
Little
};
static Arch which() { static Arch which() {
int one = 1; int one = 1;
@@ -2283,7 +2280,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 3, 8, 1, "", 0 ); static Version version( 3, 7, 1, "", 0 );
return version; return version;
} }
@@ -3519,7 +3516,7 @@ namespace {
#endif // Windows/ ANSI/ None #endif // Windows/ ANSI/ None
#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC ) || defined( __GLIBC__ ) #if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC )
# define CATCH_INTERNAL_HAS_ISATTY # define CATCH_INTERNAL_HAS_ISATTY
# include <unistd.h> # include <unistd.h>
#endif #endif
@@ -5261,7 +5258,7 @@ namespace {
SimplePcg32::result_type SimplePcg32::operator()() { SimplePcg32::result_type SimplePcg32::operator()() {
// prepare the output value // prepare the output value
const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u); const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
const auto output = rotate_right(xorshifted, static_cast<uint32_t>(m_state >> 59u)); const auto output = rotate_right(xorshifted, m_state >> 59u);
// advance state // advance state
m_state = m_state * 6364136223846793005ULL + s_inc; m_state = m_state * 6364136223846793005ULL + s_inc;
@@ -9111,7 +9108,7 @@ struct RowBreak {};
struct OutputFlush {}; struct OutputFlush {};
class Duration { class Duration {
enum class Unit : uint8_t { enum class Unit {
Auto, Auto,
Nanoseconds, Nanoseconds,
Microseconds, Microseconds,
@@ -9183,10 +9180,7 @@ public:
}; };
} // end anon namespace } // end anon namespace
enum class Justification : uint8_t { enum class Justification { Left, Right };
Left,
Right
};
struct ColumnInfo { struct ColumnInfo {
std::string name; std::string name;

View File

@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// Catch v3.8.1 // Catch v3.7.1
// Generated: 2025-04-08 12:33:19.851017 // Generated: 2024-09-17 10:36:40.974985
// ---------------------------------------------------------- // ----------------------------------------------------------
// This file is an amalgamation of multiple different files. // This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly. // You probably shouldn't edit it directly.
@@ -150,7 +150,7 @@
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ # define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
_Pragma( "GCC diagnostic ignored \"-Wshadow\"" ) _Pragma( "GCC diagnostic ignored \"-Wshadow\"" )
# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
#endif #endif
@@ -174,45 +174,14 @@
// clang-cl defines _MSC_VER as well as __clang__, which could cause the // clang-cl defines _MSC_VER as well as __clang__, which could cause the
// start/stop internal suppression macros to be double defined. // start/stop internal suppression macros to be double defined.
#if defined(__clang__) && !defined(_MSC_VER) #if defined(__clang__) && !defined(_MSC_VER)
# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
#endif // __clang__ && !_MSC_VER #endif // __clang__ && !_MSC_VER
#if defined(__clang__) #if defined(__clang__)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
# if (__clang_major__ >= 20)
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wvariadic-macro-arguments-omitted\"" )
# elif (__clang_major__ == 19)
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wc++20-extensions\"" )
# else
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
_Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
# endif
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wcomma\"" )
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wshadow\"" )
#endif // __clang__
// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
// which results in calls to destructors being emitted for each temporary, // which results in calls to destructors being emitted for each temporary,
// without a matching initialization. In practice, this can result in something // without a matching initialization. In practice, this can result in something
@@ -229,11 +198,35 @@
// https://developer.nvidia.com/nvidia_bug/3321845. // https://developer.nvidia.com/nvidia_bug/3321845.
// //
// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
#if defined( __ibmxl__ ) || defined( __CUDACC__ ) || defined( __NVCOMPILER ) # if !defined(__ibmxl__) && !defined(__CUDACC__) && !defined( __NVCOMPILER )
# define CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
#endif # endif
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wcomma\"" )
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wshadow\"" )
#endif // __clang__
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// We know some environments not to support full POSIX signals // We know some environments not to support full POSIX signals
@@ -457,22 +450,6 @@
#endif #endif
// The goal of this macro is to avoid evaluation of the arguments, but
// still have the compiler warn on problems inside...
#if defined( CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P ) && \
!defined( CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P ) && !defined(CATCH_CONFIG_USE_BUILTIN_CONSTANT_P)
#define CATCH_CONFIG_USE_BUILTIN_CONSTANT_P
#endif
#if defined( CATCH_CONFIG_USE_BUILTIN_CONSTANT_P ) && \
!defined( CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P )
# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... ) \
(void)__builtin_constant_p( __VA_ARGS__ ) /* NOLINT(cppcoreguidelines-pro-type-vararg, \
hicpp-vararg) */
#else
# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... )
#endif
// Even if we do not think the compiler has that warning, we still have // Even if we do not think the compiler has that warning, we still have
// to provide a macro that can be used by the code. // to provide a macro that can be used by the code.
#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
@@ -509,6 +486,13 @@
# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS # define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS
#endif #endif
// The goal of this macro is to avoid evaluation of the arguments, but
// still have the compiler warn on problems inside...
#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
#endif
#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#elif defined(__clang__) && (__clang_major__ < 5) #elif defined(__clang__) && (__clang_major__ < 5)
@@ -3066,11 +3050,7 @@ struct ratio_string<std::milli> {
#ifdef _MSC_VER #ifdef _MSC_VER
std::tm timeInfo = {}; std::tm timeInfo = {};
const auto err = gmtime_s(&timeInfo, &converted); gmtime_s(&timeInfo, &converted);
if ( err ) {
return "gmtime from provided timepoint has failed. This "
"happens e.g. with pre-1970 dates using Microsoft libc";
}
#else #else
std::tm* timeInfo = std::gmtime(&converted); std::tm* timeInfo = std::gmtime(&converted);
#endif #endif
@@ -7349,7 +7329,7 @@ namespace Catch {
#define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 8 #define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 1 #define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED #endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@@ -8733,7 +8713,7 @@ public:
template <typename InputIterator, template <typename InputIterator,
typename InputSentinel, typename InputSentinel,
typename ResultType = std::remove_const_t<typename std::iterator_traits<InputIterator>::value_type>> typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) { GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to)); return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to));
} }
@@ -12711,65 +12691,56 @@ namespace Catch {
* Creates a matcher that checks if all elements in a range are equal * Creates a matcher that checks if all elements in a range are equal
* to all elements in another range. * to all elements in another range.
* *
* Uses the provided predicate `predicate` to do the comparisons * Uses `std::equal_to` to do the comparison
* (defaulting to `std::equal_to`)
*/ */
template <typename RangeLike, template <typename RangeLike>
typename Equality = decltype( std::equal_to<>{} )> constexpr
std::enable_if_t<!Detail::is_matcher<RangeLike>::value,
RangeEqualsMatcher<RangeLike, std::equal_to<>>>
RangeEquals( RangeLike&& range ) {
return { CATCH_FORWARD( range ), std::equal_to<>{} };
}
/**
* Creates a matcher that checks if all elements in a range are equal
* to all elements in another range.
*
* Uses to provided predicate `predicate` to do the comparisons
*/
template <typename RangeLike, typename Equality>
constexpr constexpr
RangeEqualsMatcher<RangeLike, Equality> RangeEqualsMatcher<RangeLike, Equality>
RangeEquals( RangeLike&& range, RangeEquals( RangeLike&& range, Equality&& predicate ) {
Equality&& predicate = std::equal_to<>{} ) {
return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
} }
/** /**
* Creates a matcher that checks if all elements in a range are equal * Creates a matcher that checks if all elements in a range are equal
* to all elements in an initializer list. * to all elements in another range, in some permutation
* *
* Uses the provided predicate `predicate` to do the comparisons * Uses `std::equal_to` to do the comparison
* (defaulting to `std::equal_to`)
*/ */
template <typename T, template <typename RangeLike>
typename Equality = decltype( std::equal_to<>{} )>
constexpr constexpr
RangeEqualsMatcher<std::initializer_list<T>, Equality> std::enable_if_t<
RangeEquals( std::initializer_list<T> range, !Detail::is_matcher<RangeLike>::value,
Equality&& predicate = std::equal_to<>{} ) { UnorderedRangeEqualsMatcher<RangeLike, std::equal_to<>>>
return { range, CATCH_FORWARD( predicate ) }; UnorderedRangeEquals( RangeLike&& range ) {
return { CATCH_FORWARD( range ), std::equal_to<>{} };
} }
/** /**
* Creates a matcher that checks if all elements in a range are equal * Creates a matcher that checks if all elements in a range are equal
* to all elements in another range, in some permutation. * to all elements in another range, in some permutation.
* *
* Uses the provided predicate `predicate` to do the comparisons * Uses to provided predicate `predicate` to do the comparisons
* (defaulting to `std::equal_to`)
*/ */
template <typename RangeLike, template <typename RangeLike, typename Equality>
typename Equality = decltype( std::equal_to<>{} )>
constexpr constexpr
UnorderedRangeEqualsMatcher<RangeLike, Equality> UnorderedRangeEqualsMatcher<RangeLike, Equality>
UnorderedRangeEquals( RangeLike&& range, UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) {
Equality&& predicate = std::equal_to<>{} ) {
return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
} }
/**
* Creates a matcher that checks if all elements in a range are equal
* to all elements in an initializer list, in some permutation.
*
* Uses the provided predicate `predicate` to do the comparisons
* (defaulting to `std::equal_to`)
*/
template <typename T,
typename Equality = decltype( std::equal_to<>{} )>
constexpr
UnorderedRangeEqualsMatcher<std::initializer_list<T>, Equality>
UnorderedRangeEquals( std::initializer_list<T> range,
Equality&& predicate = std::equal_to<>{} ) {
return { range, CATCH_FORWARD( predicate ) };
}
} // namespace Matchers } // namespace Matchers
} // namespace Catch } // namespace Catch

View File

@@ -8,7 +8,7 @@
project( project(
'catch2', 'catch2',
'cpp', 'cpp',
version: '3.8.1', # CML version placeholder, don't delete version: '3.7.1', # CML version placeholder, don't delete
license: 'BSL-1.0', license: 'BSL-1.0',
meson_version: '>=0.54.1', meson_version: '>=0.54.1',
) )

View File

@@ -1,2 +1 @@
option('tests', type: 'boolean', value: true, description: 'Build the unit tests') option('tests', type: 'boolean', value: true, description: 'Build the unit tests')
option('install', type: 'boolean', value: true, description: 'Install the library')

View File

@@ -634,11 +634,7 @@ struct ratio_string<std::milli> {
#ifdef _MSC_VER #ifdef _MSC_VER
std::tm timeInfo = {}; std::tm timeInfo = {};
const auto err = gmtime_s(&timeInfo, &converted); gmtime_s(&timeInfo, &converted);
if ( err ) {
return "gmtime from provided timepoint has failed. This "
"happens e.g. with pre-1970 dates using Microsoft libc";
}
#else #else
std::tm* timeInfo = std::gmtime(&converted); std::tm* timeInfo = std::gmtime(&converted);
#endif #endif

View File

@@ -36,7 +36,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 3, 8, 1, "", 0 ); static Version version( 3, 7, 1, "", 0 );
return version; return version;
} }

View File

@@ -9,7 +9,7 @@
#define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 8 #define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 1 #define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED #endif // CATCH_VERSION_MACROS_HPP_INCLUDED

View File

@@ -103,16 +103,8 @@
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ # define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
# if (__clang_major__ >= 20) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
_Pragma( "clang diagnostic ignored \"-Wvariadic-macro-arguments-omitted\"" )
# elif (__clang_major__ == 19)
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wc++20-extensions\"" )
# else
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
_Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
# endif
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )

View File

@@ -0,0 +1,17 @@
// 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
#include <catch2/internal/catch_unreachable.hpp>
namespace Catch {
namespace Detail {
void unreachable(){}
}
} // end namespace Catch

View File

@@ -0,0 +1,21 @@
// 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_UNREACHABLE_HPP_INCLUDED
#define CATCH_UNREACHABLE_HPP_INCLUDED
namespace Catch {
namespace Detail {
// TODO: explain
[[noreturn]] void unreachable();
}
} // end namespace Catch
#endif // CATCH_UNREACHABLE_HPP_INCLUDED

View File

@@ -16,7 +16,6 @@ configure_file(
format: 'cmake@', format: 'cmake@',
install_dir: get_option('includedir') / 'catch2', install_dir: get_option('includedir') / 'catch2',
configuration: conf_data, configuration: conf_data,
install: get_option('install')
) )
fs = import('fs') fs = import('fs')
@@ -340,9 +339,7 @@ foreach file : headers
endif endif
endforeach endforeach
if get_option('install') install_headers(file, subdir: join_paths(include_subdir, folder))
install_headers(file, subdir: join_paths(include_subdir, folder))
endif
endforeach endforeach
catch2_dependencies = [] catch2_dependencies = []
@@ -359,7 +356,7 @@ catch2 = static_library(
sources, sources,
dependencies: catch2_dependencies, dependencies: catch2_dependencies,
include_directories: '..', include_directories: '..',
install: get_option('install'), install: true,
) )
catch2_dep = declare_dependency( catch2_dep = declare_dependency(
@@ -367,21 +364,19 @@ catch2_dep = declare_dependency(
include_directories: '..', include_directories: '..',
) )
if get_option('install') pkg.generate(
pkg.generate( catch2,
catch2, filebase: 'catch2',
filebase: 'catch2', description: 'A modern, C++-native, test framework for C++14 and above',
description: 'A modern, C++-native, test framework for C++14 and above', url: 'https://github.com/catchorg/Catch2',
url: 'https://github.com/catchorg/Catch2', )
)
endif
catch2_with_main = static_library( catch2_with_main = static_library(
'Catch2Main', 'Catch2Main',
'internal/catch_main.cpp', 'internal/catch_main.cpp',
link_with: catch2, link_with: catch2,
include_directories: '..', include_directories: '..',
install: get_option('install'), install: true,
) )
catch2_with_main_dep = declare_dependency( catch2_with_main_dep = declare_dependency(
@@ -389,11 +384,9 @@ catch2_with_main_dep = declare_dependency(
include_directories: '..', include_directories: '..',
) )
if get_option('install') pkg.generate(
pkg.generate( catch2_with_main,
catch2_with_main, filebase: 'catch2-with-main',
filebase: 'catch2-with-main', description: 'A modern, C++-native, test framework for C++14 and above (links in default main)',
description: 'A modern, C++-native, test framework for C++14 and above (links in default main)', requires: 'catch2 = ' + meson.project_version(),
requires: 'catch2 = ' + meson.project_version(), )
)
endif

View File

@@ -2,7 +2,7 @@
# Build extra tests. # Build extra tests.
# #
cmake_minimum_required( VERSION 3.16 ) cmake_minimum_required( VERSION 3.10 )
project( Catch2ExtraTests LANGUAGES CXX ) project( Catch2ExtraTests LANGUAGES CXX )

View File

@@ -7,13 +7,10 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_enum_values_registry.hpp> #include <catch2/internal/catch_enum_values_registry.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp> #include <catch2/matchers/catch_matchers_vector.hpp>
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/catch_template_test_macros.hpp> #include <catch2/catch_template_test_macros.hpp>
#include <chrono>
enum class EnumClass3 { Value1, Value2, Value3, Value4 }; enum class EnumClass3 { Value1, Value2, Value3, Value4 };
struct UsesSentinel { struct UsesSentinel {
@@ -98,23 +95,3 @@ TEMPLATE_TEST_CASE( "Stringifying char arrays with statically known sizes",
TestType no_null_terminator[3] = { 'a', 'b', 'c' }; TestType no_null_terminator[3] = { 'a', 'b', 'c' };
CHECK( ::Catch::Detail::stringify( no_null_terminator ) == R"("abc")"s ); CHECK( ::Catch::Detail::stringify( no_null_terminator ) == R"("abc")"s );
} }
TEST_CASE( "#2944 - Stringifying dates before 1970 should not crash", "[.approvals]" ) {
using Catch::Matchers::Equals;
using Days = std::chrono::duration<int32_t, std::ratio<86400>>;
using SysDays = std::chrono::time_point<std::chrono::system_clock, Days>;
Catch::StringMaker<std::chrono::system_clock::time_point> sm;
// Check simple date first
const SysDays post1970{ Days{ 1 } };
auto converted_post = sm.convert( post1970 );
REQUIRE( converted_post == "1970-01-02T00:00:00Z" );
const SysDays pre1970{ Days{ -1 } };
auto converted_pre = sm.convert( pre1970 );
REQUIRE_THAT(
converted_pre,
Equals( "1969-12-31T00:00:00Z" ) ||
Equals( "gmtime from provided timepoint has failed. This "
"happens e.g. with pre-1970 dates using Microsoft libc" ) );
}

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.10)
project(discover-tests-test project(discover-tests-test
LANGUAGES CXX LANGUAGES CXX
@@ -19,11 +19,4 @@ if (CMAKE_VERSION GREATER_EQUAL 3.27)
DL_PATHS "${CMAKE_CURRENT_LIST_DIR};${CMAKE_CURRENT_LIST_DIR}/.." DL_PATHS "${CMAKE_CURRENT_LIST_DIR};${CMAKE_CURRENT_LIST_DIR}/.."
) )
endif () endif ()
catch_discover_tests( catch_discover_tests(tests ${extra_args})
tests
ADD_TAGS_AS_LABELS
DISCOVERY_MODE PRE_TEST
${extra_args}
)
# DISCOVERY_MODE <POST_BUILD|PRE_TEST>

View File

@@ -12,10 +12,6 @@ import subprocess
import sys import sys
import re import re
import json import json
from collections import namedtuple
from typing import List
TestInfo = namedtuple('TestInfo', ['name', 'tags'])
cmake_version_regex = re.compile('cmake version (\d+)\.(\d+)\.(\d+)') cmake_version_regex = re.compile('cmake version (\d+)\.(\d+)\.(\d+)')
@@ -65,7 +61,7 @@ def build_project(sources_dir, output_base_path, catch2_path):
def get_test_names(build_path: str) -> List[TestInfo]: def get_test_names(build_path):
# For now we assume that Windows builds are done using MSBuild under # For now we assume that Windows builds are done using MSBuild under
# Debug configuration. This means that we need to add "Debug" folder # Debug configuration. This means that we need to add "Debug" folder
# to the path when constructing it. On Linux, we don't add anything. # to the path when constructing it. On Linux, we don't add anything.
@@ -73,23 +69,15 @@ def get_test_names(build_path: str) -> List[TestInfo]:
full_path = os.path.join(build_path, config_path, 'tests') full_path = os.path.join(build_path, config_path, 'tests')
cmd = [full_path, '--reporter', 'json', '--list-tests'] cmd = [full_path, '--reporter', 'xml', '--list-tests']
result = subprocess.run(cmd, result = subprocess.run(cmd,
capture_output = True, capture_output = True,
check = True, check = True,
text = True) text = True)
test_listing = json.loads(result.stdout) import xml.etree.ElementTree as ET
root = ET.fromstring(result.stdout)
assert test_listing['version'] == 1 return [tc.text for tc in root.findall('TestCase/Name')]
tests = []
for test in test_listing['listings']['tests']:
test_name = test['name']
tags = test['tags']
tests.append(TestInfo(test_name, tags))
return tests
def get_ctest_listing(build_path): def get_ctest_listing(build_path):
old_path = os.getcwd() old_path = os.getcwd()
@@ -103,25 +91,20 @@ def get_ctest_listing(build_path):
os.chdir(old_path) os.chdir(old_path)
return result.stdout return result.stdout
def extract_tests_from_ctest(ctest_output) -> List[TestInfo]: def extract_tests_from_ctest(ctest_output):
ctest_response = json.loads(ctest_output) ctest_response = json.loads(ctest_output)
tests = ctest_response['tests'] tests = ctest_response['tests']
test_infos = [] test_names = []
for test in tests: for test in tests:
test_command = test['command'] test_command = test['command']
# First part of the command is the binary, second is the filter. # First part of the command is the binary, second is the filter.
# If there are less, registration has failed. If there are more, # If there are less, registration has failed. If there are more,
# registration has changed and the script needs updating. # registration has changed and the script needs updating.
assert len(test_command) == 2 assert len(test_command) == 2
test_names.append(test_command[1])
test_name = test_command[1] test_name = test_command[1]
labels = []
for prop in test['properties']:
if prop['name'] == 'LABELS':
labels = prop['value']
test_infos.append(TestInfo(test_name, labels)) return test_names
return test_infos
def check_DL_PATHS(ctest_output): def check_DL_PATHS(ctest_output):
ctest_response = json.loads(ctest_output) ctest_response = json.loads(ctest_output)
@@ -132,14 +115,10 @@ def check_DL_PATHS(ctest_output):
if property['name'] == 'ENVIRONMENT_MODIFICATION': if property['name'] == 'ENVIRONMENT_MODIFICATION':
assert len(property['value']) == 2, f"The test provides 2 arguments to DL_PATHS, but instead found {len(property['value'])}" assert len(property['value']) == 2, f"The test provides 2 arguments to DL_PATHS, but instead found {len(property['value'])}"
def escape_catch2_test_names(infos: List[TestInfo]): def escape_catch2_test_name(name):
escaped = [] for char in ('\\', ',', '[', ']'):
for info in infos: name = name.replace(char, f"\\{char}")
name = info.name return name
for char in ('\\', ',', '[', ']'):
name = name.replace(char, f"\\{char}")
escaped.append(TestInfo(name, info.tags))
return escaped
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) != 3: if len(sys.argv) != 3:
@@ -151,7 +130,7 @@ if __name__ == '__main__':
build_path = build_project(sources_dir, output_base_path, catch2_path) build_path = build_project(sources_dir, output_base_path, catch2_path)
catch_test_names = escape_catch2_test_names(get_test_names(build_path)) catch_test_names = [escape_catch2_test_name(name) for name in get_test_names(build_path)]
ctest_output = get_ctest_listing(build_path) ctest_output = get_ctest_listing(build_path)
ctest_test_names = extract_tests_from_ctest(ctest_output) ctest_test_names = extract_tests_from_ctest(ctest_output)
@@ -168,7 +147,6 @@ if __name__ == '__main__':
if mismatched: if mismatched:
print(f"Found {mismatched} mismatched tests catch test names and ctest test commands!") print(f"Found {mismatched} mismatched tests catch test names and ctest test commands!")
exit(1) exit(1)
print(f"{len(catch_test_names)} tests matched")
cmake_version = get_cmake_version() cmake_version = get_cmake_version()
if cmake_version >= (3, 27): if cmake_version >= (3, 27):

View File

@@ -14,10 +14,3 @@ TEST_CASE( "Let's have a test case with a long name. Longer. No, even longer. "
"Really looooooooooooong. Even longer than that. Multiple lines " "Really looooooooooooong. Even longer than that. Multiple lines "
"worth of test name. Yep, like this." ) {} "worth of test name. Yep, like this." ) {}
TEST_CASE( "And now a test case with weird tags.", "[tl;dr][tl;dw][foo,bar]" ) {} TEST_CASE( "And now a test case with weird tags.", "[tl;dr][tl;dw][foo,bar]" ) {}
// Also check that we handle tests on class, which have name in output as 'class-name', not 'name'.
class TestCaseFixture {
public:
int m_a;
};
TEST_CASE_METHOD(TestCaseFixture, "A test case as method", "[tagstagstags]") {}

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.0)
project(CatchCoverageHelper) project(CatchCoverageHelper)