mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-18 19:05:40 +02:00
Compare commits
97 Commits
v3.0.0-pre
...
v3.1.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
97c48e0c34 | ||
![]() |
9c9f35068e | ||
![]() |
1bd233866c | ||
![]() |
f993b702c6 | ||
![]() |
caf1264588 | ||
![]() |
a6d59b62b2 | ||
![]() |
cc0e91472a | ||
![]() |
3bd0c58878 | ||
![]() |
a63ad74554 | ||
![]() |
5f9109a8dc | ||
![]() |
5a1ef7e4a6 | ||
![]() |
bea58bf8bb | ||
![]() |
34d9724058 | ||
![]() |
5d269045b2 | ||
![]() |
95a1206805 | ||
![]() |
6f9f1465c3 | ||
![]() |
8730260457 | ||
![]() |
bdfa920f93 | ||
![]() |
a369267874 | ||
![]() |
1f381a1f62 | ||
![]() |
165647abbc | ||
![]() |
7e4ec432d0 | ||
![]() |
078201fcf4 | ||
![]() |
8110ee9206 | ||
![]() |
fa9416426a | ||
![]() |
338e4ec1f8 | ||
![]() |
372b7575f6 | ||
![]() |
d32fca4a49 | ||
![]() |
a0ece7b252 | ||
![]() |
0a810c5e59 | ||
![]() |
d0177ee686 | ||
![]() |
173539ab9e | ||
![]() |
8822e28772 | ||
![]() |
ff9506cedd | ||
![]() |
0c13d021da | ||
![]() |
3644b4135d | ||
![]() |
1c4f52b24a | ||
![]() |
231c58a048 | ||
![]() |
5efd327dd4 | ||
![]() |
40dd9dd3f4 | ||
![]() |
4142e699c2 | ||
![]() |
9e445930cc | ||
![]() |
2dc657cd1f | ||
![]() |
cca5923502 | ||
![]() |
8c952bd076 | ||
![]() |
85c00eb946 | ||
![]() |
3a18a688a0 | ||
![]() |
605a34765a | ||
![]() |
abb669d4fd | ||
![]() |
dcafc605f3 | ||
![]() |
7a2a6c632f | ||
![]() |
359cd6187d | ||
![]() |
9c72b303d9 | ||
![]() |
6044f021cf | ||
![]() |
5d7883b551 | ||
![]() |
04a54b0e87 | ||
![]() |
48f3226974 | ||
![]() |
af8b54ecd5 | ||
![]() |
07bec74096 | ||
![]() |
316025a0d8 | ||
![]() |
33aeb603fe | ||
![]() |
fc3d11b1d1 | ||
![]() |
1ef65d60f1 | ||
![]() |
ed6b38b096 | ||
![]() |
5a49285e9c | ||
![]() |
ae475a3c19 | ||
![]() |
d60fbe49be | ||
![]() |
a733b58cd2 | ||
![]() |
d9b0a38f81 | ||
![]() |
40c8909a49 | ||
![]() |
91ea25e51a | ||
![]() |
e2d07d35f4 | ||
![]() |
d2cb934d28 | ||
![]() |
7752229105 | ||
![]() |
722c197855 | ||
![]() |
198808a24e | ||
![]() |
198713e5dc | ||
![]() |
b84067ea6f | ||
![]() |
332de39cd4 | ||
![]() |
c410e2596c | ||
![]() |
4c1cf4aa67 | ||
![]() |
745cc82cd3 | ||
![]() |
07dfb4b070 | ||
![]() |
5e86ead366 | ||
![]() |
9dc229693d | ||
![]() |
db57a4956f | ||
![]() |
48177831ee | ||
![]() |
ee3bbecf51 | ||
![]() |
431dcf36ea | ||
![]() |
e882cb8eb1 | ||
![]() |
c2bc321607 | ||
![]() |
ea9029c478 | ||
![]() |
c65e5b6514 | ||
![]() |
880285b433 | ||
![]() |
07cdef2096 | ||
![]() |
5baa29b6b9 | ||
![]() |
291b35b389 |
13
.github/workflows/linux-other-builds.yml
vendored
13
.github/workflows/linux-other-builds.yml
vendored
@@ -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
12
.gitignore
vendored
@@ -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
|
||||
|
@@ -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}")
|
||||
|
@@ -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()
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/mac-builds.yml)
|
||||
[](https://ci.appveyor.com/project/catchorg/catch2)
|
||||
[](https://codecov.io/gh/catchorg/Catch2)
|
||||
[](https://godbolt.org/z/9x9qoM)
|
||||
[](https://godbolt.org/z/EdoY15q9G)
|
||||
[](https://discord.gg/4CWS9zD)
|
||||
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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 <# of samples></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 <ansi|win32|none|default></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
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
35
docs/faq.md
35
docs/faq.md
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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>`
|
||||
|
@@ -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++.
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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:
|
||||
|
@@ -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.
|
||||
|
@@ -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 );
|
||||
}
|
||||
```
|
||||
|
@@ -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
95
docs/usage-tips.md
Normal 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)
|
@@ -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):
|
||||
|
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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):
|
||||
|
@@ -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):
|
||||
//
|
||||
|
@@ -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):
|
||||
|
@@ -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):
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
||||
|
66
extras/CatchShardTests.cmake
Normal file
66
extras/CatchShardTests.cmake
Normal 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()
|
52
extras/CatchShardTestsImpl.cmake
Normal file
52
extras/CatchShardTestsImpl.cmake
Normal 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
@@ -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;
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
17
src/catch2/benchmark/catch_chronometer.cpp
Normal file
17
src/catch2/benchmark/catch_chronometer.cpp
Normal 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
|
@@ -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
|
||||
|
||||
|
17
src/catch2/benchmark/detail/catch_benchmark_function.cpp
Normal file
17
src/catch2/benchmark/detail/catch_benchmark_function.cpp
Normal 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
|
30
src/catch2/benchmark/detail/catch_run_for_at_least.cpp
Normal file
30
src/catch2/benchmark/detail/catch_run_for_at_least.cpp
Normal 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
|
@@ -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);
|
||||
|
@@ -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 };
|
||||
|
@@ -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
|
@@ -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; }
|
||||
|
@@ -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;
|
||||
|
24
src/catch2/catch_tag_alias_autoregistrar.cpp
Normal file
24
src/catch2/catch_tag_alias_autoregistrar.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
17
src/catch2/generators/catch_generator_exception.cpp
Normal file
17
src/catch2/generators/catch_generator_exception.cpp
Normal 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
|
@@ -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>
|
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
13
src/catch2/generators/catch_generators_random.cpp
Normal file
13
src/catch2/generators/catch_generators_random.cpp
Normal 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()(); }
|
@@ -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())
|
||||
);
|
||||
}
|
||||
|
||||
|
13
src/catch2/interfaces/catch_interfaces_capture.cpp
Normal file
13
src/catch2/interfaces/catch_interfaces_capture.cpp
Normal 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;
|
||||
}
|
@@ -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;
|
||||
}
|
13
src/catch2/interfaces/catch_interfaces_config.cpp
Normal file
13
src/catch2/interfaces/catch_interfaces_config.cpp
Normal 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;
|
||||
}
|
@@ -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;
|
||||
|
14
src/catch2/interfaces/catch_interfaces_exception.cpp
Normal file
14
src/catch2/interfaces/catch_interfaces_exception.cpp
Normal 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;
|
||||
}
|
32
src/catch2/interfaces/catch_interfaces_generatortracker.cpp
Normal file
32
src/catch2/interfaces/catch_interfaces_generatortracker.cpp
Normal 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
|
@@ -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>;
|
||||
|
||||
|
14
src/catch2/interfaces/catch_interfaces_registry_hub.cpp
Normal file
14
src/catch2/interfaces/catch_interfaces_registry_hub.cpp
Normal 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;
|
||||
}
|
@@ -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>;
|
||||
|
||||
|
14
src/catch2/interfaces/catch_interfaces_reporter_factory.cpp
Normal file
14
src/catch2/interfaces/catch_interfaces_reporter_factory.cpp
Normal 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;
|
||||
}
|
@@ -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
|
||||
|
13
src/catch2/interfaces/catch_interfaces_reporter_registry.cpp
Normal file
13
src/catch2/interfaces/catch_interfaces_reporter_registry.cpp
Normal 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;
|
||||
}
|
14
src/catch2/interfaces/catch_interfaces_testcase.cpp
Normal file
14
src/catch2/interfaces/catch_interfaces_testcase.cpp
Normal 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;
|
||||
}
|
@@ -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() ==
|
||||
|
@@ -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
|
@@ -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)" )
|
||||
|
@@ -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
|
||||
|
@@ -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 );
|
||||
|
@@ -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
|
||||
|
@@ -55,7 +55,7 @@ namespace Catch {
|
||||
Context::~Context() = default;
|
||||
|
||||
|
||||
SimplePcg32& rng() {
|
||||
SimplePcg32& sharedRng() {
|
||||
static SimplePcg32 s_rng;
|
||||
return s_rng;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
23
src/catch2/internal/catch_decomposer.cpp
Normal file
23
src/catch2/internal/catch_decomposer.cpp
Normal 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;
|
||||
}
|
||||
}
|
16
src/catch2/internal/catch_errno_guard.cpp
Normal file
16
src/catch2/internal/catch_errno_guard.cpp
Normal 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; }
|
||||
}
|
@@ -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
|
||||
|
@@ -33,7 +33,7 @@ namespace Detail {
|
||||
setp( data, data + sizeof(data) );
|
||||
}
|
||||
|
||||
~StreamBufImpl() noexcept {
|
||||
~StreamBufImpl() noexcept override {
|
||||
StreamBufImpl::sync();
|
||||
}
|
||||
|
||||
|
29
src/catch2/internal/catch_lazy_expr.cpp
Normal file
29
src/catch2/internal/catch_lazy_expr.cpp
Normal 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
|
38
src/catch2/internal/catch_leak_detector.cpp
Normal file
38
src/catch2/internal/catch_leak_detector.cpp
Normal 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();
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
25
src/catch2/internal/catch_message_info.cpp
Normal file
25
src/catch2/internal/catch_message_info.cpp
Normal 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
|
34
src/catch2/internal/catch_polyfills.cpp
Normal file
34
src/catch2/internal/catch_polyfills.cpp
Normal 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
|
@@ -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 ) {
|
||||
|
@@ -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?
|
||||
|
@@ -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() {
|
||||
|
29
src/catch2/internal/catch_startup_exception_registry.cpp
Normal file
29
src/catch2/internal/catch_startup_exception_registry.cpp
Normal 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
|
@@ -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 {
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
26
src/catch2/internal/catch_uncaught_exceptions.cpp
Normal file
26
src/catch2/internal/catch_uncaught_exceptions.cpp
Normal 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
|
25
src/catch2/matchers/catch_matchers.cpp
Normal file
25
src/catch2/matchers/catch_matchers.cpp
Normal 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
Reference in New Issue
Block a user