Compare commits
92 Commits
devel-defa
...
devel
Author | SHA1 | Date | |
---|---|---|---|
|
33e6fd217a | ||
|
a58df2d7c5 | ||
|
a9223b2bb3 | ||
|
363ca5af18 | ||
|
cb6d713774 | ||
|
8e4ab5dd8f | ||
|
8219ed79f2 | ||
|
b3fb4b9fea | ||
|
6500dc8149 | ||
|
4be9de6c54 | ||
|
91b3b3bf40 | ||
|
a00d654437 | ||
|
756ae05d30 | ||
|
a2e41916f2 | ||
|
0e772cc0d2 | ||
|
3bcd0a4e74 | ||
|
f7e7fa0983 | ||
|
b626e4c7ae | ||
|
434bf55d47 | ||
|
9048c24fa7 | ||
|
8ed8c431c6 | ||
|
dc3a4ea41a | ||
|
cd93d202e0 | ||
|
227af796b4 | ||
|
33adb4c779 | ||
|
25319fd304 | ||
|
85c4bad86b | ||
|
582200a1f8 | ||
|
f4e05a67bb | ||
|
fb2e4fbe41 | ||
|
78a9518a28 | ||
|
3e82ef9317 | ||
|
7cad6d7539 | ||
|
644821ce28 | ||
|
03c62cdf2e | ||
|
9a3d68315b | ||
|
bcd4116df7 | ||
|
9b3f508a1b | ||
|
c5e0ef4e67 | ||
|
17fe5eaa5c | ||
|
fbfd13501c | ||
|
ccabd4de89 | ||
|
a1c7ee115f | ||
|
d547cae549 | ||
|
fee81626d2 | ||
|
b6c5a635bb | ||
|
4ed3088190 | ||
|
bdc634e9f1 | ||
|
2a8a8a7210 | ||
|
900a6d5516 | ||
|
1aa6fa215c | ||
|
5aa8d11321 | ||
|
9c5c21df82 | ||
|
10aef62f21 | ||
|
98b4bbb35e | ||
|
8c3ffe05e1 | ||
|
715558fd97 | ||
|
55b14e1b34 | ||
|
ce128f584c | ||
|
db6171a706 | ||
|
c22096846c | ||
|
ae33e5b99a | ||
|
0e8112a762 | ||
|
9be81c0e05 | ||
|
efcb76874e | ||
|
895b8af6bd | ||
|
066f00acf5 | ||
|
1b72e45354 | ||
|
f7968e9697 | ||
|
3ebc346bcb | ||
|
a483b6d7d3 | ||
|
b9c018b38a | ||
|
050e14dce0 | ||
|
6097bd6ee9 | ||
|
b62413aee3 | ||
|
3839e27f05 | ||
|
39c32b9662 | ||
|
2de12cb05f | ||
|
8dc9f1a124 | ||
|
038ee6ea13 | ||
|
bd2d918f32 | ||
|
d134b0cae3 | ||
|
ceed26842b | ||
|
04cbcfa1d1 | ||
|
416b075211 | ||
|
334827eb53 | ||
|
ac207fc90f | ||
|
1de7d0ed7b | ||
|
65cd203926 | ||
|
3013cb897b | ||
|
74fcff6e5b | ||
|
5abfc0aa9c |
4
.bazelrc
@@ -1,10 +1,8 @@
|
||||
# Enable Bzlmod for every Bazel command
|
||||
common --enable_bzlmod
|
||||
|
||||
build --enable_platform_specific_config
|
||||
|
||||
build:gcc9 --cxxopt=-std=c++2a
|
||||
build:gcc11 --cxxopt=-std=c++2a
|
||||
build:gcc13 --cxxopt=-std=c++2a
|
||||
build:clang13 --cxxopt=-std=c++17
|
||||
build:vs2019 --cxxopt=/std:c++17
|
||||
build:vs2022 --cxxopt=/std:c++17
|
||||
|
@@ -78,5 +78,5 @@ WarningsAsErrors: >-
|
||||
readability-duplicate-include,
|
||||
HeaderFilterRegex: '.*\.(c|cxx|cpp)$'
|
||||
FormatStyle: none
|
||||
CheckOptions: {}
|
||||
CheckOptions: []
|
||||
...
|
||||
|
4
.github/workflows/linux-other-builds.yml
vendored
@@ -79,8 +79,6 @@ jobs:
|
||||
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure build
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
cmake --preset basic-tests -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
@@ -106,8 +104,6 @@ jobs:
|
||||
sudo apt-get install -y ninja-build clang-15 clang-tidy-15
|
||||
|
||||
- name: Configure
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
clangtidy="clang-tidy-15;-use-color"
|
||||
# Use a dummy compiler/linker/ar/ranlib to effectively disable the
|
||||
|
8
.github/workflows/linux-simple-builds.yml
vendored
@@ -10,8 +10,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
cxx:
|
||||
- g++-7
|
||||
- g++-8
|
||||
- g++-9
|
||||
- g++-10
|
||||
- g++-11
|
||||
@@ -28,10 +26,6 @@ jobs:
|
||||
build_type: [Debug, Release]
|
||||
std: [14]
|
||||
include:
|
||||
- cxx: g++-7
|
||||
other_pkgs: g++-7
|
||||
- cxx: g++-8
|
||||
other_pkgs: g++-8
|
||||
- cxx: g++-9
|
||||
other_pkgs: g++-9
|
||||
- cxx: g++-10
|
||||
@@ -98,8 +92,6 @@ jobs:
|
||||
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
cmake --preset basic-tests -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
|
2
.github/workflows/windows-simple-builds.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, windows-2022, windows-2025]
|
||||
os: [windows-2022, windows-2025]
|
||||
platform: [Win32, x64]
|
||||
build_type: [Debug, Release]
|
||||
std: [14, 17]
|
||||
|
20
BUILD.bazel
@@ -1,4 +1,20 @@
|
||||
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_license//rules:license.bzl", "license")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = [":license"],
|
||||
)
|
||||
|
||||
exports_files([
|
||||
"LICENSE.MIT",
|
||||
])
|
||||
|
||||
license(
|
||||
name = "license",
|
||||
license_kinds = ["@rules_license//licenses/spdx:BSL-1.0"],
|
||||
license_text = "LICENSE.MIT",
|
||||
)
|
||||
|
||||
expand_template(
|
||||
name = "catch_user_config",
|
||||
@@ -16,6 +32,7 @@ expand_template(
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_STRING_VIEW": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_VARIANT": "",
|
||||
"#cmakedefine CATCH_CONFIG_DEPRECATION_ANNOTATIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_STRINGIFICATION": "",
|
||||
@@ -39,6 +56,7 @@ expand_template(
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_STRING_VIEW": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_VARIANT": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_GETENV": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_GLOBAL_NEXTAFTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_POSIX_SIGNALS": "",
|
||||
@@ -58,6 +76,8 @@ expand_template(
|
||||
"#cmakedefine CATCH_CONFIG_WINDOWS_SEH": "",
|
||||
"#cmakedefine CATCH_CONFIG_USE_BUILTIN_CONSTANT_P": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P": "",
|
||||
"#cmakedefine CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS": "",
|
||||
},
|
||||
template = "src/catch2/catch_user_config.hpp.in",
|
||||
)
|
||||
|
@@ -44,6 +44,8 @@ set(_OverridableOptions
|
||||
"GETENV"
|
||||
"EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT"
|
||||
"USE_BUILTIN_CONSTANT_P"
|
||||
"DEPRECATION_ANNOTATIONS"
|
||||
"EXPERIMENTAL_THREAD_SAFE_ASSERTIONS"
|
||||
)
|
||||
|
||||
foreach(OptionName ${_OverridableOptions})
|
||||
|
@@ -1,10 +1,10 @@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=${prefix}/@lib_dir@
|
||||
pkg_version=@Catch2_VERSION@
|
||||
|
||||
Name: Catch2-With-Main
|
||||
Name: Catch2 with main function
|
||||
Description: A modern, C++-native test framework for C++14 and above (links in default main)
|
||||
URL: https://github.com/catchorg/Catch2
|
||||
Version: ${pkg_version}
|
||||
Requires: catch2 = ${pkg_version}
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lCatch2Main
|
||||
Libs: -L${libdir} -l@lib_name@
|
||||
|
@@ -1,11 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=${prefix}/@include_dir@
|
||||
libdir=${prefix}/@lib_dir@
|
||||
|
||||
Name: Catch2
|
||||
Description: A modern, C++-native, test framework for C++14 and above
|
||||
URL: https://github.com/catchorg/Catch2
|
||||
Version: @Catch2_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lCatch2
|
||||
Libs: -L${libdir} -l@lib_name@
|
||||
|
@@ -20,6 +20,7 @@ cmake_dependent_option(CATCH_BUILD_TESTING "Build the SelfTest project" ON "CATC
|
||||
cmake_dependent_option(CATCH_BUILD_EXAMPLES "Build code examples" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_FUZZERS "Build fuzzers" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_BENCHMARKS "Build the benchmarks" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_WERROR "Enables Werror during build" ON "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_SURROGATES "Enable generating and building surrogate TUs for the main headers" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
@@ -34,7 +35,7 @@ if(CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.8.1 # CML version placeholder, don't delete
|
||||
VERSION 3.11.0 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
HOMEPAGE_URL "https://github.com/catchorg/Catch2"
|
||||
DESCRIPTION "A modern, C++-native, unit test framework."
|
||||
@@ -77,10 +78,15 @@ set(SELF_TEST_DIR ${CATCH_DIR}/tests/SelfTest)
|
||||
# We need to bring-in the variables defined there to this scope
|
||||
add_subdirectory(src)
|
||||
|
||||
if (CATCH_BUILD_BENCHMARKS)
|
||||
set(CMAKE_FOLDER "benchmarks")
|
||||
add_subdirectory(benchmarks)
|
||||
endif()
|
||||
|
||||
# Build tests only if requested
|
||||
if(BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT)
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
if(NOT TARGET Python3::Interpreter)
|
||||
message(FATAL_ERROR "Python not found, but required for tests")
|
||||
endif()
|
||||
set(CMAKE_FOLDER "tests")
|
||||
@@ -103,7 +109,13 @@ if(CATCH_BUILD_FUZZERS)
|
||||
endif()
|
||||
|
||||
if(CATCH_DEVELOPMENT_BUILD)
|
||||
add_warnings_to_targets("${CATCH_WARNING_TARGETS}")
|
||||
set(CATCH_ALL_TARGETS ${CATCH_IMPL_TARGETS} ${CATCH_TEST_TARGETS})
|
||||
add_warnings_to_targets("${CATCH_ALL_TARGETS}")
|
||||
# After we added the noreturn hint to FAIL and SKIP, Clang became
|
||||
# extremely good at diagnosing tests that test these macros as being
|
||||
# noreturn, but not marked as such. This made the warning useless for
|
||||
# our test files.
|
||||
add_cxx_flag_if_supported_to_targets("-Wno-missing-noreturn" "${CATCH_TEST_TARGETS}")
|
||||
endif()
|
||||
|
||||
# Only perform the installation steps when Catch is not being used as
|
||||
@@ -170,23 +182,47 @@ if(NOT_SUBPROJECT)
|
||||
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
|
||||
CACHE PATH "Path where catch2.pc is installed"
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/catch2.pc
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2-with-main.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/catch2-with-main.pc
|
||||
@ONLY
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/catch2.pc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/catch2-with-main.pc"
|
||||
DESTINATION
|
||||
${PKGCONFIG_INSTALL_DIR}
|
||||
|
||||
# Generate the pkg-config files
|
||||
# To understand the script below, you have to understand that it works in two steps.
|
||||
# 1) A CMake script is generated at configuration time
|
||||
# 2) It is executed at install time.
|
||||
# And both of these have access to different parts of the information we need.
|
||||
#
|
||||
# Further, the variables before "[[" are expanded at configuration time,
|
||||
# while the ones inside the [[]] block are expanded at script execution (install) time.
|
||||
string(
|
||||
JOIN "\n"
|
||||
install_script
|
||||
"set(install_pkgconfdir \"${PKGCONFIG_INSTALL_DIR}\")"
|
||||
"set(impl_pc_file \"${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in\")"
|
||||
"set(main_pc_file \"${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2-with-main.pc.in\")"
|
||||
"set(Catch2_VERSION ${Catch2_VERSION})"
|
||||
"set(include_dir \"${CMAKE_INSTALL_INCLUDEDIR}\")"
|
||||
"set(lib_dir \"${CMAKE_INSTALL_LIBDIR}\")"
|
||||
[[
|
||||
message(STATUS "DESTDIR: $ENV{DESTDIR}")
|
||||
set(DESTDIR_PREFIX "")
|
||||
if (DEFINED ENV{DESTDIR})
|
||||
set(DESTDIR_PREFIX "$ENV{DESTDIR}")
|
||||
endif ()
|
||||
message(STATUS "PREFIX: ${DESTDIR_PREFIX}")
|
||||
set(lib_name "$<TARGET_FILE_BASE_NAME:Catch2>")
|
||||
configure_file(
|
||||
"${impl_pc_file}"
|
||||
"${DESTDIR_PREFIX}${CMAKE_INSTALL_PREFIX}/${install_pkgconfdir}/catch2.pc"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
set(lib_name "$<TARGET_FILE_BASE_NAME:Catch2WithMain>")
|
||||
configure_file(
|
||||
"${main_pc_file}"
|
||||
"${DESTDIR_PREFIX}${CMAKE_INSTALL_PREFIX}/${install_pkgconfdir}/catch2-with-main.pc"
|
||||
@ONLY
|
||||
)
|
||||
]]
|
||||
)
|
||||
install(CODE "${install_script}")
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/")
|
||||
|
||||
|
@@ -15,14 +15,23 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "all-tests",
|
||||
"name": "most-tests",
|
||||
"inherits": "basic-tests",
|
||||
"displayName": "Full development build",
|
||||
"description": "Enables development build with examples and ALL tests",
|
||||
"description": "Enables development build with extended set of tests (still relatively cheap to build)",
|
||||
"cacheVariables": {
|
||||
"CATCH_BUILD_EXAMPLES": "ON",
|
||||
"CATCH_BUILD_EXTRA_TESTS": "ON",
|
||||
"CATCH_BUILD_SURROGATES": "ON",
|
||||
"CATCH_BUILD_BENCHMARKS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "all-tests",
|
||||
"inherits": "most-tests",
|
||||
"displayName": "Full development build",
|
||||
"description": "Enables development build with examples and ALL tests",
|
||||
"cacheVariables": {
|
||||
"CATCH_ENABLE_CONFIGURE_TESTS": "ON",
|
||||
"CATCH_ENABLE_CMAKE_HELPER_TESTS": "ON"
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
module(name = "catch2")
|
||||
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
bazel_dep(name = "rules_cc", version = "0.0.17")
|
||||
bazel_dep(name = "rules_cc", version = "0.1.1")
|
||||
bazel_dep(name = "rules_license", version = "1.0.0")
|
||||
|
13
README.md
@@ -1,5 +1,16 @@
|
||||
<a id="top"></a>
|
||||

|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td align="center" width="50%"><img src="/data/artwork/catch2-logo-full-with-background.svg" width="100%"></td>
|
||||
<td align="center" width="50%">
|
||||
<figure>
|
||||
<figcaption>Special thanks to:</figcaption>
|
||||
<a href="https://tuple.app/catch2"><img src="/data/sponsors/github_repo_sponsorship.png" width="100%"></a>
|
||||
</figure>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[](https://github.com/catchorg/catch2/releases)
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/linux-simple-builds.yml)
|
||||
|
16
benchmarks/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
include(CatchMiscFunctions)
|
||||
|
||||
add_executable(AssertionsFastPath
|
||||
runtime_assertion_benches.cpp
|
||||
)
|
||||
|
||||
add_executable(AssertionsSlowPath
|
||||
runtime_assertion_benches.cpp
|
||||
assertion_listener.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(AssertionsFastPath PRIVATE Catch2::Catch2WithMain)
|
||||
target_link_libraries(AssertionsSlowPath PRIVATE Catch2::Catch2WithMain)
|
||||
|
||||
list(APPEND CATCH_TEST_TARGETS AssertionsFastPath AssertionsSlowPath)
|
||||
set(CATCH_TEST_TARGETS ${CATCH_TEST_TARGETS} PARENT_SCOPE)
|
28
benchmarks/assertion_listener.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
// 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/reporters/catch_reporter_event_listener.hpp>
|
||||
#include <catch2/reporters/catch_reporter_registrars.hpp>
|
||||
|
||||
/**
|
||||
* Event listener that listens to all assertions, forcing assertion slow path
|
||||
*/
|
||||
class AssertionSlowPathListener : public Catch::EventListenerBase {
|
||||
public:
|
||||
static std::string getDescription() {
|
||||
return "Validates ordering of Catch2's listener events";
|
||||
}
|
||||
|
||||
AssertionSlowPathListener(Catch::IConfig const* config) :
|
||||
EventListenerBase(config) {
|
||||
m_preferences.shouldReportAllAssertions = true;
|
||||
m_preferences.shouldReportAllAssertionStarts = true;
|
||||
}
|
||||
};
|
||||
|
||||
CATCH_REGISTER_LISTENER( AssertionSlowPathListener )
|
27
benchmarks/runtime_assertion_benches.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
// 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/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("Simple REQUIRE - 10M") {
|
||||
for (size_t i = 0; i < 10'000'000; ++i) {
|
||||
REQUIRE(true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Simple NOTHROW - 10M") {
|
||||
for (size_t i = 0; i < 10'000'000; ++i) {
|
||||
REQUIRE_NOTHROW([](){}());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Simple THROWS - 10M") {
|
||||
for (size_t i = 0; i < 10'000'000; ++i) {
|
||||
REQUIRE_THROWS([]() { throw 1; }());
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 10 KiB |
105
data/artwork/catch2-c-logo.svg
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="104.41245mm"
|
||||
height="120.99883mm"
|
||||
viewBox="0 0 101.59999 117.7396"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4-beta (62f545ba5e, 2024-04-22)"
|
||||
sodipodi:docname="catch2-c-logo.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="181"
|
||||
inkscape:cy="192.25"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1411"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-6"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1"
|
||||
inkscape:clip-to-page="false" /><defs
|
||||
id="defs1"><inkscape:path-effect
|
||||
effect="bspline"
|
||||
id="path-effect21"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
weight="33.333333"
|
||||
steps="2"
|
||||
helper_size="0"
|
||||
apply_no_weight="true"
|
||||
apply_with_weight="true"
|
||||
only_selected="false"
|
||||
uniform="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="73.777381,64.846856"
|
||||
end_point="82.510207,65.15"
|
||||
center_point="78.143794,64.998428"
|
||||
id="path-effect17"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="free"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="true"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /></defs><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 1"
|
||||
style="display:inline;opacity:1"><path
|
||||
style="display:inline;opacity:1;fill:#ff2500;fill-opacity:1;stroke:none"
|
||||
d="m 51.144204,74.60863 c 2.755126,3.847649 8.114087,5.089451 12.620377,4.385634 2.354879,-0.367807 8.839176,-2.41493 8.839176,-4.301423 V 61.300036 c 0,-0.274854 -4.644748,-5.35579 -14.139807,-4.033868 -7.781631,0.854243 -12.297148,10.391313 -7.319746,17.342462 z"
|
||||
id="path19" /><path
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none"
|
||||
d="M 51.858331,11.754161 C 41.642983,13.144685 33.527664,20.30548 26.946464,27.781252 13.41997,43.146393 1.1940791,63.412939 0.27499404,84.40209 c -0.2484557,5.673984 0.0720803,11.551339 2.02561406,16.93334 6.4303318,17.71559 27.0809729,18.5262 42.4139739,13.56112 9.635256,-3.12006 19.559145,-9.05196 26.722916,-16.206958 2.544515,-2.541399 6.489211,-6.811827 4.760053,-10.836485 -0.807945,-1.880505 -3.120844,-1.771387 -4.760053,-1.239217 -3.777039,1.226226 -7.054253,3.815005 -10.31875,5.990284 -8.595381,5.727494 -18.582582,10.587386 -29.104166,10.583336 -5.314431,-0.002 -11.064865,-1.53917 -14.276067,-6.085419 C 14.249559,92.162607 14.966246,85.515419 15.941144,79.904173 18.379578,65.869225 26.039129,51.275896 34.494849,39.952087 37.975232,35.291195 43.042486,28.027749 49.477081,27.54157 c 2.673121,-0.201974 4.452111,1.728755 5.613208,3.943849 2.172279,4.144192 2.284401,8.974146 4.143505,13.229168 1.160297,2.655628 3.911041,5.951729 7.175599,4.380934 4.423264,-2.128318 5.563981,-8.759454 5.557271,-13.112185 -0.0164,-10.64231 -7.561412,-25.937074 -20.108333,-24.229175"
|
||||
id="path14" /><path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
d="m 53.953228,68.740885 v -1.206827 h 3.137751 v -3.266479 h 1.174645 v 3.266479 h 3.073387 v 1.206827 h -3.073387 v 3.202116 h -1.174645 v -3.202116 z"
|
||||
id="path15"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
d="m 62.418518,68.740885 v -1.206827 h 3.137751 v -3.266479 h 1.174645 v 3.266479 h 3.073387 v 1.206827 h -3.073387 v 3.202116 h -1.174645 v -3.202116 z"
|
||||
id="path16"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
d="M 85.440222,24.062768 C 86.646399,22.95745 88.272019,22.342526 89.673556,21.247484 94.611094,17.389708 103.0499,9.5981005 101.23198,3.5611216 100.54356,1.2749953 97.954172,0.02851298 95.475242,0.19207103 92.915127,0.3609856 90.311542,1.5166605 88.615222,2.3873449 86.831645,3.3028167 85.048448,3.2384541 84.477375,4.6552681 83.67664,6.6418721 85.77327,9.3242102 87.820455,9.0669662 88.433774,8.9898962 89.041201,8.700584 89.29669,8.1526509 89.865278,6.9332293 90.823337,6.6449856 92.781525,5.7141794 94.684453,4.8096405 96.75508,4.4020758 95.458862,7.6585999 93.598546,12.332323 85.734679,17.924982 80.774891,21.407129 c 0,0 -2.282573,1.504251 -2.853005,1.705572 -1.235548,0.436059 -2.378469,0.514326 -2.192851,1.747903 0.209704,1.393648 1.686087,2.720176 2.912476,2.922238 2.91246,0.479863 3.255425,0.04457 7.857045,0.896861 1.782728,0.330191 4.511564,1.873082 5.236267,1.861978 1.114192,-0.01707 2.38496,-5.01e-4 3.098369,-0.950708 1.003097,-1.336037 0.164345,-3.66292 -1.202522,-4.426382 -2.017657,-1.126959 -6.832185,-0.826419 -8.190448,-1.101823"
|
||||
style="display:inline;opacity:1;fill:#ff2500;fill-opacity:1;stroke:none"
|
||||
id="path1"
|
||||
inkscape:label="path1"
|
||||
sodipodi:nodetypes="csssssssssssssssssc" /><circle
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
id="path20"
|
||||
cx="81.427208"
|
||||
cy="64.690056"
|
||||
r="1.1207407" /><circle
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
id="circle21"
|
||||
cx="81.427208"
|
||||
cy="71.551033"
|
||||
r="1.1207407" /><path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
d="M 73.866479,74.571917 V 61.475751 c 0.716819,0.227562 4.096107,2.192671 4.096107,6.519638 0,4.326967 -3.010942,6.386799 -4.096107,6.576528 z"
|
||||
id="path21"
|
||||
sodipodi:nodetypes="cczc" /><path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
d="m 77.405059,65.799422 3.424802,-1.331236 0.204807,0.933002 -3.652363,1.353992 z"
|
||||
id="path22" /><path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14596;stroke-linecap:round"
|
||||
d="m 77.427815,70.4303 3.094839,1.115049 0.40961,-0.739575 -3.402045,-1.433636 z"
|
||||
id="path23" /></g></svg>
|
After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 33 KiB |
83
data/artwork/catch2-hand-logo.svg
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="221.19167mm"
|
||||
height="254mm"
|
||||
viewBox="0 0 221.19167 254"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4-beta (62f545ba5e, 2024-04-22)"
|
||||
sodipodi:docname="catch2-hand-logo.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="0.75528389"
|
||||
inkscape:cx="423.01975"
|
||||
inkscape:cy="494.51604"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1411"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-6"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer3" /><defs
|
||||
id="defs1" /><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Layer 1"
|
||||
style="display:inline;opacity:1"><path
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.997109"
|
||||
d="m 167.951,135.96691 c 2.74718,3.83654 8.09064,5.07475 12.58391,4.37297 2.34808,-0.36675 8.81363,-2.40795 8.81363,-4.28899 v -13.3541 c 0,-0.27407 -4.63132,-5.34032 -14.09894,-4.02222 -7.75915,0.85177 -12.26161,10.36129 -7.2986,17.29234 z"
|
||||
id="path19" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.997109"
|
||||
d="m 168.66307,73.294073 c -10.18583,1.386506 -18.27769,8.526609 -24.83988,15.980778 -13.4874,15.320749 -25.67797,35.528729 -26.59439,56.457219 -0.24775,5.65759 0.0719,11.51796 2.01975,16.88442 6.41176,17.66439 27.00272,18.47266 42.29142,13.52193 9.6074,-3.11105 19.50262,-9.0258 26.64569,-16.16012 2.53716,-2.53406 6.47045,-6.79215 4.7463,-10.80518 -0.80561,-1.87507 -3.11182,-1.76626 -4.7463,-1.23563 -3.76612,1.22268 -7.03387,3.80398 -10.28893,5.97297 -8.57055,5.71095 -18.52889,10.55679 -29.02007,10.55276 -5.29907,-0.002 -11.03289,-1.53473 -14.23481,-6.06784 -3.47888,-4.92522 -2.76426,-11.55319 -1.79218,-17.14822 2.43139,-13.99439 10.06881,-28.54555 18.5001,-39.83664 3.47032,-4.647428 8.52293,-11.889884 14.93893,-12.374659 2.6654,-0.20139 4.43924,1.72376 5.59699,3.932453 2.166,4.132217 2.2778,8.948216 4.13153,13.190946 1.15694,2.64795 3.89974,5.93453 7.15487,4.36828 4.41048,-2.12217 5.5479,-8.73415 5.5412,-13.074306 -0.0164,-10.611557 -7.53956,-25.862124 -20.05022,-24.159161"
|
||||
id="path14" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
d="m 170.75192,130.11613 v -1.20334 h 3.12868 v -3.25705 h 1.17125 v 3.25705 h 3.0645 v 1.20334 h -3.0645 v 3.19287 h -1.17125 v -3.19287 z"
|
||||
id="path15"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
d="m 179.19274,130.11613 v -1.20334 h 3.12869 v -3.25705 h 1.17125 v 3.25705 h 3.0645 v 1.20334 h -3.0645 v 3.19287 h -1.17125 v -3.19287 z"
|
||||
id="path16"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
d="m 204.99654,83.647387 c 1.20269,-1.102124 2.82361,-1.715271 4.2211,-2.807149 4.92327,-3.846627 13.33769,-11.61572 11.52502,-17.635254 -0.68642,-2.27952 -3.26833,-3.5224 -5.7401,-3.359314 -2.55271,0.168426 -5.14878,1.320761 -6.8402,2.18893 -1.77842,0.912826 -3.55647,0.84865 -4.12589,2.26137 -0.79842,1.980862 1.29215,4.655449 3.33343,4.398949 0.61154,-0.07684 1.21721,-0.365323 1.47197,-0.911673 0.56694,-1.215898 1.52223,-1.503309 3.47476,-2.431425 1.89743,-0.901925 3.96207,-1.308312 2.6696,1.938802 -1.85495,4.660217 -9.69609,10.236715 -14.64154,13.7088 0,0 -2.27598,1.499904 -2.84476,1.700643 -1.23198,0.434799 -2.37159,0.512839 -2.18652,1.742852 0.2091,1.38962 1.68122,2.712316 2.90406,2.913793 2.90404,0.478477 3.24602,0.04444 7.83434,0.89427 1.77758,0.329237 4.49854,1.867669 5.22114,1.856598 1.11097,-0.01702 2.37807,-5e-4 3.08942,-0.947962 1.00019,-1.332175 0.16387,-3.652334 -1.19905,-4.41359 -2.01182,-1.123702 -6.81244,-0.824031 -8.16678,-1.09864"
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.997109"
|
||||
id="path1-4"
|
||||
inkscape:label="path2"
|
||||
sodipodi:nodetypes="csssssssssssssssssc" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
id="path20"
|
||||
cx="198.14651"
|
||||
cy="126.077"
|
||||
r="1.117502" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
id="circle21"
|
||||
cx="198.14651"
|
||||
cy="132.91815"
|
||||
r="1.117502" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
d="m 190.60762,135.93031 v -13.05833 c 0.71475,0.22692 4.08427,2.18634 4.08427,6.50081 0,4.31446 -3.00224,6.36834 -4.08427,6.55752 z"
|
||||
id="path21"
|
||||
sodipodi:nodetypes="cczc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
d="m 194.13597,127.18316 3.41491,-1.32739 0.20422,0.93031 -3.64181,1.35009 z"
|
||||
id="path22" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.145538;stroke-linecap:round"
|
||||
d="m 194.15867,131.80066 3.08589,1.11183 0.40843,-0.73744 -3.39221,-1.42949 z"
|
||||
id="path23" /><path
|
||||
style="opacity:1;fill:#000000"
|
||||
d="m 52.485231,274.30677 c -1.44545,-0.96726 -2.86981,-3.09456 -3.13906,-4.6882 -0.39677,-2.34847 0.81078,-4.39701 5.15499,-8.74518 20.43177,-20.45035 46.487389,-31.49087 92.078009,-39.01608 2.25557,-0.37231 4.92152,-0.92104 5.92434,-1.21941 4.02143,-1.19651 9.24392,-3.85561 19.87253,-10.11836 9.8535,-5.80602 12.12477,-6.79037 15.66794,-6.79037 2.05936,0 4.57269,2.67656 4.57269,4.86966 0,1.68904 -2.6986,6.0579 -4.7121,7.6286 -2.28208,1.78021 -6.58253,4.6015 -11.7076,7.68073 -9.06231,5.44478 -11.98022,6.71427 -21.41534,9.31715 -5.04752,1.39246 -16.38447,4.02852 -25.53267,5.93683 -25.13851,5.24388 -25.00563,5.21162 -29.765619,7.22491 -7.03101,2.97384 -16.88366,8.57665 -28.32629,16.10804 -4.97279,3.27302 -5.23095,3.48606 -6.59919,5.44572 -2.03051,2.90821 -4.81825,5.75178 -6.42266,6.55129 -2.02273,1.00797 -3.9618,0.94437 -5.64997,-0.18533 z M 2.1166706,214.04812 c -4.43974,-1.17966 -6.29001,-2.86592 -6.50258,-5.92618 -0.0561,-0.80826 -0.34243,-2.18306 -0.6362,-3.05512 -0.29378,-0.87205 -0.53414,-2.12574 -0.53414,-2.78598 0,-2.4519 9.57939,-32.76364 14.76039,-46.70584 C 21.897901,121.41582 36.072191,94.814185 53.824111,71.834375 c 11.92384,-15.435387 26.74991,-30.208723 41.2936,-41.146727 5.899709,-4.437045 11.752929,-7.682035 15.523289,-8.606009 2.83253,-0.694146 6.49309,-0.456289 8.54715,0.55538 0.86947,0.428233 2.07876,1.254856 2.6873,1.836939 1.24377,1.189682 1.58018,2.435151 1.36349,5.048044 -0.19501,2.351645 -1.01118,3.232511 -6.23188,6.725914 -2.50094,1.67349 -7.49666,5.375621 -11.10159,8.226959 -8.626469,6.823143 -12.675559,9.813426 -18.592969,13.731047 -4.5713,3.026431 -5.19257,3.540143 -9.40057,7.773067 -6.75068,6.79066 -18.35611,20.995666 -21.41793,26.215466 -7.26888,12.392015 -19.02869,38.165965 -27.46982,60.205545 -7.14782,18.66277 -15.28897,43.14897 -16.8808,50.77253 -1.36968,6.55961 -2.3943804,8.86415 -4.6390304,10.43312 -1.42141,0.99355 -2.86689,1.11226 -5.38768,0.44247 z M 84.451711,131.53763 c -2.71586,-1.44798 -4.39099,-4.45284 -3.91041,-7.01452 0.22361,-1.19197 2.16953,-4.12452 4.94017,-7.44499 2.77937,-3.33091 13.49664,-14.08622 17.176859,-17.237833 20.86316,-17.866412 44.82366,-30.594172 72.62813,-38.579882 13.98648,-4.017052 21.64688,-4.578234 28.9691,-2.122202 2.68998,0.902278 3.92015,1.642753 4.93107,2.968151 2.42706,3.182092 1.37728,7.464086 -2.28839,9.334167 -1.72612,0.880603 -5.30307,1.720503 -18.52445,4.349714 -34.65213,6.890939 -45.21368,10.483785 -64.01962,21.778305 -4.90594,2.94642 -12.73144,8.97117 -19.60898,15.0967 -4.21536,3.75444 -5.629099,5.40595 -7.922789,9.25525 -2.61622,4.39059 -3.64884,5.89007 -5.11311,7.42481 -2.32969,2.44183 -5.17662,3.30181 -7.25758,2.19233 z m -19.34134,-7.37312 c -0.67308,-0.23773 -1.75582,-0.98544 -2.55596,-1.76505 -1.563,-1.52288 -2.12938,-2.99059 -1.84499,-4.78105 0.49788,-3.13453 6.69521,-13.63592 13.12251,-22.236119 17.01101,-22.761971 41.464519,-41.822254 69.705419,-54.331885 8.97055,-3.973604 14.33402,-5.413308 20.23973,-5.432901 6.16545,-0.02045 10.0683,1.082726 12.13437,3.429906 2.78341,3.162114 2.82958,6.444745 0.12416,8.826153 -1.53485,1.351031 -4.80881,2.63842 -18.21165,7.161207 -31.8573,10.75024 -42.5879,16.147741 -58.492839,29.421967 -5.67746,4.738392 -13.21765,12.843914 -18.77808,20.185972 -2.50637,3.30944 -3.41949,5.02515 -5.06932,9.525 -2.27988,6.21828 -3.86567,8.69854 -6.28046,9.823 -1.53672,0.71558 -2.4493,0.75433 -4.09289,0.1738 z"
|
||||
id="path1"
|
||||
sodipodi:nodetypes="sssssssssssssssssscssssssssssssssssssssscssssssssssssssssssssssss"
|
||||
transform="translate(5.8208328,-21.43125)" /></g></svg>
|
After Width: | Height: | Size: 9.1 KiB |
104
data/artwork/catch2-logo-full-with-background.svg
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="145.25626mm"
|
||||
height="76.199997mm"
|
||||
viewBox="0 0 145.25626 76.199997"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.4-beta (62f545ba5e, 2024-04-22)"
|
||||
sodipodi:docname="catch2-logo-full-with-background.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="2.1362654"
|
||||
inkscape:cx="260.73539"
|
||||
inkscape:cy="75.599221"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1411"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-6"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1" /><defs
|
||||
id="defs1"><inkscape:path-effect
|
||||
effect="bspline"
|
||||
id="path-effect3"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
weight="33.333333"
|
||||
steps="2"
|
||||
helper_size="0"
|
||||
apply_no_weight="true"
|
||||
apply_with_weight="true"
|
||||
only_selected="false"
|
||||
uniform="false" /></defs><path
|
||||
style="display:inline;opacity:1;fill:#ffffff;stroke-width:0.15;stroke-linecap:round"
|
||||
d="m 20.956995,75.891056 c -0.345757,0 -1.03727,0 -1.868118,-0.381881 -0.830849,-0.38188 -1.801033,-1.145642 -2.611239,-1.78039 -0.810207,-0.634747 -1.460436,-1.140482 -2.141629,-2.265482 -0.681193,-1.125 -1.393348,-2.869267 -2.275802,-4.458716 C 11.177753,65.415137 10.125,63.980505 9.288991,63.18578 8.4529816,62.391055 7.8337157,62.236239 6.9719037,61.730505 6.1100917,61.224771 5.005734,60.36812 4.3142201,59.790138 3.6227063,59.212156 3.3440368,58.912844 2.7521924,58.147933 2.1603479,57.383023 1.2553288,56.152515 0.80464381,54.814747 0.35395881,53.476979 0.35760785,52.03195 0.54006088,50.402645 0.72251392,48.773339 1.0837708,46.959757 1.6841117,44.78319 c 0.600341,-2.176566 1.4397661,-4.716117 2.4787447,-7.477291 1.0389785,-2.761174 2.2775105,-5.743971 3.7379462,-8.690646 1.4604358,-2.946674 3.1427754,-5.857225 4.9334864,-8.581996 1.790711,-2.724771 3.689793,-5.263761 5.90883,-7.756307 2.219037,-2.492546 4.758028,-4.9386471 6.873854,-6.7138764 2.115825,-1.7752293 3.808486,-2.8795875 5.294724,-3.6227067 1.486239,-0.7431192 2.766056,-1.12499991 3.627868,-1.34174306 0.861812,-0.21674314 1.305618,-0.26834858 2.002293,-0.24770639 0.696674,0.0206422 1.646216,0.11353208 3.240826,0.46961002 1.59461,0.35607793 3.834289,0.97534413 5.692086,1.43463303 1.857798,0.4592889 3.333716,0.758601 4.226491,0.9392202 0.892775,0.1806192 1.202408,0.2425458 1.708142,0.4076835 0.505734,0.1651376 1.207568,0.4334861 1.888761,0.7276375 0.681193,0.2941515 1.341744,0.6141056 2.14679,1.0837157 0.805046,0.4696101 1.754587,1.0888762 2.564794,1.6462156 0.810206,0.5573395 1.481078,1.0527523 2.327409,1.6616971 0.84633,0.6089449 1.86812,1.3314219 2.52867,1.7855509 0.660551,0.454128 0.959862,0.639908 1.486238,1.13016 0.526376,0.490253 1.279815,1.284977 2.012613,1.986812 0.732798,0.701835 1.444954,1.31078 1.955848,1.759748 0.510895,0.448968 0.820528,0.737959 1.739106,1.290138 0.918578,0.552179 2.446102,1.367546 3.860093,1.661697 1.413991,0.294152 2.71445,0.06709 3.530437,-0.08893 0.815986,-0.15602 1.147498,-0.240994 2.178082,-0.626493 1.030584,-0.385499 2.760238,-1.071523 4.061129,-1.628004 1.30089,-0.556482 2.192163,-0.992796 2.978809,-1.214324 0.786645,-0.221529 1.541055,-0.248227 2.342041,-0.216499 0.800986,0.03173 1.690589,0.123491 2.387555,0.320239 0.696966,0.196747 1.263209,0.515637 2.793374,1.465114 1.530165,0.949478 4.037903,2.537347 5.959128,3.296351 1.92123,0.759005 3.25679,0.689673 4.91893,0.56378 1.66215,-0.125892 3.65089,-0.308346 5.73086,-1.636604 2.07996,-1.328258 4.25115,-3.80232 5.64509,-5.265593 1.39394,-1.463273 2.01063,-1.915757 3.01777,-2.432099 1.00714,-0.516342 2.40473,-1.0965425 3.9574,-1.6530243 1.55268,-0.5564818 3.26044,-1.0892445 4.73466,-1.6694444 1.47422,-0.5801999 2.71491,-1.2078409 3.99573,-1.6384293 1.28082,-0.4305884 2.60178,-0.6641283 3.75853,-0.7407587 1.15675,-0.07663 2.1493,0.00365 3.1017,0.3466601 0.9524,0.3430107 1.86467,0.9487579 2.56894,1.5143606 0.70426,0.5656028 1.20054,1.0910709 1.68951,1.7989884 0.48898,0.7079176 0.97065,1.5982856 1.26623,2.8791066 0.29557,1.280821 0.40505,2.95209 0.11312,5.079492 -0.29192,2.127402 -0.98525,4.710938 -1.51071,7.049986 -0.52547,2.339048 -0.88307,4.433606 -0.88672,6.758058 -0.004,2.324452 0.34666,4.878795 0.85388,7.46233 0.50722,2.583535 1.17134,5.196259 1.45962,7.133911 0.28827,1.937653 0.2007,3.200226 -0.51087,4.627009 -0.71157,1.426784 -2.04712,3.01777 -3.52499,3.857055 -1.47787,0.839284 -3.10388,0.927177 -5.00548,0.843658 -1.90159,-0.08352 -4.13587,-0.343101 -6.08337,-0.281904 -1.94751,0.0612 -3.72418,0.445924 -5.61643,0.945314 -1.89226,0.499389 -3.93016,1.120257 -7.01361,1.499759 -3.08346,0.379502 -7.21419,0.518166 -11.35952,0.499921 -4.14534,-0.01825 -8.305268,-0.1934 -12.516283,-0.218943 -4.211016,-0.02554 -8.473119,0.09853 -12.950516,0.135015 -4.477396,0.03649 -9.170088,-0.0146 -11.88134,0.08028 -2.711251,0.09488 -3.441064,0.335715 -4.495642,0.864829 -1.054578,0.529114 -2.433923,1.346502 -3.692849,2.21133 -1.258925,0.864827 -2.397433,1.777092 -3.638113,2.557992 -1.240681,0.780899 -2.583535,1.430431 -3.959231,2.014281 -1.375696,0.583849 -2.784233,1.102015 -4.966371,1.726004 -2.182138,0.62399 -5.137876,1.353802 -7.425836,2.010633 -2.287961,0.656831 -3.908144,1.24068 -5.094089,1.718707 -1.185945,0.478026 -1.937652,0.850231 -2.981283,1.426783 -1.043632,0.576551 -2.379187,1.357451 -3.473905,2.028878 -1.094718,0.671427 -1.948598,1.233381 -2.729497,1.572744 -0.780899,0.339362 -1.488816,0.456133 -2.20046,0.515384 -0.711644,0.05925 -1.427013,0.06099 -1.784698,0.06185 -0.357685,8.67e-4 -0.357685,8.69e-4 -0.703442,8.69e-4 z"
|
||||
id="path3"
|
||||
inkscape:path-effect="#path-effect3"
|
||||
inkscape:original-d="m 21.302752,75.891056 c -0.691514,0 -1.383027,0 -2.074541,0 -0.970183,-0.763761 -1.940367,-1.527523 -2.91055,-2.291284 -0.65023,-0.505734 -1.300459,-1.011469 -1.950689,-1.517203 C 13.654816,70.338303 12.942661,68.594036 12.230505,66.84977 11.177753,65.415137 10.125,63.980505 9.0722478,62.545872 8.4529817,62.391055 7.8337156,62.236239 7.2144495,62.081422 6.1100917,61.224771 5.005734,60.36812 3.9013762,59.511469 3.6227064,59.212156 3.3440367,58.912844 3.0653669,58.613531 2.1603479,57.383023 1.2553288,56.152515 0.35030978,54.922007 c 0.003649,-1.445028 0.007298,-2.890057 0.0109471,-4.335085 0.36125697,-1.813583 0.72251392,-3.627165 1.08377092,-5.440748 0.839425,-2.53955 1.6788499,-5.079101 2.5182749,-7.618651 1.2385321,-2.982798 2.4770643,-5.965595 3.7155964,-8.948393 1.6823393,-2.910551 3.3646789,-5.821102 5.0470179,-8.731653 1.899083,-2.538991 3.798165,-5.077981 5.697248,-7.616972 2.538991,-2.446101 5.077982,-4.8922021 7.616973,-7.3383031 1.69266,-1.1043578 3.385321,-2.2087156 5.077981,-3.3130734 1.279817,-0.3818808 2.559634,-0.76376151 3.839451,-1.14564226 0.443807,-0.0516055 0.887613,-0.10321101 1.33142,-0.15481652 0.949542,0.0928899 1.899084,0.18577981 2.848626,0.27866972 2.239678,0.61926606 4.479357,1.23853206 6.719035,1.85779816 1.475917,0.2993119 2.951835,0.5986238 4.427752,0.8979357 0.309633,0.061927 0.619266,0.1238532 0.928899,0.1857798 0.701835,0.2683486 1.403669,0.5366973 2.105504,0.8050459 0.660551,0.3199542 1.321102,0.6399083 1.981653,0.9598625 0.949541,0.619266 1.899082,1.2385321 2.848623,1.8577981 0.670872,0.4954129 1.341744,0.9908257 2.012616,1.4862386 1.021789,0.7224769 2.043579,1.4449538 3.065368,2.1674308 0.299312,0.18578 0.598623,0.37156 0.897935,0.55734 0.75344,0.794725 1.506879,1.589449 2.260319,2.384174 0.712156,0.608945 1.424312,1.21789 2.136468,1.826835 0.309633,0.288991 0.619266,0.577982 0.928899,0.866973 1.527523,0.815367 3.055047,1.630734 4.58257,2.446101 1.300459,-0.227064 2.600918,-0.454129 3.901377,-0.681193 0.331513,-0.08498 0.663026,-0.169949 0.994539,-0.254924 1.729655,-0.686023 3.459309,-1.372047 5.188964,-2.05807 0.872126,-0.42694 1.674426,-1.045002 2.616377,-1.28082 0.720313,-0.02549 1.474723,-0.05219 2.20945,-0.07819 0.867245,0.08946 1.756848,0.18122 2.607953,0.269012 0.606407,0.192807 1.10907,0.624593 1.663328,0.936734 2.546995,1.522183 5.01381,3.174683 7.520715,4.762024 1.33555,-0.06933 2.67111,-0.138664 4.00666,-0.207996 1.98874,-0.182453 3.97748,-0.364907 5.96622,-0.54736 2.17119,-2.474063 4.34238,-4.948125 6.51357,-7.422188 0.61669,-0.452483 1.23338,-0.904967 1.85007,-1.35745 1.39759,-0.580201 2.79518,-1.1604015 4.19277,-1.7406023 1.70776,-0.5327628 3.41552,-1.0655255 5.12328,-1.5982883 1.24068,-0.6276383 2.48137,-1.2552767 3.72205,-1.882915 1.32096,-0.2335398 2.64192,-0.4670797 3.96288,-0.7006195 0.99254,0.080279 1.98509,0.1605585 2.97763,0.2408377 0.91226,0.6057441 1.82453,1.2114881 2.73679,1.8172322 0.49627,0.5254647 0.99255,1.0509294 1.48882,1.5763941 0.48168,0.8903707 0.96335,1.7807411 1.44503,2.6711121 0.10947,1.67127 0.21895,3.342539 0.32842,5.013809 -0.69332,2.583535 -1.38665,5.167069 -2.07997,7.750604 -0.35761,2.094561 -0.71521,4.189121 -1.07282,6.283682 0.35031,2.554342 0.70062,5.108685 1.05093,7.663027 0.66413,2.612727 1.32825,5.225453 1.99238,7.83818 -0.0876,1.262575 -0.17515,2.52515 -0.26273,3.787725 -1.33556,1.59099 -2.67111,3.18198 -4.00667,4.77297 -1.62018,0.08758 -3.23877,0.312749 -4.86055,0.262733 -2.18883,-0.254302 -4.42311,-0.513883 -6.5902,-0.765659 -1.72792,0.37417 -3.50459,0.758897 -5.25465,1.137862 -2.06002,0.53587 -4.07235,1.240681 -6.10852,1.861021 -4.13074,0.138665 -8.26147,0.277329 -12.39221,0.415994 -4.15993,-0.175155 -8.319858,-0.35031 -12.479787,-0.525465 -4.262102,0.124068 -8.524205,0.248137 -12.786307,0.372205 -4.692691,-0.05109 -9.385383,-0.102175 -14.078074,-0.153263 -0.729812,0.240839 -1.459625,0.481678 -2.189437,0.722517 -1.379344,0.817389 -2.758689,1.634777 -4.138033,2.452166 -1.138507,0.912266 -2.277015,1.824531 -3.415522,2.736797 -1.342854,0.649533 -2.685708,1.299065 -4.028562,1.948598 -1.408538,0.518166 -2.817075,1.036332 -4.225613,1.554498 -2.955738,0.729813 -5.911476,1.459625 -8.867214,2.189438 -1.620183,0.583849 -3.240366,1.167698 -4.860549,1.751547 -0.751707,0.372204 -1.503414,0.744409 -2.255121,1.116613 -1.335556,0.780899 -2.671111,1.561799 -4.006667,2.342698 -0.85388,0.561955 -1.70776,1.123909 -2.56164,1.685864 -0.707918,0.11677 -1.415835,0.233541 -2.123753,0.350311 -0.71537,0.0017 -1.430739,0.0035 -2.146109,0.0052 z"
|
||||
sodipodi:nodetypes="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-32.146873,-110.33125)"
|
||||
style="display:inline;opacity:1"><path
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.250889"
|
||||
d="m 80.95419,150.8289 c 0.691236,0.96533 2.035742,1.27689 3.166324,1.10031 0.590818,-0.0922 2.217659,-0.60588 2.217659,-1.07918 v -3.36013 c 0,-0.069 -1.165318,-1.34371 -3.547531,-1.01206 -1.952335,0.21432 -3.085228,2.60709 -1.836452,4.35106 z"
|
||||
id="path19" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.250889"
|
||||
d="m 81.13336,135.05935 c -2.562928,0.34888 -4.598977,2.14544 -6.250134,4.02102 -3.393658,3.85496 -6.461012,8.93964 -6.691599,14.2056 -0.06234,1.42355 0.01809,2.8981 0.508204,4.2484 1.613307,4.44467 6.794341,4.64804 10.641236,3.40234 2.417384,-0.78278 4.907188,-2.27103 6.704505,-4.06615 0.638393,-0.63761 1.628076,-1.70902 1.19425,-2.71876 -0.202704,-0.4718 -0.782987,-0.44442 -1.19425,-0.31091 -0.947618,0.30765 -1.76984,0.95715 -2.588867,1.50289 -2.156496,1.43698 -4.662182,2.65628 -7.301941,2.65526 -1.333335,-5e-4 -2.776062,-0.38616 -3.581718,-1.52678 -0.875345,-1.23926 -0.695536,-2.90697 -0.450943,-4.31477 0.611778,-3.52124 2.533483,-7.18254 4.654937,-10.02357 0.873192,-1.16937 2.144513,-2.99169 3.758888,-3.11367 0.670659,-0.0506 1.116987,0.43373 1.408297,0.98948 0.545003,1.03973 0.573135,2.25152 1.039561,3.31906 0.291107,0.66626 0.981242,1.49322 1.800288,1.09911 1.109752,-0.53395 1.395945,-2.19764 1.39426,-3.28969 -0.0041,-2.67006 -1.897081,-6.50736 -5.044974,-6.07886"
|
||||
id="path14" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 81.65895,149.35674 v -0.30278 h 0.787228 v -0.81953 h 0.294706 v 0.81953 h 0.771081 v 0.30278 h -0.771081 v 0.80337 h -0.294706 v -0.80337 z"
|
||||
id="path15"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 83.782802,149.35674 v -0.30278 h 0.787231 v -0.81953 h 0.294707 v 0.81953 h 0.77108 v 0.30278 h -0.77108 v 0.80337 h -0.294707 v -0.80337 z"
|
||||
id="path16"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
d="m 164.85789,130.59556 c 0.4642,-0.42537 1.08982,-0.66203 1.62919,-1.08343 1.9002,-1.4847 5.14786,-4.48328 4.44823,-6.80658 -0.26492,-0.87983 -1.26145,-1.35951 -2.21547,-1.29658 -0.98523,0.0649 -1.98724,0.50977 -2.64007,0.84484 -0.6864,0.35231 -1.37265,0.32755 -1.59243,0.87281 -0.30817,0.76454 0.49873,1.79683 1.28659,1.69784 0.23602,-0.0295 0.4698,-0.14082 0.56812,-0.35185 0.21882,-0.46933 0.58753,-0.58023 1.34113,-0.93846 0.73235,-0.34812 1.52921,-0.50494 1.03038,0.7483 -0.71596,1.79868 -3.74234,3.95101 -5.65111,5.2911 0,0 -0.87845,0.57891 -1.09797,0.6564 -0.47551,0.16781 -0.91536,0.19794 -0.84393,0.67269 0.0807,0.5363 0.64891,1.04684 1.12086,1.12458 1.12086,0.18468 1.25286,0.0172 3.02378,0.34516 0.68608,0.12686 1.73627,0.72085 2.01516,0.71659 0.4288,-0.006 0.91785,-2e-4 1.19241,-0.36589 0.38604,-0.51416 0.0632,-1.40966 -0.46279,-1.70348 -0.7765,-0.43372 -2.62935,-0.31806 -3.15208,-0.42404"
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.384847"
|
||||
id="path1-4"
|
||||
inkscape:label="path2"
|
||||
sodipodi:nodetypes="csssssssssssssssssc" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
id="path20"
|
||||
cx="88.551903"
|
||||
cy="148.34044"
|
||||
r="0.28118241" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
id="circle21"
|
||||
cx="88.551903"
|
||||
cy="150.06178"
|
||||
r="0.28118241" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 86.654979,150.81969 v -3.2857 c 0.179844,0.0571 1.027671,0.55011 1.027671,1.63571 0,1.0856 -0.755414,1.60237 -1.027671,1.64999 z"
|
||||
id="path21"
|
||||
sodipodi:nodetypes="cczc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 87.542772,148.61874 0.859248,-0.33398 0.05138,0.23408 -0.91634,0.3397 z"
|
||||
id="path22" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 87.548483,149.78059 0.776462,0.27976 0.102767,-0.18555 -0.853537,-0.35969 z"
|
||||
id="path23" /><path
|
||||
style="display:inline;fill:#000000;stroke-width:0.251618"
|
||||
d="m 53.365672,180.24507 c -0.3637,-0.24337 -0.722092,-0.77863 -0.78984,-1.17963 -0.09983,-0.59091 0.204006,-1.10636 1.297083,-2.20043 5.140978,-5.14565 11.697013,-7.92364 23.168383,-9.81711 0.56754,-0.0937 1.238338,-0.23174 1.490665,-0.30682 1.011859,-0.30107 2.325926,-0.97015 5.000265,-2.54594 2.479307,-1.46091 3.050796,-1.70859 3.942317,-1.70859 0.518171,0 1.150566,0.67347 1.150566,1.22529 0,0.425 -0.679012,1.52428 -1.185643,1.91949 -0.57421,0.44794 -1.656275,1.15781 -2.94583,1.9326 -2.280231,1.36999 -3.014427,1.68943 -5.388463,2.34435 -1.27004,0.35037 -4.122609,1.01365 -6.424451,1.4938 -6.325272,1.31945 -6.291838,1.31134 -7.489532,1.81791 -1.769123,0.74828 -4.248215,2.15803 -7.127375,4.05307 -1.251238,0.82355 -1.316194,0.87715 -1.660467,1.37023 -0.51091,0.73176 -1.212354,1.44725 -1.616051,1.64842 -0.508953,0.25361 -0.996853,0.23763 -1.421627,-0.0466 z m -12.67358,-15.16209 c -1.117114,-0.29682 -1.582673,-0.72112 -1.636159,-1.49113 -0.01411,-0.20337 -0.08617,-0.54929 -0.160079,-0.76872 -0.07391,-0.21941 -0.134398,-0.53487 -0.134398,-0.70099 0,-0.61695 2.410337,-8.2439 3.713963,-11.75198 3.193966,-8.59503 6.760455,-15.28845 11.227138,-21.07057 3.000239,-3.88379 6.730729,-7.60101 10.390169,-10.3532 1.484468,-1.11645 2.957235,-1.93293 3.905921,-2.16542 0.712713,-0.17466 1.633772,-0.11481 2.150608,0.13975 0.218773,0.10778 0.523051,0.31574 0.67617,0.46219 0.312953,0.29934 0.3976,0.61273 0.343077,1.27018 -0.04907,0.5917 -0.25443,0.81335 -1.568046,1.69235 -0.629278,0.42108 -1.886286,1.35259 -2.793347,2.07005 -2.170567,1.71681 -3.189387,2.46922 -4.678307,3.45496 -1.150216,0.76149 -1.306538,0.89075 -2.365342,1.95583 -1.698584,1.70864 -4.618708,5.28287 -5.389113,6.59626 -1.828972,3.11804 -4.78794,9.6032 -6.91187,15.14872 -1.798512,4.69589 -3.846964,10.85701 -4.247495,12.77525 -0.344636,1.65049 -0.602466,2.23034 -1.167259,2.62515 -0.357651,0.24998 -0.721358,0.27984 -1.355631,0.11132 z m 20.716887,-20.76104 c -0.683356,-0.36433 -1.104849,-1.1204 -0.983924,-1.76497 0.05627,-0.29992 0.54589,-1.0378 1.243028,-1.87329 0.699338,-0.83811 3.395984,-3.54431 4.32199,-4.33732 5.249523,-4.4955 11.27839,-7.69801 18.274464,-9.70734 3.519236,-1.01076 5.446721,-1.15198 7.289115,-0.53399 0.676845,0.22703 0.986378,0.41335 1.240742,0.74684 0.610689,0.80066 0.346547,1.87808 -0.575798,2.34864 -0.434322,0.22155 -1.334341,0.4329 -4.661064,1.09445 -8.719062,1.73387 -11.376528,2.63789 -16.108419,5.47979 -1.234418,0.74136 -3.203445,2.2573 -4.93395,3.79859 -1.060656,0.94467 -1.416377,1.36021 -1.993509,2.32877 -0.658285,1.10475 -0.91811,1.48204 -1.286545,1.86821 -0.58619,0.6144 -1.302525,0.83079 -1.82613,0.55162 z m -4.866609,-1.8552 c -0.169358,-0.0598 -0.441793,-0.24795 -0.643122,-0.44412 -0.393278,-0.38317 -0.535787,-0.75247 -0.464232,-1.20299 0.125276,-0.7887 1.684629,-3.43102 3.301847,-5.59497 4.280257,-5.7273 10.433175,-10.52319 17.539062,-13.67083 2.257142,-0.99983 3.606682,-1.36208 5.092658,-1.367 1.551331,-0.005 2.533355,0.27242 3.053214,0.86301 0.700352,0.79565 0.711968,1.62161 0.03125,2.22082 -0.386196,0.33993 -1.209978,0.66386 -4.58236,1.80187 -8.015835,2.70495 -10.715836,4.06305 -14.717787,7.40307 -1.428546,1.19226 -3.325785,3.23175 -4.724883,5.07912 -0.630645,0.83273 -0.860401,1.26441 -1.275526,2.39667 -0.573656,1.56462 -0.972669,2.18868 -1.580271,2.47163 -0.386663,0.18004 -0.616285,0.18979 -1.02984,0.0437 z"
|
||||
id="path1"
|
||||
sodipodi:nodetypes="sssssssssssssssssscssssssssssssssssssssscssssssssssssssssssssssss" /><path
|
||||
style="display:inline;fill:#000000"
|
||||
d="m 133.48506,160.85705 c -1.47006,-0.34869 -2.86219,-1.46379 -3.53601,-2.83237 -0.53009,-1.07667 -0.6102,-1.73748 -0.61653,-3.78777 -0.011,-3.55286 1.28597,-6.9802 3.99822,-10.78446 3.43411,-4.81674 7.24916,-6.89675 9.52931,-5.1955 1.72479,1.2869 2.67857,4.71416 1.81712,6.52955 -0.91147,1.92077 -2.00698,1.48885 -2.77637,-1.09461 -0.2958,-0.99324 -0.76382,-2.01041 -1.04004,-2.2604 -1.06699,-0.9656 -3.02778,0.57303 -5.16237,4.05092 -2.47566,4.03359 -3.69767,8.15661 -3.01852,10.18444 0.54006,1.61256 1.47424,2.14444 3.73914,2.12893 2.12704,-0.0146 3.80866,-0.64763 6.67945,-2.51452 1.66456,-1.08247 2.6727,-1.3143 2.91942,-0.67136 0.40619,1.05851 -1.98505,3.43599 -4.97282,4.94421 -2.71974,1.37292 -5.35218,1.82661 -7.56,1.30294 z m -26.78525,-0.34019 c -1.00102,-0.4946 -2.07206,-2.89401 -2.37957,-5.33083 -0.14531,-1.15147 -0.29901,-2.12839 -0.34156,-2.17094 -0.0425,-0.0425 -0.6917,0.63471 -1.44256,1.50503 -5.097966,5.90905 -10.482428,7.32464 -12.29287,3.23184 -1.649103,-3.72807 1.189051,-10.83392 6.372938,-15.95586 2.290109,-2.26273 4.183682,-3.38708 6.083252,-3.61206 1.87581,-0.22216 2.58127,0.036 3.3272,1.21764 0.43316,0.68618 0.91266,1.08745 1.43709,1.20263 1.44053,0.3164 1.4918,0.5906 0.83147,4.44616 -0.77497,4.52496 -0.95582,7.82865 -0.5391,9.8479 0.26514,1.28476 0.52698,1.77788 1.37305,2.58583 1.26224,1.20536 1.25691,1.90371 -0.0211,2.76289 -1.01949,0.68539 -1.46589,0.7354 -2.40826,0.26977 z m -10.504047,-4.06394 c 2.39178,-1.21409 6.010807,-5.18201 7.530037,-8.25596 0.84799,-1.7158 0.96989,-2.20587 0.97911,-3.93623 0.009,-1.76456 -0.0564,-2.03067 -0.6141,-2.48242 -0.34354,-0.27829 -0.91383,-0.50598 -1.26731,-0.50598 -2.55868,0 -7.424923,5.64575 -9.066579,10.51894 -1.294302,3.84207 -0.172132,5.98701 2.438842,4.66165 z m 20.405737,3.87902 c -1.50995,-0.76805 -2.28207,-2.23504 -2.43136,-4.61949 -0.0912,-1.45637 0.0947,-2.89929 0.83642,-6.49387 1.31879,-6.39083 1.39459,-5.96188 -1.05348,-5.96188 -1.79007,0 -2.06198,-0.0676 -2.51357,-0.62462 -0.57501,-0.7093 -0.65793,-1.63152 -0.18886,-2.10059 0.20399,-0.20399 1.24978,-0.3175 2.92529,-0.3175 h 2.60779 l 0.49503,-1.12448 c 0.27227,-0.61846 0.80837,-2.36434 1.19133,-3.87972 0.93274,-3.69084 1.24255,-4.25731 2.32558,-4.25216 0.99699,0.005 1.32698,0.18687 1.73146,0.95566 0.23837,0.45307 0.10873,1.24024 -0.66474,4.03611 -0.52847,1.91029 -0.90529,3.52883 -0.83737,3.59675 0.0679,0.0679 1.20789,0.002 2.53328,-0.14556 1.32538,-0.14798 3.28341,-0.23385 4.35117,-0.19084 l 1.94138,0.0782 0.0795,0.94868 c 0.0522,0.62233 -0.0652,1.06877 -0.34106,1.29774 -0.23669,0.19645 -1.87597,0.49966 -3.74941,0.69353 -4.15959,0.43044 -5.47316,0.62595 -5.87528,0.87448 -0.38262,0.23647 -2.08696,7.65943 -2.31923,10.10102 -0.17528,1.84246 0.15441,3.38458 0.84635,3.95884 0.56488,0.46881 2.24338,0.39367 3.28943,-0.14727 0.49891,-0.258 1.66261,-1.04814 2.58598,-1.75587 1.71946,-1.31789 2.60511,-1.59187 2.8747,-0.88931 0.31079,0.80989 -0.24712,1.89088 -1.71559,3.3241 -2.85613,2.78757 -6.50841,3.86714 -8.92476,2.63804 z m 31.63789,-0.2742 c -0.29104,-0.29104 -0.52916,-0.76168 -0.52916,-1.04587 0,-0.2842 0.40859,-2.75474 0.90798,-5.49011 1.14588,-6.27647 2.06795,-12.24512 2.93464,-18.99631 0.79357,-6.18156 1.28854,-7.61865 2.67041,-7.75318 0.6526,-0.0635 0.96978,0.0924 1.52135,0.7479 1.14432,1.35994 0.92382,3.48988 -1.30042,12.56153 -1.19529,4.87502 -2.76521,12.47087 -2.76521,13.37907 0,0.67095 0.58017,0.0743 1.46322,-1.50471 1.77764,-3.17873 4.68194,-7.30062 6.31849,-8.96744 2.7637,-2.81483 5.25631,-3.57476 6.57703,-2.00518 0.7946,0.94434 1.09911,2.12146 1.64895,6.3743 0.6711,5.19068 1.02259,6.40843 2.52592,8.75117 0.92415,1.44017 0.94813,1.66501 0.2518,2.36133 -0.76353,0.76353 -2.14817,0.69113 -3.1663,-0.16557 -1.5783,-1.32805 -2.14482,-3.12236 -2.66271,-8.43339 -0.33195,-3.40418 -0.45519,-4.02701 -0.95544,-4.82864 -1.22199,-1.9582 -4.06707,1.17361 -9.63303,10.60387 -2.31481,3.92193 -3.2163,4.9404 -4.37293,4.9404 -0.55264,0 -1.1116,-0.20618 -1.43459,-0.52917 z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="ssssssscsssssssssssssssssssssssssssssssssssscsscssssscsssssssssssssssssssscsssssssssss" /></g></svg>
|
After Width: | Height: | Size: 23 KiB |
88
data/artwork/catch2-logo-full.svg
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="132.82083mm"
|
||||
height="64.029167mm"
|
||||
viewBox="0 0 132.82083 64.029167"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4-beta (62f545ba5e, 2024-04-22)"
|
||||
sodipodi:docname="catch2-logo.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="2.1362654"
|
||||
inkscape:cx="252.77758"
|
||||
inkscape:cy="71.854367"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1411"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-6"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" /><defs
|
||||
id="defs1" /><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-38.629169,-116.41666)"
|
||||
style="display:inline;opacity:1"><path
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.250889"
|
||||
d="m 81.146047,150.57948 c 0.691236,0.96533 2.035742,1.27689 3.166324,1.10031 0.590818,-0.0922 2.217659,-0.60588 2.217659,-1.07918 v -3.36013 c 0,-0.069 -1.165318,-1.34371 -3.547531,-1.01206 -1.952335,0.21432 -3.085228,2.60709 -1.836452,4.35106 z"
|
||||
id="path19" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.250889"
|
||||
d="m 81.325217,134.80993 c -2.562928,0.34888 -4.598977,2.14544 -6.250134,4.02102 -3.393658,3.85496 -6.461012,8.93964 -6.691599,14.2056 -0.06234,1.42355 0.01809,2.8981 0.508204,4.2484 1.613307,4.44467 6.794341,4.64804 10.641236,3.40234 2.417384,-0.78278 4.907188,-2.27103 6.704505,-4.06615 0.638393,-0.63761 1.628076,-1.70902 1.19425,-2.71876 -0.202704,-0.4718 -0.782987,-0.44442 -1.19425,-0.31091 -0.947618,0.30765 -1.76984,0.95715 -2.588867,1.50289 -2.156496,1.43698 -4.662182,2.65628 -7.301941,2.65526 -1.333335,-5e-4 -2.776062,-0.38616 -3.581718,-1.52678 -0.875345,-1.23926 -0.695536,-2.90697 -0.450943,-4.31477 0.611778,-3.52124 2.533483,-7.18254 4.654937,-10.02357 0.873192,-1.16937 2.144513,-2.99169 3.758888,-3.11367 0.670659,-0.0506 1.116987,0.43373 1.408297,0.98948 0.545003,1.03973 0.573135,2.25152 1.039561,3.31906 0.291107,0.66626 0.981242,1.49322 1.800288,1.09911 1.109752,-0.53395 1.395945,-2.19764 1.39426,-3.28969 -0.0041,-2.67006 -1.897081,-6.50736 -5.044974,-6.07886"
|
||||
id="path14" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 81.850807,149.10732 v -0.30278 h 0.787228 v -0.81953 h 0.294706 v 0.81953 h 0.771081 v 0.30278 h -0.771081 v 0.80337 h -0.294706 v -0.80337 z"
|
||||
id="path15"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 83.974659,149.10732 v -0.30278 h 0.787231 v -0.81953 h 0.294707 v 0.81953 h 0.77108 v 0.30278 h -0.77108 v 0.80337 H 84.76189 v -0.80337 z"
|
||||
id="path16"
|
||||
sodipodi:nodetypes="ccccccccccccc" /><path
|
||||
d="m 165.04975,130.34614 c 0.4642,-0.42537 1.08982,-0.66203 1.62919,-1.08343 1.9002,-1.4847 5.14786,-4.48328 4.44823,-6.80658 -0.26492,-0.87983 -1.26145,-1.35951 -2.21547,-1.29658 -0.98523,0.0649 -1.98724,0.50977 -2.64007,0.84484 -0.6864,0.35231 -1.37265,0.32755 -1.59243,0.87281 -0.30817,0.76454 0.49873,1.79683 1.28659,1.69784 0.23602,-0.0295 0.4698,-0.14082 0.56812,-0.35185 0.21882,-0.46933 0.58753,-0.58023 1.34113,-0.93846 0.73235,-0.34812 1.52921,-0.50494 1.03038,0.7483 -0.71596,1.79868 -3.74234,3.95101 -5.65111,5.2911 0,0 -0.87845,0.57891 -1.09797,0.6564 -0.47551,0.16781 -0.91536,0.19794 -0.84393,0.67269 0.0807,0.5363 0.64891,1.04684 1.12086,1.12458 1.12086,0.18468 1.25286,0.0172 3.02378,0.34516 0.68608,0.12686 1.73627,0.72085 2.01516,0.71659 0.4288,-0.006 0.91785,-2e-4 1.19241,-0.36589 0.38604,-0.51416 0.0632,-1.40966 -0.46279,-1.70348 -0.7765,-0.43372 -2.62935,-0.31806 -3.15208,-0.42404"
|
||||
style="display:inline;fill:#ff2500;fill-opacity:1;stroke:none;stroke-width:0.384847"
|
||||
id="path1-4"
|
||||
inkscape:label="path2"
|
||||
sodipodi:nodetypes="csssssssssssssssssc" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
id="path20"
|
||||
cx="88.743759"
|
||||
cy="148.09102"
|
||||
r="0.28118241" /><circle
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
id="circle21"
|
||||
cx="88.743759"
|
||||
cy="149.81236"
|
||||
r="0.28118241" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 86.846836,150.57027 v -3.2857 c 0.179844,0.0571 1.027671,0.55011 1.027671,1.63571 0,1.0856 -0.755414,1.60237 -1.027671,1.64999 z"
|
||||
id="path21"
|
||||
sodipodi:nodetypes="cczc" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 87.734629,148.36932 0.859248,-0.33398 0.05138,0.23408 -0.91634,0.3397 z"
|
||||
id="path22" /><path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0366197;stroke-linecap:round"
|
||||
d="m 87.74034,149.53117 0.776462,0.27976 0.102767,-0.18555 -0.853537,-0.35969 z"
|
||||
id="path23" /><path
|
||||
style="display:inline;fill:#000000;stroke-width:0.251618"
|
||||
d="m 53.557529,179.99565 c -0.3637,-0.24337 -0.722092,-0.77863 -0.78984,-1.17963 -0.09983,-0.59091 0.204006,-1.10636 1.297083,-2.20043 5.140978,-5.14565 11.697013,-7.92364 23.168383,-9.81711 0.56754,-0.0937 1.238338,-0.23174 1.490665,-0.30682 1.011859,-0.30107 2.325926,-0.97015 5.000265,-2.54594 2.479307,-1.46091 3.050796,-1.70859 3.942317,-1.70859 0.518171,0 1.150566,0.67347 1.150566,1.22529 0,0.425 -0.679012,1.52428 -1.185643,1.91949 -0.57421,0.44794 -1.656275,1.15781 -2.94583,1.9326 -2.280231,1.36999 -3.014427,1.68943 -5.388463,2.34435 -1.27004,0.35037 -4.122609,1.01365 -6.424451,1.4938 -6.325272,1.31945 -6.291838,1.31134 -7.489532,1.81791 -1.769123,0.74828 -4.248215,2.15803 -7.127375,4.05307 -1.251238,0.82355 -1.316194,0.87715 -1.660467,1.37023 -0.51091,0.73176 -1.212354,1.44725 -1.616051,1.64842 -0.508953,0.25361 -0.996853,0.23763 -1.421627,-0.0466 z m -12.67358,-15.16209 c -1.117114,-0.29682 -1.582673,-0.72112 -1.636159,-1.49113 -0.01411,-0.20337 -0.08617,-0.54929 -0.160079,-0.76872 -0.07391,-0.21941 -0.134398,-0.53487 -0.134398,-0.70099 0,-0.61695 2.410337,-8.2439 3.713963,-11.75198 3.193966,-8.59503 6.760455,-15.28845 11.227138,-21.07057 3.000239,-3.88379 6.730729,-7.60101 10.390169,-10.3532 1.484468,-1.11645 2.957235,-1.93293 3.905921,-2.16542 0.712713,-0.17466 1.633772,-0.11481 2.150608,0.13975 0.218773,0.10778 0.523051,0.31574 0.67617,0.46219 0.312953,0.29934 0.3976,0.61273 0.343077,1.27018 -0.04907,0.5917 -0.25443,0.81335 -1.568046,1.69235 -0.629278,0.42108 -1.886286,1.35259 -2.793347,2.07005 -2.170567,1.71681 -3.189387,2.46922 -4.678307,3.45496 -1.150216,0.76149 -1.306538,0.89075 -2.365342,1.95583 -1.698584,1.70864 -4.618708,5.28287 -5.389113,6.59626 -1.828972,3.11804 -4.78794,9.6032 -6.91187,15.14872 -1.798512,4.69589 -3.846964,10.85701 -4.247495,12.77525 -0.344636,1.65049 -0.602466,2.23034 -1.167259,2.62515 -0.357651,0.24998 -0.721358,0.27984 -1.355631,0.11132 z m 20.716887,-20.76104 c -0.683356,-0.36433 -1.104849,-1.1204 -0.983924,-1.76497 0.05627,-0.29992 0.54589,-1.0378 1.243028,-1.87329 0.699338,-0.83811 3.395984,-3.54431 4.32199,-4.33732 5.249523,-4.4955 11.27839,-7.69801 18.274464,-9.70734 3.519236,-1.01076 5.446721,-1.15198 7.289115,-0.53399 0.676845,0.22703 0.986378,0.41335 1.240742,0.74684 0.610689,0.80066 0.346547,1.87808 -0.575798,2.34864 -0.434322,0.22155 -1.334341,0.4329 -4.661064,1.09445 -8.719062,1.73387 -11.376528,2.63789 -16.108419,5.47979 -1.234418,0.74136 -3.203445,2.2573 -4.93395,3.79859 -1.060656,0.94467 -1.416377,1.36021 -1.993509,2.32877 -0.658285,1.10475 -0.91811,1.48204 -1.286545,1.86821 -0.58619,0.6144 -1.302525,0.83079 -1.82613,0.55162 z m -4.866609,-1.8552 c -0.169358,-0.0598 -0.441793,-0.24795 -0.643122,-0.44412 -0.393278,-0.38317 -0.535787,-0.75247 -0.464232,-1.20299 0.125276,-0.7887 1.684629,-3.43102 3.301847,-5.59497 4.280257,-5.7273 10.433175,-10.52319 17.539062,-13.67083 2.257142,-0.99983 3.606682,-1.36208 5.092658,-1.367 1.551331,-0.005 2.533355,0.27242 3.053214,0.86301 0.700352,0.79565 0.711968,1.62161 0.03125,2.22082 -0.386196,0.33993 -1.209978,0.66386 -4.58236,1.80187 -8.015835,2.70495 -10.715836,4.06305 -14.717787,7.40307 -1.428546,1.19226 -3.325785,3.23175 -4.724883,5.07912 -0.630645,0.83273 -0.860401,1.26441 -1.275526,2.39667 -0.573656,1.56462 -0.972669,2.18868 -1.580271,2.47163 -0.386663,0.18004 -0.616285,0.18979 -1.02984,0.0437 z"
|
||||
id="path1"
|
||||
sodipodi:nodetypes="sssssssssssssssssscssssssssssssssssssssscssssssssssssssssssssssss" /><path
|
||||
style="fill:#000000"
|
||||
d="m 95.04775,44.190968 c -1.470062,-0.348685 -2.86219,-1.463789 -3.53601,-2.832367 -0.530096,-1.076667 -0.610204,-1.737477 -0.616532,-3.787771 -0.01096,-3.55286 1.285971,-6.980203 3.998224,-10.784456 3.434108,-4.81674 7.249158,-6.896758 9.529308,-5.195505 1.72479,1.286898 2.67857,4.714164 1.81712,6.529548 -0.91147,1.920769 -2.00698,1.488854 -2.77637,-1.094605 -0.2958,-0.993237 -0.76382,-2.010416 -1.04004,-2.260399 -1.06699,-0.965607 -3.02778,0.573029 -5.162374,4.05092 -2.47566,4.033589 -3.697664,8.156608 -3.01852,10.184435 0.540066,1.612562 1.474242,2.144447 3.739143,2.12893 2.127041,-0.01457 3.808661,-0.647627 6.679451,-2.514514 1.66456,-1.082469 2.6727,-1.314304 2.91942,-0.671359 0.40619,1.058506 -1.98505,3.435985 -4.97282,4.944207 -2.719738,1.372918 -5.35218,1.826609 -7.56,1.302936 z M 68.262499,43.850784 c -1.001018,-0.494607 -2.072065,-2.894018 -2.379571,-5.330829 -0.145306,-1.151471 -0.299007,-2.128397 -0.341557,-2.170948 -0.04255,-0.04255 -0.691704,0.634714 -1.442562,1.505034 -5.097967,5.90905 -10.482429,7.324644 -12.292871,3.231839 -1.649103,-3.72807 1.189051,-10.833924 6.372938,-15.955855 2.290109,-2.262738 4.183677,-3.387085 6.08325,-3.612061 1.875807,-0.222162 2.581271,0.03601 3.327199,1.217639 0.433165,0.686179 0.912665,1.087449 1.437088,1.202632 1.44053,0.316394 1.491808,0.590591 0.831478,4.446159 -0.774974,4.524958 -0.955828,7.828642 -0.539105,9.847894 0.265143,1.284765 0.526984,1.777882 1.373056,2.58583 1.262237,1.205362 1.25691,1.903716 -0.02107,2.762891 -1.019495,0.685396 -1.465899,0.735403 -2.408269,0.269775 z M 57.758451,39.78684 c 2.39178,-1.214093 6.010805,-5.182007 7.530034,-8.255959 0.847994,-1.715798 0.969897,-2.205874 0.979113,-3.93623 0.0094,-1.764565 -0.05643,-2.03067 -0.614098,-2.482417 -0.343543,-0.278293 -0.913833,-0.505987 -1.267311,-0.505987 -2.558681,0 -7.424924,5.645757 -9.06658,10.51894 -1.294302,3.842075 -0.172132,5.987013 2.438842,4.661653 z m 20.405739,3.879018 c -1.509951,-0.768049 -2.282068,-2.235036 -2.431367,-4.619485 -0.09119,-1.456372 0.09466,-2.899291 0.836427,-6.49387 1.318788,-6.390829 1.394584,-5.961881 -1.053485,-5.961881 -1.790069,0 -2.061979,-0.06757 -2.513567,-0.624624 -0.57501,-0.709301 -0.657928,-1.631522 -0.188865,-2.100585 0.203993,-0.203993 1.249787,-0.3175 2.925294,-0.3175 h 2.607794 l 0.495029,-1.124479 c 0.272266,-0.618463 0.808364,-2.364341 1.191329,-3.879728 0.932738,-3.690834 1.242549,-4.257301 2.325577,-4.252158 0.99699,0.0047 1.326986,0.186873 1.731464,0.955664 0.23837,0.453069 0.108725,1.240237 -0.664738,4.036104 -0.528474,1.910294 -0.905292,3.528832 -0.837374,3.596751 0.06792,0.06792 1.207892,0.0024 2.533275,-0.145559 1.325383,-0.147975 3.28341,-0.233853 4.351172,-0.190841 l 1.941386,0.07821 0.07952,0.948687 c 0.05217,0.622322 -0.06516,1.068768 -0.341058,1.29774 -0.236699,0.196443 -1.875978,0.499659 -3.749412,0.693525 -4.159592,0.430442 -5.473168,0.625955 -5.875288,0.874479 -0.382617,0.23647 -2.086955,7.659434 -2.319229,10.101025 -0.175277,1.842453 0.154409,3.384573 0.846351,3.958834 0.564887,0.468815 2.243378,0.393671 3.289429,-0.147263 0.498916,-0.258 1.662611,-1.048142 2.585987,-1.755871 1.719461,-1.317895 2.605103,-1.591876 2.874701,-0.889315 0.310783,0.809889 -0.247128,1.890887 -1.715596,3.324104 -2.856133,2.787571 -6.508412,3.867137 -8.92476,2.638041 z m 31.63789,-0.274194 c -0.29104,-0.291042 -0.52916,-0.761687 -0.52916,-1.045878 0,-0.284191 0.40859,-2.754738 0.90798,-5.490105 1.14588,-6.276471 2.06795,-12.245122 2.93464,-18.996309 0.79357,-6.181563 1.28854,-7.618653 2.67041,-7.753186 0.6526,-0.06353 0.96978,0.09239 1.52135,0.747904 1.14432,1.359943 0.92382,3.489885 -1.30042,12.561532 -1.19529,4.87502 -2.76521,12.47087 -2.76521,13.379072 0,0.670944 0.58017,0.07431 1.46322,-1.504712 1.77764,-3.17873 4.68194,-7.300625 6.31849,-8.967446 2.7637,-2.814823 5.25631,-3.574759 6.57703,-2.005173 0.7946,0.944334 1.09911,2.121456 1.64895,6.3743 0.6711,5.190681 1.02259,6.408426 2.52592,8.751165 0.92415,1.440168 0.94813,1.66501 0.2518,2.361335 -0.76353,0.763532 -2.14817,0.691125 -3.1663,-0.165573 -1.5783,-1.32805 -2.14482,-3.122356 -2.66271,-8.433385 -0.33195,-3.404186 -0.45519,-4.027014 -0.95544,-4.828646 -1.22199,-1.958203 -4.06707,1.173608 -9.63303,10.60387 -2.31481,3.921927 -3.2163,4.940401 -4.37293,4.940401 -0.55264,0 -1.1116,-0.206177 -1.43459,-0.529166 z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="ssssssscsssssssssssssssssssssssssssssssssssscsscssssscsssssssssssssssssssscsssssssssss"
|
||||
transform="translate(38.629169,116.41666)" /></g></svg>
|
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB |
BIN
data/sponsors/github_repo_sponsorship.png
Normal file
After Width: | Height: | Size: 264 KiB |
@@ -32,6 +32,7 @@ Once you're up and running consider the following reference material.
|
||||
* [CMake integration](cmake-integration.md#top)
|
||||
* [Tooling integration (CI, test runners, other)](ci-and-misc.md#top)
|
||||
* [Known limitations](limitations.md#top)
|
||||
* [Thread safety in Catch2](thread-safety.md#top)
|
||||
|
||||
**Other:**
|
||||
* [Why Catch2?](why-catch.md#top)
|
||||
|
@@ -66,17 +66,24 @@ test execution. Specifically it understands
|
||||
* JUnit output path via `XML_OUTPUT_FILE`
|
||||
* Test filtering via `TESTBRIDGE_TEST_ONLY`
|
||||
* Test sharding via `TEST_SHARD_INDEX`, `TEST_TOTAL_SHARDS`, and `TEST_SHARD_STATUS_FILE`
|
||||
* Creating a file to signal premature test exit via `TEST_PREMATURE_EXIT_FILE`
|
||||
* Setting the RNG seed via `TEST_RANDOM_SEED`
|
||||
|
||||
> Support for `XML_OUTPUT_FILE` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1
|
||||
|
||||
> Support for `TESTBRIDGE_TEST_ONLY` and sharding was introduced in Catch2 3.2.0
|
||||
|
||||
> Support for `TEST_PREMATURE_EXIT_FILE` and `TEST_RANDOM_SEED` was introduced in Catch2 3.11.0
|
||||
|
||||
This integration is enabled via either a [compile time configuration
|
||||
option](configuration.md#bazel-support), or via `BAZEL_TEST` environment
|
||||
variable set to "1".
|
||||
|
||||
> Support for `BAZEL_TEST` was [introduced](https://github.com/catchorg/Catch2/pull/2459) in Catch2 3.1.0
|
||||
|
||||
Note that if both the Bazel environment var and command line option for
|
||||
something are used, the environment variable wins.
|
||||
|
||||
|
||||
## Low-level tools
|
||||
|
||||
|
@@ -52,7 +52,7 @@ Include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
Catch2
|
||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||
GIT_TAG v3.4.0 # or a later release
|
||||
GIT_TAG v3.8.1 # or a later release
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
|
@@ -32,6 +32,7 @@
|
||||
[Test Sharding](#test-sharding)<br>
|
||||
[Allow running the binary without tests](#allow-running-the-binary-without-tests)<br>
|
||||
[Output verbosity](#output-verbosity)<br>
|
||||
[Create file to guard against silent early termination](#create-file-to-guard-against-silent-early-termination)<br>
|
||||
|
||||
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
|
||||
Click one of the following links to take you straight to that option - or scroll on to browse the available options.
|
||||
@@ -398,18 +399,24 @@ use test specs to filter this list down to what you want first.
|
||||
Test cases are ordered one of three ways:
|
||||
|
||||
### decl
|
||||
Declaration order (this is the default order if no --order argument is provided).
|
||||
Declaration order.
|
||||
|
||||
Tests in the same translation unit are sorted using their declaration orders,
|
||||
different TUs are sorted in an implementation (linking) dependent order.
|
||||
|
||||
|
||||
### lex
|
||||
Lexicographic order. Tests are sorted by their name, their tags are ignored.
|
||||
Lexicographic order.
|
||||
|
||||
Tests are sorted by their name, their tags are ignored.
|
||||
|
||||
|
||||
### rand
|
||||
Randomized order. The default order.
|
||||
|
||||
Randomly ordered. The order is dependent on Catch2's random seed (see
|
||||
> Randomized order has been made default in Catch2 3.9.0
|
||||
|
||||
The order is dependent on Catch2's random seed (see
|
||||
[`--rng-seed`](#rng-seed)), and is subset invariant. What this means
|
||||
is that as long as the random seed is fixed, running only some tests
|
||||
(e.g. via tag) does not change their relative order.
|
||||
@@ -643,6 +650,21 @@ ignored.
|
||||
Verbosity defaults to _normal_.
|
||||
|
||||
|
||||
## Create file to guard against silent early termination
|
||||
<pre>--premature-exit-guard-file <path></pre>
|
||||
|
||||
> Introduced in Catch2 3.11.0
|
||||
|
||||
Tells Catch2 to create an empty file at specified path before the tests
|
||||
start, and delete it after the tests finish. If the file is present after
|
||||
the process stops, it can be assumed that the testing binary exited
|
||||
prematurely, e.g. due to the OOM killer.
|
||||
|
||||
All directories in the path must already exist. If this option is used
|
||||
and Catch2 cannot create the file (e.g. the location is not writable),
|
||||
the test run will fail.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@@ -14,8 +14,10 @@
|
||||
[Other toggles](#other-toggles)<br>
|
||||
[Enabling stringification](#enabling-stringification)<br>
|
||||
[Disabling exceptions](#disabling-exceptions)<br>
|
||||
[Disabling deprecation warnings](#disabling-deprecation-warnings)<br>
|
||||
[Overriding Catch's debug break (`-b`)](#overriding-catchs-debug-break--b)<br>
|
||||
[Static analysis support](#static-analysis-support)<br>
|
||||
[Experimental thread safety](#experimental-thread-safety)<br>
|
||||
|
||||
Catch2 is designed to "just work" as much as possible, and most of the
|
||||
configuration options below are changed automatically during compilation,
|
||||
@@ -164,7 +166,7 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`.
|
||||
|
||||
> `CATCH_CONFIG_GETENV` was [introduced](https://github.com/catchorg/Catch2/pull/2562) in Catch2 3.2.0
|
||||
|
||||
> `CATCH_CONFIG_USE_BUILTIN_CONSTANT_P` was introduced in Catch2 vX.Y.Z
|
||||
> `CATCH_CONFIG_USE_BUILTIN_CONSTANT_P` was introduced in Catch2 3.8.0
|
||||
|
||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
||||
|
||||
@@ -263,6 +265,21 @@ namespace Catch {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Disabling deprecation warnings
|
||||
|
||||
> Introduced in Catch2 3.9.0
|
||||
|
||||
Catch2 has started using the C++ macro `[[deprecated]]` to mark things
|
||||
that are deprecated and should not be used any more. If you need to
|
||||
temporarily disable these warnings, use
|
||||
|
||||
CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS
|
||||
|
||||
Catch2 currently does not support more fine-grained deprecation warning
|
||||
control, nor do we plan to.
|
||||
|
||||
|
||||
## Overriding Catch's debug break (`-b`)
|
||||
|
||||
> [Introduced](https://github.com/catchorg/Catch2/pull/1846) in Catch2 2.11.2.
|
||||
@@ -299,6 +316,21 @@ no backwards compatibility guarantees._
|
||||
are not meant to be runnable, only "scannable".
|
||||
|
||||
|
||||
## Experimental thread safety
|
||||
|
||||
> Introduced in Catch2 3.9.0
|
||||
|
||||
Catch2 can optionally support thread-safe assertions, that means, multiple
|
||||
user-spawned threads can use the assertion macros at the same time. Due
|
||||
to the performance cost this imposes even on single-threaded usage, Catch2
|
||||
defaults to non-thread-safe assertions.
|
||||
|
||||
CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS // enables thread safe assertions
|
||||
CATCH_CONFIG_NO_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS // force-disables thread safe assertions
|
||||
|
||||
See [the documentation on thread safety in Catch2](thread-safety.md#top)
|
||||
for details on which macros are safe and other notes.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
@@ -38,7 +38,7 @@ macro](skipping-passing-failing.md#top).
|
||||
|
||||
### Non-const function for `TEST_CASE_METHOD`
|
||||
|
||||
> Deprecated in Catch2 vX.Y.Z
|
||||
> Deprecated in Catch2 3.7.0
|
||||
|
||||
Currently, the member function generated for `TEST_CASE_METHOD` is
|
||||
not `const` qualified. In the future, the generated member function will
|
||||
|
@@ -114,11 +114,12 @@ a test case,
|
||||
* `MapGenerator<T, U, Func>` -- returns the result of applying `Func`
|
||||
on elements from a different generator
|
||||
* `ChunkGenerator<T>` -- returns chunks (inside `std::vector`) of n elements from a generator
|
||||
* 4 specific purpose generators (defined in `catch2/generators/catch_generators_random.hpp`)
|
||||
* 2 random generators (defined in `catch2/generators/catch_generators_random.hpp`)
|
||||
* `RandomIntegerGenerator<Integral>` -- generates random Integrals from range
|
||||
* `RandomFloatGenerator<Float>` -- generates random Floats from range
|
||||
* `RangeGenerator<T>(first, last)` -- generates all values inside a `[first, last)` arithmetic range (defined in `catch2/generators/catch_generators_range.hpp`)
|
||||
* `IteratorGenerator<T>` -- copies and returns values from an iterator range (defined in `catch2/generators/catch_generators_range.hpp`)
|
||||
* 2 range generators (defined in `catch2/generators/catch_generators_range.hpp`)
|
||||
* `RangeGenerator<T>(first, last)` -- generates all values inside a `[first, last)` arithmetic range
|
||||
* `IteratorGenerator<T>` -- copies and returns values from an iterator range
|
||||
|
||||
> `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch2 2.7.0.
|
||||
|
||||
|
@@ -57,40 +57,6 @@ again.
|
||||
## Features
|
||||
This section outlines some missing features, what is their status and their possible workarounds.
|
||||
|
||||
### Thread safe assertions
|
||||
Catch2's assertion macros are not thread safe. This does not mean that
|
||||
you cannot use threads inside Catch's test, but that only single thread
|
||||
can interact with Catch's assertions and other macros.
|
||||
|
||||
This means that this is ok
|
||||
```cpp
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> cnt{ 0 };
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
threads.emplace_back([&]() {
|
||||
++cnt; ++cnt; ++cnt; ++cnt;
|
||||
});
|
||||
}
|
||||
for (auto& t : threads) { t.join(); }
|
||||
REQUIRE(cnt == 16);
|
||||
```
|
||||
because only one thread passes the `REQUIRE` macro and this is not
|
||||
```cpp
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> cnt{ 0 };
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
threads.emplace_back([&]() {
|
||||
++cnt; ++cnt; ++cnt; ++cnt;
|
||||
CHECK(cnt == 16);
|
||||
});
|
||||
}
|
||||
for (auto& t : threads) { t.join(); }
|
||||
REQUIRE(cnt == 16);
|
||||
```
|
||||
|
||||
We currently do not plan to support thread-safe assertions.
|
||||
|
||||
|
||||
### Process isolation in a test
|
||||
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
|
||||
|
||||
@@ -187,5 +153,5 @@ but only when compiled with a C++20 conforming compiler. MSVC is currently
|
||||
not conformant enough, but `clang-cl` will compile the assertion above
|
||||
using MSVC STL without problem.
|
||||
|
||||
This change got in with MSVC v19.37](https://godbolt.org/z/KG9obzdvE).
|
||||
[This change got in with MSVC v19.37](https://godbolt.org/z/KG9obzdvE).
|
||||
|
||||
|
@@ -1,32 +1,30 @@
|
||||
<a id="top"></a>
|
||||
# Logging macros
|
||||
|
||||
Additional messages can be logged during a test case. Note that the messages logged with `INFO` are scoped and thus will not be reported if failure occurs in scope preceding the message declaration. An example:
|
||||
Catch2 provides various macros for logging extra information when
|
||||
running a test. These macros default to being scoped, and associate with
|
||||
all assertions in the scope, regardless of whether they pass or fail.
|
||||
|
||||
**example**
|
||||
```cpp
|
||||
TEST_CASE("Foo") {
|
||||
TEST_CASE("Simple info") {
|
||||
INFO("Test case start");
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
INFO("The number is " << i);
|
||||
CHECK(i == 0);
|
||||
SECTION("A") {
|
||||
INFO("Section A");
|
||||
CHECK(false); // 1
|
||||
}
|
||||
SECTION("B") {
|
||||
INFO("Section B");
|
||||
CHECK(false); // 2
|
||||
}
|
||||
CHECK(false); // 3
|
||||
}
|
||||
```
|
||||
The first assertion will report messages "Test case start", and "Section A"
|
||||
as extra information. The second one will report messages "Test case
|
||||
started" and "Section B", while the third one will only report "Test case
|
||||
started" as the extra info.
|
||||
|
||||
TEST_CASE("Bar") {
|
||||
INFO("Test case start");
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
INFO("The number is " << i);
|
||||
CHECK(i == i);
|
||||
}
|
||||
CHECK(false);
|
||||
}
|
||||
```
|
||||
When the `CHECK` fails in the "Foo" test case, then two messages will be printed.
|
||||
```
|
||||
Test case start
|
||||
The number is 1
|
||||
```
|
||||
When the last `CHECK` fails in the "Bar" test case, then only one message will be printed: `Test case start`.
|
||||
|
||||
## Logging without local scope
|
||||
|
||||
|
@@ -57,17 +57,18 @@ int main( int argc, char* argv[] ) {
|
||||
|
||||
int returnCode = session.applyCommandLine( argc, argv );
|
||||
if( returnCode != 0 ) // Indicates a command line error
|
||||
return returnCode;
|
||||
return returnCode;
|
||||
|
||||
// writing to session.configData() or session.Config() here
|
||||
// overrides command line args
|
||||
// only do this if you know you need to
|
||||
|
||||
int numFailed = session.run();
|
||||
returnCode = session.run();
|
||||
|
||||
// returnCode encodes the type of error that occured. See the
|
||||
// integer constants in catch_session.hpp for more information
|
||||
// on what each return code means.
|
||||
|
||||
// numFailed is clamped to 255 as some unices only use the lower 8 bits.
|
||||
// This clamping has already been applied, so just return it here
|
||||
// You can also do any post run clean-up here
|
||||
return numFailed;
|
||||
}
|
||||
```
|
||||
|
@@ -2,6 +2,10 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[3.11.0](#3110)<br>
|
||||
[3.10.0](#3100)<br>
|
||||
[3.9.1](#391)<br>
|
||||
[3.9.0](#390)<br>
|
||||
[3.8.1](#381)<br>
|
||||
[3.8.0](#380)<br>
|
||||
[3.7.1](#371)<br>
|
||||
@@ -67,6 +71,93 @@
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
## 3.11.0
|
||||
|
||||
### Fixes
|
||||
* Fixed building on non-desktop GDK platforms (#3029)
|
||||
* Fixed message macros being susceptible to race in specific scenario (#3031)
|
||||
* Catch2's SEH filter will call the previously installed filter after reporting the error (#3033)
|
||||
|
||||
### Improvements
|
||||
* Handling of scoped messages (e.g. `CAPTURE`) is a bit faster.
|
||||
* Better out-of-the-box support for QNX (#2953)
|
||||
* Improved performance of assertions by up-to 10%
|
||||
* Release mode assertion fast-path sees the biggest improvement.
|
||||
* Faster processing of non-escaped strings in `--invisibles` mode.
|
||||
* Added support for Bazel's `TEST_RANDOM_SEED` env var (#3021)
|
||||
* Added support for Bazel's `TEST_PREMATURE_EXIT_FILE` env var (#3020)
|
||||
* This creates a file that is deleted if the tests exit normally, but stays around if the process dies unexpectedly.
|
||||
* This functionality is also exposed through CLI as `--premature-exit-guard-file`
|
||||
|
||||
### Miscellaneous
|
||||
* **[Tuple.app](https://tuple.app/catch2) has sponsored Catch2**
|
||||
|
||||
|
||||
## 3.10.0
|
||||
|
||||
### Fixes
|
||||
* pkg-config files will take `DESTDIR` env var into account when selecting install destination (#3006, #3019)
|
||||
* Changed `filter` to store the provided predicate by value (#3002, #3005)
|
||||
* This is done to avoid dangling-by-default behaviour when `filter` is used inside `GENERATE_COPY`/`GENERATE_REF`.
|
||||
|
||||
### Improvements
|
||||
* Escaping XML and JSON output is faster when the strings do not need escaping.
|
||||
* The improvement starts at about 3x throughput, up to 10x for long strings.
|
||||
* Message macros (`INFO`, `CAPTURE`, `WARN`, `SUCCEED`, etc) are now thread safe.
|
||||
|
||||
|
||||
## 3.9.1
|
||||
|
||||
### Fixes
|
||||
* Fixed bad error reporting for multiple nested assertions (#1292)
|
||||
* Fixed W4702 (unreachable code) in the polyfill for std::unreachable (#3007)
|
||||
* Fixed decomposition of assertions comparing enum-backed bitfields (#3001)
|
||||
* Fixed StringMaker specialization for `time_point<system_clock>` with non-default duration type (#2685)
|
||||
|
||||
### Improvements
|
||||
* Exceptions thrown during stringification of decomposed expression no longer fail the assertion (#2980)
|
||||
* The selection logic for `CATCH_TRAP` prefers `__builtin_debugtrap` on all platforms when Catch2 is compiled with Clang
|
||||
|
||||
|
||||
## 3.9.0
|
||||
|
||||
### Improvements
|
||||
* **Added experimental opt-in support for thread safe assertions**
|
||||
* Read the documentation for full details
|
||||
* **The default test run order has been changed to random**
|
||||
* Passing assertions are significantly faster when the reporter does not ask for `assertionEnded` events on passing assertions.
|
||||
* This is the default behaviour of e.g. Console or Compact reporter
|
||||
* Simple `REQUIRE(true)` is 60% faster in Release and 80% faster in Debug build configuration
|
||||
* Simple `REQUIRE_NOTHROW` is 230% faster in Release and 430% faster in Debug build configuration
|
||||
* Simple `REQUIRE_THROWS` is ~3% faster in Release and 20% faster in Debug build configuration (throwing introduces enough overhead that the optimizations inside Catch2 are mostly irrelevant)
|
||||
* Small (2-5%) improvement if the reporter asks for `assertionEnded` events for passing assertions.
|
||||
* The exit code constants are part of the Session API. (#2955, #2976)
|
||||
* Suppressed unsigned integer overflow checking in locations with intended overflow (#2965)
|
||||
* Reporters flush output after writing metadata, e.g. rng seed (#2964)
|
||||
* Added unreachable after `FAIL` and `SKIP` macros (#2941)
|
||||
* This allows the compiler to understand that the execution does not continue past the macro, and avoids warnings.
|
||||
* Added fast path for `assertionStarting` event when no reporter requires it
|
||||
* For backwards compatibility, this fast path is opt-in
|
||||
* A reporter can opt in by changing its `ReporterPreferences::shouldReportAllAssertionStarts`
|
||||
* Improved last seen source location tracking to be more precise
|
||||
* This is used when reporting unexpected exceptions from tests
|
||||
|
||||
### Fixes
|
||||
* Fixed formatting of tags with more than 100 tests in the default `--list-tags` output (#2963)
|
||||
* Fixed Clang-Tidy's `readability-static-accessed-through-instance` in tests
|
||||
* Fixed most of Clang-Tidy's `cppcoreguidelines-avoid-non-const-global-variables` (#2582)
|
||||
* The lifetime of scoped messages now strictly obeys their scope (#1759, #2019, #2959)
|
||||
* Previously Catch2 would try to keep them around during unexpected exception, to provide helpful context.
|
||||
* The amount of surprises the irregularities caused was not worth the occasional utility provided.
|
||||
* `TEMPLATE_TEST_CASE_SIG` can handle signatures consisting of only types (#2680, #2995)
|
||||
* Moved `catch_test_run_info.hpp` up from `internal/` subfolder into the main one (#2972)
|
||||
|
||||
### Miscellaneous
|
||||
* pkg-config files are now generated at install time (#2979)
|
||||
* This fixes missing debug suffix in library names
|
||||
* This fixes install prefix mismatch between build config and actuall installation
|
||||
|
||||
|
||||
## 3.8.1
|
||||
|
||||
### Fixes
|
||||
|
@@ -154,7 +154,7 @@ and calls itself "partial" reporter, so it can be invoked with
|
||||
|
||||
Each reporter instance contains instance of `ReporterPreferences`, a type
|
||||
that holds flags for the behaviour of Catch2 when this reporter run.
|
||||
Currently there are two customization options:
|
||||
Currently there are three customization options:
|
||||
|
||||
* `shouldRedirectStdOut` - whether the reporter wants to handle
|
||||
writes to stdout/stderr from user code, or not. This is useful for
|
||||
@@ -165,6 +165,11 @@ Currently there are two customization options:
|
||||
assertions. Usually reporters do not report successful assertions
|
||||
and don't need them for their output, but sometimes the desired output
|
||||
format includes passing assertions even without the `-s` flag.
|
||||
* `shouldReportAllAssertionStarts` - whether the reporter wants to handle
|
||||
`assertionStarting` events. Most reporters do not, and opting out
|
||||
explicitly enables a fast-path in Catch2's handling of assertions.
|
||||
|
||||
> `shouldReportAllAssertionStarts` was introduced in Catch2 3.9.0
|
||||
|
||||
|
||||
### Per-reporter configuration
|
||||
|
@@ -52,6 +52,20 @@ TEST_CASE("failing test") {
|
||||
}
|
||||
```
|
||||
|
||||
Same applies for a `SKIP` nested inside an assertion:
|
||||
|
||||
```cpp
|
||||
static bool do_skip() {
|
||||
SKIP();
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("Another failing test") {
|
||||
CHECK(do_skip());
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Interaction with Sections and Generators
|
||||
|
||||
Sections, nested sections as well as specific outputs from [generators](generators.md#top)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
**Contents**<br>
|
||||
[Non-Templated test fixtures](#non-templated-test-fixtures)<br>
|
||||
[Templated test fixtures](#templated-test-fixtures)<br>
|
||||
[Signature-based parameterised test fixtures](#signature-based-parametrised-test-fixtures)<br>
|
||||
[Signature-based parameterised test fixtures](#signature-based-parameterised-test-fixtures)<br>
|
||||
[Template fixtures with types specified in template type lists](#template-fixtures-with-types-specified-in-template-type-lists)<br>
|
||||
|
||||
## Non-Templated test fixtures
|
||||
|
229
docs/thread-safety.md
Normal file
@@ -0,0 +1,229 @@
|
||||
<a id="top"></a>
|
||||
# Thread safety in Catch2
|
||||
|
||||
**Contents**<br>
|
||||
[Using assertion macros from spawned threads](#using-assertion-macros-from-spawned-threads)<br>
|
||||
[Assertion-like message macros and spawned threads](#assertion-like-message-macros-and-spawned-threads)<br>
|
||||
[Message macros and spawned threads](#message-macros-and-spawned-threads)<br>
|
||||
[examples](#examples)<br>
|
||||
[`STATIC_REQUIRE` and `STATIC_CHECK`](#static_require-and-static_check)<br>
|
||||
[Fatal errors and multiple threads](#fatal-errors-and-multiple-threads)<br>
|
||||
[Performance overhead](#performance-overhead)<br>
|
||||
|
||||
> Thread safe assertions were introduced in Catch2 3.9.0
|
||||
|
||||
Thread safety in Catch2 is currently limited to all the assertion macros,
|
||||
and to message or message-adjacent macros (e.g. `INFO` or `WARN`).
|
||||
|
||||
Interacting with benchmark macros, sections macros, generator macros, or
|
||||
test case macros is not thread-safe. The way sections define paths through
|
||||
the test is incompatible with user spawning threads arbitrarily, so this
|
||||
limitation is here to stay.
|
||||
|
||||
**Important: thread safety in Catch2 is [opt-in](configuration.md#experimental-thread-safety)**
|
||||
|
||||
|
||||
## Using assertion macros from spawned threads
|
||||
|
||||
The full set of Catch2's runtime assertion macros is thread-safe. However,
|
||||
it is important to keep in mind that their semantics might not support
|
||||
being used from user-spawned threads.
|
||||
|
||||
Specifically, the `REQUIRE` family of assertion macros have semantics
|
||||
of stopping the test execution on failure. This is done by throwing
|
||||
an exception, but since the user-spawned thread will not have the test-level
|
||||
try-catch block ready to catch the test failure exception, failing a
|
||||
`REQUIRE` assertion inside user-spawned thread will terminate the process.
|
||||
|
||||
The `CHECK` family of assertions does not have this issue, because it
|
||||
does not try to stop the test execution.
|
||||
|
||||
Note that `CHECKED_IF` and `CHECKED_ELSE` are also thread safe (internally
|
||||
they are assertion macro + an if).
|
||||
|
||||
|
||||
## Assertion-like message macros and spawned threads
|
||||
|
||||
> Assertion-like messages were made thread safe in Catch2 3.10.0
|
||||
|
||||
Similarly to assertion macros, not all assertion-like message macros can
|
||||
be used from spawned thread.
|
||||
|
||||
`SKIP` and `FAIL` macros stop the test execution. Just like with `REQUIRE`,
|
||||
this means that they cannot be used inside user-spawned threads. `SUCCEED`,
|
||||
`FAIL_CHECK` and `WARN` do not attempt to stop the test execution and
|
||||
thus can be used from any thread.
|
||||
|
||||
|
||||
## Message macros and spawned threads
|
||||
|
||||
> Message macros were made thread safe in Catch2 3.10.0
|
||||
|
||||
Macros that add extra messages to following assertion, such as `INFO`
|
||||
or `CAPTURE`, are all thread safe and can be used in any thread. Note
|
||||
that these messages are per-thread, and thus `INFO` inside a user-spawned
|
||||
thread will not be seen by the main thread, and vice versa.
|
||||
|
||||
|
||||
## examples
|
||||
|
||||
### `REQUIRE` from the main thread, `CHECK` from spawned threads
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "Failed REQUIRE in the main thread is fine" ) {
|
||||
std::vector<std::jthread> threads;
|
||||
for ( size_t t = 0; t < 16; ++t) {
|
||||
threads.emplace_back( []() {
|
||||
for (size_t i = 0; i < 10'000; ++i) {
|
||||
CHECK( true );
|
||||
CHECK( false );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
REQUIRE( false );
|
||||
}
|
||||
```
|
||||
This will work as expected, that is, the process will finish running
|
||||
normally, the test case will fail and there will be the correct count of
|
||||
passing and failing assertions (160000 and 160001 respectively). However,
|
||||
it is important to understand that when the main thread fails its assertion,
|
||||
the spawned threads will keep running.
|
||||
|
||||
|
||||
### `REQUIRE` from spawned threads
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "Successful REQUIRE in spawned thread is fine" ) {
|
||||
std::vector<std::jthread> threads;
|
||||
for ( size_t t = 0; t < 16; ++t) {
|
||||
threads.emplace_back( []() {
|
||||
for (size_t i = 0; i < 10'000; ++i) {
|
||||
REQUIRE( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
```
|
||||
This will also work as expected, because the `REQUIRE` is successful.
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "Failed REQUIRE in spawned thread kills the process" ) {
|
||||
std::vector<std::jthread> threads;
|
||||
for ( size_t t = 0; t < 16; ++t) {
|
||||
threads.emplace_back( []() {
|
||||
for (size_t i = 0; i < 10'000; ++i) {
|
||||
REQUIRE( false );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
```
|
||||
This will fail catastrophically and terminate the process.
|
||||
|
||||
|
||||
### INFO across threads
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "messages don't cross threads" ) {
|
||||
std::jthread t1( [&]() {
|
||||
for ( size_t i = 0; i < 100; ++i ) {
|
||||
INFO( "spawned thread #1" );
|
||||
CHECK( 1 == 1 );
|
||||
}
|
||||
} );
|
||||
|
||||
std::thread t2( [&]() {
|
||||
for (size_t i = 0; i < 100; ++i) {
|
||||
UNSCOPED_INFO( "spawned thread #2" );
|
||||
}
|
||||
} );
|
||||
|
||||
for (size_t i = 0; i < 100; ++i) {
|
||||
CHECK( 1 == 2 );
|
||||
}
|
||||
}
|
||||
```
|
||||
None of the failed checks will show the "spawned thread #1" message, as
|
||||
that message is for the `t1` thread. If the reporter shows passing
|
||||
assertions (e.g. due to the tests being run with `-s`), you will see the
|
||||
"spawned thread #1" message alongside the passing `CHECK( 1 == 1 )` assertion.
|
||||
|
||||
The message "spawned thread #2" will never be shown, because there are no
|
||||
assertions in `t2`.
|
||||
|
||||
|
||||
### FAIL/SKIP from the main thread
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "FAIL in the main thread is fine" ) {
|
||||
std::vector<std::jthread> threads;
|
||||
for ( size_t t = 0; t < 16; ++t) {
|
||||
threads.emplace_back( []() {
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
CHECK( true );
|
||||
CHECK( false );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
FAIL();
|
||||
}
|
||||
```
|
||||
|
||||
This will work as expected, that is, the process will finish running
|
||||
normally, the test case will fail and there will be 321 total assertions,
|
||||
160 passing and 161 failing (`FAIL` counts as failed assertion).
|
||||
|
||||
However, when the main thread hits `FAIL`, it will wait for the other
|
||||
threads to finish due to `std::jthread`'s destructor joining the spawned
|
||||
thread. Due to this, using `SKIP` is not recommended once more threads
|
||||
are spawned; while the main thread will bail from the test execution,
|
||||
the spawned threads will keep running and may fail the test case.
|
||||
|
||||
|
||||
### FAIL/SKIP from spawned threads
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "FAIL/SKIP in spawned thread kills the process" ) {
|
||||
std::vector<std::jthread> threads;
|
||||
for ( size_t t = 0; t < 16; ++t) {
|
||||
threads.emplace_back( []() {
|
||||
for (size_t i = 0; i < 10'000; ++i) {
|
||||
FAIL();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
```
|
||||
As with failing `REQUIRE`, both `FAIL` and `SKIP` in spawned threads
|
||||
terminate the process.
|
||||
|
||||
|
||||
## `STATIC_REQUIRE` and `STATIC_CHECK`
|
||||
|
||||
All of `STATIC_REQUIRE`, `STATIC_REQUIRE_FALSE`, `STATIC_CHECK`, and
|
||||
`STATIC_CHECK_FALSE` are thread safe in the delayed evaluation configuration.
|
||||
|
||||
|
||||
## Fatal errors and multiple threads
|
||||
|
||||
By default, Catch2 tries to catch fatal errors (POSIX signals/Windows
|
||||
Structured Exceptions) and report something useful to the user. This
|
||||
always happened on a best-effort basis, but in presence of multiple
|
||||
threads and locks the chance of it working decreases. If this starts
|
||||
being an issue for you, [you can disable it](configuration.md#other-toggles).
|
||||
|
||||
|
||||
## Performance overhead
|
||||
|
||||
In the worst case, which is optimized build and assertions using the
|
||||
fast path for successful assertions, the performance overhead of using
|
||||
the thread-safe assertion implementation can reach 40%. In other cases,
|
||||
the overhead will be smaller, between 4% and 20%.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
@@ -307,7 +307,7 @@ void print( std::ostream& os, int const level, std::string const& title, Catch::
|
||||
// 2. My listener and registration:
|
||||
//
|
||||
|
||||
char const * dashed_line =
|
||||
char const * const dashed_line =
|
||||
"--------------------------------------------------------------------------";
|
||||
|
||||
|
||||
|
@@ -54,5 +54,5 @@ foreach(name ${ALL_EXAMPLE_TARGETS})
|
||||
target_link_libraries(${name} Catch2WithMain)
|
||||
endforeach()
|
||||
|
||||
list(APPEND CATCH_WARNING_TARGETS ${ALL_EXAMPLE_TARGETS})
|
||||
set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE)
|
||||
list(APPEND CATCH_TEST_TARGETS ${ALL_EXAMPLE_TARGETS})
|
||||
set(CATCH_TEST_TARGETS ${CATCH_TEST_TARGETS} PARENT_SCOPE)
|
||||
|
@@ -16,7 +16,7 @@ class NullStreambuf : public std::streambuf {
|
||||
char dummyBuffer[64];
|
||||
|
||||
protected:
|
||||
virtual int overflow(int c) override final;
|
||||
virtual int overflow(int c) final;
|
||||
};
|
||||
|
||||
class NullOStream final : private NullStreambuf, public std::ostream {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
project(
|
||||
'catch2',
|
||||
'cpp',
|
||||
version: '3.8.1', # CML version placeholder, don't delete
|
||||
version: '3.11.0', # CML version placeholder, don't delete
|
||||
license: 'BSL-1.0',
|
||||
meson_version: '>=0.54.1',
|
||||
)
|
||||
|
@@ -58,6 +58,7 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/catch_template_test_macros.hpp
|
||||
${SOURCES_DIR}/catch_test_case_info.hpp
|
||||
${SOURCES_DIR}/catch_test_macros.hpp
|
||||
${SOURCES_DIR}/catch_test_run_info.hpp
|
||||
${SOURCES_DIR}/catch_test_spec.hpp
|
||||
${SOURCES_DIR}/catch_timer.hpp
|
||||
${SOURCES_DIR}/catch_tostring.hpp
|
||||
@@ -84,6 +85,7 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/internal/catch_debug_console.hpp
|
||||
${SOURCES_DIR}/internal/catch_debugger.hpp
|
||||
${SOURCES_DIR}/internal/catch_decomposer.hpp
|
||||
${SOURCES_DIR}/internal/catch_deprecation_macro.hpp
|
||||
${SOURCES_DIR}/internal/catch_enforce.hpp
|
||||
${SOURCES_DIR}/internal/catch_enum_values_registry.hpp
|
||||
${SOURCES_DIR}/internal/catch_errno_guard.hpp
|
||||
@@ -96,6 +98,7 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/internal/catch_jsonwriter.hpp
|
||||
${SOURCES_DIR}/internal/catch_lazy_expr.hpp
|
||||
${SOURCES_DIR}/internal/catch_leak_detector.hpp
|
||||
${SOURCES_DIR}/internal/catch_lifetimebound.hpp
|
||||
${SOURCES_DIR}/internal/catch_list.hpp
|
||||
${SOURCES_DIR}/internal/catch_logical_traits.hpp
|
||||
${SOURCES_DIR}/internal/catch_message_info.hpp
|
||||
@@ -135,15 +138,16 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/internal/catch_test_failure_exception.hpp
|
||||
${SOURCES_DIR}/internal/catch_test_macro_impl.hpp
|
||||
${SOURCES_DIR}/internal/catch_test_registry.hpp
|
||||
${SOURCES_DIR}/internal/catch_test_run_info.hpp
|
||||
${SOURCES_DIR}/internal/catch_test_spec_parser.hpp
|
||||
${SOURCES_DIR}/internal/catch_textflow.hpp
|
||||
${SOURCES_DIR}/internal/catch_thread_support.hpp
|
||||
${SOURCES_DIR}/internal/catch_to_string.hpp
|
||||
${SOURCES_DIR}/internal/catch_uncaught_exceptions.hpp
|
||||
${SOURCES_DIR}/internal/catch_uniform_floating_point_distribution.hpp
|
||||
${SOURCES_DIR}/internal/catch_uniform_integer_distribution.hpp
|
||||
${SOURCES_DIR}/internal/catch_unique_name.hpp
|
||||
${SOURCES_DIR}/internal/catch_unique_ptr.hpp
|
||||
${SOURCES_DIR}/internal/catch_unreachable.hpp
|
||||
${SOURCES_DIR}/internal/catch_void_type.hpp
|
||||
${SOURCES_DIR}/internal/catch_wildcard_pattern.hpp
|
||||
${SOURCES_DIR}/internal/catch_windows_h_proxy.hpp
|
||||
@@ -450,8 +454,8 @@ if(CATCH_BUILD_EXAMPLES OR CATCH_BUILD_EXTRA_TESTS)
|
||||
target_compile_features(Catch2_buildall_interface INTERFACE cxx_std_14)
|
||||
endif()
|
||||
|
||||
list(APPEND CATCH_WARNING_TARGETS Catch2 Catch2WithMain)
|
||||
set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE)
|
||||
list(APPEND CATCH_IMPL_TARGETS Catch2 Catch2WithMain)
|
||||
set(CATCH_IMPL_TARGETS ${CATCH_IMPL_TARGETS} PARENT_SCOPE)
|
||||
|
||||
# We still do not support building dynamic library with hidden visibility
|
||||
# so we want to check & warn users if they do this. However, we won't abort
|
||||
|
@@ -86,9 +86,7 @@ namespace Catch {
|
||||
auto analysis = Detail::analyse(*cfg, samples.data(), samples.data() + samples.size());
|
||||
BenchmarkStats<> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
|
||||
getResultCapture().benchmarkEnded(stats);
|
||||
} CATCH_CATCH_ANON (TestFailureException const&) {
|
||||
getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr);
|
||||
} CATCH_CATCH_ALL{
|
||||
} CATCH_CATCH_ALL {
|
||||
getResultCapture().benchmarkFailed(translateActiveException());
|
||||
// We let the exception go further up so that the
|
||||
// test case is marked as failed.
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <catch2/catch_template_test_macros.hpp>
|
||||
#include <catch2/catch_test_case_info.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_test_run_info.hpp>
|
||||
#include <catch2/catch_test_spec.hpp>
|
||||
#include <catch2/catch_timer.hpp>
|
||||
#include <catch2/catch_tostring.hpp>
|
||||
@@ -65,6 +66,7 @@
|
||||
#include <catch2/internal/catch_debug_console.hpp>
|
||||
#include <catch2/internal/catch_debugger.hpp>
|
||||
#include <catch2/internal/catch_decomposer.hpp>
|
||||
#include <catch2/internal/catch_deprecation_macro.hpp>
|
||||
#include <catch2/internal/catch_enforce.hpp>
|
||||
#include <catch2/internal/catch_enum_values_registry.hpp>
|
||||
#include <catch2/internal/catch_errno_guard.hpp>
|
||||
@@ -77,6 +79,7 @@
|
||||
#include <catch2/internal/catch_jsonwriter.hpp>
|
||||
#include <catch2/internal/catch_lazy_expr.hpp>
|
||||
#include <catch2/internal/catch_leak_detector.hpp>
|
||||
#include <catch2/internal/catch_lifetimebound.hpp>
|
||||
#include <catch2/internal/catch_list.hpp>
|
||||
#include <catch2/internal/catch_logical_traits.hpp>
|
||||
#include <catch2/internal/catch_message_info.hpp>
|
||||
@@ -117,15 +120,16 @@
|
||||
#include <catch2/internal/catch_test_failure_exception.hpp>
|
||||
#include <catch2/internal/catch_test_macro_impl.hpp>
|
||||
#include <catch2/internal/catch_test_registry.hpp>
|
||||
#include <catch2/internal/catch_test_run_info.hpp>
|
||||
#include <catch2/internal/catch_test_spec_parser.hpp>
|
||||
#include <catch2/internal/catch_textflow.hpp>
|
||||
#include <catch2/internal/catch_thread_support.hpp>
|
||||
#include <catch2/internal/catch_to_string.hpp>
|
||||
#include <catch2/internal/catch_uncaught_exceptions.hpp>
|
||||
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
|
||||
#include <catch2/internal/catch_uniform_integer_distribution.hpp>
|
||||
#include <catch2/internal/catch_unique_name.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
#include <catch2/internal/catch_unreachable.hpp>
|
||||
#include <catch2/internal/catch_void_type.hpp>
|
||||
#include <catch2/internal/catch_wildcard_pattern.hpp>
|
||||
#include <catch2/internal/catch_xmlwriter.hpp>
|
||||
|
@@ -119,6 +119,8 @@ namespace Catch {
|
||||
m_data.reporterSpecifications.push_back( std::move( *parsed ) );
|
||||
}
|
||||
|
||||
// Reading bazel env vars can change some parts of the config data,
|
||||
// so we have to process the bazel env before acting on the config.
|
||||
if ( enableBazelEnvSupport() ) {
|
||||
readBazelEnvVars();
|
||||
}
|
||||
@@ -183,6 +185,8 @@ namespace Catch {
|
||||
|
||||
bool Config::showHelp() const { return m_data.showHelp; }
|
||||
|
||||
std::string const& Config::getExitGuardFilePath() const { return m_data.prematureExitGuardFilePath; }
|
||||
|
||||
// IConfig interface
|
||||
bool Config::allowThrows() const { return !m_data.noThrow; }
|
||||
StringRef Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
|
||||
@@ -244,6 +248,26 @@ namespace Catch {
|
||||
m_data.shardCount = bazelShardOptions->shardCount;
|
||||
}
|
||||
}
|
||||
|
||||
const auto bazelExitGuardFile = Detail::getEnv( "TEST_PREMATURE_EXIT_FILE" );
|
||||
if (bazelExitGuardFile) {
|
||||
m_data.prematureExitGuardFilePath = bazelExitGuardFile;
|
||||
}
|
||||
|
||||
const auto bazelRandomSeed = Detail::getEnv( "TEST_RANDOM_SEED" );
|
||||
if ( bazelRandomSeed ) {
|
||||
auto parsedSeed = parseUInt( bazelRandomSeed, 0 );
|
||||
if ( !parsedSeed ) {
|
||||
// Currently we handle issues with parsing other Bazel Env
|
||||
// options by warning and ignoring the issue. So we do the
|
||||
// same for random seed option.
|
||||
Catch::cerr()
|
||||
<< "Warning: could not parse 'TEST_RANDOM_SEED' ('"
|
||||
<< bazelRandomSeed << "') as proper seed.\n";
|
||||
} else {
|
||||
m_data.rngSeed = *parsedSeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
@@ -87,6 +87,8 @@ namespace Catch {
|
||||
|
||||
std::vector<std::string> testsOrTags;
|
||||
std::vector<std::string> sectionsToRun;
|
||||
|
||||
std::string prematureExitGuardFilePath;
|
||||
};
|
||||
|
||||
|
||||
@@ -114,6 +116,8 @@ namespace Catch {
|
||||
|
||||
bool showHelp() const;
|
||||
|
||||
std::string const& getExitGuardFilePath() const;
|
||||
|
||||
// IConfig interface
|
||||
bool allowThrows() const override;
|
||||
StringRef name() const override;
|
||||
|
@@ -7,7 +7,6 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include <catch2/interfaces/catch_interfaces_capture.hpp>
|
||||
#include <catch2/internal/catch_uncaught_exceptions.hpp>
|
||||
#include <catch2/internal/catch_enforce.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
|
||||
@@ -20,28 +19,26 @@ namespace Catch {
|
||||
|
||||
|
||||
ScopedMessage::ScopedMessage( MessageBuilder&& builder ):
|
||||
m_info( CATCH_MOVE(builder.m_info) ) {
|
||||
m_info.message = builder.m_stream.str();
|
||||
getResultCapture().pushScopedMessage( m_info );
|
||||
m_messageId( builder.m_info.sequence ) {
|
||||
MessageInfo info( CATCH_MOVE( builder.m_info ) );
|
||||
info.message = builder.m_stream.str();
|
||||
IResultCapture::pushScopedMessage( CATCH_MOVE( info ) );
|
||||
}
|
||||
|
||||
ScopedMessage::ScopedMessage( ScopedMessage&& old ) noexcept:
|
||||
m_info( CATCH_MOVE( old.m_info ) ) {
|
||||
m_messageId( old.m_messageId ) {
|
||||
old.m_moved = true;
|
||||
}
|
||||
|
||||
ScopedMessage::~ScopedMessage() {
|
||||
if ( !uncaught_exceptions() && !m_moved ){
|
||||
getResultCapture().popScopedMessage(m_info);
|
||||
}
|
||||
if ( !m_moved ) { IResultCapture::popScopedMessage( m_messageId ); }
|
||||
}
|
||||
|
||||
|
||||
Capturer::Capturer( StringRef macroName,
|
||||
SourceLineInfo const& lineInfo,
|
||||
ResultWas::OfType resultType,
|
||||
StringRef names ):
|
||||
m_resultCapture( getResultCapture() ) {
|
||||
StringRef names ) {
|
||||
auto trimmed = [&] (size_t start, size_t end) {
|
||||
while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
|
||||
++start;
|
||||
@@ -87,8 +84,8 @@ namespace Catch {
|
||||
case ',':
|
||||
if (start != pos && openings.empty()) {
|
||||
m_messages.emplace_back(macroName, lineInfo, resultType);
|
||||
m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
|
||||
m_messages.back().message += " := ";
|
||||
m_messages.back().message += trimmed(start, pos);
|
||||
m_messages.back().message += " := "_sr;
|
||||
start = pos;
|
||||
}
|
||||
break;
|
||||
@@ -97,21 +94,20 @@ namespace Catch {
|
||||
}
|
||||
assert(openings.empty() && "Mismatched openings");
|
||||
m_messages.emplace_back(macroName, lineInfo, resultType);
|
||||
m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
|
||||
m_messages.back().message += " := ";
|
||||
m_messages.back().message += trimmed(start, names.size() - 1);
|
||||
m_messages.back().message += " := "_sr;
|
||||
}
|
||||
Capturer::~Capturer() {
|
||||
if ( !uncaught_exceptions() ){
|
||||
assert( m_captured == m_messages.size() );
|
||||
for( size_t i = 0; i < m_captured; ++i )
|
||||
m_resultCapture.popScopedMessage( m_messages[i] );
|
||||
assert( m_captured == m_messages.size() );
|
||||
for (auto const& message : m_messages) {
|
||||
IResultCapture::popScopedMessage( message.sequence );
|
||||
}
|
||||
}
|
||||
|
||||
void Capturer::captureValue( size_t index, std::string const& value ) {
|
||||
assert( index < m_messages.size() );
|
||||
m_messages[index].message += value;
|
||||
m_resultCapture.pushScopedMessage( m_messages[index] );
|
||||
IResultCapture::pushScopedMessage( CATCH_MOVE( m_messages[index] ) );
|
||||
m_captured++;
|
||||
}
|
||||
|
||||
|
@@ -57,13 +57,12 @@ namespace Catch {
|
||||
ScopedMessage( ScopedMessage&& old ) noexcept;
|
||||
~ScopedMessage();
|
||||
|
||||
MessageInfo m_info;
|
||||
unsigned int m_messageId;
|
||||
bool m_moved = false;
|
||||
};
|
||||
|
||||
class Capturer {
|
||||
std::vector<MessageInfo> m_messages;
|
||||
IResultCapture& m_resultCapture;
|
||||
size_t m_captured = 0;
|
||||
public:
|
||||
Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
|
||||
@@ -111,7 +110,7 @@ namespace Catch {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
|
||||
Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
|
||||
Catch::IResultCapture::emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
|
||||
|
||||
|
||||
#if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
|
||||
|
@@ -96,7 +96,6 @@ namespace Catch {
|
||||
}
|
||||
void cleanUp() {
|
||||
cleanupSingletons();
|
||||
cleanUpContext();
|
||||
}
|
||||
std::string translateActiveException() {
|
||||
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <catch2/internal/catch_istream.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
@@ -33,14 +35,6 @@
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
static constexpr int TestFailureExitCode = 42;
|
||||
static constexpr int UnspecifiedErrorExitCode = 1;
|
||||
static constexpr int AllTestsSkippedExitCode = 4;
|
||||
static constexpr int NoTestsRunExitCode = 2;
|
||||
static constexpr int UnmatchedTestSpecExitCode = 3;
|
||||
static constexpr int InvalidTestSpecExitCode = 5;
|
||||
|
||||
|
||||
IEventListenerPtr createReporter(std::string const& reporterName, ReporterConfig&& config) {
|
||||
auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, CATCH_MOVE(config));
|
||||
CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << '\'');
|
||||
@@ -148,6 +142,50 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
// Creates empty file at path. The path must be writable, we do not
|
||||
// try to create directories in path because that's hard in C++14.
|
||||
void setUpGuardFile( std::string const& guardFilePath ) {
|
||||
if ( !guardFilePath.empty() ) {
|
||||
#if defined( _MSC_VER )
|
||||
std::FILE* file = nullptr;
|
||||
if ( fopen_s( &file, guardFilePath.c_str(), "w" ) ) {
|
||||
char msgBuffer[100];
|
||||
const auto err = errno;
|
||||
std::string errMsg;
|
||||
if ( !strerror_s( msgBuffer, err ) ) {
|
||||
errMsg = msgBuffer;
|
||||
} else {
|
||||
errMsg = "Could not translate errno to a string";
|
||||
}
|
||||
|
||||
#else
|
||||
std::FILE* file = std::fopen( guardFilePath.c_str(), "w" );
|
||||
if ( !file ) {
|
||||
const auto err = errno;
|
||||
const char* errMsg = std::strerror( err );
|
||||
#endif
|
||||
|
||||
CATCH_RUNTIME_ERROR( "Could not open the exit guard file '"
|
||||
<< guardFilePath << "' because '"
|
||||
<< errMsg << "' (" << err << ')' );
|
||||
}
|
||||
const int ret = std::fclose( file );
|
||||
CATCH_ENFORCE(
|
||||
ret == 0,
|
||||
"Error when closing the exit guard file: " << ret );
|
||||
}
|
||||
}
|
||||
|
||||
// Removes file at path. Assuming we created it in setUpGuardFile.
|
||||
void tearDownGuardFile( std::string const& guardFilePath ) {
|
||||
if ( !guardFilePath.empty() ) {
|
||||
const int ret = std::remove( guardFilePath.c_str() );
|
||||
CATCH_ENFORCE(
|
||||
ret == 0,
|
||||
"Error when removing the exit guard file: " << ret );
|
||||
}
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
Session::Session() {
|
||||
@@ -266,6 +304,7 @@ namespace Catch {
|
||||
static_cast<void>(std::getchar());
|
||||
}
|
||||
int exitCode = runInternal();
|
||||
|
||||
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
|
||||
Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << '\n' << std::flush;
|
||||
static_cast<void>(std::getchar());
|
||||
@@ -306,6 +345,10 @@ namespace Catch {
|
||||
CATCH_TRY {
|
||||
config(); // Force config to be constructed
|
||||
|
||||
// We need to retrieve potential Bazel config with the full Config
|
||||
// constructor, so we have to create the guard file after it is created.
|
||||
setUpGuardFile( m_config->getExitGuardFilePath() );
|
||||
|
||||
seedRng( *m_config );
|
||||
|
||||
if (m_configData.filenamesAsTags) {
|
||||
@@ -335,9 +378,12 @@ namespace Catch {
|
||||
TestGroup tests { CATCH_MOVE(reporter), m_config.get() };
|
||||
auto const totals = tests.execute();
|
||||
|
||||
// If we got here, running the tests finished normally-enough.
|
||||
// They might've failed, but that would've been reported elsewhere.
|
||||
tearDownGuardFile( m_config->getExitGuardFilePath() );
|
||||
|
||||
if ( tests.hadUnmatchedTestSpecs()
|
||||
&& m_config->warnAboutUnmatchedTestSpecs() ) {
|
||||
// UnmatchedTestSpecExitCode
|
||||
return UnmatchedTestSpecExitCode;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,14 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
// TODO: Use C++17 `inline` variables
|
||||
constexpr int UnspecifiedErrorExitCode = 1;
|
||||
constexpr int NoTestsRunExitCode = 2;
|
||||
constexpr int UnmatchedTestSpecExitCode = 3;
|
||||
constexpr int AllTestsSkippedExitCode = 4;
|
||||
constexpr int InvalidTestSpecExitCode = 5;
|
||||
constexpr int TestFailureExitCode = 42;
|
||||
|
||||
class Session : Detail::NonCopyable {
|
||||
public:
|
||||
|
||||
|
@@ -23,7 +23,7 @@ namespace Catch {
|
||||
#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
|
||||
namespace{ const Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
#endif // CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <catch2/internal/catch_section.hpp>
|
||||
#include <catch2/internal/catch_test_registry.hpp>
|
||||
#include <catch2/internal/catch_unique_name.hpp>
|
||||
#include <catch2/internal/catch_unreachable.hpp>
|
||||
|
||||
|
||||
// All of our user-facing macros support configuration toggle, that
|
||||
@@ -47,10 +48,16 @@
|
||||
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
|
||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define CATCH_FAIL( ... ) do { \
|
||||
INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
|
||||
Catch::Detail::Unreachable(); \
|
||||
} while ( false )
|
||||
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define CATCH_SKIP( ... ) do { \
|
||||
INTERNAL_CATCH_MSG( "CATCH_SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
|
||||
Catch::Detail::Unreachable(); \
|
||||
} while (false)
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
@@ -148,10 +155,16 @@
|
||||
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
|
||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define FAIL( ... ) do { \
|
||||
INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
|
||||
Catch::Detail::Unreachable(); \
|
||||
} while (false)
|
||||
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define SKIP( ... ) do { \
|
||||
INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
|
||||
Catch::Detail::Unreachable(); \
|
||||
} while (false)
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <catch2/catch_tostring.hpp>
|
||||
#include <catch2/interfaces/catch_interfaces_config.hpp>
|
||||
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
|
||||
#include <catch2/internal/catch_context.hpp>
|
||||
#include <catch2/internal/catch_polyfills.hpp>
|
||||
|
||||
@@ -56,39 +57,69 @@ namespace Detail {
|
||||
}
|
||||
} // end unnamed namespace
|
||||
|
||||
std::size_t catch_strnlen( const char* str, std::size_t n ) {
|
||||
auto ret = std::char_traits<char>::find( str, n, '\0' );
|
||||
if ( ret != nullptr ) { return static_cast<std::size_t>( ret - str ); }
|
||||
return n;
|
||||
}
|
||||
|
||||
std::string formatTimeT(std::time_t time) {
|
||||
#ifdef _MSC_VER
|
||||
std::tm timeInfo = {};
|
||||
const auto err = gmtime_s( &timeInfo, &time );
|
||||
if ( err ) {
|
||||
return "gmtime from provided timepoint has failed. This "
|
||||
"happens e.g. with pre-1970 dates using Microsoft libc";
|
||||
}
|
||||
#else
|
||||
std::tm* timeInfo = std::gmtime( &time );
|
||||
#endif
|
||||
|
||||
auto const timeStampSize = sizeof( "2017-01-16T17:06:45Z" );
|
||||
char timeStamp[timeStampSize];
|
||||
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::strftime( timeStamp, timeStampSize, fmt, &timeInfo );
|
||||
#else
|
||||
std::strftime( timeStamp, timeStampSize, fmt, timeInfo );
|
||||
#endif
|
||||
return std::string( timeStamp, timeStampSize - 1 );
|
||||
}
|
||||
|
||||
std::string convertIntoString(StringRef string, bool escapeInvisibles) {
|
||||
std::string ret;
|
||||
// This is enough for the "don't escape invisibles" case, and a good
|
||||
// lower bound on the "escape invisibles" case.
|
||||
ret.reserve(string.size() + 2);
|
||||
ret.reserve( string.size() + 2 );
|
||||
|
||||
if (!escapeInvisibles) {
|
||||
if ( !escapeInvisibles ) {
|
||||
ret += '"';
|
||||
ret += string;
|
||||
ret += '"';
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t last_start = 0;
|
||||
auto write_to = [&]( size_t idx ) {
|
||||
if ( last_start < idx ) {
|
||||
ret += string.substr( last_start, idx - last_start );
|
||||
}
|
||||
last_start = idx + 1;
|
||||
};
|
||||
|
||||
ret += '"';
|
||||
for (char c : string) {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
ret.append("\\r");
|
||||
break;
|
||||
case '\n':
|
||||
ret.append("\\n");
|
||||
break;
|
||||
case '\t':
|
||||
ret.append("\\t");
|
||||
break;
|
||||
case '\f':
|
||||
ret.append("\\f");
|
||||
break;
|
||||
default:
|
||||
ret.push_back(c);
|
||||
break;
|
||||
for ( size_t i = 0; i < string.size(); ++i ) {
|
||||
const char c = string[i];
|
||||
if ( c == '\r' || c == '\n' || c == '\t' || c == '\f' ) {
|
||||
write_to( i );
|
||||
if ( c == '\r' ) { ret.append( "\\r" ); }
|
||||
if ( c == '\n' ) { ret.append( "\\n" ); }
|
||||
if ( c == '\t' ) { ret.append( "\\t" ); }
|
||||
if ( c == '\f' ) { ret.append( "\\f" ); }
|
||||
}
|
||||
}
|
||||
write_to( string.size() );
|
||||
ret += '"';
|
||||
|
||||
return ret;
|
||||
@@ -113,6 +144,13 @@ namespace Detail {
|
||||
rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
std::string makeExceptionHappenedString() {
|
||||
return "{ stringification failed with an exception: \"" +
|
||||
translateActiveException() + "\" }";
|
||||
|
||||
}
|
||||
|
||||
} // end Detail namespace
|
||||
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef CATCH_TOSTRING_HPP_INCLUDED
|
||||
#define CATCH_TOSTRING_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
@@ -40,13 +40,9 @@ namespace Catch {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
inline std::size_t catch_strnlen(const char *str, std::size_t n) {
|
||||
auto ret = std::char_traits<char>::find(str, n, '\0');
|
||||
if (ret != nullptr) {
|
||||
return static_cast<std::size_t>(ret - str);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
std::size_t catch_strnlen(const char *str, std::size_t n);
|
||||
|
||||
std::string formatTimeT( std::time_t time );
|
||||
|
||||
constexpr StringRef unprintableString = "{?}"_sr;
|
||||
|
||||
@@ -139,11 +135,17 @@ namespace Catch {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
std::string makeExceptionHappenedString();
|
||||
|
||||
// This function dispatches all stringification requests inside of Catch.
|
||||
// Should be preferably called fully qualified, like ::Catch::Detail::stringify
|
||||
template <typename T>
|
||||
std::string stringify(const T& e) {
|
||||
return ::Catch::StringMaker<std::remove_cv_t<std::remove_reference_t<T>>>::convert(e);
|
||||
std::string stringify( const T& e ) {
|
||||
CATCH_TRY {
|
||||
return ::Catch::StringMaker<
|
||||
std::remove_cv_t<std::remove_reference_t<T>>>::convert( e );
|
||||
}
|
||||
CATCH_CATCH_ALL { return makeExceptionHappenedString(); }
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
@@ -405,44 +407,38 @@ namespace Catch {
|
||||
|
||||
// Separate std::tuple specialization
|
||||
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
|
||||
#include <tuple>
|
||||
# include <tuple>
|
||||
# include <utility>
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
template<
|
||||
typename Tuple,
|
||||
std::size_t N = 0,
|
||||
bool = (N < std::tuple_size<Tuple>::value)
|
||||
>
|
||||
struct TupleElementPrinter {
|
||||
static void print(const Tuple& tuple, std::ostream& os) {
|
||||
os << (N ? ", " : " ")
|
||||
<< ::Catch::Detail::stringify(std::get<N>(tuple));
|
||||
TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
|
||||
}
|
||||
};
|
||||
template <typename Tuple, std::size_t... Is>
|
||||
void PrintTuple( const Tuple& tuple,
|
||||
std::ostream& os,
|
||||
std::index_sequence<Is...> ) {
|
||||
// 1 + Account for when the tuple is empty
|
||||
char a[1 + sizeof...( Is )] = {
|
||||
( ( os << ( Is ? ", " : " " )
|
||||
<< ::Catch::Detail::stringify( std::get<Is>( tuple ) ) ),
|
||||
'\0' )... };
|
||||
(void)a;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Tuple,
|
||||
std::size_t N
|
||||
>
|
||||
struct TupleElementPrinter<Tuple, N, false> {
|
||||
static void print(const Tuple&, std::ostream&) {}
|
||||
};
|
||||
} // namespace Detail
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename ...Types>
|
||||
template <typename... Types>
|
||||
struct StringMaker<std::tuple<Types...>> {
|
||||
static std::string convert(const std::tuple<Types...>& tuple) {
|
||||
static std::string convert( const std::tuple<Types...>& tuple ) {
|
||||
ReusableStringStream rss;
|
||||
rss << '{';
|
||||
Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
|
||||
Detail::PrintTuple(
|
||||
tuple,
|
||||
rss.get(),
|
||||
std::make_index_sequence<sizeof...( Types )>{} );
|
||||
rss << " }";
|
||||
return rss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace Catch
|
||||
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
|
||||
|
||||
#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
|
||||
@@ -626,29 +622,10 @@ struct ratio_string<std::milli> {
|
||||
template<typename Duration>
|
||||
struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
|
||||
static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
|
||||
auto converted = std::chrono::system_clock::to_time_t(time_point);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::tm timeInfo = {};
|
||||
const auto err = 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
|
||||
std::tm* timeInfo = std::gmtime(&converted);
|
||||
#endif
|
||||
|
||||
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
#endif
|
||||
return std::string(timeStamp, timeStampSize - 1);
|
||||
const auto systemish = std::chrono::time_point_cast<
|
||||
std::chrono::system_clock::duration>( time_point );
|
||||
const auto as_time_t = std::chrono::system_clock::to_time_t( systemish );
|
||||
return ::Catch::Detail::formatTimeT( as_time_t );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ namespace Catch {
|
||||
static std::string translatorName( signature ); \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
|
||||
namespace{ const Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
static std::string translatorName( signature )
|
||||
|
||||
|
@@ -187,6 +187,24 @@
|
||||
#endif
|
||||
|
||||
|
||||
#cmakedefine CATCH_CONFIG_DEPRECATION_ANNOTATIONS
|
||||
#cmakedefine CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS
|
||||
|
||||
#if defined( CATCH_CONFIG_DEPRECATION_ANNOTATIONS ) && \
|
||||
defined( CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS )
|
||||
# error Cannot force DEPRECATION_ANNOTATIONS to both ON and OFF
|
||||
#endif
|
||||
|
||||
|
||||
#cmakedefine CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS
|
||||
#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS
|
||||
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS ) && \
|
||||
defined( CATCH_CONFIG_NO_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS )
|
||||
# error Cannot force EXPERIMENTAL_THREAD_SAFE_ASSERTIONS to both ON and OFF
|
||||
#endif
|
||||
|
||||
|
||||
// ------
|
||||
// Simple toggle defines
|
||||
// their value is never used and they cannot be overridden
|
||||
|
@@ -36,7 +36,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 8, 1, "", 0 );
|
||||
static Version version( 3, 11, 0, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 8
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
#define CATCH_VERSION_MINOR 11
|
||||
#define CATCH_VERSION_PATCH 0
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
@@ -23,7 +23,7 @@ namespace Catch {
|
||||
m_msg(msg)
|
||||
{}
|
||||
|
||||
const char* what() const noexcept override final;
|
||||
const char* what() const noexcept final;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
@@ -58,8 +58,9 @@ namespace Generators {
|
||||
class FilterGenerator final : public IGenerator<T> {
|
||||
GeneratorWrapper<T> m_generator;
|
||||
Predicate m_predicate;
|
||||
static_assert(!std::is_reference<Predicate>::value, "This would most likely result in a dangling reference");
|
||||
public:
|
||||
template <typename P = Predicate>
|
||||
template <typename P>
|
||||
FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
|
||||
m_generator(CATCH_MOVE(generator)),
|
||||
m_predicate(CATCH_FORWARD(pred))
|
||||
@@ -91,7 +92,7 @@ namespace Generators {
|
||||
|
||||
template <typename T, typename Predicate>
|
||||
GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
|
||||
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, Predicate>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
|
||||
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference<Predicate>::type>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@@ -7,7 +7,14 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#include <catch2/interfaces/catch_interfaces_capture.hpp>
|
||||
#include <catch2/internal/catch_enforce.hpp>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
void missingCaptureInstance() {
|
||||
CATCH_INTERNAL_ERROR( "No result capture instance" );
|
||||
}
|
||||
} // namespace Detail
|
||||
|
||||
IResultCapture::~IResultCapture() = default;
|
||||
}
|
||||
} // namespace Catch
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <catch2/internal/catch_context.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_result_type.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
@@ -62,10 +63,9 @@ namespace Catch {
|
||||
virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
|
||||
virtual void benchmarkFailed( StringRef error ) = 0;
|
||||
|
||||
virtual void pushScopedMessage( MessageInfo const& message ) = 0;
|
||||
virtual void popScopedMessage( MessageInfo const& message ) = 0;
|
||||
|
||||
virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0;
|
||||
static void pushScopedMessage( MessageInfo&& message );
|
||||
static void popScopedMessage( unsigned int messageId );
|
||||
static void emplaceUnscopedMessage( MessageBuilder&& builder );
|
||||
|
||||
virtual void handleFatalErrorCondition( StringRef message ) = 0;
|
||||
|
||||
@@ -93,9 +93,7 @@ namespace Catch {
|
||||
AssertionReaction &reaction ) = 0;
|
||||
|
||||
|
||||
|
||||
virtual bool lastAssertionPassed() = 0;
|
||||
virtual void assertionPassed() = 0;
|
||||
|
||||
// Deprecated, do not use:
|
||||
virtual std::string getCurrentTestName() const = 0;
|
||||
@@ -103,7 +101,18 @@ namespace Catch {
|
||||
virtual void exceptionEarlyReported() = 0;
|
||||
};
|
||||
|
||||
IResultCapture& getResultCapture();
|
||||
namespace Detail {
|
||||
[[noreturn]]
|
||||
void missingCaptureInstance();
|
||||
}
|
||||
inline IResultCapture& getResultCapture() {
|
||||
if (auto* capture = getCurrentContext().getResultCapture()) {
|
||||
return *capture;
|
||||
} else {
|
||||
Detail::missingCaptureInstance();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
|
||||
|
@@ -9,11 +9,11 @@
|
||||
#define CATCH_INTERFACES_REPORTER_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_section_info.hpp>
|
||||
#include <catch2/catch_test_run_info.hpp>
|
||||
#include <catch2/catch_totals.hpp>
|
||||
#include <catch2/catch_assertion_result.hpp>
|
||||
#include <catch2/internal/catch_message_info.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_test_run_info.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
#include <catch2/benchmark/detail/catch_benchmark_stats.hpp>
|
||||
|
||||
@@ -115,6 +115,11 @@ namespace Catch {
|
||||
//! Catch2 should call `Reporter::assertionEnded` even for passing
|
||||
//! assertions
|
||||
bool shouldReportAllAssertions = false;
|
||||
//! Catch2 should call `Reporter::assertionStarting` for all assertions
|
||||
// Defaults to true for backwards compatibility, but none of our current
|
||||
// reporters actually want this, and it enables a fast path in assertion
|
||||
// handling.
|
||||
bool shouldReportAllAssertionStarts = true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -66,15 +66,13 @@ namespace Catch {
|
||||
};
|
||||
|
||||
template <typename F, typename = void>
|
||||
struct is_unary_function : std::false_type {};
|
||||
static constexpr bool is_unary_function_v = false;
|
||||
|
||||
template <typename F>
|
||||
struct is_unary_function<
|
||||
static constexpr bool is_unary_function_v<
|
||||
F,
|
||||
Catch::Detail::void_t<decltype(
|
||||
std::declval<F>()( fake_arg() ) )
|
||||
>
|
||||
> : std::true_type {};
|
||||
Catch::Detail::void_t<decltype( std::declval<F>()(
|
||||
fake_arg() ) )>> = true;
|
||||
|
||||
// Traits for extracting arg and return type of lambdas (for single
|
||||
// argument lambdas)
|
||||
@@ -507,14 +505,14 @@ namespace Catch {
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
!Detail::is_unary_function_v<T>>>
|
||||
ParserRefImpl( T& ref, StringRef hint ):
|
||||
m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
Detail::is_unary_function_v<LambdaT>>>
|
||||
ParserRefImpl( LambdaT const& ref, StringRef hint ):
|
||||
m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
@@ -581,7 +579,7 @@ namespace Catch {
|
||||
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
Detail::is_unary_function_v<LambdaT>>>
|
||||
Opt( LambdaT const& ref, StringRef hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
@@ -591,7 +589,7 @@ namespace Catch {
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
!Detail::is_unary_function_v<T>>>
|
||||
Opt( T& ref, StringRef hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
|
@@ -305,6 +305,9 @@ namespace Catch {
|
||||
| Opt( config.allowZeroTests )
|
||||
["--allow-running-no-tests"]
|
||||
( "Treat 'No tests run' as a success" )
|
||||
| Opt( config.prematureExitGuardFilePath, "path" )
|
||||
["--premature-exit-guard-file"]
|
||||
( "create a file before running tests and delete it during clean exit" )
|
||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||
( "which test or tests to use" );
|
||||
|
||||
|
@@ -220,13 +220,17 @@
|
||||
# endif
|
||||
|
||||
// Universal Windows platform does not support SEH
|
||||
// Or console colours (or console at all...)
|
||||
# if defined(CATCH_PLATFORM_WINDOWS_UWP)
|
||||
# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
|
||||
# else
|
||||
# if !defined(CATCH_PLATFORM_WINDOWS_UWP)
|
||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||
# endif
|
||||
|
||||
// Only some Windows platform families support the console
|
||||
# if defined(WINAPI_FAMILY_PARTITION)
|
||||
# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
|
||||
# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
|
||||
# endif
|
||||
# endif
|
||||
|
||||
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
||||
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
||||
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
|
||||
|
@@ -161,7 +161,11 @@ namespace {
|
||||
#endif // Windows/ ANSI/ None
|
||||
|
||||
|
||||
#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC ) || defined( __GLIBC__ )
|
||||
#if defined( CATCH_PLATFORM_LINUX ) \
|
||||
|| defined( CATCH_PLATFORM_MAC ) \
|
||||
|| defined( __GLIBC__ ) \
|
||||
|| defined( __FreeBSD__ ) \
|
||||
|| defined( CATCH_PLATFORM_QNX )
|
||||
# define CATCH_INTERNAL_HAS_ISATTY
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
@@ -6,25 +6,14 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/internal/catch_context.hpp>
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/internal/catch_random_number_generator.hpp>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
Context* Context::currentContext = nullptr;
|
||||
|
||||
void cleanUpContext() {
|
||||
delete Context::currentContext;
|
||||
Context::currentContext = nullptr;
|
||||
}
|
||||
void Context::createContext() {
|
||||
currentContext = new Context();
|
||||
}
|
||||
Context Context::currentContext;
|
||||
|
||||
Context& getCurrentMutableContext() {
|
||||
if ( !Context::currentContext ) { Context::createContext(); }
|
||||
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
|
||||
return *Context::currentContext;
|
||||
return Context::currentContext;
|
||||
}
|
||||
|
||||
SimplePcg32& sharedRng() {
|
||||
|
@@ -19,11 +19,9 @@ namespace Catch {
|
||||
IConfig const* m_config = nullptr;
|
||||
IResultCapture* m_resultCapture = nullptr;
|
||||
|
||||
CATCH_EXPORT static Context* currentContext;
|
||||
CATCH_EXPORT static Context currentContext;
|
||||
friend Context& getCurrentMutableContext();
|
||||
friend Context const& getCurrentContext();
|
||||
static void createContext();
|
||||
friend void cleanUpContext();
|
||||
|
||||
public:
|
||||
constexpr IResultCapture* getResultCapture() const {
|
||||
@@ -34,21 +32,14 @@ namespace Catch {
|
||||
m_resultCapture = resultCapture;
|
||||
}
|
||||
constexpr void setConfig( IConfig const* config ) { m_config = config; }
|
||||
|
||||
};
|
||||
|
||||
Context& getCurrentMutableContext();
|
||||
|
||||
inline Context const& getCurrentContext() {
|
||||
// We duplicate the logic from `getCurrentMutableContext` here,
|
||||
// to avoid paying the call overhead in debug mode.
|
||||
if ( !Context::currentContext ) { Context::createContext(); }
|
||||
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
|
||||
return *Context::currentContext;
|
||||
return Context::currentContext;
|
||||
}
|
||||
|
||||
void cleanUpContext();
|
||||
|
||||
class SimplePcg32;
|
||||
SimplePcg32& sharedRng();
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@
|
||||
#endif
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
#elif defined(CATCH_PLATFORM_LINUX) || defined(CATCH_PLATFORM_QNX)
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
|
@@ -14,6 +14,17 @@ namespace Catch {
|
||||
bool isDebuggerActive();
|
||||
}
|
||||
|
||||
#if !defined( CATCH_TRAP ) && defined( __clang__ ) && defined( __has_builtin )
|
||||
# if __has_builtin( __builtin_debugtrap )
|
||||
# define CATCH_TRAP() __builtin_debugtrap()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined( CATCH_TRAP ) && defined( _MSC_VER )
|
||||
# define CATCH_TRAP() __debugbreak()
|
||||
#endif
|
||||
|
||||
#if !defined(CATCH_TRAP) // If we couldn't use compiler-specific impl from above, we get into platform-specific options
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
@@ -38,7 +49,7 @@ namespace Catch {
|
||||
#define CATCH_TRAP() __asm__(".inst 0xde01")
|
||||
#endif
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
#elif defined(CATCH_PLATFORM_LINUX) || defined(CATCH_PLATFORM_QNX)
|
||||
// If we can use inline assembler, do it because this allows us to break
|
||||
// directly at the location of the failing check instead of breaking inside
|
||||
// raise() called from it, i.e. one stack frame below.
|
||||
@@ -49,15 +60,15 @@ namespace Catch {
|
||||
|
||||
#define CATCH_TRAP() raise(SIGTRAP)
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#define CATCH_TRAP() __debugbreak()
|
||||
#elif defined(__MINGW32__)
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
#define CATCH_TRAP() DebugBreak()
|
||||
#endif
|
||||
#endif // ^^ CATCH_TRAP is not defined yet, so we define it
|
||||
|
||||
#ifndef CATCH_BREAK_INTO_DEBUGGER
|
||||
#ifdef CATCH_TRAP
|
||||
|
||||
#if !defined(CATCH_BREAK_INTO_DEBUGGER)
|
||||
#if defined(CATCH_TRAP)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{}()
|
||||
|
@@ -78,10 +78,11 @@
|
||||
*
|
||||
* 3) If a type has no linkage, we also cannot capture it by reference.
|
||||
* The solution is once again to capture them by value. We handle
|
||||
* the common cases by using `std::is_arithmetic` as the default
|
||||
* for `Catch::capture_by_value`, but that is only a some-effort
|
||||
* heuristic. But as with 2), users can specialize `capture_by_value`
|
||||
* for their own types as needed.
|
||||
* the common cases by using `std::is_arithmetic` and `std::is_enum`
|
||||
* as the default for `Catch::capture_by_value`, but that is only a
|
||||
* some-effort heuristic. These combine to capture all possible bitfield
|
||||
* bases, and also some trait-like types. As with 2), users can
|
||||
* specialize `capture_by_value` for their own types as needed.
|
||||
*
|
||||
* 4) To support C++20 and make the SFINAE on our decomposing operators
|
||||
* work, the SFINAE has to happen in return type, rather than in
|
||||
@@ -133,13 +134,22 @@ namespace Catch {
|
||||
using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
}
|
||||
|
||||
// Note: There is nothing that stops us from extending this,
|
||||
// e.g. to `std::is_scalar`, but the more encompassing
|
||||
// traits are usually also more expensive. For now we
|
||||
// keep this as it used to be and it can be changed later.
|
||||
// Note: This is about as much as we can currently reasonably support.
|
||||
// In an ideal world, we could capture by value small trivially
|
||||
// copyable types, but the actual `std::is_trivially_copyable`
|
||||
// trait is a huge mess with standard-violating results on
|
||||
// GCC and Clang, which are unlikely to be fixed soon due to ABI
|
||||
// concerns.
|
||||
// `std::is_scalar` also causes issues due to the `is_pointer`
|
||||
// component, which causes ambiguity issues with (references-to)
|
||||
// function pointer. If those are resolved, we still need to
|
||||
// disambiguate the overload set for arrays, through explicit
|
||||
// overload for references to sized arrays.
|
||||
template <typename T>
|
||||
struct capture_by_value
|
||||
: std::integral_constant<bool, std::is_arithmetic<T>{}> {};
|
||||
: std::integral_constant<bool,
|
||||
std::is_arithmetic<T>::value ||
|
||||
std::is_enum<T>::value> {};
|
||||
|
||||
#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS )
|
||||
template <>
|
||||
|
19
src/catch2/internal/catch_deprecation_macro.hpp
Normal 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_DEPRECATION_MACRO_HPP_INCLUDED
|
||||
#define CATCH_DEPRECATION_MACRO_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_user_config.hpp>
|
||||
|
||||
#if !defined( CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS )
|
||||
# define DEPRECATED( msg ) [[deprecated( msg )]]
|
||||
#else
|
||||
# define DEPRECATED( msg )
|
||||
#endif
|
||||
|
||||
#endif // CATCH_DEPRECATION_MACRO_HPP_INCLUDED
|
@@ -59,10 +59,10 @@ namespace Catch {
|
||||
// To avoid having to handle TFE explicitly everywhere, we just
|
||||
// rethrow it so that it goes back up the caller.
|
||||
catch( TestFailureException& ) {
|
||||
std::rethrow_exception(std::current_exception());
|
||||
return "{ nested assertion failed }";
|
||||
}
|
||||
catch( TestSkipException& ) {
|
||||
std::rethrow_exception(std::current_exception());
|
||||
return "{ nested SKIP() called }";
|
||||
}
|
||||
catch( std::exception const& ex ) {
|
||||
return ex.what();
|
||||
|
@@ -79,30 +79,34 @@ namespace Catch {
|
||||
// There is no 1-1 mapping between signals and windows exceptions.
|
||||
// Windows can easily distinguish between SO and SigSegV,
|
||||
// but SigInt, SigTerm, etc are handled differently.
|
||||
static SignalDefs signalDefs[] = {
|
||||
static constexpr SignalDefs signalDefs[] = {
|
||||
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
|
||||
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
|
||||
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
|
||||
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
||||
};
|
||||
|
||||
// Since we do not support multiple instantiations, we put these
|
||||
// into global variables and rely on cleaning them up in outlined
|
||||
// constructors/destructors
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr;
|
||||
|
||||
|
||||
static LONG CALLBACK topLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (auto const& def : signalDefs) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
|
||||
reportFatal(def.name);
|
||||
}
|
||||
}
|
||||
// If its not an exception we care about, pass it along.
|
||||
// If a filter was previously registered, invoke it
|
||||
if (previousTopLevelExceptionFilter) {
|
||||
return previousTopLevelExceptionFilter(ExceptionInfo);
|
||||
}
|
||||
// Otherwise, pass along all exceptions.
|
||||
// This stops us from eating debugger breaks etc.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Since we do not support multiple instantiations, we put these
|
||||
// into global variables and rely on cleaning them up in outlined
|
||||
// constructors/destructors
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr;
|
||||
|
||||
|
||||
// For MSVC, we reserve part of the stack memory for handling
|
||||
// memory overflow structured exception.
|
||||
FatalConditionHandler::FatalConditionHandler() {
|
||||
@@ -150,7 +154,7 @@ namespace Catch {
|
||||
const char* name;
|
||||
};
|
||||
|
||||
static SignalDefs signalDefs[] = {
|
||||
static constexpr SignalDefs signalDefs[] = {
|
||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||
{ SIGILL, "SIGILL - Illegal instruction signal" },
|
||||
{ SIGFPE, "SIGFPE - Floating point error signal" },
|
||||
|
@@ -7,8 +7,36 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/internal/catch_enforce.hpp>
|
||||
#include <catch2/internal/catch_jsonwriter.hpp>
|
||||
#include <catch2/internal/catch_unreachable.hpp>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
static bool needsEscape( char c ) {
|
||||
return c == '"' || c == '\\' || c == '\b' || c == '\f' ||
|
||||
c == '\n' || c == '\r' || c == '\t';
|
||||
}
|
||||
|
||||
static Catch::StringRef makeEscapeStringRef( char c ) {
|
||||
if ( c == '"' ) {
|
||||
return "\\\""_sr;
|
||||
} else if ( c == '\\' ) {
|
||||
return "\\\\"_sr;
|
||||
} else if ( c == '\b' ) {
|
||||
return "\\b"_sr;
|
||||
} else if ( c == '\f' ) {
|
||||
return "\\f"_sr;
|
||||
} else if ( c == '\n' ) {
|
||||
return "\\n"_sr;
|
||||
} else if ( c == '\r' ) {
|
||||
return "\\r"_sr;
|
||||
} else if ( c == '\t' ) {
|
||||
return "\\t"_sr;
|
||||
}
|
||||
Catch::Detail::Unreachable();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void JsonUtils::indent( std::ostream& os, std::uint64_t level ) {
|
||||
for ( std::uint64_t i = 0; i < level; ++i ) {
|
||||
os << " ";
|
||||
@@ -118,30 +146,19 @@ namespace Catch {
|
||||
|
||||
void JsonValueWriter::writeImpl( Catch::StringRef value, bool quote ) {
|
||||
if ( quote ) { m_os << '"'; }
|
||||
for (char c : value) {
|
||||
// Escape list taken from https://www.json.org/json-en.html,
|
||||
// string definition.
|
||||
// Note that while forward slash _can_ be escaped, it does
|
||||
// not have to be, if JSON is not further embedded somewhere
|
||||
// where forward slash is meaningful.
|
||||
if ( c == '"' ) {
|
||||
m_os << "\\\"";
|
||||
} else if ( c == '\\' ) {
|
||||
m_os << "\\\\";
|
||||
} else if ( c == '\b' ) {
|
||||
m_os << "\\b";
|
||||
} else if ( c == '\f' ) {
|
||||
m_os << "\\f";
|
||||
} else if ( c == '\n' ) {
|
||||
m_os << "\\n";
|
||||
} else if ( c == '\r' ) {
|
||||
m_os << "\\r";
|
||||
} else if ( c == '\t' ) {
|
||||
m_os << "\\t";
|
||||
} else {
|
||||
m_os << c;
|
||||
size_t current_start = 0;
|
||||
for ( size_t i = 0; i < value.size(); ++i ) {
|
||||
if ( needsEscape( value[i] ) ) {
|
||||
if ( current_start < i ) {
|
||||
m_os << value.substr( current_start, i - current_start );
|
||||
}
|
||||
m_os << makeEscapeStringRef( value[i] );
|
||||
current_start = i + 1;
|
||||
}
|
||||
}
|
||||
if ( current_start < value.size() ) {
|
||||
m_os << value.substr( current_start, value.size() - current_start );
|
||||
}
|
||||
if ( quote ) { m_os << '"'; }
|
||||
}
|
||||
|
||||
|
24
src/catch2/internal/catch_lifetimebound.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
// 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_LIFETIMEBOUND_HPP_INCLUDED
|
||||
#define CATCH_LIFETIMEBOUND_HPP_INCLUDED
|
||||
|
||||
#if !defined( __has_cpp_attribute )
|
||||
# define CATCH_ATTR_LIFETIMEBOUND
|
||||
#elif __has_cpp_attribute( msvc::lifetimebound )
|
||||
# define CATCH_ATTR_LIFETIMEBOUND [[msvc::lifetimebound]]
|
||||
#elif __has_cpp_attribute( clang::lifetimebound )
|
||||
# define CATCH_ATTR_LIFETIMEBOUND [[clang::lifetimebound]]
|
||||
#elif __has_cpp_attribute( lifetimebound )
|
||||
# define CATCH_ATTR_LIFETIMEBOUND [[lifetimebound]]
|
||||
#else
|
||||
# define CATCH_ATTR_LIFETIMEBOUND
|
||||
#endif
|
||||
|
||||
#endif // CATCH_LIFETIMEBOUND_HPP_INCLUDED
|
@@ -14,7 +14,7 @@
|
||||
namespace Catch {
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
|
||||
static LeakDetector leakDetector;
|
||||
static const LeakDetector leakDetector;
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
}
|
||||
|
||||
|
@@ -10,16 +10,17 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
MessageInfo::MessageInfo( StringRef _macroName,
|
||||
SourceLineInfo const& _lineInfo,
|
||||
ResultWas::OfType _type )
|
||||
MessageInfo::MessageInfo( StringRef _macroName,
|
||||
SourceLineInfo const& _lineInfo,
|
||||
ResultWas::OfType _type )
|
||||
: macroName( _macroName ),
|
||||
lineInfo( _lineInfo ),
|
||||
type( _type ),
|
||||
sequence( ++globalCount )
|
||||
{}
|
||||
|
||||
// This may need protecting if threading support is added
|
||||
unsigned int MessageInfo::globalCount = 0;
|
||||
// Messages are owned by their individual threads, so the counter should be thread-local as well.
|
||||
// Alternative consideration: atomic, so threads don't share IDs and things are easier to debug.
|
||||
thread_local unsigned int MessageInfo::globalCount = 0;
|
||||
|
||||
} // end namespace Catch
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef CATCH_MESSAGE_INFO_HPP_INCLUDED
|
||||
#define CATCH_MESSAGE_INFO_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_deprecation_macro.hpp>
|
||||
#include <catch2/internal/catch_result_type.hpp>
|
||||
#include <catch2/internal/catch_source_line_info.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
@@ -25,16 +26,19 @@ namespace Catch {
|
||||
std::string message;
|
||||
SourceLineInfo lineInfo;
|
||||
ResultWas::OfType type;
|
||||
// The "ID" of the message, used to know when to remove it from reporter context.
|
||||
unsigned int sequence;
|
||||
|
||||
DEPRECATED( "Explicitly use the 'sequence' member instead" )
|
||||
bool operator == (MessageInfo const& other) const {
|
||||
return sequence == other.sequence;
|
||||
}
|
||||
DEPRECATED( "Explicitly use the 'sequence' member instead" )
|
||||
bool operator < (MessageInfo const& other) const {
|
||||
return sequence < other.sequence;
|
||||
}
|
||||
private:
|
||||
static unsigned int globalCount;
|
||||
static thread_local unsigned int globalCount;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
@@ -13,6 +13,7 @@ namespace Catch {
|
||||
|
||||
//! Deriving classes become noncopyable and nonmovable
|
||||
class NonCopyable {
|
||||
public:
|
||||
NonCopyable( NonCopyable const& ) = delete;
|
||||
NonCopyable( NonCopyable&& ) = delete;
|
||||
NonCopyable& operator=( NonCopyable const& ) = delete;
|
||||
|
@@ -25,6 +25,9 @@
|
||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define CATCH_PLATFORM_LINUX
|
||||
|
||||
#elif defined(__QNX__)
|
||||
# define CATCH_PLATFORM_QNX
|
||||
|
||||
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define CATCH_PLATFORM_WINDOWS
|
||||
|
||||
|
@@ -16,6 +16,15 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
template <int N>
|
||||
struct priority_tag : priority_tag<N - 1> {};
|
||||
template <>
|
||||
struct priority_tag<0> {};
|
||||
}
|
||||
}
|
||||
|
||||
#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
|
||||
#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
|
||||
#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
|
||||
@@ -75,10 +84,10 @@
|
||||
#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>(Catch::Detail::priority_tag<1>{}))
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
|
||||
#else
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>(Catch::Detail::priority_tag<1>{})))
|
||||
#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
|
||||
#endif
|
||||
|
||||
@@ -101,11 +110,11 @@
|
||||
|
||||
#define INTERNAL_CATCH_TYPE_GEN\
|
||||
template<typename...> struct TypeList {};\
|
||||
template<typename...Ts>\
|
||||
constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
|
||||
template<typename... Ts>\
|
||||
constexpr auto get_wrapper(Catch::Detail::priority_tag<1>) noexcept -> TypeList<Ts...> { return {}; }\
|
||||
template<template<typename...> class...> struct TemplateTypeList{};\
|
||||
template<template<typename...> class...Cs>\
|
||||
constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
|
||||
constexpr auto get_wrapper(Catch::Detail::priority_tag<1>) noexcept -> TemplateTypeList<Cs...> { return {}; }\
|
||||
template<typename...>\
|
||||
struct append;\
|
||||
template<typename...>\
|
||||
@@ -135,10 +144,10 @@
|
||||
#define INTERNAL_CATCH_NTTP_1(signature, ...)\
|
||||
template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
|
||||
template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
|
||||
constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
|
||||
constexpr auto get_wrapper(Catch::Detail::priority_tag<0>) noexcept -> Nttp<__VA_ARGS__> { return {}; } \
|
||||
template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
|
||||
template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
|
||||
constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
|
||||
constexpr auto get_wrapper(Catch::Detail::priority_tag<0>) noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
|
||||
\
|
||||
template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
|
||||
struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
|
||||
@@ -163,13 +172,14 @@
|
||||
template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
|
||||
static void TestName()
|
||||
|
||||
#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
|
||||
template<typename Type>\
|
||||
void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
|
||||
#define INTERNAL_CATCH_TYPES_REGISTER(TestFunc)\
|
||||
template<typename... Ts>\
|
||||
void reg_test(TypeList<Ts...>, Catch::NameAndTags nameAndTags)\
|
||||
{\
|
||||
Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
|
||||
Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Ts...>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
|
||||
}
|
||||
|
||||
#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature, ...)
|
||||
#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
|
||||
template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
|
||||
void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
|
||||
@@ -218,7 +228,7 @@
|
||||
#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_TYPES_REGISTER(TestFunc) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
|
||||
@@ -228,7 +238,7 @@
|
||||
#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_TYPES_REGISTER(TestFunc) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
|
||||
#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
|
||||
|
@@ -7,6 +7,12 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/internal/catch_random_number_generator.hpp>
|
||||
|
||||
#if defined( __clang__ )
|
||||
# define CATCH2_CLANG_NO_SANITIZE_INTEGER \
|
||||
__attribute__( ( no_sanitize( "unsigned-integer-overflow" ) ) )
|
||||
#else
|
||||
# define CATCH2_CLANG_NO_SANITIZE_INTEGER
|
||||
#endif
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
@@ -16,6 +22,7 @@ namespace {
|
||||
#pragma warning(disable:4146) // we negate uint32 during the rotate
|
||||
#endif
|
||||
// Safe rotr implementation thanks to John Regehr
|
||||
CATCH2_CLANG_NO_SANITIZE_INTEGER
|
||||
uint32_t rotate_right(uint32_t val, uint32_t count) {
|
||||
const uint32_t mask = 31;
|
||||
count &= mask;
|
||||
@@ -49,6 +56,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
CATCH2_CLANG_NO_SANITIZE_INTEGER
|
||||
SimplePcg32::result_type SimplePcg32::operator()() {
|
||||
// prepare the output value
|
||||
const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
|
||||
|
@@ -7,10 +7,12 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/internal/catch_reusable_string_stream.hpp>
|
||||
#include <catch2/internal/catch_singletons.hpp>
|
||||
#include <catch2/internal/catch_thread_support.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace Catch {
|
||||
@@ -20,34 +22,40 @@ namespace Catch {
|
||||
std::vector<Detail::unique_ptr<std::ostringstream>> m_streams;
|
||||
std::vector<std::size_t> m_unused;
|
||||
std::ostringstream m_referenceStream; // Used for copy state/ flags from
|
||||
Detail::Mutex m_mutex;
|
||||
|
||||
auto add() -> std::size_t {
|
||||
auto add() -> std::pair<std::size_t, std::ostringstream*> {
|
||||
Detail::LockGuard _( m_mutex );
|
||||
if( m_unused.empty() ) {
|
||||
m_streams.push_back( Detail::make_unique<std::ostringstream>() );
|
||||
return m_streams.size()-1;
|
||||
return { m_streams.size()-1, m_streams.back().get() };
|
||||
}
|
||||
else {
|
||||
auto index = m_unused.back();
|
||||
m_unused.pop_back();
|
||||
return index;
|
||||
return { index, m_streams[index].get() };
|
||||
}
|
||||
}
|
||||
|
||||
void release( std::size_t index ) {
|
||||
m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
|
||||
m_unused.push_back(index);
|
||||
void release( std::size_t index, std::ostream* originalPtr ) {
|
||||
assert( originalPtr );
|
||||
originalPtr->copyfmt( m_referenceStream ); // Restore initial flags and other state
|
||||
|
||||
Detail::LockGuard _( m_mutex );
|
||||
assert( originalPtr == m_streams[index].get() && "Mismatch between release index and stream ptr" );
|
||||
m_unused.push_back( index );
|
||||
}
|
||||
};
|
||||
|
||||
ReusableStringStream::ReusableStringStream()
|
||||
: m_index( Singleton<StringStreams>::getMutable().add() ),
|
||||
m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
|
||||
{}
|
||||
ReusableStringStream::ReusableStringStream() {
|
||||
std::tie( m_index, m_oss ) =
|
||||
Singleton<StringStreams>::getMutable().add();
|
||||
}
|
||||
|
||||
ReusableStringStream::~ReusableStringStream() {
|
||||
static_cast<std::ostringstream*>( m_oss )->str("");
|
||||
m_oss->clear();
|
||||
Singleton<StringStreams>::getMutable().release( m_index );
|
||||
Singleton<StringStreams>::getMutable().release( m_index, m_oss );
|
||||
}
|
||||
|
||||
std::string ReusableStringStream::str() const {
|
||||
|
@@ -165,23 +165,64 @@ namespace Catch {
|
||||
} // namespace
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
// Assertions are owned by the thread that is executing them.
|
||||
// This allows for lock-free progress in common cases where we
|
||||
// do not need to send the assertion events to the reporter.
|
||||
// This also implies that messages are owned by their respective
|
||||
// threads, and should not be shared across different threads.
|
||||
//
|
||||
// This implies that various pieces of metadata referring to last
|
||||
// assertion result/source location/message handling, etc
|
||||
// should also be thread local. For now we just use naked globals
|
||||
// below, in the future we will want to allocate piece of memory
|
||||
// from heap, to avoid consuming too much thread-local storage.
|
||||
|
||||
// This is used for the "if" part of CHECKED_IF/CHECKED_ELSE
|
||||
static thread_local bool g_lastAssertionPassed = false;
|
||||
|
||||
// This is the source location for last encountered macro. It is
|
||||
// used to provide the users with more precise location of error
|
||||
// when an unexpected exception/fatal error happens.
|
||||
static thread_local SourceLineInfo g_lastKnownLineInfo("DummyLocation", static_cast<size_t>(-1));
|
||||
|
||||
// Should we clear message scopes before sending off the messages to
|
||||
// reporter? Set in `assertionPassedFastPath` to avoid doing the full
|
||||
// clear there for performance reasons.
|
||||
static thread_local bool g_clearMessageScopes = false;
|
||||
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
|
||||
// Actual messages to be provided to the reporter
|
||||
static thread_local std::vector<MessageInfo> g_messages;
|
||||
|
||||
// Owners for the UNSCOPED_X information macro
|
||||
static thread_local std::vector<ScopedMessage> g_messageScopes;
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter)
|
||||
: m_runInfo(_config->name()),
|
||||
m_config(_config),
|
||||
m_reporter(CATCH_MOVE(reporter)),
|
||||
m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
|
||||
m_outputRedirect( makeOutputRedirect( m_reporter->getPreferences().shouldRedirectStdOut ) ),
|
||||
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
|
||||
m_abortAfterXFailedAssertions( m_config->abortAfter() ),
|
||||
m_reportAssertionStarting( m_reporter->getPreferences().shouldReportAllAssertionStarts ),
|
||||
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions ),
|
||||
m_shouldDebugBreak( m_config->shouldDebugBreak() )
|
||||
{
|
||||
getCurrentMutableContext().setResultCapture( this );
|
||||
m_reporter->testRunStarting(m_runInfo);
|
||||
}
|
||||
|
||||
RunContext::~RunContext() {
|
||||
updateTotalsFromAtomics();
|
||||
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
|
||||
}
|
||||
|
||||
Totals RunContext::runTest(TestCaseHandle const& testCase) {
|
||||
updateTotalsFromAtomics();
|
||||
const Totals prevTotals = m_totals;
|
||||
|
||||
auto const& testInfo = testCase.getTestCaseInfo();
|
||||
@@ -236,6 +277,7 @@ namespace Catch {
|
||||
|
||||
m_reporter->testCasePartialStarting(testInfo, testRuns);
|
||||
|
||||
updateTotalsFromAtomics();
|
||||
const auto beforeRunTotals = m_totals;
|
||||
runCurrentTest();
|
||||
std::string oneRunCout = m_outputRedirect->getStdout();
|
||||
@@ -244,6 +286,7 @@ namespace Catch {
|
||||
redirectedCout += oneRunCout;
|
||||
redirectedCerr += oneRunCerr;
|
||||
|
||||
updateTotalsFromAtomics();
|
||||
const auto singleRunTotals = m_totals.delta(beforeRunTotals);
|
||||
auto statsForOneRun = TestCaseStats(testInfo, singleRunTotals, CATCH_MOVE(oneRunCout), CATCH_MOVE(oneRunCerr), aborting());
|
||||
m_reporter->testCasePartialEnded(statsForOneRun, testRuns);
|
||||
@@ -273,47 +316,54 @@ namespace Catch {
|
||||
|
||||
|
||||
void RunContext::assertionEnded(AssertionResult&& result) {
|
||||
Detail::g_lastKnownLineInfo = result.m_info.lineInfo;
|
||||
if (result.getResultType() == ResultWas::Ok) {
|
||||
m_totals.assertions.passed++;
|
||||
m_lastAssertionPassed = true;
|
||||
m_atomicAssertionCount.passed++;
|
||||
Detail::g_lastAssertionPassed = true;
|
||||
} else if (result.getResultType() == ResultWas::ExplicitSkip) {
|
||||
m_totals.assertions.skipped++;
|
||||
m_lastAssertionPassed = true;
|
||||
m_atomicAssertionCount.skipped++;
|
||||
Detail::g_lastAssertionPassed = true;
|
||||
} else if (!result.succeeded()) {
|
||||
m_lastAssertionPassed = false;
|
||||
Detail::g_lastAssertionPassed = false;
|
||||
if (result.isOk()) {
|
||||
}
|
||||
else if( m_activeTestCase->getTestCaseInfo().okToFail() )
|
||||
m_totals.assertions.failedButOk++;
|
||||
else if( m_activeTestCase->getTestCaseInfo().okToFail() ) // Read from a shared state established before the threads could start, this is fine
|
||||
m_atomicAssertionCount.failedButOk++;
|
||||
else
|
||||
m_totals.assertions.failed++;
|
||||
m_atomicAssertionCount.failed++;
|
||||
}
|
||||
else {
|
||||
m_lastAssertionPassed = true;
|
||||
Detail::g_lastAssertionPassed = true;
|
||||
}
|
||||
|
||||
if ( Detail::g_clearMessageScopes ) {
|
||||
Detail::g_messageScopes.clear();
|
||||
Detail::g_clearMessageScopes = false;
|
||||
}
|
||||
|
||||
// From here, we are touching shared state and need mutex.
|
||||
Detail::LockGuard lock( m_assertionMutex );
|
||||
{
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) );
|
||||
updateTotalsFromAtomics();
|
||||
m_reporter->assertionEnded( AssertionStats( result, Detail::g_messages, m_totals ) );
|
||||
}
|
||||
|
||||
if ( result.getResultType() != ResultWas::Warning ) {
|
||||
m_messageScopes.clear();
|
||||
Detail::g_messageScopes.clear();
|
||||
}
|
||||
|
||||
// Reset working state. assertion info will be reset after
|
||||
// populateReaction is run if it is needed
|
||||
m_lastResult = CATCH_MOVE( result );
|
||||
}
|
||||
void RunContext::resetAssertionInfo() {
|
||||
m_lastAssertionInfo.macroName = StringRef();
|
||||
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
|
||||
m_lastAssertionInfo.resultDisposition = ResultDisposition::Normal;
|
||||
}
|
||||
|
||||
void RunContext::notifyAssertionStarted( AssertionInfo const& info ) {
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
m_reporter->assertionStarting( info );
|
||||
if (m_reportAssertionStarting) {
|
||||
Detail::LockGuard lock( m_assertionMutex );
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
m_reporter->assertionStarting( info );
|
||||
}
|
||||
}
|
||||
|
||||
bool RunContext::sectionStarted( StringRef sectionName,
|
||||
@@ -329,13 +379,14 @@ namespace Catch {
|
||||
m_activeSections.push_back(§ionTracker);
|
||||
|
||||
SectionInfo sectionInfo( sectionLineInfo, static_cast<std::string>(sectionName) );
|
||||
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
|
||||
Detail::g_lastKnownLineInfo = sectionLineInfo;
|
||||
|
||||
{
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
m_reporter->sectionStarting( sectionInfo );
|
||||
}
|
||||
|
||||
updateTotalsFromAtomics();
|
||||
assertions = m_totals.assertions;
|
||||
|
||||
return true;
|
||||
@@ -343,12 +394,11 @@ namespace Catch {
|
||||
IGeneratorTracker*
|
||||
RunContext::acquireGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo const& lineInfo ) {
|
||||
using namespace Generators;
|
||||
GeneratorTracker* tracker = GeneratorTracker::acquire(
|
||||
auto* tracker = Generators::GeneratorTracker::acquire(
|
||||
m_trackerContext,
|
||||
TestCaseTracking::NameAndLocationRef(
|
||||
generatorName, lineInfo ) );
|
||||
m_lastAssertionInfo.lineInfo = lineInfo;
|
||||
Detail::g_lastKnownLineInfo = lineInfo;
|
||||
return tracker;
|
||||
}
|
||||
|
||||
@@ -380,12 +430,13 @@ namespace Catch {
|
||||
return false;
|
||||
if (m_trackerContext.currentTracker().hasChildren())
|
||||
return false;
|
||||
m_totals.assertions.failed++;
|
||||
m_atomicAssertionCount.failed++;
|
||||
assertions.failed++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RunContext::sectionEnded(SectionEndInfo&& endInfo) {
|
||||
updateTotalsFromAtomics();
|
||||
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
|
||||
bool missingAssertions = testForMissingAssertions(assertions);
|
||||
|
||||
@@ -402,9 +453,6 @@ namespace Catch {
|
||||
endInfo.durationInSeconds,
|
||||
missingAssertions ) );
|
||||
}
|
||||
|
||||
m_messages.clear();
|
||||
m_messageScopes.clear();
|
||||
}
|
||||
|
||||
void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) {
|
||||
@@ -435,18 +483,6 @@ namespace Catch {
|
||||
m_reporter->benchmarkFailed( error );
|
||||
}
|
||||
|
||||
void RunContext::pushScopedMessage(MessageInfo const & message) {
|
||||
m_messages.push_back(message);
|
||||
}
|
||||
|
||||
void RunContext::popScopedMessage(MessageInfo const & message) {
|
||||
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
|
||||
}
|
||||
|
||||
void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) {
|
||||
m_messageScopes.emplace_back( CATCH_MOVE(builder) );
|
||||
}
|
||||
|
||||
std::string RunContext::getCurrentTestName() const {
|
||||
return m_activeTestCase
|
||||
? m_activeTestCase->getTestCaseInfo().name
|
||||
@@ -454,6 +490,18 @@ namespace Catch {
|
||||
}
|
||||
|
||||
const AssertionResult * RunContext::getLastResult() const {
|
||||
// m_lastResult is updated inside the assertion slow-path, under
|
||||
// a mutex, so the read needs to happen under mutex as well.
|
||||
|
||||
// TBD: The last result only makes sense if it is a thread-local
|
||||
// thing, because the answer is different per thread, like
|
||||
// last line info, whether last assertion passed, and so on.
|
||||
//
|
||||
// However, the last result was also never updated in the
|
||||
// assertion fast path, so it was always somewhat broken,
|
||||
// and since IResultCapture::getLastResult is deprecated,
|
||||
// we will leave it as is, until it is finally removed.
|
||||
Detail::LockGuard _( m_assertionMutex );
|
||||
return &(*m_lastResult);
|
||||
}
|
||||
|
||||
@@ -462,28 +510,44 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void RunContext::handleFatalErrorCondition( StringRef message ) {
|
||||
// TODO: scoped deactivate here? Just give up and do best effort?
|
||||
// the deactivation can break things further, OTOH so can the
|
||||
// capture
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
// We lock only when touching the reporters directly, to avoid
|
||||
// deadlocks when we call into other functions that also want
|
||||
// to lock the mutex before touching reporters.
|
||||
//
|
||||
// This does mean that we allow other threads to run while handling
|
||||
// a fatal error, but this is all a best effort attempt anyway.
|
||||
{
|
||||
Detail::LockGuard lock( m_assertionMutex );
|
||||
// TODO: scoped deactivate here? Just give up and do best effort?
|
||||
// the deactivation can break things further, OTOH so can the
|
||||
// capture
|
||||
auto _ = scopedDeactivate( *m_outputRedirect );
|
||||
|
||||
// First notify reporter that bad things happened
|
||||
m_reporter->fatalErrorEncountered( message );
|
||||
// First notify reporter that bad things happened
|
||||
m_reporter->fatalErrorEncountered( message );
|
||||
}
|
||||
|
||||
// Don't rebuild the result -- the stringification itself can cause more fatal errors
|
||||
// Instead, fake a result data.
|
||||
AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
|
||||
tempResult.message = static_cast<std::string>(message);
|
||||
AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult));
|
||||
AssertionResult result( makeDummyAssertionInfo(),
|
||||
CATCH_MOVE( tempResult ) );
|
||||
|
||||
assertionEnded(CATCH_MOVE(result) );
|
||||
resetAssertionInfo();
|
||||
|
||||
|
||||
// At this point we touch sections/test cases from this thread
|
||||
// to try and end them. Technically that is not supported when
|
||||
// using multiple threads, but the worst thing that can happen
|
||||
// is that the process aborts harder :-D
|
||||
Detail::LockGuard lock( m_assertionMutex );
|
||||
|
||||
// Best effort cleanup for sections that have not been destructed yet
|
||||
// Since this is a fatal error, we have not had and won't have the opportunity to destruct them properly
|
||||
while (!m_activeSections.empty()) {
|
||||
auto nl = m_activeSections.back()->nameAndLocation();
|
||||
SectionEndInfo endInfo{ SectionInfo(CATCH_MOVE(nl.location), CATCH_MOVE(nl.name)), {}, 0.0 };
|
||||
auto const& nl = m_activeSections.back()->nameAndLocation();
|
||||
SectionEndInfo endInfo{ SectionInfo(nl.location, nl.name), {}, 0.0 };
|
||||
sectionEndedEarly(CATCH_MOVE(endInfo));
|
||||
}
|
||||
handleUnfinishedSections();
|
||||
@@ -508,32 +572,44 @@ namespace Catch {
|
||||
std::string(),
|
||||
false));
|
||||
m_totals.testCases.failed++;
|
||||
updateTotalsFromAtomics();
|
||||
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
|
||||
}
|
||||
|
||||
bool RunContext::lastAssertionPassed() {
|
||||
return m_lastAssertionPassed;
|
||||
return Detail::g_lastAssertionPassed;
|
||||
}
|
||||
|
||||
void RunContext::assertionPassed() {
|
||||
m_lastAssertionPassed = true;
|
||||
++m_totals.assertions.passed;
|
||||
resetAssertionInfo();
|
||||
m_messageScopes.clear();
|
||||
void RunContext::assertionPassedFastPath(SourceLineInfo lineInfo) {
|
||||
// We want to save the line info for better experience with unexpected assertions
|
||||
Detail::g_lastKnownLineInfo = lineInfo;
|
||||
++m_atomicAssertionCount.passed;
|
||||
Detail::g_lastAssertionPassed = true;
|
||||
Detail::g_clearMessageScopes = true;
|
||||
}
|
||||
|
||||
void RunContext::updateTotalsFromAtomics() {
|
||||
m_totals.assertions = Counts{
|
||||
m_atomicAssertionCount.passed,
|
||||
m_atomicAssertionCount.failed,
|
||||
m_atomicAssertionCount.failedButOk,
|
||||
m_atomicAssertionCount.skipped,
|
||||
};
|
||||
}
|
||||
|
||||
bool RunContext::aborting() const {
|
||||
return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
|
||||
return m_atomicAssertionCount.failed >= m_abortAfterXFailedAssertions;
|
||||
}
|
||||
|
||||
void RunContext::runCurrentTest() {
|
||||
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
||||
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
|
||||
m_reporter->sectionStarting(testCaseSection);
|
||||
updateTotalsFromAtomics();
|
||||
Counts prevAssertions = m_totals.assertions;
|
||||
double duration = 0;
|
||||
m_shouldReportUnexpected = true;
|
||||
m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
|
||||
Detail::g_lastKnownLineInfo = testCaseInfo.lineInfo;
|
||||
|
||||
Timer timer;
|
||||
CATCH_TRY {
|
||||
@@ -550,18 +626,23 @@ namespace Catch {
|
||||
} CATCH_CATCH_ALL {
|
||||
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
|
||||
// are reported without translation at the point of origin.
|
||||
if( m_shouldReportUnexpected ) {
|
||||
if ( m_shouldReportUnexpected ) {
|
||||
AssertionReaction dummyReaction;
|
||||
handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
|
||||
handleUnexpectedInflightException( makeDummyAssertionInfo(),
|
||||
translateActiveException(),
|
||||
dummyReaction );
|
||||
}
|
||||
}
|
||||
updateTotalsFromAtomics();
|
||||
Counts assertions = m_totals.assertions - prevAssertions;
|
||||
bool missingAssertions = testForMissingAssertions(assertions);
|
||||
|
||||
m_testCaseTracker->close();
|
||||
handleUnfinishedSections();
|
||||
m_messages.clear();
|
||||
m_messageScopes.clear();
|
||||
Detail::g_messageScopes.clear();
|
||||
// TBD: At this point, m_messages should be empty. Do we want to
|
||||
// assert that this is true, or keep the defensive clear call?
|
||||
Detail::g_messages.clear();
|
||||
|
||||
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions);
|
||||
m_reporter->sectionEnded(testCaseSectionStats);
|
||||
@@ -602,7 +683,7 @@ namespace Catch {
|
||||
|
||||
if( result ) {
|
||||
if (!m_includeSuccessfulResults) {
|
||||
assertionPassed();
|
||||
assertionPassedFastPath(info.lineInfo);
|
||||
}
|
||||
else {
|
||||
reportExpr(info, ResultWas::Ok, &expr, negated);
|
||||
@@ -610,9 +691,9 @@ namespace Catch {
|
||||
}
|
||||
else {
|
||||
reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
|
||||
populateReaction( reaction );
|
||||
populateReaction(
|
||||
reaction, info.resultDisposition & ResultDisposition::Normal );
|
||||
}
|
||||
resetAssertionInfo();
|
||||
}
|
||||
void RunContext::reportExpr(
|
||||
AssertionInfo const &info,
|
||||
@@ -620,7 +701,7 @@ namespace Catch {
|
||||
ITransientExpression const *expr,
|
||||
bool negated ) {
|
||||
|
||||
m_lastAssertionInfo = info;
|
||||
Detail::g_lastKnownLineInfo = info.lineInfo;
|
||||
AssertionResultData data( resultType, LazyExpression( negated ) );
|
||||
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
|
||||
@@ -635,24 +716,25 @@ namespace Catch {
|
||||
std::string&& message,
|
||||
AssertionReaction& reaction
|
||||
) {
|
||||
m_lastAssertionInfo = info;
|
||||
Detail::g_lastKnownLineInfo = info.lineInfo;
|
||||
|
||||
AssertionResultData data( resultType, LazyExpression( false ) );
|
||||
data.message = CATCH_MOVE( message );
|
||||
AssertionResult assertionResult{ m_lastAssertionInfo,
|
||||
AssertionResult assertionResult{ info,
|
||||
CATCH_MOVE( data ) };
|
||||
|
||||
const auto isOk = assertionResult.isOk();
|
||||
assertionEnded( CATCH_MOVE(assertionResult) );
|
||||
if ( !isOk ) {
|
||||
populateReaction( reaction );
|
||||
populateReaction(
|
||||
reaction, info.resultDisposition & ResultDisposition::Normal );
|
||||
} else if ( resultType == ResultWas::ExplicitSkip ) {
|
||||
// TODO: Need to handle this explicitly, as ExplicitSkip is
|
||||
// considered "OK"
|
||||
reaction.shouldSkip = true;
|
||||
}
|
||||
resetAssertionInfo();
|
||||
}
|
||||
|
||||
void RunContext::handleUnexpectedExceptionNotThrown(
|
||||
AssertionInfo const& info,
|
||||
AssertionReaction& reaction
|
||||
@@ -665,55 +747,88 @@ namespace Catch {
|
||||
std::string&& message,
|
||||
AssertionReaction& reaction
|
||||
) {
|
||||
m_lastAssertionInfo = info;
|
||||
Detail::g_lastKnownLineInfo = info.lineInfo;
|
||||
|
||||
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
|
||||
data.message = CATCH_MOVE(message);
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE(data) };
|
||||
assertionEnded( CATCH_MOVE(assertionResult) );
|
||||
populateReaction( reaction );
|
||||
resetAssertionInfo();
|
||||
populateReaction( reaction,
|
||||
info.resultDisposition & ResultDisposition::Normal );
|
||||
}
|
||||
|
||||
void RunContext::populateReaction( AssertionReaction& reaction ) {
|
||||
reaction.shouldDebugBreak = m_config->shouldDebugBreak();
|
||||
reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
|
||||
void RunContext::populateReaction( AssertionReaction& reaction,
|
||||
bool has_normal_disposition ) {
|
||||
reaction.shouldDebugBreak = m_shouldDebugBreak;
|
||||
reaction.shouldThrow = aborting() || has_normal_disposition;
|
||||
}
|
||||
|
||||
AssertionInfo RunContext::makeDummyAssertionInfo() {
|
||||
const bool testCaseJustStarted =
|
||||
Detail::g_lastKnownLineInfo ==
|
||||
m_activeTestCase->getTestCaseInfo().lineInfo;
|
||||
|
||||
return AssertionInfo{
|
||||
testCaseJustStarted ? "TEST_CASE"_sr : StringRef(),
|
||||
Detail::g_lastKnownLineInfo,
|
||||
testCaseJustStarted ? StringRef() : "{Unknown expression after the reported line}"_sr,
|
||||
ResultDisposition::Normal
|
||||
};
|
||||
}
|
||||
|
||||
void RunContext::handleIncomplete(
|
||||
AssertionInfo const& info
|
||||
) {
|
||||
using namespace std::string_literals;
|
||||
m_lastAssertionInfo = info;
|
||||
Detail::g_lastKnownLineInfo = info.lineInfo;
|
||||
|
||||
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( CATCH_MOVE(assertionResult) );
|
||||
resetAssertionInfo();
|
||||
}
|
||||
|
||||
void RunContext::handleNonExpr(
|
||||
AssertionInfo const &info,
|
||||
ResultWas::OfType resultType,
|
||||
AssertionReaction &reaction
|
||||
) {
|
||||
m_lastAssertionInfo = info;
|
||||
|
||||
AssertionResultData data( resultType, LazyExpression( false ) );
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
|
||||
|
||||
const auto isOk = assertionResult.isOk();
|
||||
if ( isOk && !m_includeSuccessfulResults ) {
|
||||
assertionPassedFastPath( info.lineInfo );
|
||||
return;
|
||||
}
|
||||
|
||||
assertionEnded( CATCH_MOVE(assertionResult) );
|
||||
if ( !isOk ) { populateReaction( reaction ); }
|
||||
resetAssertionInfo();
|
||||
if ( !isOk ) {
|
||||
populateReaction(
|
||||
reaction, info.resultDisposition & ResultDisposition::Normal );
|
||||
}
|
||||
}
|
||||
|
||||
void IResultCapture::pushScopedMessage( MessageInfo&& message ) {
|
||||
Detail::g_messages.push_back( CATCH_MOVE( message ) );
|
||||
}
|
||||
|
||||
IResultCapture& getResultCapture() {
|
||||
if (auto* capture = getCurrentContext().getResultCapture())
|
||||
return *capture;
|
||||
else
|
||||
CATCH_INTERNAL_ERROR("No result capture instance");
|
||||
void IResultCapture::popScopedMessage( unsigned int messageId ) {
|
||||
// Note: On average, it would probably be better to look for the message
|
||||
// backwards. However, we do not expect to have to deal with more
|
||||
// messages than low single digits, so the optimization is tiny,
|
||||
// and we would have to hand-write the loop to avoid terrible
|
||||
// codegen of reverse iterators in debug mode.
|
||||
Detail::g_messages.erase( std::find_if( Detail::g_messages.begin(),
|
||||
Detail::g_messages.end(),
|
||||
[=]( MessageInfo const& msg ) {
|
||||
return msg.sequence ==
|
||||
messageId;
|
||||
} ) );
|
||||
}
|
||||
|
||||
void IResultCapture::emplaceUnscopedMessage( MessageBuilder&& builder ) {
|
||||
Detail::g_messageScopes.emplace_back( CATCH_MOVE( builder ) );
|
||||
}
|
||||
|
||||
void seedRng(IConfig const& config) {
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <catch2/interfaces/catch_interfaces_capture.hpp>
|
||||
#include <catch2/internal/catch_test_registry.hpp>
|
||||
#include <catch2/internal/catch_test_run_info.hpp>
|
||||
#include <catch2/catch_test_run_info.hpp>
|
||||
#include <catch2/internal/catch_fatal_condition_handler.hpp>
|
||||
#include <catch2/catch_test_case_info.hpp>
|
||||
#include <catch2/catch_message.hpp>
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <catch2/catch_assertion_result.hpp>
|
||||
#include <catch2/internal/catch_optional.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_thread_support.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -93,11 +94,6 @@ namespace Catch {
|
||||
void benchmarkEnded( BenchmarkStats<> const& stats ) override;
|
||||
void benchmarkFailed( StringRef error ) override;
|
||||
|
||||
void pushScopedMessage( MessageInfo const& message ) override;
|
||||
void popScopedMessage( MessageInfo const& message ) override;
|
||||
|
||||
void emplaceUnscopedMessage( MessageBuilder&& builder ) override;
|
||||
|
||||
std::string getCurrentTestName() const override;
|
||||
|
||||
const AssertionResult* getLastResult() const override;
|
||||
@@ -108,18 +104,18 @@ namespace Catch {
|
||||
|
||||
bool lastAssertionPassed() override;
|
||||
|
||||
void assertionPassed() override;
|
||||
|
||||
public:
|
||||
// !TBD We need to do this another way!
|
||||
bool aborting() const;
|
||||
|
||||
private:
|
||||
void assertionPassedFastPath( SourceLineInfo lineInfo );
|
||||
// Update the non-thread-safe m_totals from the atomic assertion counts.
|
||||
void updateTotalsFromAtomics();
|
||||
|
||||
void runCurrentTest();
|
||||
void invokeActiveTestCase();
|
||||
|
||||
void resetAssertionInfo();
|
||||
bool testForMissingAssertions( Counts& assertions );
|
||||
|
||||
void assertionEnded( AssertionResult&& result );
|
||||
@@ -129,31 +125,39 @@ namespace Catch {
|
||||
ITransientExpression const *expr,
|
||||
bool negated );
|
||||
|
||||
void populateReaction( AssertionReaction& reaction );
|
||||
void populateReaction( AssertionReaction& reaction, bool has_normal_disposition );
|
||||
|
||||
// Creates dummy info for unexpected exceptions/fatal errors,
|
||||
// where we do not have the access to one, but we still need
|
||||
// to send one to the reporters.
|
||||
AssertionInfo makeDummyAssertionInfo();
|
||||
|
||||
private:
|
||||
|
||||
void handleUnfinishedSections();
|
||||
|
||||
mutable Detail::Mutex m_assertionMutex;
|
||||
TestRunInfo m_runInfo;
|
||||
TestCaseHandle const* m_activeTestCase = nullptr;
|
||||
ITracker* m_testCaseTracker = nullptr;
|
||||
Optional<AssertionResult> m_lastResult;
|
||||
|
||||
IConfig const* m_config;
|
||||
Totals m_totals;
|
||||
Detail::AtomicCounts m_atomicAssertionCount;
|
||||
IEventListenerPtr m_reporter;
|
||||
std::vector<MessageInfo> m_messages;
|
||||
std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
|
||||
AssertionInfo m_lastAssertionInfo;
|
||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||
std::vector<ITracker*> m_activeSections;
|
||||
TrackerContext m_trackerContext;
|
||||
Detail::unique_ptr<OutputRedirect> m_outputRedirect;
|
||||
FatalConditionHandler m_fatalConditionhandler;
|
||||
bool m_lastAssertionPassed = false;
|
||||
// Caches m_config->abortAfter() to avoid vptr calls/allow inlining
|
||||
size_t m_abortAfterXFailedAssertions;
|
||||
bool m_shouldReportUnexpected = true;
|
||||
// Caches whether `assertionStarting` events should be sent to the reporter.
|
||||
bool m_reportAssertionStarting;
|
||||
// Caches whether `assertionEnded` events for successful assertions should be sent to the reporter
|
||||
bool m_includeSuccessfulResults;
|
||||
// Caches m_config->shouldDebugBreak() to avoid vptr calls/allow inlining
|
||||
bool m_shouldDebugBreak;
|
||||
};
|
||||
|
||||
void seedRng(IConfig const& config);
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef CATCH_STRING_MANIP_HPP_INCLUDED
|
||||
#define CATCH_STRING_MANIP_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_lifetimebound.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -28,10 +29,10 @@ namespace Catch {
|
||||
//! Returns a new string without whitespace at the start/end
|
||||
std::string trim( std::string const& str );
|
||||
//! Returns a substring of the original ref without whitespace. Beware lifetimes!
|
||||
StringRef trim(StringRef ref);
|
||||
StringRef trim( StringRef ref CATCH_ATTR_LIFETIMEBOUND );
|
||||
|
||||
// !!! Be aware, returns refs into original string - make sure original string outlives them
|
||||
std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
|
||||
std::vector<StringRef> splitStringRef( StringRef str CATCH_ATTR_LIFETIMEBOUND, char delimiter );
|
||||
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
|
||||
|
||||
/**
|
||||
@@ -49,7 +50,7 @@ namespace Catch {
|
||||
StringRef m_label;
|
||||
|
||||
public:
|
||||
constexpr pluralise(std::uint64_t count, StringRef label):
|
||||
constexpr pluralise(std::uint64_t count, StringRef label CATCH_ATTR_LIFETIMEBOUND):
|
||||
m_count(count),
|
||||
m_label(label)
|
||||
{}
|
||||
|
@@ -8,11 +8,12 @@
|
||||
#ifndef CATCH_STRINGREF_HPP_INCLUDED
|
||||
#define CATCH_STRINGREF_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_lifetimebound.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Catch {
|
||||
@@ -36,14 +37,16 @@ namespace Catch {
|
||||
public: // construction
|
||||
constexpr StringRef() noexcept = default;
|
||||
|
||||
StringRef( char const* rawChars ) noexcept;
|
||||
StringRef( char const* rawChars CATCH_ATTR_LIFETIMEBOUND ) noexcept;
|
||||
|
||||
constexpr StringRef( char const* rawChars, size_type size ) noexcept
|
||||
constexpr StringRef( char const* rawChars CATCH_ATTR_LIFETIMEBOUND,
|
||||
size_type size ) noexcept
|
||||
: m_start( rawChars ),
|
||||
m_size( size )
|
||||
{}
|
||||
|
||||
StringRef( std::string const& stdString ) noexcept
|
||||
StringRef(
|
||||
std::string const& stdString CATCH_ATTR_LIFETIMEBOUND ) noexcept
|
||||
: m_start( stdString.c_str() ),
|
||||
m_size( stdString.size() )
|
||||
{}
|
||||
@@ -89,7 +92,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
// Returns the current start pointer. May not be null-terminated.
|
||||
constexpr char const* data() const noexcept {
|
||||
constexpr char const* data() const noexcept CATCH_ATTR_LIFETIMEBOUND {
|
||||
return m_start;
|
||||
}
|
||||
|
||||
|
@@ -135,11 +135,11 @@
|
||||
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
|
||||
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
|
||||
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags } ), index++)... };/* NOLINT */\
|
||||
} \
|
||||
}; \
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
|
||||
using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
|
||||
using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(Catch::Detail::priority_tag<1>{})), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
|
||||
TestInit t; \
|
||||
t.reg_tests(); \
|
||||
return 0; \
|
||||
@@ -184,7 +184,7 @@
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
|
||||
} \
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
|
||||
using TestInit = typename convert<TestName, TmplList>::type; \
|
||||
TestInit t; \
|
||||
t.reg_tests(); \
|
||||
@@ -220,7 +220,7 @@
|
||||
(void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
|
||||
return 0;\
|
||||
}();\
|
||||
@@ -267,11 +267,11 @@
|
||||
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
|
||||
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
|
||||
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */ \
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags } ), index++)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(Catch::Detail::priority_tag<1>{})), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
|
||||
TestInit t;\
|
||||
t.reg_tests();\
|
||||
return 0;\
|
||||
@@ -319,7 +319,7 @@
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
using TestInit = typename convert<TestNameClass, TmplList>::type;\
|
||||
TestInit t;\
|
||||
t.reg_tests();\
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
||||
#define CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_lifetimebound.hpp>
|
||||
#include <catch2/internal/catch_source_line_info.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
@@ -48,7 +49,7 @@ namespace TestCaseTracking {
|
||||
StringRef name;
|
||||
SourceLineInfo location;
|
||||
|
||||
constexpr NameAndLocationRef( StringRef name_,
|
||||
constexpr NameAndLocationRef( StringRef name_ CATCH_ATTR_LIFETIMEBOUND,
|
||||
SourceLineInfo location_ ):
|
||||
name( name_ ), location( location_ ) {}
|
||||
|
||||
|
49
src/catch2/internal/catch_thread_support.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
// 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_THREAD_SUPPORT_HPP_INCLUDED
|
||||
#define CATCH_THREAD_SUPPORT_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_user_config.hpp>
|
||||
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS )
|
||||
# include <atomic>
|
||||
# include <mutex>
|
||||
#endif
|
||||
|
||||
#include <catch2/catch_totals.hpp>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS )
|
||||
using Mutex = std::mutex;
|
||||
using LockGuard = std::lock_guard<std::mutex>;
|
||||
struct AtomicCounts {
|
||||
std::atomic<std::uint64_t> passed = 0;
|
||||
std::atomic<std::uint64_t> failed = 0;
|
||||
std::atomic<std::uint64_t> failedButOk = 0;
|
||||
std::atomic<std::uint64_t> skipped = 0;
|
||||
};
|
||||
#else // ^^ Use actual mutex, lock and atomics
|
||||
// vv Dummy implementations for single-thread performance
|
||||
|
||||
struct Mutex {
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
};
|
||||
|
||||
struct LockGuard {
|
||||
LockGuard( Mutex ) {}
|
||||
};
|
||||
|
||||
using AtomicCounts = Counts;
|
||||
#endif
|
||||
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_THREAD_SUPPORT_HPP_INCLUDED
|
@@ -92,7 +92,7 @@ namespace Detail {
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return m_ptr;
|
||||
return m_ptr != nullptr;
|
||||
}
|
||||
|
||||
friend void swap(unique_ptr& lhs, unique_ptr& rhs) {
|
||||
|