Compare commits

...

97 Commits

Author SHA1 Message Date
Martin Hořeňovský
97c48e0c34 v3.1.0 2022-07-17 20:18:44 +02:00
Martin Hořeňovský
9c9f35068e Normalize C++ namespace in JUnit's reporter classname field
Closes #2468
2022-07-17 19:15:20 +02:00
Raphael Schaller
1bd233866c Add AllTrue, AnyTrue, NoneTrue matchers 2022-07-16 16:16:05 +02:00
Raphael Schaller
f993b702c6 extend gitignore 2022-07-16 16:16:05 +02:00
Martin Hořeňovský
caf1264588 Fixes for matcher testing helpers when testing bools 2022-07-16 16:16:05 +02:00
Martin Hořeňovský
a6d59b62b2 Remove obsolete link to benchmarking tests
The benchmarking feature is now documented, so there is no need
to direct our users towards our test file to understand how it
works.

Closes #2471
2022-07-15 19:49:24 +02:00
Martin Hořeňovský
cc0e91472a Different way of checking for support of local warning suppression
Closes #2474
2022-07-15 19:34:35 +02:00
Martin Hořeňovský
3bd0c58878 Fix Wunused-variable warning for MinGW
Closes #2132
2022-07-11 22:28:15 +02:00
mheimlich
a63ad74554 Added new DL_PATHS option to catch_discover_tests() (#2467)
This enables setting the required PATH/LD_LIBRARY_PATH environment variables both when retrieving the list of text cases and when executing the tests.

Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
2022-07-11 18:31:32 +02:00
Niels Kristian Kjærgård Madsen
5f9109a8dc Fix nvcc compile error (#2477)
Co-authored-by: Niels Kristian Kjærgård Madsen <nkm@kvantify.dk>
2022-07-07 00:03:02 +02:00
Martin Hořeňovský
5a1ef7e4a6 Redo visibility fallback 2022-06-27 13:10:22 +02:00
Martin Hořeňovský
bea58bf8bb Allow building Catch2 as dynamic library
Also have a check that warns users if they try to combined dynamic
library with hidden visibility, which we do not support.

Closes #2397
Closes #2398
2022-06-24 16:26:12 +02:00
Martin Hořeňovský
34d9724058 Add experimental CMake script for sharding tests in binaries 2022-06-24 14:12:55 +02:00
Martin Hořeňovský
5d269045b2 Add section on running tests in parallel to the FAQ 2022-06-24 11:20:31 +02:00
Martin Hořeňovský
95a1206805 Add doc page with best practices and other usage tips 2022-06-24 11:20:22 +02:00
Martin Hořeňovský
6f9f1465c3 Shorten lines in sharding docs 2022-06-22 00:12:16 +02:00
Martin Hořeňovský
8730260457 Split apart combined TUs
The compile time improvements from using combined TUs mostly isn't
worth the annoyance they cause with various IDE shortcuts, like
when switching between header and its impl. file.

Splitting them apart also fixes the issue of empty subdirs being
installed due to `foo/internal` folders that only contained the
combined TUs and no headers.

Closes #2457
Closes #2463
2022-06-21 18:48:44 +02:00
Martin Hořeňovský
bdfa920f93 Use binary path in testBazelReporter reporter output path 2022-06-21 14:21:12 +02:00
Frank Dana
a369267874 test-fixtures.md: Line-wrap code examples (#2464)
* test-fixtures.md: Line-wrap code examples

* relinebreak

Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
2022-06-19 16:24:59 +02:00
Nexus Web Development
1f381a1f62 Update commercial-users.md (#2465)
Using Catch2 and now Catch3 for our client's as well as our own projects and loving it. Especially the easy C++ BDD setup and implementation.
2022-06-18 23:47:49 +02:00
Martin Hořeňovský
165647abbc Change provideBazelReporterOutput to local linkage 2022-06-17 18:23:06 +02:00
Brandon Jones
7e4ec432d0 Change Bazel XML support to depend upon BAZEL_TEST 2022-06-17 16:36:14 +02:00
Martin Hořeňovský
078201fcf4 Remove HOMEPAGE_URL from project call
Closes #2428
2022-06-16 22:16:44 +02:00
Murray Johnson
8110ee9206 Add lib/cmake/Catch2 to conan builddirs in package recipe so extras/*.cmake files are packaged 2022-06-15 10:50:24 +02:00
Martin Hořeňovský
fa9416426a Refactor shared args in approvalTests.py 2022-06-14 23:42:00 +02:00
Martin Hořeňovský
338e4ec1f8 Force disable console colours for tests that regex check output
Fixes #2458
2022-06-14 23:24:06 +02:00
Martin Hořeňovský
372b7575f6 Remove deprecation notice for console colour CLI
The required changes were one of the last commits before the full
v3 release.
2022-06-13 23:52:31 +02:00
Martin Hořeňovský
d32fca4a49 Merge pull request #2452 from lizzyd710/devel
Added Cytopia to opensource-users.md
2022-06-08 15:59:57 +02:00
Morwenn
a0ece7b252 Compatility fixes for GCC5 (#2448)
* GCC5 compat: work around inherited constructor issues

Don't use inherited constructors, forward manually instead. This
basically reverts 61f803126d.

I believe that GCC5 does not implement P0136, a C++17 change that made
inherited constructors actually usable and was backported as a DR all
the way to C++11.

* GCC5 compat: bypass std::pair construction issue

Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
2022-06-07 18:46:46 +02:00
Elizabeth Sherrock
0a810c5e59 Added Cytopia to opensource-users.md 2022-06-07 09:06:10 -04:00
Joe Noël
d0177ee686 Fix implicit long to double conversion
Raises a compiler warning when compiled with `-Wimplicit-int-float-conversion` using clang.
2022-06-07 00:27:37 +02:00
Martin Hořeňovský
173539ab9e Update the 'Try online' badge link for 3.0.1 2022-06-06 00:29:05 +02:00
Martin Hořeňovský
8822e28772 Update CE link in BDD documentation for 3.0.1
The old compiler was no longer built-for, so it couldn't link
against new versions, and also didn't properly provide the
user-config header.

Closes #2396
2022-06-06 00:29:02 +02:00
Martin Hořeňovský
ff9506cedd Only test SEH handling with MSVC
MinGW doesn't support `__try` and friends at all, while Clang
only supports it partially, and the test would require some
changes to make it work there. Since this is only a test, we can
afford to keep it MSVC-only.

Closes #2447
2022-06-06 00:29:01 +02:00
Petr Kubánek
0c13d021da Update documentation - add pkg-config examples.
Use -std=c++14 (instead of c++11). Pointers how to integrate with
pkg-config for non-CMake projects.
2022-06-05 15:58:41 +02:00
balus
3644b4135d Doc: correct the address of the link to the command-line doc in tutorial.md 2022-06-04 10:20:01 +02:00
ahans
1c4f52b24a Suppress NVCC unused variable warnings (#2427)
Closes #2306
2022-06-03 16:17:14 +02:00
Sergio Losilla
231c58a048 Add table with verbosity levels (missing --list-listeners) (#2443)
Co-authored-by: Sergio Losilla <sergio.losilla@nt-bnct.com>
Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
2022-06-02 21:50:51 +02:00
Sergio Losilla
5efd327dd4 Fix crash when running with --list-listeners and no registered listeners (#2442)
Co-authored-by: Sergio Losilla <sergio.losilla@nt-bnct.com>
2022-06-02 16:11:12 +02:00
Martin Hořeňovský
40dd9dd3f4 Fix copy paste error in the new random gen constraint 2022-06-02 15:51:21 +02:00
Martin Hořeňovský
4142e699c2 Add full set of constraints to random integral generator
Related to #2433
2022-06-02 12:15:35 +02:00
Martin Hořeňovský
9e445930cc Remove obsolete todo 2022-06-02 11:54:15 +02:00
Martin Hořeňovský
2dc657cd1f Make default colour selection fall-through
Closes #2426
2022-06-02 09:16:10 +02:00
Martin Hořeňovský
cca5923502 Leak full Wparentheses suppression for GCC 9
Reported as an issue on Discord. I thought that by GCC 9, the
C++ frontend was fixed enough to support `_Pragma`-based
suppression correctly, but apparently I was wrong.
2022-05-31 23:57:09 +02:00
Martin Hořeňovský
8c952bd076 Point to 3.0.1 in FetchContent example
Closes #2326
Closes #2438
2022-05-31 11:49:24 +02:00
Martin Hořeňovský
85c00eb946 Ensure that console_width.hpp includes user_config.hpp first
Otherwise we can get macro redefinition warnings when another
file includes console_width.hpp first, before user_config.hpp.

Closes #2431
2022-05-23 23:57:42 +02:00
Martin Hořeňovský
3a18a688a0 Mention CMake's integration with CATCH_CONFIG options 2022-05-21 13:04:09 +02:00
Martin Hořeňovský
605a34765a v3.0.1 2022-05-17 22:13:36 +02:00
Martin Hořeňovský
abb669d4fd Extend project call for Catch2
This provides some extra metadata for CPack and related tools.
2022-05-17 22:12:44 +02:00
Martin Hořeňovský
dcafc605f3 Only reseed the internal RNG when a test is first entered
This fixes multiple issues with random generators, with the most
important one being that multiple nested generators could return
values from the same sequence, due to internal implementation
details of `GENERATE`, and how they interact with test case
paths.

The cost of doing this is that given this simple `TEST_CASE`,
```cpp
TEST_CASE("foo") {
    auto i = GENERATE(take(10, random(0, 100));
    SECTION("A") {
        auto j = GENERATE(take(10, random(0, 100));
    }
    SECTION("B") {
        auto k = GENERATE(take(10, random(0, 100));
    }
}
```

`k` will have different values between running the test as
a whole, e.g. with `./tests "foo"`, and running only the "B"
section with `./tests "foo" -c "B"`.

I consider this an acceptable cost, because the only alternative
would be very messy to implement, and add a lot of brittle and
complex code for relatively little benefit.

If this calculation changes, we will need to instead walk
the current tracker tree whenever a random generator is being
constructed, check for random generators on the path to root,
and take a seed from them.
2022-05-17 21:49:26 +02:00
Martin Hořeňovský
7a2a6c632f Make Random*Generators be seedable
This is a necessary step to fix issue with combining multiple
random generators in one test case, with different section nesting.
2022-05-17 17:57:21 +02:00
Martin Hořeňovský
359cd6187d Rename global rng() to sharedRng() 2022-05-17 15:43:23 +02:00
Martin Hořeňovský
9c72b303d9 Reseed global rng instance unconditionally 2022-05-17 12:35:34 +02:00
Martin Hořeňovský
6044f021cf Don't reseed std::srand when resetting rng state
We no longer use `std::rand` anywhere, so there is no point,
and it might even interfere with our users use of `std::(s)rand`.
2022-05-17 11:54:19 +02:00
Martin Hořeňovský
5d7883b551 Remove leftover comment in tests 2022-05-16 21:50:52 +02:00
Martin Hořeňovský
04a54b0e87 Fix release automation script 2022-05-16 18:39:01 +02:00
Martin Hořeňovský
48f3226974 Add support for retrieving generator's element as string 2022-05-16 16:34:06 +02:00
Martin Hořeňovský
af8b54ecd5 Generators now keep track of the index of current element
This might become potentially useful in the future, when we want
to provide the ability to forward jump generators, to be able to
simply reproduce specific input to a test.

I am not yet sure how it would work, but the basic idea is that
it could be similar to the `-c` switch for selecting specific
`SECTION` in a test case.
2022-05-16 11:56:21 +02:00
Martin Hořeňovský
07bec74096 Use better instruction for CATCH_TRAP on ARM Macs
The old instruction would cause the debugger to be stuck at the
triggering source line forever, while the new one should have the
expected semantics, where the debugger can then single-step,
continue. or generally do things, afterwards.

Closes #2422
2022-05-15 23:22:00 +02:00
Martin Hořeňovský
316025a0d8 Properly handle startup reporter registration errors 2022-05-15 10:35:12 +02:00
Martin Hořeňovský
33aeb603fe Add check for registering multiple reporters under same name 2022-05-15 09:54:27 +02:00
Martin Hořeňovský
fc3d11b1d1 Add Wfloat-equal to default-enabled warnings
This is kinda messy, because there is no good way to signal to
the compiler that some code uses direct comparison of floating
point numbers intentionally, so instead we have to use diagnostic
pragmas.

We also have to over-suppress the test files, because Clang (and
possibly GCC) still issue warnings from template instantiation
even if the instantion site is under warning suppression, so the
template definition has to be under warning suppression as well.

Closes #2406
2022-05-14 15:47:20 +02:00
Martin Hořeňovský
1ef65d60f1 Tiny fixup in Misc.tests.cpp 2022-05-11 22:56:30 +02:00
Martin Hořeňovský
ed6b38b096 Specialize XML reporter's listener listing 2022-05-10 20:58:02 +02:00
Martin Hořeňovský
5a49285e9c Add --list-listeners option 2022-05-10 20:57:59 +02:00
Martin Hořeňovský
ae475a3c19 Optional support for listener descriptions 2022-05-10 20:57:53 +02:00
Martin Hořeňovský
d60fbe49be Slight improvement for reporter test 2022-05-10 20:57:50 +02:00
Martin Hořeňovský
a733b58cd2 Replace C++23-deprecated aligned_storage_t 2022-05-10 00:07:22 +02:00
Martin Hořeňovský
d9b0a38f81 Report Catch2's version in the xml reporter output 2022-05-03 19:46:35 +02:00
Martin Hořeňovský
40c8909a49 Rename useColourOnPlatform => useImplementationForStream 2022-05-03 19:04:43 +02:00
Martin Hořeňovský
91ea25e51a Fix use of u8-literal that would break in C++20 2022-05-03 13:54:07 +02:00
Martin Hořeňovský
e2d07d35f4 Add -Wmissing-prototypes to common warnings 2022-05-03 13:54:05 +02:00
Martin Hořeňovský
d2cb934d28 Add -Wmissing-variable-declarations to common warnings 2022-05-03 13:54:03 +02:00
Martin Hořeňovský
7752229105 Add -Wsuggest-destructor-override to enabled warnings 2022-05-03 13:54:02 +02:00
Martin Hořeňovský
722c197855 Enable a bunch of extra warnings 2022-05-03 13:54:00 +02:00
Martin Hořeňovský
198808a24e Misc cleanups from exploring Clang warnings 2022-05-03 13:53:55 +02:00
Martin Hořeňovský
198713e5dc Cleanup of unused functions
The cleanup also found out that custom translation for std-derived
exceptions test wasn't running properly, and fixed that.
We cannot enable the warning globally, because the tests contain
some functions that are unused by design -- e.g. when checking
stringification priority of StringMaker vs range fallback and so
on.
2022-05-02 21:32:24 +02:00
Martin Hořeňovský
b84067ea6f Clean up .gitignore 2022-05-01 23:10:37 +02:00
Martin Hořeňovský
332de39cd4 Remove some useless casts 2022-04-28 14:56:33 +02:00
Martin Hořeňovský
c410e2596c Add some extra warnings 2022-04-28 14:56:31 +02:00
Martin Hořeňovský
4c1cf4aa67 Sorted and removed duplicates from the compiler warning list
The duplicates were '-Wreturn-std-move' and '-Wunreachable-code'.
2022-04-28 11:06:53 +02:00
Martin Hořeňovský
745cc82cd3 Remove some old commented out CMake code 2022-04-28 10:53:03 +02:00
Martin Hořeňovský
07dfb4b070 Update PARENT_SCOPE cmake module path with path to extras/
This allows projects including us directly to do e.g.
`include(Catch)` and get access to the test autoregistration
CMake scripts. Note that this inclusion can be done directly
through `add_subdirectory`, or indirectly via `FetchContent`.

Closes #1805
Closes #2026
Closes #2130
2022-04-28 10:52:16 +02:00
Martin Hořeňovský
5e86ead366 Exclude doxygen docs from documentation install step
We might want to keep them in at some point, but currently the
doxygen docs are very incomplete and unfinished.
2022-04-27 14:57:59 +02:00
Martin Hořeňovský
9dc229693d Document the stability guarantees of '--order rand' option 2022-04-25 21:45:50 +02:00
Martin Hořeňovský
db57a4956f Fixup ToC in command-line.md 2022-04-25 21:39:48 +02:00
Martin Hořeňovský
48177831ee Add version placeholder to the example doc in contributing.md 2022-04-25 21:36:03 +02:00
Martin Hořeňovský
ee3bbecf51 Improve include guard docs in contributing.md 2022-04-25 21:33:05 +02:00
Martin Hořeňovský
431dcf36ea Document Catch2's API/ABI stability policies 2022-04-25 18:58:50 +02:00
Martin Hořeňovský
e882cb8eb1 Document the new --skip-benchmarks flag 2022-04-25 18:36:40 +02:00
Martin Hořeňovský
c2bc321607 Add pipeline running tests under Valgrind to GitHub Action 2022-04-24 13:34:50 +02:00
Martin Hořeňovský
ea9029c478 Fix pkg list name in CMake config workflow 2022-04-24 13:34:36 +02:00
Martin Hořeňovský
c65e5b6514 Add 'uses-python' label to tests using Python 2022-04-24 13:31:28 +02:00
Martin Hořeňovský
880285b433 Tiny cleanup in catch_clara.cpp 2022-04-24 13:31:25 +02:00
Martin Hořeňovský
07cdef2096 Fix uninit memory in Clara tests 2022-04-24 13:31:19 +02:00
Martin Hořeňovský
5baa29b6b9 Add test for %debug stream name 2022-04-23 23:34:27 +02:00
Daniel Feist
291b35b389 Added --skip-benchmarks command-line option. (#2408)
Closes #2392

Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
2022-04-23 23:14:49 +02:00
170 changed files with 6758 additions and 1892 deletions

View File

@@ -56,9 +56,18 @@ jobs:
build_description: CMake configuration tests
build_type: Debug
std: 14
other_pks: clang-10
other_pkgs: clang-10
cmake_configurations: -DCATCH_ENABLE_CONFIGURE_TESTS=ON
# Valgrind test Clang-10
- cxx: clang++-10
build_description: Valgrind tests
build_type: Debug
std: 14
other_pkgs: clang-10 valgrind
cmake_configurations: -DMEMORYCHECK_COMMAND=`which valgrind` -DMEMORYCHECK_COMMAND_OPTIONS="-q --track-origins=yes --leak-check=full --num-callers=50 --show-leak-kinds=definite --error-exitcode=1"
other_ctest_args: -T memcheck -LE uses-python
steps:
- uses: actions/checkout@v2
@@ -91,4 +100,4 @@ jobs:
CTEST_OUTPUT_ON_FAILURE: 1
working-directory: ${{runner.workspace}}/build
# Hardcode 2 cores we know are there
run: ctest -C ${{matrix.build_type}} -j 2
run: ctest -C ${{matrix.build_type}} -j 2 ${{matrix.other_ctest_args}}

12
.gitignore vendored
View File

@@ -11,11 +11,6 @@ Release
xcuserdata
CatchSelfTest.xcscheme
Breakpoints.xcbkptlist
projects/VS2010/TestCatch/_UpgradeReport_Files/
projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters
projects/VisualStudio/TestCatch/UpgradeLog.XML
projects/CMake/.idea
projects/CMake/cmake-build-debug
UpgradeLog.XML
Resources/DWARF
projects/Generated
@@ -25,6 +20,7 @@ DerivedData
Build
.idea
.vs
.vscode
cmake-build-*
benchmark-dir
.conan/test_package/build
@@ -32,3 +28,9 @@ bazel-*
build-fuzzers
debug-build
.vscode
msvc-sln*
# Currently we use Doxygen for dep graphs and the full docs are only slowly
# being filled in, so we definitely do not want git to deal with the docs.
docs/doxygen
*.cache
compile_commands.json

View File

@@ -43,35 +43,58 @@ function(add_warnings_to_targets targets)
if (NOT MSVC)
set(CHECKED_WARNING_FLAGS
"-Wall"
"-Wextra"
"-Wpedantic"
"-Wweak-vtables"
"-Wunreachable-code"
"-Wmissing-declarations"
"-Wexit-time-destructors"
"-Wglobal-constructors"
"-Wmissing-noreturn"
"-Wparentheses"
"-Wextra-semi"
"-Wunreachable-code"
"-Wstrict-aliasing"
"-Wreturn-std-move"
"-Wmissing-braces"
"-Wdeprecated"
"-Wvla"
"-Wundef"
"-Wmisleading-indentation"
"-Wcatch-value"
"-Wabsolute-value"
"-Wreturn-std-move"
"-Wunused-parameter"
"-Wunused-function"
"-Wall"
"-Wc++20-compat"
"-Wcall-to-pure-virtual-from-ctor-dtor"
"-Wcast-align"
"-Wcatch-value"
"-Wdangling"
"-Wdeprecated"
"-Wdeprecated-register"
"-Wsuggest-override"
"-Wshadow"
"-Wexceptions"
"-Wexit-time-destructors"
"-Wextra"
"-Wextra-semi"
"-Wfloat-equal"
"-Wglobal-constructors"
"-Winit-self"
"-Wmisleading-indentation"
"-Wmismatched-new-delete"
"-Wmismatched-return-types"
"-Wmismatched-tags"
"-Wmissing-braces"
"-Wmissing-declarations"
"-Wmissing-noreturn"
"-Wmissing-prototypes"
"-Wmissing-variable-declarations"
"-Wnull-dereference"
"-Wold-style-cast"
"-Woverloaded-virtual"
"-Wparentheses"
"-Wpedantic"
"-Wreorder"
"-Wreturn-std-move"
"-Wshadow"
"-Wstrict-aliasing"
"-Wsuggest-destructor-override"
"-Wsuggest-override"
"-Wundef"
"-Wuninitialized"
"-Wunneeded-internal-declaration"
"-Wunreachable-code"
"-Wunused"
"-Wunused-function"
"-Wunused-parameter"
"-Wvla"
"-Wweak-vtables"
# This is a useful warning, but our tests sometimes rely on
# functions being present, but not picked (e.g. various checks
# for stringification implementation ordering).
# Ergo, we should use it every now and then, but we cannot
# enable it by default.
# "-Wunused-member-function"
)
foreach(warning ${CHECKED_WARNING_FLAGS})
add_cxx_flag_if_supported_to_targets(${warning} "${targets}")

View File

@@ -36,10 +36,26 @@ if(CMAKE_VERSION VERSION_GREATER 3.8)
endif()
project(Catch2 LANGUAGES CXX VERSION 3.0.0)
project(Catch2
VERSION 3.1.0 # CML version placeholder, don't delete
LANGUAGES CXX
# HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet.
# HOMEPAGE_URL "https://github.com/catchorg/Catch2"
DESCRIPTION "A modern, C++-native, unit test framework."
)
# Provide path for scripts
# Provide path for scripts. We first add path to the scripts we don't use,
# but projects including us might, and set the path up to parent scope.
# Then we also add path that we use to configure the project, but is of
# no use to top level projects.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/extras")
if (NOT NOT_SUBPROJECT)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(CatchConfigOptions)
@@ -95,13 +111,6 @@ if (CATCH_DEVELOPMENT_BUILD)
add_warnings_to_targets("${CATCH_WARNING_TARGETS}")
endif()
#set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#
#
#
#
#
# Only perform the installation steps when Catch is not being used as
# a subproject via `add_subdirectory`, or the destinations will break,
# see https://github.com/catchorg/Catch2/issues/1373
@@ -134,6 +143,7 @@ if (NOT_SUBPROJECT)
docs/
DESTINATION
"${CMAKE_INSTALL_DOCDIR}"
PATTERN "doxygen" EXCLUDE
)
endif()

View File

@@ -7,7 +7,7 @@
[![MacOS build status](https://github.com/catchorg/Catch2/actions/workflows/mac-builds.yml/badge.svg)](https://github.com/catchorg/Catch2/actions/workflows/mac-builds.yml)
[![Build Status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true&branch=devel)](https://ci.appveyor.com/project/catchorg/catch2)
[![Code Coverage](https://codecov.io/gh/catchorg/Catch2/branch/devel/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://godbolt.org/z/9x9qoM)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://godbolt.org/z/EdoY15q9G)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)

View File

@@ -51,6 +51,7 @@ conan_basic_setup()'''.format(line_to_replace, self.install_folder.replace("\\",
self.cpp_info.components["catch2base"].names["cmake_find_package_multi"] = "Catch2"
self.cpp_info.components["catch2base"].names["pkg_config"] = "Catch2"
self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix]
self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2")
# Catch2WithMain
self.cpp_info.components["catch2main"].names["cmake_find_package"] = "Catch2WithMain"
self.cpp_info.components["catch2main"].names["cmake_find_package_multi"] = "Catch2WithMain"

View File

@@ -26,6 +26,7 @@ Running:
Odds and ends:
* [Frequently Asked Questions (FAQ)](faq.md#top)
* [Best practices and other tips](usage-tips.md#top)
* [CMake integration](cmake-integration.md#top)
* [CI and other miscellaneous pieces](ci-and-misc.md#top)
* [Known limitations](limitations.md#top)

View File

@@ -5,6 +5,7 @@
[CMake targets](#cmake-targets)<br>
[Automatic test registration](#automatic-test-registration)<br>
[CMake project options](#cmake-project-options)<br>
[`CATCH_CONFIG_*` customization options in CMake](#catch_config_-customization-options-in-cmake)<br>
[Installing Catch2 from git repository](#installing-catch2-from-git-repository)<br>
[Installing Catch2 from vcpkg](#installing-catch2-from-vcpkg)<br>
@@ -50,7 +51,7 @@ Include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.0.0-preview3
GIT_TAG v3.0.1 # or a later release
)
FetchContent_MakeAvailable(Catch2)
@@ -62,17 +63,19 @@ target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
## Automatic test registration
Catch2's repository also contains two CMake scripts that help users
Catch2's repository also contains three CMake scripts that help users
with automatically registering their `TEST_CASE`s with CTest. They
can be found in the `extras` folder, and are
1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
2) `ParseAndAddCatchTests.cmake` (deprecated)
3) `CatchShardTests.cmake` (and its dependency `CatchShardTestsImpl.cmake`)
If Catch2 has been installed in system, both of these can be used after
doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
to your CMake module path.
<a id="catch_discover_tests"></a>
### `Catch.cmake` and `CatchAddTests.cmake`
`Catch.cmake` provides function `catch_discover_tests` to get tests from
@@ -256,6 +259,49 @@ unset(OptionalCatchTestLauncher)
ParseAndAddCatchTests(bar)
```
### `CatchShardTests.cmake`
> `CatchShardTests.cmake` was introduced in Catch2 3.1.0.
`CatchShardTests.cmake` provides a function
`catch_add_sharded_tests(TEST_BINARY)` that splits tests from `TEST_BINARY`
into multiple shards. The tests in each shard and their order is randomized,
and the seed changes every invocation of CTest.
Currently there are 3 customization points for this script:
* SHARD_COUNT - number of shards to split target's tests into
* REPORTER - reporter spec to use for tests
* TEST_SPEC - test spec used for filtering tests
Example usage:
```
include(CatchShardTests)
catch_add_sharded_tests(foo-tests
SHARD_COUNT 4
REPORTER "xml::out=-"
TEST_SPEC "A"
)
catch_add_sharded_tests(tests
SHARD_COUNT 8
REPORTER "xml::out=-"
TEST_SPEC "B"
)
```
This registers total of 12 CTest tests (4 + 8 shards) to run shards
from `foo-tests` test binary, filtered by a test spec.
_Note that this script is currently a proof-of-concept for reseeding
shards per CTest run, and thus does not support (nor does it currently
aim to support) all customization points from
[`catch_discover_tests`](#catch_discover_tests)._
## CMake project options
Catch2's CMake project also provides some options for other projects
@@ -293,6 +339,31 @@ compiled separately to ensure that they are self-sufficient.
Defaults to `OFF`.
## `CATCH_CONFIG_*` customization options in CMake
> CMake support for `CATCH_CONFIG_*` options was introduced in Catch2 3.0.1
Due to the new separate compilation model, all the options from the
[Compile-time configuration docs](configuration.md#top) can also be set
through Catch2's CMake. To set them, define the option you want as `ON`,
e.g. `-DCATCH_CONFIG_NOSTDOUT=ON`.
Note that setting the option to `OFF` doesn't disable it. To force disable
an option, you need to set the `_NO_` form of it to `ON`, e.g.
`-DCATCH_CONFIG_NO_COLOUR_WIN32=ON`.
To summarize the configuration option behaviour with an example:
| `-DCATCH_CONFIG_COLOUR_WIN32` | `-DCATCH_CONFIG_NO_COLOUR_WIN32` | Result |
|-------------------------------|----------------------------------|-------------|
| `ON` | `ON` | error |
| `ON` | `OFF` | force-on |
| `OFF` | `ON` | force-off |
| `OFF` | `OFF` | auto-detect |
## Installing Catch2 from git repository
If you cannot install Catch2 from a package manager (e.g. Ubuntu 16.04

View File

@@ -19,6 +19,7 @@
[Specify a seed for the Random Number Generator](#specify-a-seed-for-the-random-number-generator)<br>
[Identify framework and version according to the libIdentify standard](#identify-framework-and-version-according-to-the-libidentify-standard)<br>
[Wait for key before continuing](#wait-for-key-before-continuing)<br>
[Skip all benchmarks](#skip-all-benchmarks)<br>
[Specify the number of benchmark samples to collect](#specify-the-number-of-benchmark-samples-to-collect)<br>
[Specify the number of resamples for bootstrapping](#specify-the-number-of-resamples-for-bootstrapping)<br>
[Specify the confidence-interval for bootstrapping](#specify-the-confidence-interval-for-bootstrapping)<br>
@@ -58,10 +59,12 @@ Click one of the following links to take you straight to that option - or scroll
<a href="#listing-available-tests-tags-or-reporters"> ` --list-tests`</a><br />
<a href="#listing-available-tests-tags-or-reporters"> ` --list-tags`</a><br />
<a href="#listing-available-tests-tags-or-reporters"> ` --list-reporters`</a><br />
<a href="#listing-available-tests-tags-or-reporters"> ` --list-listeners`</a><br />
<a href="#order"> ` --order`</a><br />
<a href="#rng-seed"> ` --rng-seed`</a><br />
<a href="#libidentify"> ` --libidentify`</a><br />
<a href="#wait-for-keypress"> ` --wait-for-keypress`</a><br />
<a href="#skip-benchmarks"> ` --skip-benchmarks`</a><br />
<a href="#benchmark-samples"> ` --benchmark-samples`</a><br />
<a href="#benchmark-resamples"> ` --benchmark-resamples`</a><br />
<a href="#benchmark-confidence-interval"> ` --benchmark-confidence-interval`</a><br />
@@ -142,7 +145,7 @@ hardcoded into Catch2. Currently there are only 2,
_Note that the reporter might still check the X-prefixed options for
validity, and throw an error if they are wrong._
> Support for passing arguments to reporters through the `-r`, `--reporter` flag was introduced in Catch2 X.Y.Z
> Support for passing arguments to reporters through the `-r`, `--reporter` flag was introduced in Catch2 3.0.1
There are multiple built-in reporters, you can see what they do by using the
[`--list-reporter`](command-line.md#listing-available-tests-tags-or-reporters)
@@ -157,7 +160,7 @@ reporter can be provided without the output-file part of reporter spec.
This reporter will use the "default" output destination, based on
the [`-o`, `--out`](#sending-output-to-a-file) option.
> Support for using multiple different reporters at the same time was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 X.Y.Z
> Support for using multiple different reporters at the same time was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 3.0.1
_Note: There is currently no way to escape `::` in the reporter spec,
@@ -198,9 +201,12 @@ Sometimes this results in a flood of failure messages and you'd rather just see
--list-tests
--list-tags
--list-reporters
--list-listeners
```
> The `--list*` options became customizable through reporters in Catch2 X.Y.Z
> The `--list*` options became customizable through reporters in Catch2 3.0.1
> The `--list-listeners` option was added in Catch2 3.0.1
`--list-tests` lists all registered tests matching specified test spec.
Usually this listing also includes tags, and potentially also other
@@ -212,6 +218,17 @@ similar information.
`--list-reporters` lists all available reporters and their descriptions.
`--list-listeners` lists all registered listeners and their descriptions.
The [`--verbosity` argument](#output-verbosity) modifies the level of detail provided by the default `--list*` options
as follows:
| Option | `normal` (default) | `quiet` | `high` |
|--------------------|---------------------------------|---------------------|-----------------------------------------|
| `--list-tests` | Test names and tags | Test names only | Same as `normal`, plus source code line |
| `--list-tags` | Tags and counts | Same as `normal` | Same as `normal` |
| `--list-reporters` | Reporter names and descriptions | Reporter names only | Same as `normal` |
| `--list-listeners` | Listener names and descriptions | Same as `normal` | Same as `normal` |
<a id="sending-output-to-a-file"></a>
## Sending output to a file
@@ -222,7 +239,7 @@ Use this option to send all output to a file, instead of stdout. You can
use `-` as the filename to explicitly send the output to stdout (this is
useful e.g. when using multiple reporters).
> Support for `-` as the filename was introduced in Catch2 X.Y.Z
> Support for `-` as the filename was introduced in Catch2 3.0.1
Filenames starting with "%" (percent symbol) are reserved by Catch2 for
meta purposes, e.g. using `%debug` as the filename opens stream that
@@ -234,7 +251,7 @@ Catch2 currently recognizes 3 meta streams:
* `%stdout` - writes to stdout
* `%stderr` - writes to stderr
> Support for `%stdout` and `%stderr` was introduced in Catch2 X.Y.Z
> Support for `%stdout` and `%stderr` was introduced in Catch2 3.0.1
<a id="naming-a-test-run"></a>
@@ -282,7 +299,7 @@ There are currently two warnings implemented:
// not match any tests.
```
> `UnmatchedTestSpec` was introduced in Catch2 X.Y.Z.
> `UnmatchedTestSpec` was introduced in Catch2 3.0.1.
<a id="reporting-timings"></a>
@@ -332,13 +349,19 @@ Lexicographic order. Tests are sorted by their name, their tags are ignored.
### rand
Randomly sorted. The order is dependent on Catch2's random seed (see
Randomly ordered. 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.
> The subset stability was introduced in Catch2 v2.12.0
Since the random order was made subset stable, we promise that given
the same random seed, the order of test cases will be the same across
different platforms, as long as the tests were compiled against identical
version of Catch2. We reserve the right to change the relative order
of tests cases between Catch2 versions, but it is unlikely to happen often.
<a id="rng-seed"></a>
## Specify a seed for the Random Number Generator
@@ -370,6 +393,16 @@ See [The LibIdentify repo for more information and examples](https://github.com/
Will cause the executable to print a message and wait until the return/ enter key is pressed before continuing -
either before running any tests, after running all tests - or both, depending on the argument.
<a id="skip-benchmarks"></a>
## Skip all benchmarks
<pre>--skip-benchmarks</pre>
> [Introduced](https://github.com/catchorg/Catch2/issues/2408) in Catch2 3.0.1.
This flag tells Catch2 to skip running all benchmarks. Benchmarks in this
case mean code blocks in `BENCHMARK` and `BENCHMARK_ADVANCED` macros, not
test cases with the `[!benchmark]` tag.
<a id="benchmark-samples"></a>
## Specify the number of benchmark samples to collect
<pre>--benchmark-samples &lt;# of samples&gt;</pre>
@@ -483,7 +516,7 @@ So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be t
## Override output colouring
<pre>--colour-mode &lt;ansi|win32|none|default&gt;</pre>
> The `--colour-mode` option replaced the old `--colour` option in Catch2 X.Y.Z
> The `--colour-mode` option replaced the old `--colour` option in Catch2 3.0.1
Catch2 support two different ways of colouring terminal output, and by
@@ -507,20 +540,25 @@ when writing to a file
## Test Sharding
<pre>--shard-count <#number of shards>, --shard-index <#shard index to run></pre>
> [Introduced](https://github.com/catchorg/Catch2/pull/2257) in Catch2 X.Y.Z.
> [Introduced](https://github.com/catchorg/Catch2/pull/2257) in Catch2 3.0.1.
When `--shard-count <#number of shards>` is used, the tests to execute will be split evenly in to the given number of sets,
identified by indicies starting at 0. The tests in the set given by `--shard-index <#shard index to run>` will be executed.
The default shard count is `1`, and the default index to run is `0`. It is an error to specify a shard index greater than
the number of shards.
When `--shard-count <#number of shards>` is used, the tests to execute
will be split evenly in to the given number of sets, identified by indices
starting at 0. The tests in the set given by
`--shard-index <#shard index to run>` will be executed. The default shard
count is `1`, and the default index to run is `0`.
_It is an error to specify a shard index greater than the number of shards._
Sharding is useful when you want to split test execution across multiple
processes, as is done with the [Bazel test sharding](https://docs.bazel.build/versions/main/test-encyclopedia.html#test-sharding).
This is useful when you want to split test execution across multiple processes, as is done with [Bazel test sharding](https://docs.bazel.build/versions/main/test-encyclopedia.html#test-sharding).
<a id="no-tests-override"></a>
## Allow running the binary without tests
<pre>--allow-running-no-tests</pre>
> Introduced in Catch2 X.Y.Z.
> Introduced in Catch2 3.0.1.
By default, Catch2 test binaries return non-0 exit code if no tests were
run, e.g. if the binary was compiled with no tests, or the provided test

View File

@@ -13,6 +13,7 @@ with you sharing this fact.
- Locksley.CZ
- [Makimo](https://makimo.pl/)
- NASA
- [Nexus Software Systems](https://nexwebsites.com)
- [UX3D](https://ux3d.io)
- [King](https://king.com)

View File

@@ -98,10 +98,12 @@ is equivalent with the out-of-the-box experience.
## Bazel support
When `CATCH_CONFIG_BAZEL_SUPPORT` is defined, Catch2 will register a `JUnit`
reporter writing to a path pointed by `XML_OUTPUT_FILE` provided by Bazel.
When `CATCH_CONFIG_BAZEL_SUPPORT` is defined or when `BAZEL_TEST=1` (which is set by the Bazel inside of a test environment),
Catch2 will register a `JUnit` reporter writing to a path pointed by `XML_OUTPUT_FILE` provided by Bazel.
> `CATCH_CONFIG_BAZEL_SUPPORT` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 X.Y.Z.
> `CATCH_CONFIG_BAZEL_SUPPORT` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1.
> `CATCH_CONFIG_BAZEL_SUPPORT` was [deprecated](https://github.com/catchorg/Catch2/pull/2459) in Catch2 3.1.0.
## C++11 toggles

View File

@@ -136,6 +136,8 @@ should use. It provides you with the top anchor mentioned to link to
<a id="top"></a>
# Cool feature
> [Introduced](https://github.com/catchorg/Catch2/pull/123456) in Catch2 X.Y.Z
Text that explains how to use the cool feature.
@@ -296,9 +298,9 @@ Specifically, every source file should start with the licence header:
```
The include guards for header files should follow the pattern `{FILENAME}_INCLUDED`.
This means that for file `catch_matchers_foo`, the include guard should
be `CATCH_MATCHERS_FOO_INCLUDED`, for `catch_generators_bar`, the include
guard should be `CATCH_GENERATORS_BAR_INCLUDED`, and so on.
This means that for file `catch_matchers_foo.hpp`, the include guard should
be `CATCH_MATCHERS_FOO_HPP_INCLUDED`, for `catch_generators_bar.hpp`, the include
guard should be `CATCH_GENERATORS_BAR_HPP_INCLUDED`, and so on.
## CoC

View File

@@ -17,13 +17,14 @@ as it can be replaced by `Catch.cmake` that provides the function
command line interface instead of parsing C++ code with regular expressions.
## Planned changes
### Console Colour API
The API for Catch2's console colour will be changed to take an extra
argument, the stream to which the colour code should be applied.
### `CATCH_CONFIG_BAZEL_SUPPORT`
Catch2 supports writing the Bazel JUnit XML output file when it is aware
that is within a bazel testing environment. Originally there was no way
to accurately probe the environment for this information so the flag
`CATCH_CONFIG_BAZEL_SUPPORT` was added. This now deprecated. Bazel has now had a change
where it will export `BAZEL_TEST=1` for purposes like the above. Catch2
will now instead inspect the environment instead of relying on build configuration.
---

View File

@@ -1,6 +1,13 @@
<a id="top"></a>
# Frequently Asked Questions (FAQ)
**Contents**<br>
[How do I run global setup/teardown only if tests will be run?](#how-do-i-run-global-setupteardown-only-if-tests-will-be-run)<br>
[How do I clean up global state between running different tests?](#how-do-i-clean-up-global-state-between-running-different-tests)<br>
[Why cannot I derive from the built-in reporters?](#why-cannot-i-derive-from-the-built-in-reporters)<br>
[What is Catch2's ABI stability policy?](#what-is-catch2s-abi-stability-policy)<br>
[What is Catch2's API stability policy?](#what-is-catch2s-api-stability-policy)<br>
## How do I run global setup/teardown only if tests will be run?
Write a custom [event listener](event-listeners.md#top) and place the
@@ -22,6 +29,34 @@ forbidding users from using them as a base class, we can refactor them
as needed later.
## What is Catch2's ABI stability policy?
Catch2 provides no ABI stability guarantees whatsoever. Catch2 provides
rich C++ interface, and trying to freeze its ABI would take a lot of
pointless work.
Catch2 is not designed to be distributed as dynamic library, and you
should really be able to compile everything with the same compiler binary.
## What is Catch2's API stability policy?
Catch2 follows [semver](https://semver.org/) to the best of our ability.
This means that we will not knowingly make backwards-incompatible changes
without incrementing the major version number.
## Does Catch2 support running tests in parallel?
Not natively, no. We see running tests in parallel as the job of an
external test runner, that can also run them in separate processes,
support test execution timeouts and so on.
However, Catch2 provides some tools that make the job of external test
runners easier. [See the relevant section in our page on best
practices](usage-tips.md#parallel-tests).
---
[Home](Readme.md#top)

View File

@@ -248,7 +248,7 @@ Note that `DerivedException` in the example above has to derive from
### Generic range Matchers
> Generic range matchers were introduced in Catch2 X.Y.Z
> Generic range matchers were introduced in Catch2 3.0.1
Catch2 also provides some matchers that use the new style matchers
definitions to handle generic range-like types. These are:
@@ -258,6 +258,12 @@ definitions to handle generic range-like types. These are:
* `SizeIs(Matcher size_matcher)`
* `Contains(T&& target_element, Comparator = std::equal_to<>{})`
* `Contains(Matcher element_matcher)`
* `AllMatch(Matcher element_matcher)`
* `NoneMatch(Matcher element_matcher)`
* `AnyMatch(Matcher element_matcher)`
* `AllTrue()`
* `NoneTrue()`
* `AnyTrue()`
`IsEmpty` should be self-explanatory. It successfully matches objects
that are empty according to either `std::empty`, or ADL-found `empty`
@@ -275,6 +281,14 @@ the target element. The other variant is constructed from a matcher,
in which case a range is accepted if any of its elements is accepted
by the provided matcher.
`AllMatch`, `NoneMatch`, and `AnyMatch` match ranges for which either
all, none, or any of the contained elements matches the given matcher,
respectively.
`AllTrue`, `NoneTrue`, and `AnyTrue` match ranges for which either
all, none, or any of the contained elements are `true`, respectively.
It works for ranges of `bool`s and ranges of elements (explicitly)
convertible to `bool`.
## Writing custom matchers (old style)
@@ -350,7 +364,7 @@ style matchers arbitrarily.
## Writing custom matchers (new style)
> New style matchers were introduced in Catch2 X.Y.Z
> New style matchers were introduced in Catch2 3.0.1
To create a new-style matcher, you have to create your own type that
derives from `Catch::Matchers::MatcherGenericBase`. Your type has to

View File

@@ -50,7 +50,8 @@ compilation times in the v3 version. The basic steps to do so are:
1. Change your CMakeLists.txt to link against `Catch2WithMain` target if
you use Catch2's default main. (If you do not, keep linking against
the `Catch2` target.)
the `Catch2` target.). If you use pkg-config, change `pkg-config catch2` to
`pkg-config catch2-with-main`.
2. Delete TU with `CATCH_CONFIG_RUNNER` or `CATCH_CONFIG_MAIN` defined,
as it is no longer needed.
3. Change `#include <catch2/catch.hpp>` to `#include <catch2/catch_all.hpp>`

View File

@@ -118,6 +118,9 @@ A high available cloud native micro-service application management platform impl
### [ArangoDB](https://github.com/arangodb/arangodb)
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
### [Cytopia](https://github.com/CytopiaTeam/Cytopia)
Cytopia is a free, open source retro pixel-art city building game with a big focus on mods. It utilizes a custom isometric rendering engine based on SDL2.
### [d-SEAMS](https://github.com/d-SEAMS/seams-core)
Open source molecular dynamics simulation structure analysis suite of tools in modern C++.

View File

@@ -15,7 +15,7 @@ stringification machinery to the _expr_ and records the result. As with
evaluates to `true`. `CHECKED_ELSE( expr )` work similarly, but the block
is entered only if the _expr_ evaluated to `false`.
> `CHECKED_X` macros were changed to not count as failure in Catch2 X.Y.Z.
> `CHECKED_X` macros were changed to not count as failure in Catch2 3.0.1.
Example:
```cpp
@@ -77,7 +77,7 @@ TEST_CASE("STATIC_REQUIRE showcase", "[traits]") {
}
```
> `STATIC_CHECK` was [introduced](https://github.com/catchorg/Catch2/pull/2318) in Catch2 X.Y.Z.
> `STATIC_CHECK` was [introduced](https://github.com/catchorg/Catch2/pull/2318) in Catch2 3.0.1.
`STATIC_CHECK( expr )` is equivalent to `STATIC_REQUIRE( expr )`, with the
difference that when `CATCH_CONFIG_RUNTIME_STATIC_REQUIRE` is defined, it

View File

@@ -2,7 +2,8 @@
# Release notes
**Contents**<br>
[3.0.1 (in progress)](#301-in-progress)<br>
[3.1.0](#310)<br>
[3.0.1](#301)<br>
[2.13.7](#2137)<br>
[2.13.6](#2136)<br>
[2.13.5](#2135)<br>
@@ -49,7 +50,46 @@
[Even Older versions](#even-older-versions)<br>
## 3.0.1 (in progress)
## 3.1.0
### Improvements
* Improved suppression of `-Wparentheses` for older GCCs
* Turns out that even GCC 9 does not properly handle `_Pragma`s in the C++ frontend.
* Added type constraints onto `random` generator (#2433)
* These constraints copy what the standard says for the underlying `std::uniform_int_distribution`
* Suppressed -Wunused-variable from nvcc (#2306, #2427)
* Suppressed -Wunused-variable from MinGW (#2132)
* Added All/Any/NoneTrue range matchers (#2319)
* These check that all/any/none of boolean values in a range are true.
* The JUnit reporter now normalizes classnames from C++ namespaces to Java-like namespaces (#2468)
* This provides better support for other JUnit based tools.
* The Bazel support now understands `BAZEL_TEST` environment variable (#2459)
* The `CATCH_CONFIG_BAZEL_SUPPORT` configuration option is also still supported.
* Returned support for compiling Catch2 with GCC 5 (#2448)
* This required removing inherited constructors from Catch2's internals.
* I recommend updating to a newer GCC anyway.
* `catch_discover_tests` now has a new options for setting library load path(s) when running the Catch2 binary (#2467)
### Fixes
* Fixed crash when listing listeners without any registered listeners (#2442)
* Fixed nvcc compilation error in constructor benchmarking helper (#2477)
* Catch2's CMakeList supports pre-3.12 CMake again (#2428)
* The gain from requiring CMake 3.12 was very minor, but y'all should really update to newer CMake
### Miscellaneous
* Fixed SelfTest build on MinGW (#2447)
* The in-repo conan recipe exports the CMake helper (#2460)
* Added experimental CMake script to showcase using test case sharding together with CTest
* Compared to `catch_discover_tests`, it supports very limited number of options and customization
* Added documentation page on best practices when running Catch2 tests
* Catch2 can be built as a dynamic library (#2397, #2398)
* Note that Catch2 does not have visibility annotations, and you are responsible for ensuring correct visibility built into the resulting library.
## 3.0.1
**Catch2 now uses statically compiled library as its distribution model.
This also means that to get all of Catch2's functionality in a test file,
@@ -191,6 +231,8 @@ v3 releases.
* For details see the docs for command-line and compile-time Catch2 configuration
* Added a support for Bazel integration with `XML_OUTPUT_FILE` env var (#2399)
* This has to be enabled during compilation.
* Added `--skip-benchmarks` flag to run tests without any `BENCHMARK`s (#2392, #2408)
* Added option to list all listeners in the binary via `--list-listeners`
### Fixes
@@ -204,6 +246,7 @@ v3 releases.
* The cumulative reporter base stores benchmark results alongside assertion results
* Catch2's SE handling should no longer interferes with ASan on Windows (#2334)
* Fixed Windows console colour handling for tests that redirect stdout (#2345)
* Fixed issue with the `random` generators returning the same value over and over again
### Other changes
@@ -228,6 +271,7 @@ v3 releases.
* `-DCATCH_CONFIG_ANDROID_LOGWRITE=OFF` does nothing (the define will not exist)
## 2.13.7
### Fixes

View File

@@ -56,7 +56,7 @@ are handled by a different event.
### `testCasePartial` events
> Introduced in Catch2 X.Y.Z
> Introduced in Catch2 3.0.1
```cpp
void testCasePartialStarting( TestCaseInfo const& testInfo, uint64_t partNumber );
@@ -135,7 +135,7 @@ benchmarking itself fails.
## Listings events
> Introduced in Catch2 X.Y.Z.
> Introduced in Catch2 3.0.1.
Listings events are events that correspond to the test binary being
invoked with `--list-foo` flag.

View File

@@ -30,7 +30,7 @@ reporters](#multiple-reporters) to avoid any surprises from doing so.
<a id="multiple-reporters"></a>
## Using multiple reporters
> Support for having multiple parallel reporters was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 X.Y.Z
> Support for having multiple parallel reporters was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 3.0.1
Catch2 supports using multiple reporters at the same time while having
them write into different destinations. The two main uses of this are
@@ -169,7 +169,7 @@ Currently there are two customization options:
### Per-reporter configuration
> Per-reporter configuration was introduced in Catch2 X.Y.Z
> Per-reporter configuration was introduced in Catch2 3.0.1
Catch2 supports some configuration to happen per reporter. The configuration
options fall into one of two categories:

View File

@@ -72,7 +72,8 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
* `[@<alias>]` - tag aliases all begin with `@` (see below).
* `[!benchmark]` - this test case is actually a benchmark. This is an experimental feature, and currently has no documentation. If you want to try it out, look at `projects/SelfTest/Benchmark.tests.cpp` for details.
* `[!benchmark]` - this test case is actually a benchmark. Currently this only serves to hide the test case by default, to avoid the execution time costs.
## Tag aliases
@@ -153,7 +154,7 @@ Scenario : vector can be sized and resized
Then : The size changes
```
See also [runnable example on godbolt](https://godbolt.org/z/e5vPPM),
See also [runnable example on godbolt](https://godbolt.org/z/eY5a64r99),
with a more complicated (and failing) example.
> `AND_GIVEN` was [introduced](https://github.com/catchorg/Catch2/issues/1360) in Catch2 2.4.0.

View File

@@ -59,7 +59,10 @@ struct Template_Fixture {
T m_a;
};
TEMPLATE_TEST_CASE_METHOD(Template_Fixture,"A TEMPLATE_TEST_CASE_METHOD based test run that succeeds", "[class][template]", int, float, double) {
TEMPLATE_TEST_CASE_METHOD(Template_Fixture,
"A TEMPLATE_TEST_CASE_METHOD based test run that succeeds",
"[class][template]",
int, float, double) {
REQUIRE( Template_Fixture<TestType>::m_a == 1 );
}
@@ -77,7 +80,11 @@ struct Foo_class {
}
};
TEMPLATE_PRODUCT_TEST_CASE_METHOD(Template_Template_Fixture, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test succeeds", "[class][template]", (Foo_class, std::vector), int) {
TEMPLATE_PRODUCT_TEST_CASE_METHOD(Template_Template_Fixture,
"A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test succeeds",
"[class][template]",
(Foo_class, std::vector),
int) {
REQUIRE( Template_Template_Fixture<TestType>::m_a.size() == 0 );
}
```
@@ -101,7 +108,12 @@ struct Nttp_Fixture{
int value = V;
};
TEMPLATE_TEST_CASE_METHOD_SIG(Nttp_Fixture, "A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][nttp]",((int V), V), 1, 3, 6) {
TEMPLATE_TEST_CASE_METHOD_SIG(
Nttp_Fixture,
"A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds",
"[class][template][nttp]",
((int V), V),
1, 3, 6) {
REQUIRE(Nttp_Fixture<V>::value > 0);
}
@@ -117,8 +129,13 @@ struct Template_Foo_2 {
size_t size() { return V; }
};
TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(Template_Fixture_2, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds", "[class][template][product][nttp]", ((typename T, size_t S), T, S),(std::array, Template_Foo_2), ((int,2), (float,6)))
{
TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(
Template_Fixture_2,
"A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds",
"[class][template][product][nttp]",
((typename T, size_t S), T, S),
(std::array, Template_Foo_2),
((int,2), (float,6))) {
REQUIRE(Template_Fixture_2<TestType>{}.m_a.size() >= 2);
}
```
@@ -132,8 +149,10 @@ only difference is the source of types. This allows you to reuse the template ty
Example:
```cpp
using MyTypes = std::tuple<int, char, double>;
TEMPLATE_LIST_TEST_CASE_METHOD(Template_Fixture, "Template test case method with test types specified inside std::tuple", "[class][template][list]", MyTypes)
{
TEMPLATE_LIST_TEST_CASE_METHOD(Template_Fixture,
"Template test case method with test types specified inside std::tuple",
"[class][template][list]",
MyTypes) {
REQUIRE( Template_Fixture<TestType>::m_a == 1 );
}
```

View File

@@ -94,7 +94,7 @@ before we move on.
* The test automatically self-registers with the test runner, and user
does not have do anything more to ensure that it is picked up by the test
framework. _Note that you can run specific test, or set of tests,
through the [command line](command-line#top)._
through the [command line](command-line.md#top)._
* The individual test assertions are written using the `REQUIRE` macro.
It accepts a boolean expression, and uses expression templates to
internally decompose it, so that it can be individually stringified

95
docs/usage-tips.md Normal file
View File

@@ -0,0 +1,95 @@
<a id="top"></a>
# Best practices and other tips on using Catch2
## Running tests
Your tests should be run in a manner roughly equivalent with:
```
./tests --order rand --warn NoAssertions
```
Notice that all the tests are run in a large batch, their relative order
is randomized, and that you ask Catch2 to fail test whose leaf-path
does not contain an assertion.
The reason I recommend running all your tests in the same process is that
this exposes your tests to interference from their runs. This can be both
positive interference, where the changes in global state from previous
test allow later tests to pass, but also negative interference, where
changes in global state from previous test causes later tests to fail.
In my experience, interference, especially destructive interference,
usually comes from errors in the code under test, rather than the tests
themselves. This means that by allowing interference to happen, our tests
can find these issues. Obviously, to shake out interference coming from
different orderings of tests, the test order also need to be shuffled
between runs.
However, running all tests in a single batch eventually becomes impractical
as they will take too long to run, and you will want to run your tests
in parallel.
<a id="parallel-tests"></a>
## Running tests in parallel
There are multiple ways of running tests in parallel, with various level
of structure. If you are using CMake and CTest, then we provide a helper
function [`catch_discover_tests`](cmake-integration.md#automatic-test-registration)
that registers each Catch2 `TEST_CASE` as a single CTest test, which
is then run in a separate process. This is an easy way to set up parallel
tests if you are already using CMake & CTest to run your tests, but you
will lose the advantage of running tests in batches.
Catch2 also supports [splitting tests in a binary into multiple
shards](command-line.md#test-sharding). This can be used by any test
runner to run batches of tests in parallel. Do note that when selecting
on the number of shards, you should have more shards than there are cores,
to avoid issues with long running tests getting accidentally grouped in
the same shard, and causing long-tailed execution time.
**Note that naively composing sharding and random ordering of tests will break.**
Invoking Catch2 test executable like this
```text
./tests --order rand --shard-index 0 --shard-count 3
./tests --order rand --shard-index 1 --shard-count 3
./tests --order rand --shard-index 2 --shard-count 3
```
does not guarantee covering all tests inside the executable, because
each invocation will have its own random seed, thus it will have its own
random order of tests and thus the partitioning of tests into shards will
be different as well.
To do this properly, you need the individual shards to share the random
seed, e.g.
```text
./tests --order rand --shard-index 0 --shard-count 3 --rng-seed 0xBEEF
./tests --order rand --shard-index 1 --shard-count 3 --rng-seed 0xBEEF
./tests --order rand --shard-index 2 --shard-count 3 --rng-seed 0xBEEF
```
## Organizing tests into binaries
Both overly large and overly small test binaries can cause issues. Overly
large test binaries have to be recompiled and relinked often, and the
link times are usually also long. Overly small test binaries in turn pay
significant overhead from linking against Catch2 more often per compiled
test case, and also make it hard/impossible to run tests in batches.
Because there is no hard and fast rule for the right size of a test binary,
I recommend having 1:1 correspondence between libraries in project and test
binaries. (At least if it is possible, in some cases it is not.) Having
a test binary for each library in project keeps related tests together,
and makes tests easy to navigate by reflecting the project's organizational
structure.
---
[Home](Readme.md#top)

View File

@@ -19,7 +19,7 @@ TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) {
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 010-TestCase.cpp && 010-TestCase --success
// Expected compact output (all assertions):

View File

@@ -10,8 +10,8 @@ TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:
// Here just to show there are two source files via option --list-tests.
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success
//
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 020-TestCase-1.cpp
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -Fe020-TestCase.exe 020-TestCase-1.obj 020-TestCase-2.cpp && 020-TestCase --success

View File

@@ -53,7 +53,7 @@ TEST_CASE( "Assert that something is false (continue after failure)", "[check-fa
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 030-Asn-Require-Check.cpp && 030-Asn-Require-Check --success
// Expected compact output (all assertions):

View File

@@ -45,7 +45,7 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp && 100-Fix-Section --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp && 100-Fix-Section --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 100-Fix-Section.cpp && 100-Fix-Section --success
// Expected compact output (all assertions):

View File

@@ -52,8 +52,11 @@ TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/Normal", "[create]" ) {
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 110-Fix-ClassFixture.cpp && 110-Fix-ClassFixture --success
//
// Compile with pkg-config:
// - g++ -std=c++14 -Wall $(pkg-config catch2-with-main --cflags) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp $(pkg-config catch2-with-main --libs)
// Expected compact output (all assertions):
//

View File

@@ -48,7 +48,7 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) {
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 120-Bdd-ScenarioGivenWhenThen.cpp && 120-Bdd-ScenarioGivenWhenThen --success
// Expected compact output (all assertions):

View File

@@ -308,7 +308,7 @@ struct MyListener : Catch::EventListenerBase {
using EventListenerBase::EventListenerBase; // inherit constructor
// Get rid of Wweak-tables
~MyListener();
~MyListener() override;
// The whole test run starting
void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
@@ -420,7 +420,7 @@ TEST_CASE_METHOD( Fixture, "3: Testcase with class-based fixture", "[tag-C][tag-
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success
// - g++ -std=c++14 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 210-Evt-EventListeners.cpp && 210-Evt-EventListeners --success
// Expected compact output (all assertions):

View File

@@ -116,6 +116,13 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
``--out dir/<test_name>suffix``. This can be used to add a file extension to
the output e.g. ".xml".
``DL_PATHS path...``
Specifies paths that need to be set for the dynamic linker to find shared
libraries/DLLs when running the test executable (PATH/LD_LIBRARY_PATH respectively).
These paths will both be set when retrieving the list of test cases from the
test executable and when the tests are executed themselves. This requires
cmake/ctest >= 3.22.
#]=======================================================================]
#------------------------------------------------------------------------------
@@ -124,7 +131,7 @@ function(catch_discover_tests TARGET)
""
""
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX"
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
"TEST_SPEC;EXTRA_ARGS;PROPERTIES;DL_PATHS"
${ARGN}
)
@@ -135,6 +142,12 @@ function(catch_discover_tests TARGET)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
if (_DL_PATHS)
if(${CMAKE_VERSION} VERSION_LESS "3.22.0")
message(FATAL_ERROR "The DL_PATHS option requires at least cmake 3.22")
endif()
endif()
## Generate a unique name based on the extra arguments
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}")
string(SUBSTRING ${args_hash} 0 7 args_hash)
@@ -164,6 +177,7 @@ function(catch_discover_tests TARGET)
-D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
-D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
-D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
-D "TEST_DL_PATHS=${_DL_PATHS}"
-D "CTEST_FILE=${ctest_tests_file}"
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
VERBATIM

View File

@@ -10,10 +10,17 @@ set(reporter ${TEST_REPORTER})
set(output_dir ${TEST_OUTPUT_DIR})
set(output_prefix ${TEST_OUTPUT_PREFIX})
set(output_suffix ${TEST_OUTPUT_SUFFIX})
set(dl_paths ${TEST_DL_PATHS})
set(script)
set(suite)
set(tests)
if(WIN32)
set(dl_paths_variable_name PATH)
else()
set(dl_paths_variable_name LD_LIBRARY_PATH)
endif()
function(add_command NAME)
set(_args "")
# use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments
@@ -35,6 +42,12 @@ if(NOT EXISTS "${TEST_EXECUTABLE}")
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
)
endif()
if(dl_paths)
cmake_path(CONVERT "${dl_paths}" TO_NATIVE_PATH_LIST paths)
set(ENV{${dl_paths_variable_name}} "${paths}")
endif()
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-tests --verbosity quiet
OUTPUT_VARIABLE output
@@ -85,6 +98,13 @@ if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
endif()
endif()
if(dl_paths)
foreach(path ${dl_paths})
cmake_path(NATIVE_PATH path native_path)
list(APPEND environment_modifications "${dl_paths_variable_name}=path_list_prepend:${native_path}")
endforeach()
endif()
# Parse output
foreach(line ${output})
set(test ${line})
@@ -115,6 +135,14 @@ foreach(line ${output})
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
${properties}
)
if(environment_modifications)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
ENVIRONMENT_MODIFICATION "${environment_modifications}")
endif()
list(APPEND tests "${prefix}${test}${suffix}")
endforeach()

View File

@@ -0,0 +1,66 @@
# Copyright Catch2 Authors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# https://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
# Supported optional args:
# * SHARD_COUNT - number of shards to split target's tests into
# * REPORTER - reporter spec to use for tests
# * TEST_SPEC - test spec used for filtering tests
function(catch_add_sharded_tests TARGET)
if (${CMAKE_VERSION} VERSION_LESS "3.10.0")
message(FATAL_ERROR "add_sharded_catch_tests only supports CMake versions 3.10.0 and up")
endif()
cmake_parse_arguments(
""
""
"SHARD_COUNT;REPORTER;TEST_SPEC"
""
${ARGN}
)
if (NOT DEFINED _SHARD_COUNT)
set(_SHARD_COUNT 2)
endif()
# Generate a unique name based on the extra arguments
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX} ${_SHARD_COUNT}")
string(SUBSTRING ${args_hash} 0 7 args_hash)
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-sharded-tests-include-${args_hash}.cmake")
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-sharded-tests-impl-${args_hash}.cmake")
file(WRITE "${ctest_include_file}"
"if(EXISTS \"${ctest_tests_file}\")\n"
" include(\"${ctest_tests_file}\")\n"
"else()\n"
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
"endif()\n"
)
set_property(DIRECTORY
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
set(shard_impl_script_file "${CMAKE_CURRENT_LIST_DIR}/CatchShardTestsImpl.cmake")
add_custom_command(
TARGET ${TARGET} POST_BUILD
BYPRODUCTS "${ctest_tests_file}"
COMMAND "${CMAKE_COMMAND}"
-D "TARGET_NAME=${TARGET}"
-D "TEST_BINARY=$<TARGET_FILE:${TARGET}>"
-D "CTEST_FILE=${ctest_tests_file}"
-D "SHARD_COUNT=${_SHARD_COUNT}"
-D "REPORTER_SPEC=${_REPORTER}"
-D "TEST_SPEC=${_TEST_SPEC}"
-P "${shard_impl_script_file}"
VERBATIM
)
endfunction()

View File

@@ -0,0 +1,52 @@
# Copyright Catch2 Authors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# https://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
# Indirection for CatchShardTests that allows us to delay the script
# file generation until build time.
# Expected args:
# * TEST_BINARY - full path to the test binary to run sharded
# * CTEST_FILE - full path to ctest script file to write to
# * TARGET_NAME - name of the target to shard (used for test names)
# * SHARD_COUNT - number of shards to split the binary into
# Optional args:
# * REPORTER_SPEC - reporter specs to be passed down to the binary
# * TEST_SPEC - test spec to pass down to the test binary
if(NOT EXISTS "${TEST_BINARY}")
message(FATAL_ERROR
"Specified test binary '${TEST_BINARY}' does not exist"
)
endif()
set(other_args "")
if (TEST_SPEC)
set(other_args "${other_args} ${TEST_SPEC}")
endif()
if (REPORTER_SPEC)
set(other_args "${other_args} --reporter ${REPORTER_SPEC}")
endif()
# foreach RANGE in cmake is inclusive of the end, so we have to adjust it
math(EXPR adjusted_shard_count "${SHARD_COUNT} - 1")
file(WRITE "${CTEST_FILE}"
"string(RANDOM LENGTH 8 ALPHABET \"0123456789abcdef\" rng_seed)\n"
"\n"
"foreach(shard_idx RANGE ${adjusted_shard_count})\n"
" add_test(${TARGET_NAME}-shard-" [[${shard_idx}]] "/${adjusted_shard_count}\n"
" ${TEST_BINARY}"
" --shard-index " [[${shard_idx}]]
" --shard-count ${SHARD_COUNT}"
" --rng-seed " [[0x${rng_seed}]]
" --order rand"
"${other_args}"
"\n"
" )\n"
"endforeach()\n"
)

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
// Catch v3.0.0-preview.5
// Generated: 2022-04-20 23:45:13.582550
// Catch v3.1.0
// Generated: 2022-07-17 20:14:04.055157
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -274,6 +274,7 @@ namespace Catch {
virtual std::vector<std::string> const& getSectionsToRun() const = 0;
virtual Verbosity verbosity() const = 0;
virtual bool skipBenchmarks() const = 0;
virtual bool benchmarkNoAnalysis() const = 0;
virtual unsigned int benchmarkSamples() const = 0;
virtual double benchmarkConfidenceInterval() const = 0;
@@ -359,11 +360,23 @@ namespace Catch {
#endif
#if defined(__CUDACC__) && !defined(__clang__)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
#endif
// clang-cl defines _MSC_VER as well as __clang__, which could cause the
// start/stop internal suppression macros to be double defined.
#if defined(__clang__) && !defined(_MSC_VER)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
#endif // __clang__ && !_MSC_VER
#if defined(__clang__)
// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
// which results in calls to destructors being emitted for each temporary,
// without a matching initialization. In practice, this can result in something
@@ -688,7 +701,7 @@ namespace Catch {
class IMutableContext : public IContext {
public:
virtual ~IMutableContext(); // = default
~IMutableContext() override; // = default
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setConfig( IConfig const* config ) = 0;
@@ -715,7 +728,7 @@ namespace Catch {
void cleanUpContext();
class SimplePcg32;
SimplePcg32& rng();
SimplePcg32& sharedRng();
}
#endif // CATCH_CONTEXT_HPP_INCLUDED
@@ -1287,6 +1300,7 @@ namespace Catch {
namespace Catch {
struct ReporterDescription;
struct ListenerDescription;
struct TagInfo;
struct TestCaseInfo;
class TestCaseHandle;
@@ -1509,11 +1523,12 @@ namespace Catch {
//! Writes out information about provided reporters using reporter-specific format
virtual void listReporters(std::vector<ReporterDescription> const& descriptions) = 0;
//! Writes out the provided listeners descriptions using reporter-specific format
virtual void listListeners(std::vector<ListenerDescription> const& descriptions) = 0;
//! Writes out information about provided tests using reporter-specific format
virtual void listTests(std::vector<TestCaseHandle> const& tests) = 0;
//! Writes out information about the provided tags using reporter-specific format
virtual void listTags(std::vector<TagInfo> const& tags) = 0;
};
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
@@ -2226,6 +2241,10 @@ namespace Catch {
namespace Detail {
using sample = std::vector<double>;
// Used when we know we want == comparison of two doubles
// to centralize warning suppression
bool directCompare( double lhs, double rhs );
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
template <typename Iterator>
@@ -2256,7 +2275,7 @@ namespace Catch {
double mean(Iterator first, Iterator last) {
auto count = last - first;
double sum = std::accumulate(first, last, 0.);
return sum / count;
return sum / static_cast<double>(count);
}
template <typename Estimator, typename Iterator>
@@ -2302,23 +2321,25 @@ namespace Catch {
});
double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
int n = static_cast<int>(resample.size());
long n = static_cast<long>(resample.size());
double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / static_cast<double>(n);
// degenerate case with uniform samples
if (prob_n == 0) return { point, point, point, confidence_level };
if ( directCompare( prob_n, 0. ) ) {
return { point, point, point, confidence_level };
}
double bias = normal_quantile(prob_n);
double z1 = normal_quantile((1. - confidence_level) / 2.);
auto cumn = [n]( double x ) -> int {
return std::lround( normal_cdf( x ) * n );
auto cumn = [n]( double x ) -> long {
return std::lround( normal_cdf( x ) * static_cast<double>(n) );
};
auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
double b1 = bias + z1;
double b2 = bias - z1;
double a1 = a(b1);
double a2 = a(b2);
auto lo = static_cast<size_t>((std::max)(cumn(a1), 0));
auto lo = static_cast<size_t>((std::max)(cumn(a1), 0l));
auto hi = static_cast<size_t>((std::min)(cumn(a2), n - 1));
return { point, resample[lo], resample[hi], confidence_level };
@@ -2619,8 +2640,11 @@ namespace Catch {
// sets lambda to be used in fun *and* executes benchmark!
template <typename Fun, std::enable_if_t<!Detail::is_related<Fun, Benchmark>::value, int> = 0>
Benchmark & operator=(Fun func) {
fun = Detail::BenchmarkFunction(func);
run();
auto const* cfg = getCurrentContext().getConfig();
if (!cfg->skipBenchmarks()) {
fun = Detail::BenchmarkFunction(func);
run();
}
return *this;
}
@@ -2679,9 +2703,7 @@ namespace Catch {
template <typename T, bool Destruct>
struct ObjectStorage
{
using TStorage = std::aligned_storage_t<sizeof(T), std::alignment_of<T>::value>;
ObjectStorage() : data() {}
ObjectStorage() = default;
ObjectStorage(const ObjectStorage& other)
{
@@ -2690,7 +2712,7 @@ namespace Catch {
ObjectStorage(ObjectStorage&& other)
{
new(&data) T(CATCH_MOVE(other.stored_object()));
new(data) T(CATCH_MOVE(other.stored_object()));
}
~ObjectStorage() { destruct_on_exit<T>(); }
@@ -2698,7 +2720,7 @@ namespace Catch {
template <typename... Args>
void construct(Args&&... args)
{
new (&data) T(CATCH_FORWARD(args)...);
new (data) T(CATCH_FORWARD(args)...);
}
template <bool AllowManualDestruction = !Destruct>
@@ -2710,21 +2732,21 @@ namespace Catch {
private:
// If this is a constructor benchmark, destruct the underlying object
template <typename U>
void destruct_on_exit(std::enable_if_t<Destruct, U>* = 0) { destruct<true>(); }
void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
// Otherwise, don't
template <typename U>
void destruct_on_exit(std::enable_if_t<!Destruct, U>* = 0) { }
void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
T& stored_object() {
return *static_cast<T*>(static_cast<void*>(&data));
return *static_cast<T*>(static_cast<void*>(data));
}
T const& stored_object() const {
return *static_cast<T*>(static_cast<void*>(&data));
return *static_cast<T const*>(static_cast<void const*>(data));
}
TStorage data;
alignas( T ) unsigned char data[sizeof( T )]{};
};
} // namespace Detail
@@ -4147,6 +4169,7 @@ namespace Catch {
bool listTests = false;
bool listTags = false;
bool listReporters = false;
bool listListeners = false;
bool showSuccessfulTests = false;
bool shouldDebugBreak = false;
@@ -4163,6 +4186,7 @@ namespace Catch {
unsigned int shardCount = 1;
unsigned int shardIndex = 0;
bool skipBenchmarks = false;
bool benchmarkNoAnalysis = false;
unsigned int benchmarkSamples = 100;
double benchmarkConfidenceInterval = 0.95;
@@ -4197,6 +4221,7 @@ namespace Catch {
bool listTests() const;
bool listTags() const;
bool listReporters() const;
bool listListeners() const;
std::vector<ReporterSpec> const& getReporterSpecs() const;
std::vector<ProcessedReporterSpec> const&
@@ -4228,6 +4253,7 @@ namespace Catch {
int abortAfter() const override;
bool showInvisibles() const override;
Verbosity verbosity() const override;
bool skipBenchmarks() const override;
bool benchmarkNoAnalysis() const override;
unsigned int benchmarkSamples() const override;
double benchmarkConfidenceInterval() const override;
@@ -5554,9 +5580,9 @@ namespace Catch {
#endif // CATCH_ASSERTION_HANDLER_HPP_INCLUDED
// We need this suppression to leak, because it took until GCC 9
// We need this suppression to leak, because it took until GCC 10
// for the front end to handle local suppression via _Pragma properly
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 9
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9
#pragma GCC diagnostic ignored "-Wparentheses"
#endif
@@ -5865,6 +5891,7 @@ struct AutoReg : Detail::NonCopyable {
static void TestName(); \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
@@ -5875,6 +5902,7 @@ struct AutoReg : Detail::NonCopyable {
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
@@ -5882,6 +5910,7 @@ struct AutoReg : Detail::NonCopyable {
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
@@ -5898,6 +5927,7 @@ struct AutoReg : Detail::NonCopyable {
do { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} while(false)
@@ -6993,6 +7023,7 @@ namespace Catch {
#endif // CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
#ifndef CATCH_VERSION_HPP_INCLUDED
#define CATCH_VERSION_HPP_INCLUDED
@@ -7031,7 +7062,7 @@ namespace Catch {
#define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 0
#define CATCH_VERSION_MINOR 1
#define CATCH_VERSION_PATCH 0
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@@ -7090,10 +7121,30 @@ namespace Catch {
#define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
#include <string>
namespace Catch {
namespace Generators {
class GeneratorUntypedBase {
// Caches result from `toStringImpl`, assume that when it is an
// empty string, the cache is invalidated.
mutable std::string m_stringReprCache;
// Counts based on `next` returning true
std::size_t m_currentElementIndex = 0;
/**
* Attempts to move the generator to the next element
*
* Returns true iff the move succeeded (and a valid element
* can be retrieved).
*/
virtual bool next() = 0;
//! Customization point for `currentElementAsString`
virtual std::string stringifyImpl() const = 0;
public:
GeneratorUntypedBase() = default;
// Generation of copy ops is deprecated (and Clang will complain)
@@ -7103,11 +7154,34 @@ namespace Catch {
virtual ~GeneratorUntypedBase(); // = default;
// Attempts to move the generator to the next element
//
// Returns true iff the move succeeded (and a valid element
// can be retrieved).
virtual bool next() = 0;
/**
* Attempts to move the generator to the next element
*
* Serves as a non-virtual interface to `next`, so that the
* top level interface can provide sanity checking and shared
* features.
*
* As with `next`, returns true iff the move succeeded and
* the generator has new valid element to provide.
*/
bool countedNext();
std::size_t currentElementIndex() const { return m_currentElementIndex; }
/**
* Returns generator's current element as user-friendly string.
*
* By default returns string equivalent to calling
* `Catch::Detail::stringify` on the current element, but generators
* can customize their implementation as needed.
*
* Not thread-safe due to internal caching.
*
* The returned ref is valid only until the generator instance
* is destructed, or it moves onto the next element, whichever
* comes first.
*/
StringRef currentElementAsString() const;
};
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
@@ -7142,6 +7216,10 @@ namespace Detail {
template<typename T>
class IGenerator : public GeneratorUntypedBase {
std::string stringifyImpl() const override {
return ::Catch::Detail::stringify( get() );
}
public:
~IGenerator() override = default;
IGenerator() = default;
@@ -7174,7 +7252,7 @@ namespace Detail {
return m_generator->get();
}
bool next() {
return m_generator->next();
return m_generator->countedNext();
}
};
@@ -7641,16 +7719,21 @@ namespace Catch {
namespace Catch {
namespace Generators {
namespace Detail {
// Returns a suitable seed for a random floating generator based off
// the primary internal rng. It does so by taking current value from
// the rng and returning it as the seed.
std::uint32_t getSeed();
}
template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
Catch::SimplePcg32& m_rng;
Catch::SimplePcg32 m_rng;
std::uniform_real_distribution<Float> m_dist;
Float m_current_number;
public:
RandomFloatingGenerator(Float a, Float b):
m_rng(rng()),
RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
m_rng(seed),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -7666,13 +7749,12 @@ public:
template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
Catch::SimplePcg32& m_rng;
Catch::SimplePcg32 m_rng;
std::uniform_int_distribution<Integer> m_dist;
Integer m_current_number;
public:
RandomIntegerGenerator(Integer a, Integer b):
m_rng(rng()),
RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
m_rng(seed),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -7686,14 +7768,19 @@ public:
}
};
// TODO: Ideally this would be also constrained against the various char types,
// but I don't expect users to run into that in practice.
template <typename T>
std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value,
GeneratorWrapper<T>>
std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
random(T a, T b) {
static_assert(
!std::is_same<T, char>::value &&
!std::is_same<T, int8_t>::value &&
!std::is_same<T, uint8_t>::value &&
!std::is_same<T, signed char>::value &&
!std::is_same<T, unsigned char>::value &&
!std::is_same<T, bool>::value,
"The requested type is not supported by the underlying random distributions from std" );
return GeneratorWrapper<T>(
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
);
}
@@ -7702,7 +7789,7 @@ std::enable_if_t<std::is_floating_point<T>::value,
GeneratorWrapper<T>>
random(T a, T b) {
return GeneratorWrapper<T>(
Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
);
}
@@ -7867,6 +7954,9 @@ namespace Catch {
public:
virtual ~EventListenerFactory(); // = default
virtual IEventListenerPtr create( IConfig const* config ) const = 0;
//! Return a meaningful name for the listener, e.g. its type name
virtual StringRef getName() const = 0;
//! Return listener's description if available
virtual std::string getDescription() const = 0;
};
} // namespace Catch
@@ -7901,6 +7991,7 @@ namespace Catch {
} // namespace Catch
#endif // CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
#include <string>
#include <vector>
#include <map>
@@ -8027,12 +8118,16 @@ namespace Catch {
#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
// This include must be kept so that user's configured value for CONSOLE_WIDTH
// is used before we attempt to provide a default value
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
#endif
#endif // CATCH_CONSOLE_WIDTH_HPP_INCLUDED
#ifndef CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
#define CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
@@ -8125,7 +8220,7 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
#define CATCH_TRAP() __asm__(".inst 0xd43e0000")
#endif
#elif defined(CATCH_PLATFORM_IPHONE)
@@ -8367,6 +8462,7 @@ namespace Catch {
#endif // CATCH_POLYFILLS_HPP_INCLUDED
#include <cassert>
#include <cmath>
#include <cstdint>
#include <utility>
@@ -8381,6 +8477,15 @@ namespace Catch {
} // end namespace Detail
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic push
// We do a bunch of direct compensations of floating point numbers,
// because we know what we are doing and actually do want the direct
// comparison behaviour.
# pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
/**
* Calculates the ULP distance between two floating point numbers
*
@@ -8440,6 +8545,11 @@ namespace Catch {
return lc - rc;
}
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic pop
#endif
} // end namespace Catch
#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
@@ -8523,6 +8633,10 @@ namespace Catch {
struct ReporterDescription {
std::string name, description;
};
struct ListenerDescription {
StringRef name;
std::string description;
};
struct TagInfo {
void add(StringRef spelling);
@@ -10074,7 +10188,7 @@ namespace Matchers {
class MatcherGenericBase : public MatcherUntypedBase {
public:
MatcherGenericBase() = default;
virtual ~MatcherGenericBase(); // = default;
~MatcherGenericBase() override; // = default;
MatcherGenericBase(MatcherGenericBase&) = default;
MatcherGenericBase(MatcherGenericBase&&) = default;
@@ -10365,7 +10479,6 @@ namespace Catch {
class IsEmptyMatcher final : public MatcherGenericBase {
public:
// todo: Use polyfills
template <typename RangeLike>
bool match(RangeLike&& rng) const {
#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
@@ -10766,7 +10879,55 @@ namespace Catch {
}
};
// Creates a matcher that checks whether a range contains element matching a matcher
// Matcher for checking that all elements in range are true.
class AllTrueMatcher final : public MatcherGenericBase {
public:
std::string describe() const override;
template <typename RangeLike>
bool match(RangeLike&& rng) const {
for (auto&& elem : rng) {
if (!elem) {
return false;
}
}
return true;
}
};
// Matcher for checking that no element in range is true.
class NoneTrueMatcher final : public MatcherGenericBase {
public:
std::string describe() const override;
template <typename RangeLike>
bool match(RangeLike&& rng) const {
for (auto&& elem : rng) {
if (elem) {
return false;
}
}
return true;
}
};
// Matcher for checking that any element in range is true.
class AnyTrueMatcher final : public MatcherGenericBase {
public:
std::string describe() const override;
template <typename RangeLike>
bool match(RangeLike&& rng) const {
for (auto&& elem : rng) {
if (elem) {
return true;
}
}
return false;
}
};
// Creates a matcher that checks whether all elements in a range match a matcher
template <typename Matcher>
AllMatchMatcher<Matcher> AllMatch(Matcher&& matcher) {
return { CATCH_FORWARD(matcher) };
@@ -10783,6 +10944,15 @@ namespace Catch {
AnyMatchMatcher<Matcher> AnyMatch(Matcher&& matcher) {
return { CATCH_FORWARD(matcher) };
}
// Creates a matcher that checks whether all elements in a range are true
AllTrueMatcher AllTrue();
// Creates a matcher that checks whether no element in a range is true
NoneTrueMatcher NoneTrue();
// Creates a matcher that checks whether any element in a range is true
AnyTrueMatcher AnyTrue();
}
}
@@ -11128,6 +11298,14 @@ namespace Catch {
*/
void listReporters(
std::vector<ReporterDescription> const& descriptions ) override;
/**
* Provides a simple default listing of listeners
*
* Looks similarly to listing of reporters, but with listener type
* instead of reporter name.
*/
void listListeners(
std::vector<ListenerDescription> const& descriptions ) override;
/**
* Provides a simple default listing of tests.
*
@@ -11154,7 +11332,11 @@ namespace Catch {
class StreamingReporterBase : public ReporterBase {
public:
using ReporterBase::ReporterBase;
// GCC5 compat: we cannot use inherited constructor, because it
// doesn't implement backport of P0136
StreamingReporterBase(ReporterConfig&& _config):
ReporterBase(CATCH_MOVE(_config))
{}
~StreamingReporterBase() override;
void benchmarkPreparing( StringRef ) override {}
@@ -11211,7 +11393,11 @@ namespace Catch {
class AutomakeReporter final : public StreamingReporterBase {
public:
using StreamingReporterBase::StreamingReporterBase;
// GCC5 compat: we cannot use inherited constructor, because it
// doesn't implement backport of P0136
AutomakeReporter(ReporterConfig&& _config):
StreamingReporterBase(CATCH_MOVE(_config))
{}
~AutomakeReporter() override;
static std::string getDescription() {
@@ -11407,7 +11593,11 @@ namespace Catch {
using TestCaseNode = Node<TestCaseStats, SectionNode>;
using TestRunNode = Node<TestRunStats, TestCaseNode>;
using ReporterBase::ReporterBase;
// GCC5 compat: we cannot use inherited constructor, because it
// doesn't implement backport of P0136
CumulativeReporterBase(ReporterConfig&& _config):
ReporterBase(CATCH_MOVE(_config))
{}
~CumulativeReporterBase() override;
void benchmarkPreparing( StringRef ) override {}
@@ -11495,6 +11685,8 @@ namespace Catch {
void listReporters(
std::vector<ReporterDescription> const& descriptions ) override;
void listListeners(
std::vector<ListenerDescription> const& descriptions ) override;
void listTests( std::vector<TestCaseHandle> const& tests ) override;
void listTags( std::vector<TagInfo> const& tagInfos ) override;
@@ -11559,6 +11751,13 @@ namespace Catch {
std::vector<ReporterDescription> const& descriptions,
Verbosity verbosity );
/**
* Lists listeners descriptions to the provided stream in user-friendly
* format
*/
void defaultListListeners( std::ostream& out,
std::vector<ListenerDescription> const& descriptions );
/**
* Lists tag information to the provided stream in user-friendly format
*
@@ -11692,6 +11891,7 @@ namespace Catch {
void skipTest( TestCaseInfo const& testInfo ) override;
void listReporters(std::vector<ReporterDescription> const& descriptions) override;
void listListeners(std::vector<ListenerDescription> const& descriptions) override;
void listTests(std::vector<TestCaseHandle> const& tests) override;
void listTags(std::vector<TagInfo> const& tags) override;
@@ -11707,8 +11907,28 @@ namespace Catch {
#define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#include <type_traits>
namespace Catch {
namespace Detail {
template <typename T, typename = void>
struct has_description : std::false_type {};
template <typename T>
struct has_description<
T,
void_t<decltype( T::getDescription() )>>
: std::true_type {};
//! Indirection for reporter registration, so that the error handling is
//! independent on the reporter's concrete type
void registerReporterImpl( std::string const& name,
IReporterFactoryPtr reporterPtr );
} // namespace Detail
class IEventListener;
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
@@ -11729,7 +11949,8 @@ namespace Catch {
class ReporterRegistrar {
public:
explicit ReporterRegistrar( std::string const& name ) {
getMutableRegistryHub().registerReporter( name, Detail::make_unique<ReporterFactory<T>>() );
registerReporterImpl( name,
Detail::make_unique<ReporterFactory<T>>() );
}
};
@@ -11737,37 +11958,60 @@ namespace Catch {
class ListenerRegistrar {
class TypedListenerFactory : public EventListenerFactory {
StringRef m_listenerName;
IEventListenerPtr
create( IConfig const* config ) const override {
return Detail::make_unique<T>(config);
std::string getDescriptionImpl( std::true_type ) const {
return T::getDescription();
}
std::string getDescriptionImpl( std::false_type ) const {
return "(No description provided)";
}
public:
TypedListenerFactory( StringRef listenerName ):
m_listenerName( listenerName ) {}
IEventListenerPtr create( IConfig const* config ) const override {
return Detail::make_unique<T>( config );
}
StringRef getName() const override {
return m_listenerName;
}
std::string getDescription() const override {
return std::string();
return getDescriptionImpl( Detail::has_description<T>{} );
}
};
public:
ListenerRegistrar() {
getMutableRegistryHub().registerListener( Detail::make_unique<TypedListenerFactory>() );
ListenerRegistrar(StringRef listenerName) {
getMutableRegistryHub().registerListener( Detail::make_unique<TypedListenerFactory>(listenerName) );
}
};
}
#if !defined(CATCH_CONFIG_DISABLE)
#define CATCH_REGISTER_REPORTER( name, reporterType ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# define CATCH_REGISTER_REPORTER( name, reporterType ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
Catch::ReporterRegistrar<reporterType> INTERNAL_CATCH_UNIQUE_NAME( \
catch_internal_RegistrarFor )( name ); \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# define CATCH_REGISTER_LISTENER( listenerType ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
catch_internal_RegistrarFor )( #listenerType ); \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#define CATCH_REGISTER_LISTENER( listenerType ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#else // CATCH_CONFIG_DISABLE
#define CATCH_REGISTER_REPORTER(name, reporterType)
@@ -11969,6 +12213,7 @@ namespace Catch {
void benchmarkFailed( StringRef error ) override;
void listReporters(std::vector<ReporterDescription> const& descriptions) override;
void listListeners(std::vector<ListenerDescription> const& descriptions) override;
void listTests(std::vector<TestCaseHandle> const& tests) override;
void listTags(std::vector<TagInfo> const& tags) override;

View File

@@ -31,7 +31,9 @@ set(BENCHMARK_HEADERS
${SOURCES_DIR}/benchmark/detail/catch_timing.hpp
)
set(BENCHMARK_SOURCES
${SOURCES_DIR}/benchmark/internal/catch_benchmark_combined_tu.cpp
${SOURCES_DIR}/benchmark/catch_chronometer.cpp
${SOURCES_DIR}/benchmark/detail/catch_benchmark_function.cpp
${SOURCES_DIR}/benchmark/detail/catch_run_for_at_least.cpp
${SOURCES_DIR}/benchmark/detail/catch_stats.cpp
)
@@ -120,7 +122,6 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/internal/catch_preprocessor_remove_parens.hpp
${SOURCES_DIR}/internal/catch_random_number_generator.hpp
${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
${SOURCES_DIR}/reporters/catch_reporter_registrars.hpp
${SOURCES_DIR}/internal/catch_reporter_registry.hpp
${SOURCES_DIR}/internal/catch_reporter_spec_parser.hpp
${SOURCES_DIR}/internal/catch_result_type.hpp
@@ -167,7 +168,6 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_approx.cpp
${SOURCES_DIR}/internal/catch_assertion_handler.cpp
${SOURCES_DIR}/catch_assertion_result.cpp
${SOURCES_DIR}/matchers/internal/catch_matchers_combined_tu.cpp
${SOURCES_DIR}/internal/catch_clara.cpp
${SOURCES_DIR}/internal/catch_commandline.cpp
${SOURCES_DIR}/internal/catch_source_line_info.cpp
@@ -183,17 +183,16 @@ set(IMPL_SOURCES
${SOURCES_DIR}/internal/catch_fatal_condition_handler.cpp
${SOURCES_DIR}/internal/catch_floating_point_helpers.cpp
${SOURCES_DIR}/internal/catch_istream.cpp
${SOURCES_DIR}/generators/internal/catch_generators_combined_tu.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_combined_tu.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_generatortracker.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter.cpp
${SOURCES_DIR}/internal/catch_list.cpp
${SOURCES_DIR}/matchers/catch_matchers_floating_point.cpp
${SOURCES_DIR}/matchers/catch_matchers_quantifiers.cpp
${SOURCES_DIR}/matchers/catch_matchers_string.cpp
${SOURCES_DIR}/matchers/catch_matchers_templated.cpp
${SOURCES_DIR}/catch_message.cpp
${SOURCES_DIR}/internal/catch_output_redirect.cpp
${SOURCES_DIR}/catch_registry_hub.cpp
${SOURCES_DIR}/internal/catch_combined_tu.cpp
${SOURCES_DIR}/internal/catch_random_number_generator.cpp
${SOURCES_DIR}/internal/catch_random_seed_generation.cpp
${SOURCES_DIR}/internal/catch_reporter_registry.cpp
@@ -222,6 +221,30 @@ set(IMPL_SOURCES
${SOURCES_DIR}/internal/catch_wildcard_pattern.cpp
${SOURCES_DIR}/internal/catch_xmlwriter.cpp
${SOURCES_DIR}/internal/catch_test_case_info_hasher.cpp
${SOURCES_DIR}/generators/catch_generators_random.cpp
${SOURCES_DIR}/generators/catch_generator_exception.cpp
${SOURCES_DIR}/generators/catch_generators.cpp
${SOURCES_DIR}/matchers/catch_matchers.cpp
${SOURCES_DIR}/matchers/catch_matchers_container_properties.cpp
${SOURCES_DIR}/matchers/catch_matchers_exception.cpp
${SOURCES_DIR}/matchers/catch_matchers_predicate.cpp
${SOURCES_DIR}/matchers/internal/catch_matchers_impl.cpp
${SOURCES_DIR}/catch_tag_alias_autoregistrar.cpp
${SOURCES_DIR}/internal/catch_decomposer.cpp
${SOURCES_DIR}/internal/catch_errno_guard.cpp
${SOURCES_DIR}/internal/catch_lazy_expr.cpp
${SOURCES_DIR}/internal/catch_leak_detector.cpp
${SOURCES_DIR}/internal/catch_message_info.cpp
${SOURCES_DIR}/internal/catch_polyfills.cpp
${SOURCES_DIR}/internal/catch_startup_exception_registry.cpp
${SOURCES_DIR}/internal/catch_uncaught_exceptions.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_capture.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_config.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_exception.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_registry_hub.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_factory.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_registry.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_testcase.cpp
)
set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
@@ -237,6 +260,7 @@ set(REPORTER_HEADERS
${SOURCES_DIR}/reporters/catch_reporter_helpers.hpp
${SOURCES_DIR}/reporters/catch_reporter_junit.hpp
${SOURCES_DIR}/reporters/catch_reporter_multi.hpp
${SOURCES_DIR}/reporters/catch_reporter_registrars.hpp
${SOURCES_DIR}/reporters/catch_reporter_sonarqube.hpp
${SOURCES_DIR}/reporters/catch_reporter_streaming_base.hpp
${SOURCES_DIR}/reporters/catch_reporter_tap.hpp
@@ -245,13 +269,15 @@ set(REPORTER_HEADERS
)
set(REPORTER_SOURCES
${SOURCES_DIR}/reporters/catch_reporter_automake.cpp
${SOURCES_DIR}/reporters/catch_reporter_combined_tu.cpp
${SOURCES_DIR}/reporters/catch_reporter_common_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_compact.cpp
${SOURCES_DIR}/reporters/catch_reporter_console.cpp
${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_event_listener.cpp
${SOURCES_DIR}/reporters/catch_reporter_helpers.cpp
${SOURCES_DIR}/reporters/catch_reporter_junit.cpp
${SOURCES_DIR}/reporters/catch_reporter_multi.cpp
${SOURCES_DIR}/reporters/catch_reporter_registrars.cpp
${SOURCES_DIR}/reporters/catch_reporter_sonarqube.cpp
${SOURCES_DIR}/reporters/catch_reporter_streaming_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_tap.cpp
@@ -260,9 +286,7 @@ set(REPORTER_SOURCES
)
set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
# Fixme: STATIC because for dynamic, we would need to handle visibility
# and I don't want to do the annotations right now
add_library(Catch2 STATIC
add_library(Catch2
${REPORTER_FILES}
${INTERNAL_FILES}
${BENCHMARK_HEADERS}
@@ -315,7 +339,7 @@ target_include_directories(Catch2
)
add_library(Catch2WithMain STATIC
add_library(Catch2WithMain
${SOURCES_DIR}/internal/catch_main.cpp
)
add_build_reproducibility_settings(Catch2WithMain)
@@ -406,3 +430,27 @@ endif()
list(APPEND CATCH_WARNING_TARGETS Catch2 Catch2WithMain)
set(CATCH_WARNING_TARGETS ${CATCH_WARNING_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
# the configuration step so that we don't have to also provide an override.
if (BUILD_SHARED_LIBS)
if (MSVC)
set_target_properties(Catch2 Catch2WithMain
PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS ON
)
endif()
get_target_property(_VisPreset Catch2 CXX_VISIBILITY_PRESET)
if (NOT MSVC AND _VisPreset STREQUAL "hidden")
set_target_properties(Catch2 Catch2WithMain
PROPERTIES
CXX_VISIBILITY_PRESET "default"
VISIBILITY_INLINES_HIDDEN OFF
)
message(WARNING "Setting Catch2's visibility to default."
" Hidden visibility is not supported.")
endif()
endif()

View File

@@ -95,8 +95,11 @@ namespace Catch {
// sets lambda to be used in fun *and* executes benchmark!
template <typename Fun, std::enable_if_t<!Detail::is_related<Fun, Benchmark>::value, int> = 0>
Benchmark & operator=(Fun func) {
fun = Detail::BenchmarkFunction(func);
run();
auto const* cfg = getCurrentContext().getConfig();
if (!cfg->skipBenchmarks()) {
fun = Detail::BenchmarkFunction(func);
run();
}
return *this;
}

View File

@@ -0,0 +1,17 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/benchmark/catch_chronometer.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
ChronometerConcept::~ChronometerConcept() = default;
} // namespace Detail
} // namespace Benchmark
} // namespace Catch

View File

@@ -20,9 +20,7 @@ namespace Catch {
template <typename T, bool Destruct>
struct ObjectStorage
{
using TStorage = std::aligned_storage_t<sizeof(T), std::alignment_of<T>::value>;
ObjectStorage() : data() {}
ObjectStorage() = default;
ObjectStorage(const ObjectStorage& other)
{
@@ -31,7 +29,7 @@ namespace Catch {
ObjectStorage(ObjectStorage&& other)
{
new(&data) T(CATCH_MOVE(other.stored_object()));
new(data) T(CATCH_MOVE(other.stored_object()));
}
~ObjectStorage() { destruct_on_exit<T>(); }
@@ -39,7 +37,7 @@ namespace Catch {
template <typename... Args>
void construct(Args&&... args)
{
new (&data) T(CATCH_FORWARD(args)...);
new (data) T(CATCH_FORWARD(args)...);
}
template <bool AllowManualDestruction = !Destruct>
@@ -51,21 +49,21 @@ namespace Catch {
private:
// If this is a constructor benchmark, destruct the underlying object
template <typename U>
void destruct_on_exit(std::enable_if_t<Destruct, U>* = 0) { destruct<true>(); }
void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
// Otherwise, don't
template <typename U>
void destruct_on_exit(std::enable_if_t<!Destruct, U>* = 0) { }
void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
T& stored_object() {
return *static_cast<T*>(static_cast<void*>(&data));
return *static_cast<T*>(static_cast<void*>(data));
}
T const& stored_object() const {
return *static_cast<T*>(static_cast<void*>(&data));
return *static_cast<T const*>(static_cast<void const*>(data));
}
TStorage data;
alignas( T ) unsigned char data[sizeof( T )]{};
};
} // namespace Detail

View File

@@ -0,0 +1,17 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
BenchmarkFunction::callable::~callable() = default;
} // namespace Detail
} // namespace Benchmark
} // namespace Catch

View File

@@ -0,0 +1,30 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/benchmark/detail/catch_run_for_at_least.hpp>
#include <exception>
#include <catch2/internal/catch_enforce.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
struct optimized_away_error : std::exception {
const char* what() const noexcept override;
};
const char* optimized_away_error::what() const noexcept {
return "could not measure benchmark, maybe it was optimized away";
}
void throw_optimized_away_error() {
Catch::throw_exception(optimized_away_error{});
}
} // namespace Detail
} // namespace Benchmark
} // namespace Catch

View File

@@ -137,6 +137,15 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
bool directCompare( double lhs, double rhs ) { return lhs == rhs; }
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic pop
#endif
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
auto count = last - first;
double idx = (count - 1) * k / static_cast<double>(q);
@@ -144,7 +153,9 @@ namespace Catch {
double g = idx - j;
std::nth_element(first, first + j, last);
auto xj = first[j];
if (g == 0) return xj;
if ( directCompare( g, 0 ) ) {
return xj;
}
auto xj1 = *std::min_element(first + (j + 1), last);
return xj + g * (xj1 - xj);

View File

@@ -24,6 +24,10 @@ namespace Catch {
namespace Detail {
using sample = std::vector<double>;
// Used when we know we want == comparison of two doubles
// to centralize warning suppression
bool directCompare( double lhs, double rhs );
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
template <typename Iterator>
@@ -54,7 +58,7 @@ namespace Catch {
double mean(Iterator first, Iterator last) {
auto count = last - first;
double sum = std::accumulate(first, last, 0.);
return sum / count;
return sum / static_cast<double>(count);
}
template <typename Estimator, typename Iterator>
@@ -100,23 +104,25 @@ namespace Catch {
});
double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
int n = static_cast<int>(resample.size());
long n = static_cast<long>(resample.size());
double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / static_cast<double>(n);
// degenerate case with uniform samples
if (prob_n == 0) return { point, point, point, confidence_level };
if ( directCompare( prob_n, 0. ) ) {
return { point, point, point, confidence_level };
}
double bias = normal_quantile(prob_n);
double z1 = normal_quantile((1. - confidence_level) / 2.);
auto cumn = [n]( double x ) -> int {
return std::lround( normal_cdf( x ) * n );
auto cumn = [n]( double x ) -> long {
return std::lround( normal_cdf( x ) * static_cast<double>(n) );
};
auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
double b1 = bias + z1;
double b2 = bias - z1;
double a1 = a(b1);
double a2 = a(b2);
auto lo = static_cast<size_t>((std::max)(cumn(a1), 0));
auto lo = static_cast<size_t>((std::max)(cumn(a1), 0l));
auto hi = static_cast<size_t>((std::min)(cumn(a2), n - 1));
return { point, resample[lo], resample[hi], confidence_level };

View File

@@ -1,75 +0,0 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/** \file
* This is a special TU that combines what would otherwise be a very
* small benchmarking-related TUs into one bigger TU.
*
* The reason for this is compilation performance improvements by
* avoiding reparsing headers for many small TUs, instead having this
* one TU include bit more, but having it all parsed only once.
*
* To avoid heavy-tail problem with compilation times, each "subpart"
* of Catch2 has its own combined TU like this.
*/
////////////////////////////////////////////
// vvv formerly catch_chronometer.cpp vvv //
////////////////////////////////////////////
#include <catch2/benchmark/catch_chronometer.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
ChronometerConcept::~ChronometerConcept() = default;
} // namespace Detail
} // namespace Benchmark
} // namespace Catch
///////////////////////////////////////////////////
// vvv formerly catch_benchmark_function.cpp vvv //
///////////////////////////////////////////////////
#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
BenchmarkFunction::callable::~callable() = default;
} // namespace Detail
} // namespace Benchmark
} // namespace Catch
/////////////////////////////////////////////////
// vvv formerly catch_run_for_at_least.cpp vvv //
/////////////////////////////////////////////////
#include <catch2/benchmark/detail/catch_run_for_at_least.hpp>
#include <exception>
#include <catch2/internal/catch_enforce.hpp>
namespace Catch {
namespace Benchmark {
namespace Detail {
struct optimized_away_error : std::exception {
const char* what() const noexcept override;
};
const char* optimized_away_error::what() const noexcept {
return "could not measure benchmark, maybe it was optimized away";
}
void throw_optimized_away_error() {
Catch::throw_exception(optimized_away_error{});
}
} // namespace Detail
} // namespace Benchmark
} // namespace Catch

View File

@@ -13,6 +13,28 @@
#include <catch2/internal/catch_test_spec_parser.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
namespace {
bool provideBazelReporterOutput() {
#ifdef CATCH_CONFIG_BAZEL_SUPPORT
return true;
#else
# if defined( _MSC_VER )
// On Windows getenv throws a warning as there is no input validation,
// since the switch is hardcoded, this should not be an issue.
# pragma warning( push )
# pragma warning( disable : 4996 )
# endif
return std::getenv( "BAZEL_TEST" ) != nullptr;
# if defined( _MSC_VER )
# pragma warning( pop )
# endif
#endif
}
}
namespace Catch {
bool operator==( ProcessedReporterSpec const& lhs,
@@ -59,27 +81,27 @@ namespace Catch {
} );
}
#if defined( CATCH_CONFIG_BAZEL_SUPPORT )
// Register a JUnit reporter for Bazel. Bazel sets an environment
// variable with the path to XML output. If this file is written to
// during test, Bazel will not generate a default XML output.
// This allows the XML output file to contain higher level of detail
// than what is possible otherwise.
if(provideBazelReporterOutput()){
// Register a JUnit reporter for Bazel. Bazel sets an environment
// variable with the path to XML output. If this file is written to
// during test, Bazel will not generate a default XML output.
// This allows the XML output file to contain higher level of detail
// than what is possible otherwise.
# if defined( _MSC_VER )
// On Windows getenv throws a warning as there is no input validation,
// since the key is hardcoded, this should not be an issue.
# pragma warning( push )
# pragma warning( disable : 4996 )
// On Windows getenv throws a warning as there is no input validation,
// since the key is hardcoded, this should not be an issue.
# pragma warning( push )
# pragma warning( disable : 4996 )
# endif
const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" );
const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" );
# if defined( _MSC_VER )
# pragma warning( pop )
# endif
if ( bazelOutputFilePtr != nullptr ) {
m_data.reporterSpecifications.push_back(
{ "junit", std::string( bazelOutputFilePtr ), {}, {} } );
}
#endif
if ( bazelOutputFilePtr != nullptr ) {
m_data.reporterSpecifications.push_back(
{ "junit", std::string( bazelOutputFilePtr ), {}, {} } );
}
}
// We now fixup the reporter specs to handle default output spec,
@@ -111,6 +133,7 @@ namespace Catch {
bool Config::listTests() const { return m_data.listTests; }
bool Config::listTags() const { return m_data.listTags; }
bool Config::listReporters() const { return m_data.listReporters; }
bool Config::listListeners() const { return m_data.listListeners; }
std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
@@ -152,6 +175,7 @@ namespace Catch {
bool Config::showInvisibles() const { return m_data.showInvisibles; }
Verbosity Config::verbosity() const { return m_data.verbosity; }
bool Config::skipBenchmarks() const { return m_data.skipBenchmarks; }
bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
unsigned int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }

View File

@@ -48,6 +48,7 @@ namespace Catch {
bool listTests = false;
bool listTags = false;
bool listReporters = false;
bool listListeners = false;
bool showSuccessfulTests = false;
bool shouldDebugBreak = false;
@@ -64,6 +65,7 @@ namespace Catch {
unsigned int shardCount = 1;
unsigned int shardIndex = 0;
bool skipBenchmarks = false;
bool benchmarkNoAnalysis = false;
unsigned int benchmarkSamples = 100;
double benchmarkConfidenceInterval = 0.95;
@@ -98,6 +100,7 @@ namespace Catch {
bool listTests() const;
bool listTags() const;
bool listReporters() const;
bool listListeners() const;
std::vector<ReporterSpec> const& getReporterSpecs() const;
std::vector<ProcessedReporterSpec> const&
@@ -129,6 +132,7 @@ namespace Catch {
int abortAfter() const override;
bool showInvisibles() const override;
Verbosity verbosity() const override;
bool skipBenchmarks() const override;
bool benchmarkNoAnalysis() const override;
unsigned int benchmarkSamples() const override;
double benchmarkConfidenceInterval() const override;

View File

@@ -0,0 +1,24 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_tag_alias_autoregistrar.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
namespace Catch {
RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
CATCH_TRY {
getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
} CATCH_CATCH_ALL {
// Do not throw when constructing global objects, instead register the exception to be processed later
getMutableRegistryHub().registerStartupException();
}
}
}

View File

@@ -58,7 +58,7 @@ namespace Catch {
else if( tag == "!nonportable"_sr )
return TestCaseProperties::NonPortable;
else if( tag == "!benchmark"_sr )
return static_cast<TestCaseProperties>(TestCaseProperties::Benchmark | TestCaseProperties::IsHidden );
return TestCaseProperties::Benchmark | TestCaseProperties::IsHidden;
else
return TestCaseProperties::None;
}

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/generators/catch_generator_exception.hpp>
namespace Catch {
const char* GeneratorException::what() const noexcept {
return m_msg;
}
} // end namespace Catch

View File

@@ -5,36 +5,6 @@
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/** \file
* This is a special TU that combines what would otherwise be a very
* small generator-related TUs into one bigger TU.
*
* The reason for this is compilation performance improvements by
* avoiding reparsing headers for many small TUs, instead having this
* one TU include bit more, but having it all parsed only once.
*
* To avoid heavy-tail problem with compilation times, each "subpart"
* of Catch2 has its own combined TU like this.
*/
////////////////////////////////////////////////////
// vvv formerly catch_generator_exception.cpp vvv //
////////////////////////////////////////////////////
#include <catch2/generators/catch_generator_exception.hpp>
namespace Catch {
const char* GeneratorException::what() const noexcept {
return m_msg;
}
} // end namespace Catch
///////////////////////////////////////////
// vvv formerly catch_generators.cpp vvv //
///////////////////////////////////////////
#include <catch2/generators/catch_generators.hpp>
#include <catch2/internal/catch_enforce.hpp>

View File

@@ -8,6 +8,7 @@
#ifndef CATCH_GENERATORS_HPP_INCLUDED
#define CATCH_GENERATORS_HPP_INCLUDED
#include <catch2/catch_tostring.hpp>
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
#include <catch2/internal/catch_stringref.hpp>
@@ -32,6 +33,10 @@ namespace Detail {
template<typename T>
class IGenerator : public GeneratorUntypedBase {
std::string stringifyImpl() const override {
return ::Catch::Detail::stringify( get() );
}
public:
~IGenerator() override = default;
IGenerator() = default;
@@ -64,7 +69,7 @@ namespace Detail {
return m_generator->get();
}
bool next() {
return m_generator->next();
return m_generator->countedNext();
}
};

View File

@@ -0,0 +1,13 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/generators/catch_generators_random.hpp>
#include <catch2/internal/catch_context.hpp>
std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); }

View File

@@ -16,16 +16,21 @@
namespace Catch {
namespace Generators {
namespace Detail {
// Returns a suitable seed for a random floating generator based off
// the primary internal rng. It does so by taking current value from
// the rng and returning it as the seed.
std::uint32_t getSeed();
}
template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
Catch::SimplePcg32& m_rng;
Catch::SimplePcg32 m_rng;
std::uniform_real_distribution<Float> m_dist;
Float m_current_number;
public:
RandomFloatingGenerator(Float a, Float b):
m_rng(rng()),
RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
m_rng(seed),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -41,13 +46,12 @@ public:
template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
Catch::SimplePcg32& m_rng;
Catch::SimplePcg32 m_rng;
std::uniform_int_distribution<Integer> m_dist;
Integer m_current_number;
public:
RandomIntegerGenerator(Integer a, Integer b):
m_rng(rng()),
RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
m_rng(seed),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -61,14 +65,19 @@ public:
}
};
// TODO: Ideally this would be also constrained against the various char types,
// but I don't expect users to run into that in practice.
template <typename T>
std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value,
GeneratorWrapper<T>>
std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
random(T a, T b) {
static_assert(
!std::is_same<T, char>::value &&
!std::is_same<T, int8_t>::value &&
!std::is_same<T, uint8_t>::value &&
!std::is_same<T, signed char>::value &&
!std::is_same<T, unsigned char>::value &&
!std::is_same<T, bool>::value,
"The requested type is not supported by the underlying random distributions from std" );
return GeneratorWrapper<T>(
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
);
}
@@ -77,7 +86,7 @@ std::enable_if_t<std::is_floating_point<T>::value,
GeneratorWrapper<T>>
random(T a, T b) {
return GeneratorWrapper<T>(
Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b)
Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
);
}

View File

@@ -0,0 +1,13 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_capture.hpp>
namespace Catch {
IResultCapture::~IResultCapture() = default;
}

View File

@@ -1,90 +0,0 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/** \file
* This is a special TU that combines what would otherwise be a very
* small interfaces-related TUs into one bigger TU.
*
* The reason for this is compilation performance improvements by
* avoiding reparsing headers for many small TUs, instead having this
* one TU include bit more, but having it all parsed only once.
*
* To avoid heavy-tail problem with compilation times, each "subpart"
* of Catch2 has its own combined TU like this.
*/
///////////////////////////////////////////////////
// vvv formerly catch_interfaces_capture.cpp vvv //
///////////////////////////////////////////////////
#include <catch2/interfaces/catch_interfaces_capture.hpp>
namespace Catch {
IResultCapture::~IResultCapture() = default;
}
//////////////////////////////////////////////////
// vvv formerly catch_interfaces_config.cpp vvv //
//////////////////////////////////////////////////
#include <catch2/interfaces/catch_interfaces_config.hpp>
namespace Catch {
IConfig::~IConfig() = default;
}
/////////////////////////////////////////////////////
// vvv formerly catch_interfaces_exception.cpp vvv //
/////////////////////////////////////////////////////
#include <catch2/interfaces/catch_interfaces_exception.hpp>
namespace Catch {
IExceptionTranslator::~IExceptionTranslator() = default;
IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
}
////////////////////////////////////////////////////////
// vvv formerly catch_interfaces_registry_hub.cpp vvv //
////////////////////////////////////////////////////////
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
namespace Catch {
IRegistryHub::~IRegistryHub() = default;
IMutableRegistryHub::~IMutableRegistryHub() = default;
}
////////////////////////////////////////////////////
// vvv formerly catch_interfaces_testcase.cpp vvv //
////////////////////////////////////////////////////
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
namespace Catch {
ITestInvoker::~ITestInvoker() = default;
ITestCaseRegistry::~ITestCaseRegistry() = default;
}
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
namespace Catch {
IReporterRegistry::~IReporterRegistry() = default;
}
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
namespace Catch {
IReporterFactory::~IReporterFactory() = default;
EventListenerFactory::~EventListenerFactory() = default;
}

View File

@@ -0,0 +1,13 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_config.hpp>
namespace Catch {
IConfig::~IConfig() = default;
}

View File

@@ -88,6 +88,7 @@ namespace Catch {
virtual std::vector<std::string> const& getSectionsToRun() const = 0;
virtual Verbosity verbosity() const = 0;
virtual bool skipBenchmarks() const = 0;
virtual bool benchmarkNoAnalysis() const = 0;
virtual unsigned int benchmarkSamples() const = 0;
virtual double benchmarkConfidenceInterval() const = 0;

View File

@@ -0,0 +1,14 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_exception.hpp>
namespace Catch {
IExceptionTranslator::~IExceptionTranslator() = default;
IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
}

View File

@@ -0,0 +1,32 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <string>
namespace Catch {
namespace Generators {
bool GeneratorUntypedBase::countedNext() {
auto ret = next();
if ( ret ) {
m_stringReprCache.clear();
++m_currentElementIndex;
}
return ret;
}
StringRef GeneratorUntypedBase::currentElementAsString() const {
if ( m_stringReprCache.empty() ) {
m_stringReprCache = stringifyImpl();
}
return m_stringReprCache;
}
} // namespace Generators
} // namespace Catch

View File

@@ -9,11 +9,32 @@
#define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <string>
namespace Catch {
namespace Generators {
class GeneratorUntypedBase {
// Caches result from `toStringImpl`, assume that when it is an
// empty string, the cache is invalidated.
mutable std::string m_stringReprCache;
// Counts based on `next` returning true
std::size_t m_currentElementIndex = 0;
/**
* Attempts to move the generator to the next element
*
* Returns true iff the move succeeded (and a valid element
* can be retrieved).
*/
virtual bool next() = 0;
//! Customization point for `currentElementAsString`
virtual std::string stringifyImpl() const = 0;
public:
GeneratorUntypedBase() = default;
// Generation of copy ops is deprecated (and Clang will complain)
@@ -23,11 +44,34 @@ namespace Catch {
virtual ~GeneratorUntypedBase(); // = default;
// Attempts to move the generator to the next element
//
// Returns true iff the move succeeded (and a valid element
// can be retrieved).
virtual bool next() = 0;
/**
* Attempts to move the generator to the next element
*
* Serves as a non-virtual interface to `next`, so that the
* top level interface can provide sanity checking and shared
* features.
*
* As with `next`, returns true iff the move succeeded and
* the generator has new valid element to provide.
*/
bool countedNext();
std::size_t currentElementIndex() const { return m_currentElementIndex; }
/**
* Returns generator's current element as user-friendly string.
*
* By default returns string equivalent to calling
* `Catch::Detail::stringify` on the current element, but generators
* can customize their implementation as needed.
*
* Not thread-safe due to internal caching.
*
* The returned ref is valid only until the generator instance
* is destructed, or it moves onto the next element, whichever
* comes first.
*/
StringRef currentElementAsString() const;
};
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;

View File

@@ -0,0 +1,14 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
namespace Catch {
IRegistryHub::~IRegistryHub() = default;
IMutableRegistryHub::~IMutableRegistryHub() = default;
}

View File

@@ -27,6 +27,7 @@
namespace Catch {
struct ReporterDescription;
struct ListenerDescription;
struct TagInfo;
struct TestCaseInfo;
class TestCaseHandle;
@@ -249,11 +250,12 @@ namespace Catch {
//! Writes out information about provided reporters using reporter-specific format
virtual void listReporters(std::vector<ReporterDescription> const& descriptions) = 0;
//! Writes out the provided listeners descriptions using reporter-specific format
virtual void listListeners(std::vector<ListenerDescription> const& descriptions) = 0;
//! Writes out information about provided tests using reporter-specific format
virtual void listTests(std::vector<TestCaseHandle> const& tests) = 0;
//! Writes out information about the provided tags using reporter-specific format
virtual void listTags(std::vector<TagInfo> const& tags) = 0;
};
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;

View File

@@ -0,0 +1,14 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
namespace Catch {
IReporterFactory::~IReporterFactory() = default;
EventListenerFactory::~EventListenerFactory() = default;
}

View File

@@ -9,6 +9,7 @@
#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <string>
@@ -34,6 +35,9 @@ namespace Catch {
public:
virtual ~EventListenerFactory(); // = default
virtual IEventListenerPtr create( IConfig const* config ) const = 0;
//! Return a meaningful name for the listener, e.g. its type name
virtual StringRef getName() const = 0;
//! Return listener's description if available
virtual std::string getDescription() const = 0;
};
} // namespace Catch

View File

@@ -0,0 +1,13 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
namespace Catch {
IReporterRegistry::~IReporterRegistry() = default;
}

View File

@@ -0,0 +1,14 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
namespace Catch {
ITestInvoker::~ITestInvoker() = default;
ITestCaseRegistry::~ITestCaseRegistry() = default;
}

View File

@@ -233,7 +233,7 @@ namespace Catch {
return Detail::InternalParseResult::runtimeError(
"Expected argument following " +
token.token);
auto result = valueRef->setValue(argToken.token);
const auto result = valueRef->setValue(argToken.token);
if (!result)
return Detail::InternalParseResult(result);
if (result.value() ==

View File

@@ -1,237 +0,0 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/** \file
* This is a special TU that combines what would otherwise be a very
* small top-level TUs into one bigger TU.
*
* The reason for this is compilation performance improvements by
* avoiding reparsing headers for many small TUs, instead having this
* one TU include bit more, but having it all parsed only once.
*
* To avoid heavy-tail problem with compilation times, each "subpart"
* of Catch2 has its own combined TU like this.
*/
////////////////////////////////////////////////////////
// vvv formerly catch_tag_alias_autoregistrar.cpp vvv //
////////////////////////////////////////////////////////
#include <catch2/catch_tag_alias_autoregistrar.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
namespace Catch {
RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
CATCH_TRY {
getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
} CATCH_CATCH_ALL {
// Do not throw when constructing global objects, instead register the exception to be processed later
getMutableRegistryHub().registerStartupException();
}
}
}
//////////////////////////////////////////
// vvv formerly catch_polyfills.cpp vvv //
//////////////////////////////////////////
#include <catch2/internal/catch_polyfills.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <cmath>
namespace Catch {
#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
bool isnan(float f) {
return std::isnan(f);
}
bool isnan(double d) {
return std::isnan(d);
}
#else
// For now we only use this for embarcadero
bool isnan(float f) {
return std::_isnan(f);
}
bool isnan(double d) {
return std::_isnan(d);
}
#endif
} // end namespace Catch
////////////////////////////////////////////////////
// vvv formerly catch_uncaught_exceptions.cpp vvv //
////////////////////////////////////////////////////
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_config_uncaught_exceptions.hpp>
#include <exception>
namespace Catch {
bool uncaught_exceptions() {
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
return false;
#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
#endif
}
} // end namespace Catch
////////////////////////////////////////////
// vvv formerly catch_errno_guard.cpp vvv //
////////////////////////////////////////////
#include <catch2/internal/catch_errno_guard.hpp>
#include <cerrno>
namespace Catch {
ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
}
///////////////////////////////////////////
// vvv formerly catch_decomposer.cpp vvv //
///////////////////////////////////////////
#include <catch2/internal/catch_decomposer.hpp>
namespace Catch {
ITransientExpression::~ITransientExpression() = default;
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
if( lhs.size() + rhs.size() < 40 &&
lhs.find('\n') == std::string::npos &&
rhs.find('\n') == std::string::npos )
os << lhs << ' ' << op << ' ' << rhs;
else
os << lhs << '\n' << op << '\n' << rhs;
}
}
///////////////////////////////////////////////////////////
// vvv formerly catch_startup_exception_registry.cpp vvv //
///////////////////////////////////////////////////////////
#include <catch2/internal/catch_startup_exception_registry.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
namespace Catch {
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
CATCH_TRY {
m_exceptions.push_back(exception);
} CATCH_CATCH_ALL {
// If we run out of memory during start-up there's really not a lot more we can do about it
std::terminate();
}
}
std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
return m_exceptions;
}
#endif
} // end namespace Catch
//////////////////////////////////////////////
// vvv formerly catch_leak_detector.cpp vvv //
//////////////////////////////////////////////
#include <catch2/internal/catch_leak_detector.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
#include <crtdbg.h>
namespace Catch {
LeakDetector::LeakDetector() {
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
flag |= _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(flag);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
// Change this to leaking allocation's number to break there
_CrtSetBreakAlloc(-1);
}
}
#else // ^^ Windows crt debug heap enabled // Windows crt debug heap disabled vv
Catch::LeakDetector::LeakDetector() {}
#endif // CATCH_CONFIG_WINDOWS_CRTDBG
Catch::LeakDetector::~LeakDetector() {
Catch::cleanUp();
}
/////////////////////////////////////////////
// vvv formerly catch_message_info.cpp vvv //
/////////////////////////////////////////////
#include <catch2/internal/catch_message_info.hpp>
namespace Catch {
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;
} // end namespace Catch
//////////////////////////////////////////
// vvv formerly catch_lazy_expr.cpp vvv //
//////////////////////////////////////////
#include <catch2/internal/catch_lazy_expr.hpp>
#include <catch2/internal/catch_decomposer.hpp>
namespace Catch {
auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& {
if (lazyExpr.m_isNegated)
os << '!';
if (lazyExpr) {
if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
os << '(' << *lazyExpr.m_transientExpression << ')';
else
os << *lazyExpr.m_transientExpression;
} else {
os << "{** error - unchecked empty expression requested **}";
}
return os;
}
} // namespace Catch

View File

@@ -280,7 +280,10 @@ namespace Catch {
( "list all/matching tags" )
| Opt( config.listReporters )
["--list-reporters"]
( "list all reporters" )
( "list all available reporters" )
| Opt( config.listListeners )
["--list-listeners"]
( "list all listeners" )
| Opt( setTestOrder, "decl|lex|rand" )
["--order"]
( "test case order (defaults to decl)" )
@@ -296,6 +299,9 @@ namespace Catch {
| Opt( setWaitForKeypress, "never|start|exit|both" )
["--wait-for-keypress"]
( "waits for a keypress before exiting" )
| Opt( config.skipBenchmarks)
["--skip-benchmarks"]
( "disable running benchmarks")
| Opt( config.benchmarkSamples, "samples" )
["--benchmark-samples"]
( "number of samples to collect (default: 100)" )

View File

@@ -57,11 +57,23 @@
#endif
#if defined(__CUDACC__) && !defined(__clang__)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
#endif
// clang-cl defines _MSC_VER as well as __clang__, which could cause the
// start/stop internal suppression macros to be double defined.
#if defined(__clang__) && !defined(_MSC_VER)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
#endif // __clang__ && !_MSC_VER
#if defined(__clang__)
// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
// which results in calls to destructors being emitted for each temporary,
// without a matching initialization. In practice, this can result in something

View File

@@ -88,7 +88,6 @@ namespace Catch {
class NoColourImpl : public ColourImpl {
public:
NoColourImpl( IStream* stream ): ColourImpl( stream ) {}
static bool useColourOnPlatform() { return true; }
private:
void use( Colour::Code ) const override {}
@@ -115,7 +114,7 @@ namespace {
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
}
static bool useColourOnPlatform(IStream const& stream) {
static bool useImplementationForStream(IStream const& stream) {
// Win32 text colour APIs can only be used on console streams
// We cannot check that the output hasn't been redirected,
// so we just check that the original stream is console stream.
@@ -174,7 +173,7 @@ namespace {
public:
ANSIColourImpl( IStream* stream ): ColourImpl( stream ) {}
static bool useColourOnPlatform(IStream const& stream) {
static bool useImplementationForStream(IStream const& stream) {
// This is kinda messy due to trying to support a bunch of
// different platforms at once.
// The basic idea is that if we are asked to do autodetection (as
@@ -233,28 +232,25 @@ namespace Catch {
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode implSelection,
IStream* stream ) {
if ( implSelection == ColourMode::None ) {
return Detail::make_unique<NoColourImpl>( stream );
}
if ( implSelection == ColourMode::ANSI ) {
return Detail::make_unique<ANSIColourImpl>( stream );
}
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
if ( implSelection == ColourMode::Win32 ) {
return Detail::make_unique<Win32ColourImpl>( stream );
}
#endif
if ( implSelection == ColourMode::ANSI ) {
return Detail::make_unique<ANSIColourImpl>( stream );
}
if ( implSelection == ColourMode::None ) {
return Detail::make_unique<NoColourImpl>( stream );
}
// todo: check win32 eligibility under ifdef, otherwise ansi
if ( implSelection == ColourMode::PlatformDefault) {
#if defined (CATCH_CONFIG_COLOUR_WIN32)
if ( Win32ColourImpl::useColourOnPlatform( *stream ) ) {
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
if ( Win32ColourImpl::useImplementationForStream( *stream ) ) {
return Detail::make_unique<Win32ColourImpl>( stream );
} else {
return Detail::make_unique<NoColourImpl>( stream );
}
#endif
if ( ANSIColourImpl::useColourOnPlatform( *stream ) ) {
if ( ANSIColourImpl::useImplementationForStream( *stream ) ) {
return Detail::make_unique<ANSIColourImpl>( stream );
}
return Detail::make_unique<NoColourImpl>( stream );

View File

@@ -8,6 +8,10 @@
#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
// This include must be kept so that user's configured value for CONSOLE_WIDTH
// is used before we attempt to provide a default value
#include <catch2/catch_user_config.hpp>
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
#endif

View File

@@ -55,7 +55,7 @@ namespace Catch {
Context::~Context() = default;
SimplePcg32& rng() {
SimplePcg32& sharedRng() {
static SimplePcg32 s_rng;
return s_rng;
}

View File

@@ -23,7 +23,7 @@ namespace Catch {
class IMutableContext : public IContext {
public:
virtual ~IMutableContext(); // = default
~IMutableContext() override; // = default
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setConfig( IConfig const* config ) = 0;
@@ -50,7 +50,7 @@ namespace Catch {
void cleanUpContext();
class SimplePcg32;
SimplePcg32& rng();
SimplePcg32& sharedRng();
}
#endif // CATCH_CONTEXT_HPP_INCLUDED

View File

@@ -19,7 +19,7 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
#define CATCH_TRAP() __asm__(".inst 0xd43e0000")
#endif
#elif defined(CATCH_PLATFORM_IPHONE)

View File

@@ -0,0 +1,23 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_decomposer.hpp>
namespace Catch {
ITransientExpression::~ITransientExpression() = default;
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
if( lhs.size() + rhs.size() < 40 &&
lhs.find('\n') == std::string::npos &&
rhs.find('\n') == std::string::npos )
os << lhs << ' ' << op << ' ' << rhs;
else
os << lhs << '\n' << op << '\n' << rhs;
}
}

View File

@@ -0,0 +1,16 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_errno_guard.hpp>
#include <cerrno>
namespace Catch {
ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
}

View File

@@ -10,6 +10,7 @@
#include <catch2/internal/catch_polyfills.hpp>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <utility>
@@ -24,6 +25,15 @@ namespace Catch {
} // end namespace Detail
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic push
// We do a bunch of direct compensations of floating point numbers,
// because we know what we are doing and actually do want the direct
// comparison behaviour.
# pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
/**
* Calculates the ULP distance between two floating point numbers
*
@@ -83,6 +93,11 @@ namespace Catch {
return lc - rc;
}
#if defined( __GNUC__ ) || defined( __clang__ )
# pragma GCC diagnostic pop
#endif
} // end namespace Catch
#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED

View File

@@ -33,7 +33,7 @@ namespace Detail {
setp( data, data + sizeof(data) );
}
~StreamBufImpl() noexcept {
~StreamBufImpl() noexcept override {
StreamBufImpl::sync();
}

View File

@@ -0,0 +1,29 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_lazy_expr.hpp>
#include <catch2/internal/catch_decomposer.hpp>
namespace Catch {
auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& {
if (lazyExpr.m_isNegated)
os << '!';
if (lazyExpr) {
if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
os << '(' << *lazyExpr.m_transientExpression << ')';
else
os << *lazyExpr.m_transientExpression;
} else {
os << "{** error - unchecked empty expression requested **}";
}
return os;
}
} // namespace Catch

View File

@@ -0,0 +1,38 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_leak_detector.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/catch_user_config.hpp>
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
#include <crtdbg.h>
namespace Catch {
LeakDetector::LeakDetector() {
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
flag |= _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(flag);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
// Change this to leaking allocation's number to break there
_CrtSetBreakAlloc(-1);
}
}
#else // ^^ Windows crt debug heap enabled // Windows crt debug heap disabled vv
Catch::LeakDetector::LeakDetector() {}
#endif // CATCH_CONFIG_WINDOWS_CRTDBG
Catch::LeakDetector::~LeakDetector() {
Catch::cleanUp();
}

View File

@@ -63,6 +63,19 @@ namespace Catch {
reporter.listReporters(descriptions);
}
void listListeners(IEventListener& reporter) {
std::vector<ListenerDescription> descriptions;
auto const& factories =
getRegistryHub().getReporterRegistry().getListeners();
descriptions.reserve( factories.size() );
for ( auto const& fac : factories ) {
descriptions.push_back( { fac->getName(), fac->getDescription() } );
}
reporter.listListeners( descriptions );
}
} // end anonymous namespace
void TagInfo::add( StringRef spelling ) {
@@ -100,6 +113,10 @@ namespace Catch {
listed = true;
listReporters(reporter);
}
if ( config.listListeners() ) {
listed = true;
listListeners( reporter );
}
return listed;
}

View File

@@ -23,6 +23,10 @@ namespace Catch {
struct ReporterDescription {
std::string name, description;
};
struct ListenerDescription {
StringRef name;
std::string description;
};
struct TagInfo {
void add(StringRef spelling);

View File

@@ -14,7 +14,7 @@
namespace Catch {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
LeakDetector leakDetector;
static LeakDetector leakDetector;
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
}

View File

@@ -0,0 +1,25 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_message_info.hpp>
namespace Catch {
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;
} // end namespace Catch

View File

@@ -0,0 +1,34 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_polyfills.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/catch_user_config.hpp>
#include <cmath>
namespace Catch {
#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
bool isnan(float f) {
return std::isnan(f);
}
bool isnan(double d) {
return std::isnan(d);
}
#else
// For now we only use this for embarcadero
bool isnan(float f) {
return std::_isnan(f);
}
bool isnan(double d) {
return std::_isnan(d);
}
#endif
} // end namespace Catch

View File

@@ -47,7 +47,8 @@ namespace Catch {
void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr factory ) {
CATCH_ENFORCE( name.find( "::" ) == name.npos,
"'::' is not allowed in reporter name: '" + name + '\'' );
m_factories.emplace(name, CATCH_MOVE(factory));
auto ret = m_factories.emplace(name, CATCH_MOVE(factory));
CATCH_ENFORCE( ret.second, "reporter using '" + name + "' as name was already registered" );
}
void ReporterRegistry::registerListener(
Detail::unique_ptr<EventListenerFactory> factory ) {

View File

@@ -126,7 +126,7 @@ namespace Catch {
return {};
}
auto ret = kvPairs.emplace( kv.key, kv.value );
auto ret = kvPairs.emplace( std::string(kv.key), std::string(kv.value) );
if ( !ret.second ) {
// Duplicated key. We might want to handle this differently,
// e.g. by overwriting the existing value?

View File

@@ -32,7 +32,7 @@ namespace Catch {
GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
: TrackerBase( nameAndLocation, ctx, parent )
{}
~GeneratorTracker();
~GeneratorTracker() override;
static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
GeneratorTracker* tracker;
@@ -143,7 +143,7 @@ namespace Catch {
// this generator is still waiting for any child to start.
if ( should_wait_for_child ||
( m_runState == CompletedSuccessfully &&
m_generator->next() ) ) {
m_generator->countedNext() ) ) {
m_children.clear();
m_runState = Executing;
}
@@ -193,6 +193,39 @@ namespace Catch {
assert(rootTracker.isSectionTracker());
static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
// We intentionally only seed the internal RNG once per test case,
// before it is first invoked. The reason for that is a complex
// interplay of generator/section implementation details and the
// Random*Generator types.
//
// The issue boils down to us needing to seed the Random*Generators
// with different seed each, so that they return different sequences
// of random numbers. We do this by giving them a number from the
// shared RNG instance as their seed.
//
// However, this runs into an issue if the reseeding happens each
// time the test case is entered (as opposed to first time only),
// because multiple generators could get the same seed, e.g. in
// ```cpp
// TEST_CASE() {
// auto i = GENERATE(take(10, random(0, 100));
// SECTION("A") {
// auto j = GENERATE(take(10, random(0, 100));
// }
// SECTION("B") {
// auto k = GENERATE(take(10, random(0, 100));
// }
// }
// ```
// `i` and `j` would properly return values from different sequences,
// but `i` and `k` would return the same sequence, because their seed
// would be the same.
// (The reason their seeds would be the same is that the generator
// for k would be initialized when the test case is entered the second
// time, after the shared RNG instance was reset to the same value
// it had when the generator for i was initialized.)
seedRng( *m_config );
uint64_t testRuns = 0;
do {
m_trackerContext.startCycle();
@@ -422,8 +455,6 @@ namespace Catch {
m_shouldReportUnexpected = true;
m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
seedRng(*m_config);
Timer timer;
CATCH_TRY {
if (m_reporter->getPreferences().shouldRedirectStdOut) {
@@ -469,6 +500,11 @@ namespace Catch {
// before running the tests themselves, or the binary can crash
// without failed test being reported.
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
// We keep having issue where some compilers warn about an unused
// variable, even though the type has non-trivial constructor and
// destructor. This is annoying and ugly, but it makes them stfu.
(void)_;
m_activeTestCase->invoke();
}
@@ -598,10 +634,7 @@ namespace Catch {
}
void seedRng(IConfig const& config) {
if (config.rngSeed() != 0) {
std::srand(config.rngSeed());
rng().seed(config.rngSeed());
}
sharedRng().seed(config.rngSeed());
}
unsigned int rngSeed() {

View File

@@ -0,0 +1,29 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_startup_exception_registry.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/catch_user_config.hpp>
namespace Catch {
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
CATCH_TRY {
m_exceptions.push_back(exception);
} CATCH_CATCH_ALL {
// If we run out of memory during start-up there's really not a lot more we can do about it
std::terminate();
}
}
std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
return m_exceptions;
}
#endif
} // end namespace Catch

View File

@@ -14,7 +14,7 @@
namespace Catch {
StringRef::StringRef( char const* rawChars ) noexcept
: StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
: StringRef( rawChars, std::strlen(rawChars) )
{}
auto StringRef::operator == ( StringRef other ) const noexcept -> bool {

View File

@@ -14,9 +14,9 @@
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
// We need this suppression to leak, because it took until GCC 9
// We need this suppression to leak, because it took until GCC 10
// for the front end to handle local suppression via _Pragma properly
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 9
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9
#pragma GCC diagnostic ignored "-Wparentheses"
#endif

View File

@@ -77,6 +77,7 @@ struct AutoReg : Detail::NonCopyable {
static void TestName(); \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
@@ -87,6 +88,7 @@ struct AutoReg : Detail::NonCopyable {
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
@@ -94,6 +96,7 @@ struct AutoReg : Detail::NonCopyable {
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
namespace{ \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
@@ -110,6 +113,7 @@ struct AutoReg : Detail::NonCopyable {
do { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} while(false)

View File

@@ -0,0 +1,26 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_config_uncaught_exceptions.hpp>
#include <catch2/catch_user_config.hpp>
#include <exception>
namespace Catch {
bool uncaught_exceptions() {
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
return false;
#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
#endif
}
} // end namespace Catch

View File

@@ -0,0 +1,25 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/matchers/catch_matchers.hpp>
namespace Catch {
namespace Matchers {
std::string MatcherUntypedBase::toString() const {
if (m_cachedToString.empty()) {
m_cachedToString = describe();
}
return m_cachedToString;
}
MatcherUntypedBase::~MatcherUntypedBase() = default;
} // namespace Matchers
} // namespace Catch

Some files were not shown because too many files have changed in this diff Show More