Merge branch 'devel' into docs_includes

This commit is contained in:
Nandan V 2022-10-18 09:03:45 +00:00 committed by GitHub
commit ea37a0c965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 511 additions and 223 deletions

View File

@ -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:

View File

@ -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()

View File

@ -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.

View File

@ -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:

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -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).

View File

@ -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)
---

View 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)

View File

@ -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.

View File

@ -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:

View File

@ -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).

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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))) {

View File

@ -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.

View File

@ -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() {

View File

@ -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

View File

@ -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',
)

View File

@ -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")

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);
};