mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-22 11:23:29 +01:00
Merge branch 'devel' into docs_includes
This commit is contained in:
commit
ea37a0c965
6
.github/workflows/mac-builds.yml
vendored
6
.github/workflows/mac-builds.yml
vendored
@ -4,7 +4,11 @@ on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-12
|
||||
# macos-12 updated to a toolchain that crashes when linking the
|
||||
# test binary. This seems to be a known bug in that version,
|
||||
# and will eventually get fixed in an update. After that, we can go
|
||||
# back to newer macos images.
|
||||
runs-on: macos-11
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
|
@ -8,9 +8,10 @@
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
function(add_cxx_flag_if_supported_to_targets flagname targets)
|
||||
check_cxx_compiler_flag("${flagname}" HAVE_FLAG_${flagname})
|
||||
string(MAKE_C_IDENTIFIER ${flagname} flag_identifier )
|
||||
check_cxx_compiler_flag("${flagname}" HAVE_FLAG_${flag_identifier})
|
||||
|
||||
if (HAVE_FLAG_${flagname})
|
||||
if (HAVE_FLAG_${flag_identifier})
|
||||
foreach(target ${targets})
|
||||
target_compile_options(${target} PUBLIC ${flagname})
|
||||
endforeach()
|
||||
@ -112,9 +113,8 @@ endfunction()
|
||||
# Adds flags required for reproducible build to the target
|
||||
# Currently only supports GCC and Clang
|
||||
function(add_build_reproducibility_settings target)
|
||||
# Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map
|
||||
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8) OR
|
||||
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10))
|
||||
target_compile_options(${target} PRIVATE "-ffile-prefix-map=${CATCH_DIR}=.")
|
||||
# Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||
add_cxx_flag_if_supported_to_targets("-ffile-prefix-map=${CATCH_DIR}/=" "${target}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.1.0 # CML version placeholder, don't delete
|
||||
VERSION 3.1.1 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||
# we do not target yet.
|
||||
|
66
README.md
66
README.md
@ -11,31 +11,77 @@
|
||||
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
|
||||
|
||||
|
||||
## What's the Catch2?
|
||||
## What is Catch2?
|
||||
|
||||
Catch2 is mainly a unit testing framework for C++, but it also
|
||||
provides basic micro-benchmarking features, and simple BDD macros.
|
||||
|
||||
Catch2's main advantage is that using it is both simple and natural.
|
||||
Tests autoregister themselves and do not have to be named with valid
|
||||
identifiers, assertions look like normal C++ code, and sections provide
|
||||
a nice way to share set-up and tear-down code in tests.
|
||||
Test names do not have to be valid identifiers, assertions look like
|
||||
normal C++ boolean expressions, and sections provide a nice and local way
|
||||
to share set-up and tear-down code in tests.
|
||||
|
||||
**Example unit test**
|
||||
```cpp
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
## Catch2 v3 is being developed!
|
||||
#include <cstdint>
|
||||
|
||||
You are on the `devel` branch, where the next major version, v3, of
|
||||
Catch2 is being developed. As it is a significant rework, you will
|
||||
find that parts of this documentation are likely still stuck on v2.
|
||||
uint32_t factorial( uint32_t number ) {
|
||||
return number <= 1 ? number : factorial(number-1) * number;
|
||||
}
|
||||
|
||||
For stable (and documentation-matching) version of Catch2, [go to the
|
||||
`v2.x` branch](https://github.com/catchorg/Catch2/tree/v2.x).
|
||||
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||
REQUIRE( factorial( 1) == 1 );
|
||||
REQUIRE( factorial( 2) == 2 );
|
||||
REQUIRE( factorial( 3) == 6 );
|
||||
REQUIRE( factorial(10) == 3'628'800 );
|
||||
}
|
||||
```
|
||||
|
||||
**Example microbenchmark**
|
||||
```cpp
|
||||
#include <catch2/benchmark/catch_benchmark.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint64_t fibonacci(uint64_t number) {
|
||||
return number < 2 ? 1 : fibonacci(number - 1) + fibonacci(number - 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Benchmark Fibonacci", "[!benchmark]") {
|
||||
REQUIRE(Fibonacci(5) == 5);
|
||||
|
||||
REQUIRE(Fibonacci(20) == 6'765);
|
||||
BENCHMARK("Fibonacci 20") {
|
||||
return Fibonacci(20);
|
||||
};
|
||||
|
||||
REQUIRE(Fibonacci(25) == 75'025);
|
||||
BENCHMARK("Fibonacci 25") {
|
||||
return Fibonacci(25);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Catch2 v3 has been released!
|
||||
|
||||
You are on the `devel` branch, where the v3 version is being developed.
|
||||
v3 brings a bunch of significant changes, the big one being that Catch2
|
||||
is no longer a single-header library. Catch2 now behaves as a normal
|
||||
library, with multiple headers and separately compiled implementation.
|
||||
|
||||
The documentation is slowly being updated to take these changes into
|
||||
account, but this work is currently still ongoing.
|
||||
|
||||
For migrating from the v2 releases to v3, you should look at [our
|
||||
documentation](docs/migrate-v2-to-v3.md#top). It provides a simple
|
||||
guidelines on getting started, and collects most common migration
|
||||
problems.
|
||||
|
||||
For the previous major version of Catch2 [look into the `v2.x` branch
|
||||
here on GitHub](https://github.com/catchorg/Catch2/tree/v2.x).
|
||||
|
||||
|
||||
## How to use it
|
||||
This documentation comprises these three parts:
|
||||
|
@ -4,34 +4,35 @@
|
||||
To get the most out of Catch2, start with the [tutorial](tutorial.md#top).
|
||||
Once you're up and running consider the following reference material.
|
||||
|
||||
Writing tests:
|
||||
**Writing tests:**
|
||||
* [Assertion macros](assertions.md#top)
|
||||
* [Matchers](matchers.md#top)
|
||||
* [Matchers (asserting complex properties)](matchers.md#top)
|
||||
* [Comparing floating point numbers](comparing-floating-point-numbers.md#top)
|
||||
* [Logging macros](logging.md#top)
|
||||
* [Test cases and sections](test-cases-and-sections.md#top)
|
||||
* [Test fixtures](test-fixtures.md#top)
|
||||
* [Reporters](reporters.md#top)
|
||||
* [Reporters (output customization)](reporters.md#top)
|
||||
* [Event Listeners](event-listeners.md#top)
|
||||
* [Data Generators](generators.md#top)
|
||||
* [Data Generators (value parameterized tests)](generators.md#top)
|
||||
* [Other macros](other-macros.md#top)
|
||||
* [Micro benchmarking](benchmarks.md#top)
|
||||
|
||||
Fine tuning:
|
||||
**Fine tuning:**
|
||||
* [Supplying your own main()](own-main.md#top)
|
||||
* [Compile-time configuration](configuration.md#top)
|
||||
* [String Conversions](tostring.md#top)
|
||||
|
||||
Running:
|
||||
**Running:**
|
||||
* [Command line](command-line.md#top)
|
||||
|
||||
Odds and ends:
|
||||
**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)
|
||||
|
||||
Other:
|
||||
|
||||
**Other:**
|
||||
* [Why Catch2?](why-catch.md#top)
|
||||
* [Migrating from v2 to v3](migrate-v2-to-v3.md#top)
|
||||
* [Open Source Projects using Catch2](opensource-users.md#top)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
**Contents**<br>
|
||||
[Natural Expressions](#natural-expressions)<br>
|
||||
[Floating point comparisons](#floating-point-comparisons)<br>
|
||||
[Exceptions](#exceptions)<br>
|
||||
[Matcher expressions](#matcher-expressions)<br>
|
||||
[Thread Safety](#thread-safety)<br>
|
||||
@ -22,7 +23,7 @@ Most of these macros come in two forms:
|
||||
The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails.
|
||||
The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure.
|
||||
|
||||
* **REQUIRE(** _expression_ **)** and
|
||||
* **REQUIRE(** _expression_ **)** and
|
||||
* **CHECK(** _expression_ **)**
|
||||
|
||||
Evaluates the expression and records the result. If an exception is thrown, it is caught, reported, and counted as a failure. These are the macros you will use most of the time.
|
||||
@ -34,101 +35,82 @@ CHECK( thisReturnsTrue() );
|
||||
REQUIRE( i == 42 );
|
||||
```
|
||||
|
||||
* **REQUIRE_FALSE(** _expression_ **)** and
|
||||
Expressions prefixed with `!` cannot be decomposed. If you have a type
|
||||
that is convertible to bool and you want to assert that it evaluates to
|
||||
false, use the two forms below:
|
||||
|
||||
|
||||
* **REQUIRE_FALSE(** _expression_ **)** and
|
||||
* **CHECK_FALSE(** _expression_ **)**
|
||||
|
||||
Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure.
|
||||
(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed).
|
||||
Note that there is no reason to use these forms for plain bool variables,
|
||||
because there is no added value in decomposing them.
|
||||
|
||||
Example:
|
||||
```cpp
|
||||
Status ret = someFunction();
|
||||
REQUIRE_FALSE(ret); // ret must evaluate to false, and Catch2 will print
|
||||
// out the value of ret if possibly
|
||||
```
|
||||
REQUIRE_FALSE( thisReturnsFalse() );
|
||||
```
|
||||
|
||||
Do note that "overly complex" expressions cannot be decomposed and thus will not compile. This is done partly for practical reasons (to keep the underlying expression template machinery to minimum) and partly for philosophical reasons (assertions should be simple and deterministic).
|
||||
|
||||
Examples:
|
||||
* `CHECK(a == 1 && b == 2);`
|
||||
This expression is too complex because of the `&&` operator. If you want to check that 2 or more properties hold, you can either put the expression into parenthesis, which stops decomposition from working, or you need to decompose the expression into two assertions: `CHECK( a == 1 ); CHECK( b == 2);`
|
||||
* `CHECK( a == 2 || b == 1 );`
|
||||
This expression is too complex because of the `||` operator. If you want to check that one of several properties hold, you can put the expression into parenthesis (unlike with `&&`, expression decomposition into several `CHECK`s is not possible).
|
||||
|
||||
|
||||
### Floating point comparisons
|
||||
```cpp
|
||||
#include <catch2/catch_approx.hpp>
|
||||
```
|
||||
|
||||
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
|
||||
### Other limitations
|
||||
|
||||
Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called `Approx`. `Approx` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
|
||||
Note that expressions containing either of the binary logical operators,
|
||||
`&&` or `||`, cannot be decomposed and will not compile. The reason behind
|
||||
this is that it is impossible to overload `&&` and `||` in a way that
|
||||
keeps their short-circuiting semantics, and expression decomposition
|
||||
relies on overloaded operators to work.
|
||||
|
||||
```cpp
|
||||
REQUIRE( performComputation() == Approx( 2.1 ) );
|
||||
```
|
||||
Simple example of an issue with overloading binary logical operators
|
||||
is a common pointer idiom, `p && p->foo == 2`. Using the built-in `&&`
|
||||
operator, `p` is only dereferenced if it is not null. With overloaded
|
||||
`&&`, `p` is always dereferenced, thus causing a segfault if
|
||||
`p == nullptr`.
|
||||
|
||||
Catch also provides a user-defined literal for `Approx`; `_a`. It resides in
|
||||
the `Catch::literals` namespace and can be used like so:
|
||||
```cpp
|
||||
using namespace Catch::literals;
|
||||
REQUIRE( performComputation() == 2.1_a );
|
||||
```
|
||||
If you want to test expression that contains `&&` or `||`, you have two
|
||||
options.
|
||||
|
||||
`Approx` is constructed with defaults that should cover most simple cases.
|
||||
For the more complex cases, `Approx` provides 3 customization points:
|
||||
1) Enclose it in parentheses. Parentheses force evaluation of the expression
|
||||
before the expression decomposition can touch it, and thus it cannot
|
||||
be used.
|
||||
|
||||
* __epsilon__ - epsilon serves to set the coefficient by which a result
|
||||
can differ from `Approx`'s value before it is rejected.
|
||||
_By default set to `std::numeric_limits<float>::epsilon()*100`._
|
||||
* __margin__ - margin serves to set the the absolute value by which
|
||||
a result can differ from `Approx`'s value before it is rejected.
|
||||
_By default set to `0.0`._
|
||||
* __scale__ - scale is used to change the magnitude of `Approx` for relative check.
|
||||
_By default set to `0.0`._
|
||||
2) Rewrite the expression. `REQUIRE(a == 1 && b == 2)` can always be split
|
||||
into `REQUIRE(a == 1); REQUIRE(b == 2);`. Alternatively, if this is a
|
||||
common pattern in your tests, think about using [Matchers](#matcher-expressions).
|
||||
instead. There is no simple rewrite rule for `||`, but I generally
|
||||
believe that if you have `||` in your test expression, you should rethink
|
||||
your tests.
|
||||
|
||||
#### epsilon example
|
||||
```cpp
|
||||
Approx target = Approx(100).epsilon(0.01);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
100.5 == target; // True, because we set target to allow up to 1% difference
|
||||
```
|
||||
|
||||
#### margin example
|
||||
```cpp
|
||||
Approx target = Approx(100).margin(5);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
104.0 == target; // True, because we set target to allow absolute difference of at most 5
|
||||
```
|
||||
## Floating point comparisons
|
||||
|
||||
#### scale
|
||||
Scale can be useful if the computation leading to the result worked
|
||||
on different scale than is used by the results. Since allowed difference
|
||||
between Approx's value and compared value is based primarily on Approx's value
|
||||
(the allowed difference is computed as
|
||||
`(Approx::scale + Approx::value) * epsilon`), the resulting comparison could
|
||||
need rescaling to be correct.
|
||||
Comparing floating point numbers is complex, and [so it has its own
|
||||
documentation page](comparing-floating-point-numbers.md#top).
|
||||
|
||||
|
||||
## Exceptions
|
||||
|
||||
* **REQUIRE_NOTHROW(** _expression_ **)** and
|
||||
* **REQUIRE_NOTHROW(** _expression_ **)** and
|
||||
* **CHECK_NOTHROW(** _expression_ **)**
|
||||
|
||||
Expects that no exception is thrown during evaluation of the expression.
|
||||
|
||||
* **REQUIRE_THROWS(** _expression_ **)** and
|
||||
* **REQUIRE_THROWS(** _expression_ **)** and
|
||||
* **CHECK_THROWS(** _expression_ **)**
|
||||
|
||||
Expects that an exception (of any type) is be thrown during evaluation of the expression.
|
||||
|
||||
* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
|
||||
* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
|
||||
* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
|
||||
|
||||
Expects that an exception of the _specified type_ is thrown during evaluation of the expression. Note that the _exception type_ is extended with `const&` and you should not include it yourself.
|
||||
|
||||
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
|
||||
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
|
||||
* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
|
||||
```cpp
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
@ -166,8 +148,8 @@ REQUIRE_NOTHROW([&](){
|
||||
|
||||
To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md#top).
|
||||
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
|
||||
|
||||
Matchers can be composed using `&&`, `||` and `!` operators.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<a id="top"></a>
|
||||
# CI and other odd pieces
|
||||
|
||||
This page talks about how Catch integrates with Continuous Integration
|
||||
This page talks about how Catch integrates with Continuous Integration
|
||||
Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
|
||||
|
||||
## Continuous Integration systems
|
||||
@ -11,9 +11,9 @@ Probably the most important aspect to using Catch with a build server is the use
|
||||
Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
|
||||
|
||||
### XML Reporter
|
||||
```-r xml```
|
||||
```-r xml```
|
||||
|
||||
The XML Reporter writes in an XML format that is specific to Catch.
|
||||
The XML Reporter writes in an XML format that is specific to Catch.
|
||||
|
||||
The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing.
|
||||
|
||||
|
@ -548,7 +548,8 @@ 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._
|
||||
_Shard index must be less than number of shards. As the name suggests,
|
||||
it is treated as an index of the shard to run._
|
||||
|
||||
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).
|
||||
|
@ -6,7 +6,7 @@ some of them that are willing to share this information.
|
||||
|
||||
If you want to add your organisation, please check that there is no issue
|
||||
with you sharing this fact.
|
||||
|
||||
|
||||
- Bloomberg
|
||||
- [Bloomlife](https://bloomlife.com)
|
||||
- [Inscopix Inc.](https://www.inscopix.com/)
|
||||
@ -16,7 +16,7 @@ with you sharing this fact.
|
||||
- [Nexus Software Systems](https://nexwebsites.com)
|
||||
- [UX3D](https://ux3d.io)
|
||||
- [King](https://king.com)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
192
docs/comparing-floating-point-numbers.md
Normal file
192
docs/comparing-floating-point-numbers.md
Normal file
@ -0,0 +1,192 @@
|
||||
<a id="top"></a>
|
||||
# Comparing floating point numbers with Catch2
|
||||
|
||||
If you are not deeply familiar with them, floating point numbers can be
|
||||
unintuitive. This also applies to comparing floating point numbers for
|
||||
(in)equality.
|
||||
|
||||
This page assumes that you have some understanding of both FP, and the
|
||||
meaning of different kinds of comparisons, and only goes over what
|
||||
functionality Catch2 provides to help you with comparing floating point
|
||||
numbers. If you do not have this understanding, we recommend that you first
|
||||
study up on floating point numbers and their comparisons, e.g. by [reading
|
||||
this blog post](https://codingnest.com/the-little-things-comparing-floating-point-numbers/).
|
||||
|
||||
|
||||
## Floating point matchers
|
||||
|
||||
```
|
||||
#include <catch2/matchers/catch_matchers_floating.hpp
|
||||
```
|
||||
|
||||
[Matchers](matchers.md#top) are the preferred way of comparing floating
|
||||
point numbers in Catch2. We provide 3 of them:
|
||||
|
||||
* `WithinAbs(double target, double margin)`,
|
||||
* `WithinRel(FloatingPoint target, FloatingPoint eps)`, and
|
||||
* `WithinULP(FloatingPoint target, uint64_t maxUlpDiff)`.
|
||||
|
||||
> `WithinRel` matcher was introduced in Catch2 2.10.0
|
||||
|
||||
As with all matchers, you can combine multiple floating point matchers
|
||||
in a single assertion. For example, to check that some computation matches
|
||||
a known good value within 0.1% or is close enough (no different to 5
|
||||
decimal places) to zero, we would write this assertion:
|
||||
|
||||
```cpp
|
||||
REQUIRE_THAT( computation(input),
|
||||
Catch::Matchers::WithinRel(expected, 0.001)
|
||||
|| Catch::Matchers::WithinAbs(0, 0.000001) );
|
||||
```
|
||||
|
||||
|
||||
### WithinAbs
|
||||
|
||||
`WithinAbs` creates a matcher that accepts floating point numbers whose
|
||||
difference with `target` is less-or-equal to the `margin`. Since `float`
|
||||
can be converted to `double` without losing precision, only `double`
|
||||
overload exists.
|
||||
|
||||
```cpp
|
||||
REQUIRE_THAT(1.0, WithinAbs(1.2, 0.2));
|
||||
REQUIRE_THAT(0.f, !WithinAbs(1.0, 0.5));
|
||||
// Notice that infinity == infinity for WithinAbs
|
||||
REQUIRE_THAT(INFINITY, WithinAbs(INFINITY, 0));
|
||||
```
|
||||
|
||||
|
||||
### WithinRel
|
||||
|
||||
`WithinRel` creates a matcher that accepts floating point numbers that
|
||||
are _approximately equal_ to the `target` with a tolerance of `eps.`
|
||||
Specifically, it matches if
|
||||
`|arg - target| <= eps * max(|arg|, |target|)` holds. If you do not
|
||||
specify `eps`, `std::numeric_limits<FloatingPoint>::epsilon * 100`
|
||||
is used as the default.
|
||||
|
||||
```cpp
|
||||
// Notice that WithinRel comparison is symmetric, unlike Approx's.
|
||||
REQUIRE_THAT(1.0, WithinRel(1.1, 0.1));
|
||||
REQUIRE_THAT(1.1, WithinRel(1.0, 0.1));
|
||||
// Notice that inifnity == infinity for WithinRel
|
||||
REQUIRE_THAT(INFINITY, WithinRel(INFINITY));
|
||||
```
|
||||
|
||||
|
||||
### WithinULP
|
||||
|
||||
`WithinULP` creates a matcher that accepts floating point numbers that
|
||||
are no more than `maxUlpDiff`
|
||||
[ULPs](https://en.wikipedia.org/wiki/Unit_in_the_last_place)
|
||||
away from the `target` value. The short version of what this means
|
||||
is that there is no more than `maxUlpDiff - 1` representable floating
|
||||
point numbers between the argument for matching and the `target` value.
|
||||
|
||||
When using the ULP matcher in Catch2, it is important to keep in mind
|
||||
that Catch2 interprets ULP distance slightly differently than
|
||||
e.g. `std::nextafter` does.
|
||||
|
||||
Catch2's ULP calculation obeys these relations:
|
||||
* `ulpDistance(-x, x) == 2 * ulpDistance(x, 0)`
|
||||
* `ulpDistance(-0, 0) == 0` (due to the above)
|
||||
* `ulpDistance(DBL_MAX, INFINITY) == 1`
|
||||
* `ulpDistancE(NaN, x) == infinity`
|
||||
|
||||
|
||||
**Important**: The WithinULP matcher requires the platform to use the
|
||||
[IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) representation for
|
||||
floating point numbers.
|
||||
|
||||
```cpp
|
||||
REQUIRE_THAT( -0.f, WithinULP( 0.f, 0 ) );
|
||||
```
|
||||
|
||||
|
||||
## `Approx`
|
||||
|
||||
```
|
||||
#include <catch2/catch_approx.hpp>
|
||||
```
|
||||
|
||||
**We strongly recommend against using `Approx` when writing new code.**
|
||||
You should be using floating point matchers instead.
|
||||
|
||||
Catch2 provides one more way to handle floating point comparisons. It is
|
||||
`Approx`, a special type with overloaded comparison operators, that can
|
||||
be used in standard assertions, e.g.
|
||||
|
||||
```cpp
|
||||
REQUIRE(0.99999 == Catch::Approx(1));
|
||||
```
|
||||
|
||||
`Approx` supports four comparison operators, `==`, `!=`, `<=`, `>=`, and can
|
||||
also be used with strong typedefs over `double`s. It can be used for both
|
||||
relative and margin comparisons by using its three customization points.
|
||||
Note that the semantics of this is always that of an _or_, so if either
|
||||
the relative or absolute margin comparison passes, then the whole comparison
|
||||
passes.
|
||||
|
||||
The downside to `Approx` is that it has a couple of issues that we cannot
|
||||
fix without breaking backwards compatibility. Because Catch2 also provides
|
||||
complete set of matchers that implement different floating point comparison
|
||||
methods, `Approx` is left as-is, is considered deprecated, and should
|
||||
not be used in new code.
|
||||
|
||||
The issues are
|
||||
* All internal computation is done in `double`s, leading to slightly
|
||||
different results if the inputs were floats.
|
||||
* `Approx`'s relative margin comparison is not symmetric. This means
|
||||
that `Approx( 10 ).epsilon(0.1) != 11.1` but `Approx( 11.1 ).epsilon(0.1) == 10`.
|
||||
* By default, `Approx` only uses relative margin comparison. This means
|
||||
that `Approx(0) == X` only passes for `X == 0`.
|
||||
|
||||
|
||||
### Approx details
|
||||
|
||||
If you still want/need to know more about `Approx`, read on.
|
||||
|
||||
Catch2 provides a UDL for `Approx`; `_a`. It resides in the `Catch::literals`
|
||||
namespace, and can be used like this:
|
||||
|
||||
```cpp
|
||||
using namespace Catch::literals;
|
||||
REQUIRE( performComputation() == 2.1_a );
|
||||
```
|
||||
|
||||
`Approx` has three customization points for the comparison:
|
||||
|
||||
* **epsilon** - epsilon sets the coefficient by which a result
|
||||
can differ from `Approx`'s value before it is rejected.
|
||||
_Defaults to `std::numeric_limits<float>::epsilon()*100`._
|
||||
|
||||
```cpp
|
||||
Approx target = Approx(100).epsilon(0.01);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
100.5 == target; // True, because we set target to allow up to 1% difference
|
||||
```
|
||||
|
||||
|
||||
* **margin** - margin sets the absolute value by which
|
||||
a result can differ from `Approx`'s value before it is rejected.
|
||||
_Defaults to `0.0`._
|
||||
|
||||
```cpp
|
||||
Approx target = Approx(100).margin(5);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
104.0 == target; // True, because we set target to allow absolute difference of at most 5
|
||||
```
|
||||
|
||||
* **scale** - scale is used to change the magnitude of `Approx` for the relative check.
|
||||
_By default, set to `0.0`._
|
||||
|
||||
Scale could be useful if the computation leading to the result worked
|
||||
on a different scale than is used by the results. Approx's scale is added
|
||||
to Approx's value when computing the allowed relative margin from the
|
||||
Approx's value.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
@ -98,7 +98,7 @@ is equivalent with the out-of-the-box experience.
|
||||
|
||||
|
||||
## Bazel support
|
||||
When `CATCH_CONFIG_BAZEL_SUPPORT` is defined or when `BAZEL_TEST=1` (which is set by the Bazel inside of a test environment),
|
||||
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 3.0.1.
|
||||
|
@ -125,7 +125,7 @@ information that you will need for updating Catch2's documentation, and
|
||||
possibly some generic advise as well.
|
||||
|
||||
|
||||
### Technicalities
|
||||
### Technicalities
|
||||
|
||||
First, the technicalities:
|
||||
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
CATCH_REGISTER_LISTENER(testRunListener)
|
||||
```
|
||||
|
||||
_Note that you should not use any assertion macros within a Listener!_
|
||||
_Note that you should not use any assertion macros within a Listener!_
|
||||
|
||||
[You can find the list of events that the listeners can react to on its
|
||||
own page](reporter-events.md#top).
|
||||
|
@ -153,49 +153,8 @@ are:
|
||||
|
||||
> `WithinRel` matcher was introduced in Catch2 2.10.0
|
||||
|
||||
|
||||
`WithinAbs` creates a matcher that accepts floating point numbers whose
|
||||
difference with `target` is less than the `margin`.
|
||||
|
||||
`WithinULP` creates a matcher that accepts floating point numbers that
|
||||
are no more than `maxUlpDiff`
|
||||
[ULPs](https://en.wikipedia.org/wiki/Unit_in_the_last_place)
|
||||
away from the `target` value. The short version of what this means
|
||||
is that there is no more than `maxUlpDiff - 1` representable floating
|
||||
point numbers between the argument for matching and the `target` value.
|
||||
|
||||
**Important**: The WithinULP matcher requires the platform to use the
|
||||
[IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) representation for
|
||||
floating point numbers.
|
||||
|
||||
|
||||
`WithinRel` creates a matcher that accepts floating point numbers that
|
||||
are _approximately equal_ with the `target` with tolerance of `eps.`
|
||||
Specifically, it matches if
|
||||
`|arg - target| <= eps * max(|arg|, |target|)` holds. If you do not
|
||||
specify `eps`, `std::numeric_limits<FloatingPoint>::epsilon * 100`
|
||||
is used as the default.
|
||||
|
||||
|
||||
In practice, you will often want to combine multiple of these matchers,
|
||||
together for an assertion, because all 3 options have edge cases where
|
||||
they behave differently than you would expect. As an example, under
|
||||
the `WithinRel` matcher, a `0.` only ever matches a `0.` (or `-0.`),
|
||||
regardless of the relative tolerance specified. Thus, if you want to
|
||||
handle numbers that are "close enough to 0 to be 0", you have to combine
|
||||
it with the `WithinAbs` matcher.
|
||||
|
||||
For example, to check that our computation matches known good value
|
||||
within 0.1%, or is close enough (no different to 5 decimal places)
|
||||
to zero, we would write this assertion:
|
||||
```cpp
|
||||
REQUIRE_THAT( computation(input),
|
||||
Catch::Matchers::WithinRel(expected, 0.001)
|
||||
|| Catch::Matchers::WithinAbs(0, 0.000001) );
|
||||
```
|
||||
|
||||
|
||||
> floating point matchers live in `catch2/matchers/catch_matchers_floating.hpp`
|
||||
For more details, read [the docs on comparing floating point
|
||||
numbers](comparing-floating-point-numbers.md#floating-point-matchers).
|
||||
|
||||
|
||||
### Miscellaneous matchers
|
||||
@ -285,12 +244,12 @@ 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,
|
||||
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)
|
||||
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)
|
||||
|
@ -72,7 +72,7 @@ A header-only template engine for modern C++.
|
||||
A C++17 template header-only library for the abstraction of memory access patterns.
|
||||
|
||||
### [libcluon](https://github.com/chrberger/libcluon)
|
||||
A single-header-only library written in C++14 to glue distributed software components (UDP, TCP, shared memory) supporting natively Protobuf, LCM/ZCM, MsgPack, and JSON for dynamic message transformations in-between.
|
||||
A single-header-only library written in C++14 to glue distributed software components (UDP, TCP, shared memory) supporting natively Protobuf, LCM/ZCM, MsgPack, and JSON for dynamic message transformations in-between.
|
||||
|
||||
### [MNMLSTC Core](https://github.com/mnmlstc/core)
|
||||
A small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions.
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[3.1.1](#311)<br>
|
||||
[3.1.0](#310)<br>
|
||||
[3.0.1](#301)<br>
|
||||
[2.13.7](#2137)<br>
|
||||
@ -50,6 +51,39 @@
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
|
||||
## 3.1.1
|
||||
|
||||
### Improvements
|
||||
* Added `Catch::getSeed` function that user code can call to retrieve current rng-seed
|
||||
* Better detection of compiler support for `-ffile-prefix-map` (#2517)
|
||||
* Catch2's shared libraries now have `SOVERSION` set (#2516)
|
||||
* `catch2/catch_all.hpp` convenience header no longer transitively includes `windows.h` (#2432, #2526)
|
||||
|
||||
|
||||
### Fixes
|
||||
* Fixed compilation on Universal Windows Platform
|
||||
* Fixed compilation on VxWorks (#2515)
|
||||
* Fixed compilation on Cygwin (#2540)
|
||||
* Remove unused variable in reporter registration (#2538)
|
||||
* Fixed some symbol visibility issues with dynamic library on Windows (#2527)
|
||||
* Suppressed `-Wuseless-cast` warnings in `REQUIRE_THROWS*` macros (#2520, #2521)
|
||||
* This was triggered when the potentially throwing expression evaluates to `void`
|
||||
* Fixed "warning: storage class is not first" with `nvc++` (#2533)
|
||||
* Fixed handling of `DL_PATHS` argument to `catch_discover_tests` on MacOS (#2483)
|
||||
* Suppressed `*-avoid-c-arrays` clang-tidy warning in `TEMPLATE_TEST_CASE` (#2095, #2536)
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
* Fixed CMake install step for Catch2 build as dynamic library (#2485)
|
||||
* Raised minimum CMake version to 3.10 (#2523)
|
||||
* Expect the minimum CMake version to increase once more in next few releases.
|
||||
* Whole bunch of doc updates and fixes
|
||||
* #1444, #2497, #2547, #2549, and more
|
||||
* Added support for building Catch2 with Meson (#2530, #2539)
|
||||
|
||||
|
||||
|
||||
## 3.1.0
|
||||
|
||||
### Improvements
|
||||
|
@ -138,7 +138,7 @@ benchmarking itself fails.
|
||||
> Introduced in Catch2 3.0.1.
|
||||
|
||||
Listings events are events that correspond to the test binary being
|
||||
invoked with `--list-foo` flag.
|
||||
invoked with `--list-foo` flag.
|
||||
|
||||
There are currently 3 listing events, one for reporters, one for tests,
|
||||
and one for tags. Note that they are not exclusive to each other.
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
## Defining test fixtures
|
||||
|
||||
Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
|
||||
Although Catch allows you to group tests together as [sections within a test case](test-cases-and-sections.md), it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
|
||||
|
||||
```c++
|
||||
class UniqueTestsFixture {
|
||||
@ -130,9 +130,9 @@ struct Template_Foo_2 {
|
||||
};
|
||||
|
||||
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]",
|
||||
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))) {
|
||||
|
@ -100,7 +100,7 @@ before we move on.
|
||||
It accepts a boolean expression, and uses expression templates to
|
||||
internally decompose it, so that it can be individually stringified
|
||||
on test failure.
|
||||
|
||||
|
||||
On the last point, note that there are more testing macros available,
|
||||
because not all useful checks can be expressed as a simple boolean
|
||||
expression. As an example, checking that an expression throws an exception
|
||||
@ -178,7 +178,7 @@ To continue on the vector example above, you could add a check that
|
||||
}
|
||||
```
|
||||
|
||||
Another way to look at sections is that they are a way to define a tree
|
||||
Another way to look at sections is that they are a way to define a tree
|
||||
of paths through the test. Each section represents a node, and the final
|
||||
tree is walked in depth-first manner, with each path only visiting only
|
||||
one leaf node.
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.1.0
|
||||
// Generated: 2022-07-17 20:14:05.885021
|
||||
// Catch v3.1.1
|
||||
// Generated: 2022-10-17 18:47:22.400176
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@ -15,6 +15,28 @@
|
||||
#include "catch_amalgamated.hpp"
|
||||
|
||||
|
||||
#ifndef CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
#define CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
|
||||
|
||||
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
// We might end up with the define made globally through the compiler,
|
||||
// and we don't want to trigger warnings for this
|
||||
#if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif // defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
#endif // CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Catch {
|
||||
@ -488,8 +510,11 @@ namespace Catch {
|
||||
|
||||
namespace {
|
||||
bool provideBazelReporterOutput() {
|
||||
#ifdef CATCH_CONFIG_BAZEL_SUPPORT
|
||||
#if defined(CATCH_CONFIG_BAZEL_SUPPORT)
|
||||
return true;
|
||||
#elif defined(CATCH_PLATFORM_WINDOWS_UWP)
|
||||
// UWP does not support environment variables
|
||||
return false;
|
||||
#else
|
||||
|
||||
# if defined( _MSC_VER )
|
||||
@ -554,6 +579,7 @@ namespace Catch {
|
||||
} );
|
||||
}
|
||||
|
||||
#if !defined(CATCH_PLATFORM_WINDOWS_UWP)
|
||||
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
|
||||
@ -575,7 +601,7 @@ namespace Catch {
|
||||
{ "junit", std::string( bazelOutputFilePtr ), {}, {} } );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// We now fixup the reporter specs to handle default output spec,
|
||||
// default colour spec, etc
|
||||
@ -659,6 +685,16 @@ namespace Catch {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Catch {
|
||||
std::uint32_t getSeed() {
|
||||
return getCurrentContext().getConfig()->rngSeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <stack>
|
||||
|
||||
@ -882,7 +918,6 @@ namespace Catch {
|
||||
multi->addListener(listener->create(config));
|
||||
}
|
||||
|
||||
std::size_t reporterIdx = 0;
|
||||
for ( auto const& reporterSpec : config->getProcessedReporterSpecs() ) {
|
||||
multi->addReporter( createReporter(
|
||||
reporterSpec.name,
|
||||
@ -890,7 +925,6 @@ namespace Catch {
|
||||
makeStream( reporterSpec.outputFilename ),
|
||||
reporterSpec.colourMode,
|
||||
reporterSpec.customOptions ) ) );
|
||||
reporterIdx++;
|
||||
}
|
||||
|
||||
return multi;
|
||||
@ -1890,7 +1924,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 1, 0, "", 0 );
|
||||
static Version version( 3, 1, 1, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
@ -3957,6 +3991,7 @@ namespace Detail {
|
||||
FileStream( std::string const& filename ) {
|
||||
m_ofs.open( filename.c_str() );
|
||||
CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << '\'' );
|
||||
m_ofs << std::unitbuf;
|
||||
}
|
||||
~FileStream() override = default;
|
||||
public: // IStream
|
||||
@ -7878,7 +7913,7 @@ private:
|
||||
<< serializeFilters( m_config->getTestsOrTags() )
|
||||
<< '\n';
|
||||
}
|
||||
m_stream << "RNG seed: " << m_config->rngSeed() << '\n';
|
||||
m_stream << "RNG seed: " << getSeed() << '\n';
|
||||
}
|
||||
|
||||
void CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
|
||||
@ -8399,7 +8434,7 @@ void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
|
||||
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
|
||||
<< serializeFilters( m_config->getTestsOrTags() ) << '\n';
|
||||
}
|
||||
m_stream << "Randomness seeded to: " << m_config->rngSeed() << '\n';
|
||||
m_stream << "Randomness seeded to: " << getSeed() << '\n';
|
||||
}
|
||||
|
||||
void ConsoleReporter::lazyPrint() {
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.1.0
|
||||
// Generated: 2022-07-17 20:14:04.055157
|
||||
// Catch v3.1.1
|
||||
// Generated: 2022-10-17 18:47:20.510385
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@ -326,6 +326,10 @@ namespace Catch {
|
||||
|
||||
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define CATCH_PLATFORM_WINDOWS
|
||||
|
||||
# if defined( WINAPI_FAMILY ) && ( WINAPI_FAMILY == WINAPI_FAMILY_APP )
|
||||
# define CATCH_PLATFORM_WINDOWS_UWP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // CATCH_PLATFORM_HPP_INCLUDED
|
||||
@ -356,6 +360,9 @@ namespace Catch {
|
||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
_Pragma( "GCC diagnostic ignored \"-Wunused-variable\"" )
|
||||
|
||||
# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
|
||||
_Pragma( "GCC diagnostic ignored \"-Wuseless-cast\"" )
|
||||
|
||||
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
@ -477,7 +484,7 @@ namespace Catch {
|
||||
|
||||
// Universal Windows platform does not support SEH
|
||||
// Or console colours (or console at all...)
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
# if defined(CATCH_PLATFORM_WINDOWS_UWP)
|
||||
# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
|
||||
# else
|
||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||
@ -638,6 +645,9 @@ namespace Catch {
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
|
||||
#endif
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS
|
||||
#endif
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
|
||||
#endif
|
||||
@ -679,6 +689,16 @@ namespace Catch {
|
||||
# define CATCH_CONFIG_COLOUR_WIN32
|
||||
#endif
|
||||
|
||||
#if defined( CATCH_CONFIG_SHARED_LIBRARY ) && defined( _MSC_VER ) && \
|
||||
!defined( CATCH_CONFIG_STATIC )
|
||||
# ifdef Catch2_EXPORTS
|
||||
# define CATCH_EXPORT //__declspec( dllexport ) // not needed
|
||||
# else
|
||||
# define CATCH_EXPORT __declspec( dllimport )
|
||||
# endif
|
||||
#else
|
||||
# define CATCH_EXPORT
|
||||
#endif
|
||||
|
||||
#endif // CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
|
||||
|
||||
@ -686,6 +706,7 @@ namespace Catch {
|
||||
#ifndef CATCH_CONTEXT_HPP_INCLUDED
|
||||
#define CATCH_CONTEXT_HPP_INCLUDED
|
||||
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class IResultCapture;
|
||||
@ -706,7 +727,7 @@ namespace Catch {
|
||||
virtual void setConfig( IConfig const* config ) = 0;
|
||||
|
||||
private:
|
||||
static IMutableContext *currentContext;
|
||||
CATCH_EXPORT static IMutableContext* currentContext;
|
||||
friend IMutableContext& getCurrentMutableContext();
|
||||
friend void cleanUpContext();
|
||||
static void createContext();
|
||||
@ -1716,9 +1737,9 @@ namespace Catch {
|
||||
template <typename> struct true_given : std::true_type {};
|
||||
struct is_callable_tester {
|
||||
template <typename Fun, typename... Args>
|
||||
true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
|
||||
static true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
|
||||
template <typename...>
|
||||
std::false_type static test(...);
|
||||
static std::false_type test(...);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -2737,14 +2758,18 @@ namespace Catch {
|
||||
template <typename U>
|
||||
void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
|
||||
|
||||
T& stored_object() {
|
||||
return *static_cast<T*>(static_cast<void*>(data));
|
||||
}
|
||||
#if defined( __GNUC__ ) && __GNUC__ <= 6
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
T& stored_object() { return *reinterpret_cast<T*>( data ); }
|
||||
|
||||
T const& stored_object() const {
|
||||
return *static_cast<T const*>(static_cast<void const*>(data));
|
||||
return *reinterpret_cast<T const*>( data );
|
||||
}
|
||||
|
||||
#if defined( __GNUC__ ) && __GNUC__ <= 6
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
alignas( T ) unsigned char data[sizeof( T )]{};
|
||||
};
|
||||
@ -2776,7 +2801,6 @@ namespace Catch {
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
@ -2939,6 +2963,13 @@ namespace Catch {
|
||||
|
||||
namespace Detail {
|
||||
|
||||
inline std::size_t catch_strnlen(const char *str, std::size_t n) {
|
||||
auto ret = std::char_traits<char>::find(str, n, '\0');
|
||||
if (ret != nullptr) {
|
||||
return static_cast<std::size_t>(ret - str);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
constexpr StringRef unprintableString = "{?}"_sr;
|
||||
|
||||
@ -3106,28 +3137,24 @@ namespace Catch {
|
||||
template<size_t SZ>
|
||||
struct StringMaker<char[SZ]> {
|
||||
static std::string convert(char const* str) {
|
||||
// Note that `strnlen` is not actually part of standard C++,
|
||||
// but both POSIX and Windows cstdlib provide it.
|
||||
return Detail::convertIntoString(
|
||||
StringRef( str, strnlen( str, SZ ) ) );
|
||||
StringRef( str, Detail::catch_strnlen( str, SZ ) ) );
|
||||
}
|
||||
};
|
||||
template<size_t SZ>
|
||||
struct StringMaker<signed char[SZ]> {
|
||||
static std::string convert(signed char const* str) {
|
||||
// See the plain `char const*` overload
|
||||
auto reinterpreted = reinterpret_cast<char const*>(str);
|
||||
return Detail::convertIntoString(
|
||||
StringRef(reinterpreted, strnlen(reinterpreted, SZ)));
|
||||
StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
|
||||
}
|
||||
};
|
||||
template<size_t SZ>
|
||||
struct StringMaker<unsigned char[SZ]> {
|
||||
static std::string convert(unsigned char const* str) {
|
||||
// See the plain `char const*` overload
|
||||
auto reinterpreted = reinterpret_cast<char const*>(str);
|
||||
return Detail::convertIntoString(
|
||||
StringRef(reinterpreted, strnlen(reinterpreted, SZ)));
|
||||
StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -3194,13 +3221,13 @@ namespace Catch {
|
||||
template<>
|
||||
struct StringMaker<float> {
|
||||
static std::string convert(float value);
|
||||
static int precision;
|
||||
CATCH_EXPORT static int precision;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct StringMaker<double> {
|
||||
static std::string convert(double value);
|
||||
static int precision;
|
||||
CATCH_EXPORT static int precision;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -4271,6 +4298,19 @@ namespace Catch {
|
||||
#endif // CATCH_CONFIG_HPP_INCLUDED
|
||||
|
||||
|
||||
#ifndef CATCH_GET_RANDOM_SEED_HPP_INCLUDED
|
||||
#define CATCH_GET_RANDOM_SEED_HPP_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Catch {
|
||||
//! Returns Catch2's current RNG seed.
|
||||
std::uint32_t getSeed();
|
||||
}
|
||||
|
||||
#endif // CATCH_GET_RANDOM_SEED_HPP_INCLUDED
|
||||
|
||||
|
||||
#ifndef CATCH_MESSAGE_HPP_INCLUDED
|
||||
#define CATCH_MESSAGE_HPP_INCLUDED
|
||||
|
||||
@ -5642,7 +5682,10 @@ namespace Catch {
|
||||
do { \
|
||||
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
|
||||
try { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
|
||||
static_cast<void>(__VA_ARGS__); \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
@ -5657,7 +5700,10 @@ namespace Catch {
|
||||
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
|
||||
if( catchAssertionHandler.allowThrows() ) \
|
||||
try { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
|
||||
static_cast<void>(__VA_ARGS__); \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
@ -5674,7 +5720,10 @@ namespace Catch {
|
||||
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
|
||||
if( catchAssertionHandler.allowThrows() ) \
|
||||
try { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
|
||||
static_cast<void>(expr); \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
||||
} \
|
||||
catch( exceptionType const& ) { \
|
||||
@ -5697,7 +5746,10 @@ namespace Catch {
|
||||
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
|
||||
if( catchAssertionHandler.allowThrows() ) \
|
||||
try { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
|
||||
static_cast<void>(__VA_ARGS__); \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
@ -6447,12 +6499,12 @@ struct AutoReg : Detail::NonCopyable {
|
||||
struct TestName{\
|
||||
TestName(){\
|
||||
size_t index = 0; \
|
||||
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
|
||||
using expander = size_t[];\
|
||||
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
|
||||
using expander = size_t[]; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
|
||||
(void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
|
||||
return 0;\
|
||||
}();\
|
||||
@ -7063,7 +7115,7 @@ namespace Catch {
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 1
|
||||
#define CATCH_VERSION_PATCH 0
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
||||
@ -9122,6 +9174,7 @@ namespace Catch {
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -9673,32 +9726,6 @@ namespace Catch {
|
||||
#endif // CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
|
||||
|
||||
|
||||
#ifndef CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
#define CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
|
||||
|
||||
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
// We might end up with the define made globally through the compiler,
|
||||
// and we don't want to trigger warnings for this
|
||||
#if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#endif // defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
#endif // CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
|
||||
|
||||
|
||||
#ifndef CATCH_XMLWRITER_HPP_INCLUDED
|
||||
#define CATCH_XMLWRITER_HPP_INCLUDED
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
project(
|
||||
'catch2',
|
||||
'cpp',
|
||||
version: '3.1.0', # CML version placeholder, don't delete
|
||||
version: '3.1.1', # CML version placeholder, don't delete
|
||||
license: 'BSL-1.0',
|
||||
meson_version: '>=0.49.0',
|
||||
)
|
||||
|
@ -301,7 +301,10 @@ if (ANDROID)
|
||||
target_link_libraries(Catch2 INTERFACE log)
|
||||
endif()
|
||||
|
||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "d")
|
||||
set_target_properties(Catch2 PROPERTIES
|
||||
DEBUG_POSTFIX "d"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION})
|
||||
|
||||
# depend on bunch of C++11 and C++14 features to have C++14 enabled by default
|
||||
target_compile_features(Catch2
|
||||
@ -350,6 +353,8 @@ target_link_libraries(Catch2WithMain PUBLIC Catch2)
|
||||
set_target_properties(Catch2WithMain
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "Catch2Main"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION}
|
||||
)
|
||||
set_target_properties(Catch2WithMain PROPERTIES DEBUG_POSTFIX "d")
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace Catch {
|
||||
inline std::size_t catch_strnlen(const char *str, std::size_t n) {
|
||||
auto ret = std::char_traits<char>::find(str, n, '\0');
|
||||
if (ret != nullptr) {
|
||||
return ret - str;
|
||||
return static_cast<std::size_t>(ret - str);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 1, 0, "", 0 );
|
||||
static Version version( 3, 1, 1, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 1
|
||||
#define CATCH_VERSION_PATCH 0
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
@ -16,21 +16,23 @@
|
||||
|
||||
namespace {
|
||||
std::uint64_t Fibonacci(std::uint64_t number) {
|
||||
return number < 2 ? 1 : Fibonacci(number - 1) + Fibonacci(number - 2);
|
||||
return number < 2 ? number : Fibonacci(number - 1) + Fibonacci(number - 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Benchmark Fibonacci", "[!benchmark]") {
|
||||
CHECK(Fibonacci(0) == 1);
|
||||
CHECK(Fibonacci(0) == 0);
|
||||
// some more asserts..
|
||||
CHECK(Fibonacci(5) == 8);
|
||||
CHECK(Fibonacci(5) == 5);
|
||||
// some more asserts..
|
||||
|
||||
BENCHMARK("Fibonacci 20") {
|
||||
REQUIRE( Fibonacci( 20 ) == 6'765 );
|
||||
BENCHMARK( "Fibonacci 20" ) {
|
||||
return Fibonacci(20);
|
||||
};
|
||||
|
||||
BENCHMARK("Fibonacci 25") {
|
||||
REQUIRE( Fibonacci( 25 ) == 75'025 );
|
||||
BENCHMARK( "Fibonacci 25" ) {
|
||||
return Fibonacci(25);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user