forked from catchorg/Catch2
Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3f0283de7a | ||
|
6fbb3f0723 | ||
|
9ff3cde87b | ||
|
4d802ca58f | ||
|
13711be7cf | ||
|
27ba26f743 | ||
|
a209bcfb54 | ||
|
584973a485 | ||
|
4f7c8cb28a | ||
|
e1dbad4c9e | ||
|
2befd98da2 | ||
|
00f259aeb2 | ||
|
fed1436246 | ||
|
0477326ad9 | ||
|
f04c93462b | ||
|
1af351cea1 | ||
|
dcc9fa3f38 | ||
|
bf6a15a69a | ||
|
6135a78c31 | ||
|
e8ba329b6c | ||
|
4aa88299af | ||
|
4ff9be3bc5 | ||
|
76cdaa3b51 | ||
|
644294df60 | ||
|
cefa8fcf32 | ||
|
772fa3f790 | ||
|
f3c0a3cd09 | ||
|
42d9d4533e | ||
|
618d44c448 | ||
|
388f7e1737 | ||
|
2ab20a0e00 | ||
|
60264b8807 | ||
|
65ffee5189 | ||
|
43f02027e4 | ||
|
906552f8c8 | ||
|
356dfc1439 | ||
|
e5d1eb757f | ||
|
2403f5620e | ||
|
d58491c85a | ||
|
c837cb4a8a | ||
|
8359a6b244 | ||
|
adf43494e1 | ||
|
efca9a0f18 | ||
|
dd36f83b88 | ||
|
baab9e8d28 | ||
|
2d3c9713a3 | ||
|
956f915e31 | ||
|
aa8da505ec | ||
|
e27bb7198d | ||
|
3486f8ed9e | ||
|
b5be642042 | ||
|
d59572f46f | ||
|
16f48f8c7c | ||
|
367c2cb248 | ||
|
d548be26e3 | ||
|
52066dbc2a | ||
|
cdf604f30e | ||
|
04382af4c6 | ||
|
ac93f19437 | ||
|
72b60dfd28 | ||
|
0c62167fea | ||
|
1be954ff70 | ||
|
78bb4fda05 | ||
|
e6ec1c238b | ||
|
477c1f5152 | ||
|
f8b9f77259 | ||
|
77fbacb03f | ||
|
e3fc97dffb | ||
|
9c0533a905 | ||
|
ed02710b83 | ||
|
8b84438be4 |
@@ -4,41 +4,42 @@ Standard: c++14
|
||||
|
||||
# Note that we cannot use IncludeIsMainRegex functionality, because it
|
||||
# does not support includes in angle brackets (<>)
|
||||
SortIncludes: True
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '<catch2/.*\.hpp>'
|
||||
- Regex: <catch2/.*\.hpp>
|
||||
Priority: 1
|
||||
- Regex: '<.*/.*\.hpp>'
|
||||
- Regex: <.*/.*\.hpp>
|
||||
Priority: 2
|
||||
- Regex: '<.*>'
|
||||
- Regex: <.*>
|
||||
Priority: 3
|
||||
|
||||
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
|
||||
AccessModifierOffset: '-4'
|
||||
AccessModifierOffset: "-4"
|
||||
AlignEscapedNewlines: Left
|
||||
AllowAllConstructorInitializersOnNextLine: 'true'
|
||||
BinPackArguments: 'false'
|
||||
BinPackParameters: 'false'
|
||||
AllowAllConstructorInitializersOnNextLine: "true"
|
||||
BinPackArguments: "false"
|
||||
BinPackParameters: "false"
|
||||
BreakConstructorInitializers: AfterColon
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
DerivePointerAlignment: 'false'
|
||||
FixNamespaceComments: 'true'
|
||||
IndentCaseLabels: 'false'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: "true"
|
||||
DerivePointerAlignment: "false"
|
||||
FixNamespaceComments: "true"
|
||||
IndentCaseLabels: "false"
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: '4'
|
||||
IndentWidth: "4"
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
SpaceBeforeCtorInitializerColon: 'false'
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesInParentheses: 'true'
|
||||
TabWidth: '4'
|
||||
SpaceBeforeCtorInitializerColon: "false"
|
||||
SpaceInEmptyParentheses: "false"
|
||||
SpacesInParentheses: "true"
|
||||
TabWidth: "4"
|
||||
UseTab: Never
|
||||
|
||||
...
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SortUsingDeclarations: true
|
||||
ReflowComments: true
|
||||
|
37
.github/workflows/windows-simple-builds.yml
vendored
Normal file
37
.github/workflows/windows-simple-builds.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Windows builds (basic)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{matrix.os}}, ${{matrix.std}}, ${{matrix.build_type}}, ${{matrix.platform}}
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-2019, windows-2022]
|
||||
platform: [Win32, x64]
|
||||
build_type: [Debug, Release]
|
||||
std: [14, 17]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: |
|
||||
cmake -S $Env:GITHUB_WORKSPACE `
|
||||
-B ${{runner.workspace}}/build `
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
|
||||
-A ${{matrix.platform}} `
|
||||
--preset all-tests
|
||||
|
||||
- name: Build tests
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: cmake --build build --config ${{matrix.build_type}} --parallel %NUMBER_OF_PROCESSORS%
|
||||
shell: cmd
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C ${{matrix.build_type}} -j %NUMBER_OF_PROCESSORS%
|
||||
shell: cmd
|
@@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.2.1 # CML version placeholder, don't delete
|
||||
VERSION 3.3.2 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||
# we do not target yet.
|
||||
|
2
Doxyfile
2
Doxyfile
@@ -1319,7 +1319,7 @@ CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
# (YES) or that it should be included in the main .chm file (NO).
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
|
20
README.md
20
README.md
@@ -47,24 +47,28 @@ TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||
#include <cstdint>
|
||||
|
||||
uint64_t fibonacci(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]") {
|
||||
REQUIRE(Fibonacci(5) == 5);
|
||||
REQUIRE(fibonacci(5) == 5);
|
||||
|
||||
REQUIRE(Fibonacci(20) == 6'765);
|
||||
BENCHMARK("Fibonacci 20") {
|
||||
return Fibonacci(20);
|
||||
REQUIRE(fibonacci(20) == 6'765);
|
||||
BENCHMARK("fibonacci 20") {
|
||||
return fibonacci(20);
|
||||
};
|
||||
|
||||
REQUIRE(Fibonacci(25) == 75'025);
|
||||
BENCHMARK("Fibonacci 25") {
|
||||
return Fibonacci(25);
|
||||
REQUIRE(fibonacci(25) == 75'025);
|
||||
BENCHMARK("fibonacci 25") {
|
||||
return fibonacci(25);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
_Note that benchmarks are not run by default, so you need to run it explicitly
|
||||
with the `[!benchmark]` tag._
|
||||
|
||||
|
||||
## Catch2 v3 has been released!
|
||||
|
||||
You are on the `devel` branch, where the v3 version is being developed.
|
||||
|
46
appveyor.yml
46
appveyor.yml
@@ -51,18 +51,6 @@ test_script:
|
||||
# build explicitly.
|
||||
environment:
|
||||
matrix:
|
||||
- FLAVOR: VS 2019 x64 Debug Surrogates Configure Tests
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
surrogates: 1
|
||||
configure_tests: 1
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2019 x64 Release
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
platform: x64
|
||||
configuration: Release
|
||||
|
||||
- FLAVOR: VS 2019 x64 Debug Coverage Examples
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
examples: 1
|
||||
@@ -77,11 +65,6 @@ environment:
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2019 Win32 Debug
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
platform: Win32
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2019 x64 Debug Latest Strict
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
@@ -93,37 +76,8 @@ environment:
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 x64 Release
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
platform: x64
|
||||
configuration: Release
|
||||
|
||||
- FLAVOR: VS 2017 x64 Release Coverage
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
coverage: 1
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 Win32 Debug
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
platform: Win32
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 Win32 Debug Examples
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
examples: 1
|
||||
platform: Win32
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 Win32 Debug WMain
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
wmain: 1
|
||||
additional_flags: "/D_UNICODE /DUNICODE"
|
||||
platform: Win32
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 x64 Debug Latest Strict
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
@@ -11,6 +11,7 @@ Once you're up and running consider the following reference material.
|
||||
* [Logging macros](logging.md#top)
|
||||
* [Test cases and sections](test-cases-and-sections.md#top)
|
||||
* [Test fixtures](test-fixtures.md#top)
|
||||
* [Explicitly skipping, passing, and failing tests at runtime](skipping-passing-failing.md#top)
|
||||
* [Reporters (output customization)](reporters.md#top)
|
||||
* [Event Listeners](event-listeners.md#top)
|
||||
* [Data Generators (value parameterized tests)](generators.md#top)
|
||||
|
@@ -90,12 +90,12 @@ cmake_minimum_required(VERSION 3.5)
|
||||
project(baz LANGUAGES CXX VERSION 0.0.1)
|
||||
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(foo test.cpp)
|
||||
target_link_libraries(foo PRIVATE Catch2::Catch2)
|
||||
add_executable(tests test.cpp)
|
||||
target_link_libraries(tests PRIVATE Catch2::Catch2)
|
||||
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
catch_discover_tests(foo)
|
||||
catch_discover_tests(tests)
|
||||
```
|
||||
|
||||
When using `FetchContent`, `include(Catch)` will fail unless
|
||||
@@ -108,7 +108,7 @@ directory.
|
||||
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
catch_discover_tests()
|
||||
catch_discover_tests(tests)
|
||||
```
|
||||
|
||||
#### Customization
|
||||
@@ -222,12 +222,12 @@ cmake_minimum_required(VERSION 3.5)
|
||||
project(baz LANGUAGES CXX VERSION 0.0.1)
|
||||
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(foo test.cpp)
|
||||
target_link_libraries(foo PRIVATE Catch2::Catch2)
|
||||
add_executable(tests test.cpp)
|
||||
target_link_libraries(tests PRIVATE Catch2::Catch2)
|
||||
|
||||
include(CTest)
|
||||
include(ParseAndAddCatchTests)
|
||||
ParseAndAddCatchTests(foo)
|
||||
ParseAndAddCatchTests(tests)
|
||||
```
|
||||
|
||||
|
||||
|
@@ -148,7 +148,7 @@ validity, and throw an error if they are wrong._
|
||||
> Support for passing arguments to reporters through the `-r`, `--reporter` flag was introduced in Catch2 3.0.1
|
||||
|
||||
There are multiple built-in reporters, you can see what they do by using the
|
||||
[`--list-reporter`](command-line.md#listing-available-tests-tags-or-reporters)
|
||||
[`--list-reporters`](command-line.md#listing-available-tests-tags-or-reporters)
|
||||
flag. If you need a reporter providing custom format outside of the already
|
||||
provided ones, look at the ["write your own reporter" part of the reporter
|
||||
documentation](reporters.md#writing-your-own-reporter).
|
||||
@@ -507,10 +507,13 @@ start of the first section.</br>
|
||||
## Filenames as tags
|
||||
<pre>-#, --filenames-as-tags</pre>
|
||||
|
||||
When this option is used then every test is given an additional tag which is formed of the unqualified
|
||||
filename it is found in, with any extension stripped, prefixed with the `#` character.
|
||||
This option adds an extra tag to all test cases. The tag is `#` followed
|
||||
by the unqualified filename the test case is defined in, with the _last_
|
||||
extension stripped out.
|
||||
|
||||
For example, tests within the file `tests\SelfTest\UsageTests\BDD.tests.cpp`
|
||||
will be given the `[#BDD.tests]` tag.
|
||||
|
||||
So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`.
|
||||
|
||||
<a id="colour-mode"></a>
|
||||
## Override output colouring
|
||||
@@ -561,10 +564,10 @@ processes, as is done with the [Bazel test sharding](https://docs.bazel.build/ve
|
||||
|
||||
> Introduced in Catch2 3.0.1.
|
||||
|
||||
By default, Catch2 test binaries return non-0 exit code if no tests were
|
||||
run, e.g. if the binary was compiled with no tests, or the provided test
|
||||
spec matched no tests. This flag overrides that, so a test run with no
|
||||
tests still returns 0.
|
||||
By default, Catch2 test binaries return non-0 exit code if no tests were run,
|
||||
e.g. if the binary was compiled with no tests, the provided test spec matched no
|
||||
tests, or all tests [were skipped at runtime](skipping-passing-failing.md#top). This flag
|
||||
overrides that, so a test run with no tests still returns 0.
|
||||
|
||||
## Output verbosity
|
||||
```
|
||||
|
@@ -55,6 +55,15 @@ tests from `SelfTest` through a specific reporter and then compare the
|
||||
generated output with a known good output ("Baseline"). By default, new
|
||||
tests should be placed here.
|
||||
|
||||
To configure a Catch2 build with just the basic tests, use the `basic-tests`
|
||||
preset, like so:
|
||||
|
||||
```
|
||||
# Assuming you are in Catch2's root folder
|
||||
|
||||
cmake -B basic-test-build -S . -DCMAKE_BUILD_TYPE=Debug --preset basic-tests
|
||||
```
|
||||
|
||||
However, not all tests can be written as plain unit tests. For example,
|
||||
checking that Catch2 orders tests randomly when asked to, and that this
|
||||
random ordering is subset-invariant, is better done as an integration
|
||||
@@ -76,21 +85,23 @@ configuration and require separate compilation.
|
||||
Finally, CMake config tests test that you set Catch2's compile-time
|
||||
configuration options through CMake, using CMake options of the same name.
|
||||
|
||||
None of these tests are enabled by default. To enable them, add
|
||||
These test categories can be enabled one by one, by passing
|
||||
`-DCATCH_BUILD_EXAMPLES=ON`, `-DCATCH_BUILD_EXTRA_TESTS=ON`, and
|
||||
`-DCATCH_ENABLE_CONFIGURE_TESTS=ON` when configuration the CMake build.
|
||||
`-DCATCH_ENABLE_CONFIGURE_TESTS=ON` when configuring the build.
|
||||
|
||||
Bringing this all together, the steps below should configure, build,
|
||||
and run all tests in the `Debug` compilation.
|
||||
Catch2 also provides a preset that promises to enable _all_ test types,
|
||||
`all-tests`.
|
||||
|
||||
The snippet below will build & run all tests, in `Debug` compilation mode.
|
||||
|
||||
<!-- snippet: catch2-build-and-test -->
|
||||
<a id='snippet-catch2-build-and-test'></a>
|
||||
```sh
|
||||
# 1. Regenerate the amalgamated distribution
|
||||
# 1. Regenerate the amalgamated distribution (some tests are built against it)
|
||||
./tools/scripts/generateAmalgamatedFiles.py
|
||||
|
||||
# 2. Configure the full test build
|
||||
cmake -Bdebug-build -H. -DCMAKE_BUILD_TYPE=Debug -DCATCH_DEVELOPMENT_BUILD=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_BUILD_EXTRA_TESTS=ON
|
||||
cmake -B debug-build -S . -DCMAKE_BUILD_TYPE=Debug --preset all-tests
|
||||
|
||||
# 3. Run the actual build
|
||||
cmake --build debug-build
|
||||
|
@@ -26,6 +26,15 @@ to accurately probe the environment for this information so the flag
|
||||
where it will export `BAZEL_TEST=1` for purposes like the above. Catch2
|
||||
will now instead inspect the environment instead of relying on build configuration.
|
||||
|
||||
### `IEventLister::skipTest( TestCaseInfo const& testInfo )`
|
||||
|
||||
This event (including implementations in derived classes such as `ReporterBase`)
|
||||
is deprecated and will be removed in the next major release. It is currently
|
||||
invoked for all test cases that are not going to be executed due to the test run
|
||||
being aborted (when using `--abort` or `--abortx`). It is however
|
||||
**NOT** invoked for test cases that are [explicitly skipped using the `SKIP`
|
||||
macro](skipping-passing-failing.md#top).
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@@ -205,13 +205,17 @@ struct IGenerator : GeneratorUntypedBase {
|
||||
// Precondition:
|
||||
// The generator is either freshly constructed or the last call to next() returned true
|
||||
virtual T const& get() const = 0;
|
||||
|
||||
// Returns user-friendly string showing the current generator element
|
||||
// Does not have to be overridden, IGenerator provides default implementation
|
||||
virtual std::string stringifyImpl() const;
|
||||
};
|
||||
```
|
||||
|
||||
However, to be able to use your custom generator inside `GENERATE`, it
|
||||
will need to be wrapped inside a `GeneratorWrapper<T>`.
|
||||
`GeneratorWrapper<T>` is a value wrapper around a
|
||||
`std::unique_ptr<IGenerator<T>>`.
|
||||
`Catch::Detail::unique_ptr<IGenerator<T>>`.
|
||||
|
||||
For full example of implementing your own generator, look into Catch2's
|
||||
examples, specifically
|
||||
|
@@ -88,8 +88,8 @@ because only one thread passes the `REQUIRE` macro and this is not
|
||||
REQUIRE(cnt == 16);
|
||||
```
|
||||
|
||||
Because C++11 provides the necessary tools to do this, we are planning
|
||||
to remove this limitation in the future.
|
||||
We currently do not plan to support thread-safe assertions.
|
||||
|
||||
|
||||
### Process isolation in a test
|
||||
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
|
||||
@@ -155,7 +155,7 @@ with expansion:
|
||||
|
||||
|
||||
### Clang/G++ -- skipping leaf sections after an exception
|
||||
Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from master
|
||||
Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from the master branch
|
||||
```cpp
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
|
@@ -141,18 +141,27 @@ are a permutation of the ones in `some_vec`.
|
||||
|
||||
### Floating point matchers
|
||||
|
||||
Catch2 provides 3 matchers that target floating point numbers. These
|
||||
Catch2 provides 4 matchers that target floating point numbers. These
|
||||
are:
|
||||
|
||||
* `WithinAbs(double target, double margin)`,
|
||||
* `WithinULP(FloatingPoint target, uint64_t maxUlpDiff)`, and
|
||||
* `WithinRel(FloatingPoint target, FloatingPoint eps)`.
|
||||
* `IsNaN()`
|
||||
|
||||
> `WithinRel` matcher was introduced in Catch2 2.10.0
|
||||
|
||||
For more details, read [the docs on comparing floating point
|
||||
> `IsNaN` matcher was introduced in Catch2 3.3.2.
|
||||
|
||||
The first three serve to compare two floating pointe numbers. For more
|
||||
details about how they work, read [the docs on comparing floating point
|
||||
numbers](comparing-floating-point-numbers.md#floating-point-matchers).
|
||||
|
||||
`IsNaN` then does exactly what it says on the tin. It matches the input
|
||||
if it is a NaN (Not a Number). The advantage of using it over just plain
|
||||
`REQUIRE(std::isnan(x))`, is that if the check fails, with `REQUIRE` you
|
||||
won't see the value of `x`, but with `REQUIRE_THAT(x, IsNaN())`, you will.
|
||||
|
||||
|
||||
### Miscellaneous matchers
|
||||
|
||||
@@ -190,13 +199,23 @@ properties. The macro is `REQUIRE_THROWS_MATCHES(expr, ExceptionType, Matcher)`.
|
||||
> `REQUIRE_THROWS_MATCHES` macro lives in `catch2/matchers/catch_matchers.hpp`
|
||||
|
||||
|
||||
Catch2 currently provides only one matcher for exceptions,
|
||||
`Message(std::string message)`. `Message` checks that the exception's
|
||||
Catch2 currently provides two matchers for exceptions.
|
||||
These are:
|
||||
* `Message(std::string message)`.
|
||||
* `MessageMatches(Matcher matcher)`.
|
||||
|
||||
> `MessageMatches` was [introduced](https://github.com/catchorg/Catch2/pull/2570) in Catch2 3.3.0
|
||||
|
||||
`Message` checks that the exception's
|
||||
message, as returned from `what` is exactly equal to `message`.
|
||||
|
||||
`MessageMatches` applies the provided matcher on the exception's
|
||||
message, as returned from `what`. This is useful in conjunctions with the `std::string` matchers (e.g. `StartsWith`)
|
||||
|
||||
Example use:
|
||||
```cpp
|
||||
REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, Message("DerivedException::what"));
|
||||
REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, MessageMatches(StartsWith("DerivedException")));
|
||||
```
|
||||
|
||||
Note that `DerivedException` in the example above has to derive from
|
||||
@@ -218,11 +237,19 @@ definitions to handle generic range-like types. These are:
|
||||
* `Contains(T&& target_element, Comparator = std::equal_to<>{})`
|
||||
* `Contains(Matcher element_matcher)`
|
||||
* `AllMatch(Matcher element_matcher)`
|
||||
* `NoneMatch(Matcher element_matcher)`
|
||||
* `AnyMatch(Matcher element_matcher)`
|
||||
* `AllTrue()`
|
||||
* `NoneTrue()`
|
||||
* `AnyTrue()`
|
||||
* `NoneMatch(Matcher element_matcher)`
|
||||
* `AllTrue()`, `AnyTrue()`, `NoneTrue()`
|
||||
* `RangeEquals(TargetRangeLike&&, Comparator = std::equal_to<>{})`
|
||||
* `UnorderedRangeEquals(TargetRangeLike&&, Comparator = std::equal_to<>{})`
|
||||
|
||||
> `IsEmpty`, `SizeIs`, `Contains` were introduced in Catch2 3.0.1
|
||||
|
||||
> `All/Any/NoneMatch` were introduced in Catch2 3.0.1
|
||||
|
||||
> `All/Any/NoneTrue` were introduced in Catch2 3.1.0
|
||||
|
||||
> `RangeEquals` and `UnorderedRangeEquals` matchers were [introduced](https://github.com/catchorg/Catch2/pull/2377) in Catch2 3.3.0
|
||||
|
||||
`IsEmpty` should be self-explanatory. It successfully matches objects
|
||||
that are empty according to either `std::empty`, or ADL-found `empty`
|
||||
@@ -249,6 +276,25 @@ 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`.
|
||||
|
||||
`RangeEquals` compares the range that the matcher is constructed with
|
||||
(the "target range") against the range to be tested, element-wise. The
|
||||
match succeeds if all elements from the two ranges compare equal (using
|
||||
`operator==` by default). The ranges do not need to be the same type,
|
||||
and the element types do not need to be the same, as long as they are
|
||||
comparable. (e.g. you may compare `std::vector<int>` to `std::array<char>`).
|
||||
|
||||
`UnorderedRangeEquals` is similar to `RangeEquals`, but the order
|
||||
does not matter. For example "1, 2, 3" would match "3, 2, 1", but not
|
||||
"1, 1, 2, 3" As with `RangeEquals`, `UnorderedRangeEquals` compares
|
||||
the individual elements using using `operator==` by default.
|
||||
|
||||
Both `RangeEquals` and `UnorderedRangeEquals` optionally accept a
|
||||
predicate which can be used to compare the containers element-wise.
|
||||
|
||||
To check a container elementwise against a given matcher, use
|
||||
`AllMatch`.
|
||||
|
||||
|
||||
## Writing custom matchers (old style)
|
||||
|
||||
The old style of writing matchers has been introduced back in Catch
|
||||
|
@@ -2,6 +2,9 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[3.3.2](#332)<br>
|
||||
[3.3.1](#331)<br>
|
||||
[3.3.0](#330)<br>
|
||||
[3.2.1](#321)<br>
|
||||
[3.2.0](#320)<br>
|
||||
[3.1.1](#311)<br>
|
||||
@@ -54,6 +57,67 @@
|
||||
|
||||
|
||||
|
||||
## 3.3.2
|
||||
|
||||
### Improvements
|
||||
* Further reduced allocations
|
||||
* The compact, console, TAP and XML reporters perform less allocations in various cases
|
||||
* Removed 1 allocation per entered `SECTION`/`TEST_CASE`.
|
||||
* Removed 2 allocations per test case exit, if stdout/stderr is captured
|
||||
* Improved performance
|
||||
* Section tracking is 10%-25% faster than in v3.3.0
|
||||
* Assertion handling is 5%-10% faster than in v3.3.0
|
||||
* Test case registration is 1%-2% faster than in v3.3.0
|
||||
* Tiny speedup for registering listeners
|
||||
* Tiny speedup for `CAPTURE`, `TEST_CASE_METHOD`, `METHOD_AS_TEST_CASE`, and `TEMPLATE_LIST_TEST_*` macros.
|
||||
* `Contains`, `RangeEquals` and `UnorderedRangeEquals` matchers now support ranges with iterator + sentinel pair
|
||||
* Added `IsNaN` matcher
|
||||
* Unlike `REQUIRE(isnan(x))`, `REQUIRE_THAT(x, IsNaN())` shows you the value of `x`.
|
||||
* Suppressed `declared_but_not_referenced` warning for NVHPC (#2637)
|
||||
|
||||
### Fixes
|
||||
* Fixed performance regression in section tracking introduced in v3.3.1
|
||||
* Extreme cases would cause the tracking to run about 4x slower than in 3.3.0
|
||||
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Improvements
|
||||
* Reduced allocations and improved performance
|
||||
* The exact improvements are dependent on your usage of Catch2.
|
||||
* For example running Catch2's SelfTest binary performs 8k less allocations.
|
||||
* The main improvement comes from smarter handling of `SECTION`s, especially sibling `SECTION`s
|
||||
|
||||
|
||||
## 3.3.0
|
||||
|
||||
### Improvements
|
||||
|
||||
* Added `MessageMatches` exception matcher (#2570)
|
||||
* Added `RangeEquals` and `UnorderedRangeEquals` generic range matchers (#2377)
|
||||
* Added `SKIP` macro for skipping tests from within the test body (#2360)
|
||||
* All built-in reporters have been extended to handle it properly, whether your custom reporter needs changes depends on how it was written
|
||||
* `skipTest` reporter event **is unrelated** to this, and has been deprecated since it has practically no uses
|
||||
* Restored support for PPC Macs in the break-into-debugger functionality (#2619)
|
||||
* Made our warning suppression compatible with CUDA toolkit pre 11.5 (#2626)
|
||||
* Cleaned out some static analysis complaints
|
||||
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fixed macro redefinition warning when NVCC was reporting as MSVC (#2603)
|
||||
* Fixed throws in generator constructor causing the whole binary to abort (#2615)
|
||||
* Now it just fails the test
|
||||
* Fixed missing transitive include with libstdc++13 (#2611)
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Improved support for dynamic library build with non-MSVC compilers on Windows (#2630)
|
||||
* When used as a subproject, Catch2 keeps its generated header in a separate directory from the main project (#2604)
|
||||
|
||||
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Improvements
|
||||
|
129
docs/skipping-passing-failing.md
Normal file
129
docs/skipping-passing-failing.md
Normal file
@@ -0,0 +1,129 @@
|
||||
<a id="top"></a>
|
||||
# Explicitly skipping, passing, and failing tests at runtime
|
||||
|
||||
## Skipping Test Cases at Runtime
|
||||
|
||||
> [Introduced](https://github.com/catchorg/Catch2/pull/2360) in Catch2 3.3.0.
|
||||
|
||||
In some situations it may not be possible to meaningfully execute a test case,
|
||||
for example when the system under test is missing certain hardware capabilities.
|
||||
If the required conditions can only be determined at runtime, it often
|
||||
doesn't make sense to consider such a test case as either passed or failed,
|
||||
because it simply can not run at all.
|
||||
|
||||
To properly express such scenarios, Catch2 provides a way to explicitly
|
||||
_skip_ test cases, using the `SKIP` macro:
|
||||
|
||||
```
|
||||
SKIP( [streamable expression] )
|
||||
```
|
||||
|
||||
Example usage:
|
||||
|
||||
```c++
|
||||
TEST_CASE("copy files between drives") {
|
||||
if(getNumberOfHardDrives() < 2) {
|
||||
SKIP("at least two hard drives required");
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This test case is then reported as _skipped_ instead of _passed_ or _failed_.
|
||||
|
||||
The `SKIP` macro behaves similarly to an explicit [`FAIL`](#passing-and-failing-test-cases),
|
||||
in that it is the last expression that will be executed:
|
||||
|
||||
```c++
|
||||
TEST_CASE("my test") {
|
||||
printf("foo");
|
||||
SKIP();
|
||||
printf("bar"); // not printed
|
||||
}
|
||||
```
|
||||
|
||||
However a failed assertion _before_ a `SKIP` still causes the entire
|
||||
test case to fail:
|
||||
|
||||
```c++
|
||||
TEST_CASE("failing test") {
|
||||
CHECK(1 == 2);
|
||||
SKIP();
|
||||
}
|
||||
```
|
||||
|
||||
### Interaction with Sections and Generators
|
||||
|
||||
Sections, nested sections as well as specific outputs from [generators](generators.md#top)
|
||||
can all be individually skipped, with the rest executing as usual:
|
||||
|
||||
```c++
|
||||
TEST_CASE("complex test case") {
|
||||
int value = GENERATE(2, 4, 6);
|
||||
SECTION("a") {
|
||||
SECTION("a1") { CHECK(value < 8); }
|
||||
SECTION("a2") {
|
||||
if (value == 4) {
|
||||
SKIP();
|
||||
}
|
||||
CHECK(value % 2 == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This test case will report 5 passing assertions; one for each of the three
|
||||
values in section `a1`, and then two in section `a2`, from values 2 and 4.
|
||||
|
||||
Note that as soon as one section is skipped, the entire test case will
|
||||
be reported as _skipped_ (unless there is a failing assertion, in which
|
||||
case the test is handled as _failed_ instead).
|
||||
|
||||
Note that if all test cases in a run are skipped, Catch2 returns a non-zero
|
||||
exit code, same as it does if no test cases have run. This behaviour can
|
||||
be overridden using the [--allow-running-no-tests](command-line.md#no-tests-override)
|
||||
flag.
|
||||
|
||||
|
||||
## Passing and failing test cases
|
||||
|
||||
Test cases can also be explicitly passed or failed, without the use of
|
||||
assertions, and with a specific message. This can be useful to handle
|
||||
complex preconditions/postconditions and give useful error messages
|
||||
when they fail.
|
||||
|
||||
* `SUCCEED( [streamable expression] )`
|
||||
|
||||
`SUCCEED` is morally equivalent with `INFO( [streamable expression] ); REQUIRE( true );`.
|
||||
Note that it does not stop further test execution, so it cannot be used
|
||||
to guard failing assertions from being executed.
|
||||
|
||||
_In practice, `SUCCEED` is usually used as a test placeholder, to avoid
|
||||
[failing a test case due to missing assertions](command-line.md#warnings)._
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "SUCCEED showcase" ) {
|
||||
int I = 1;
|
||||
SUCCEED( "I is " << I );
|
||||
// ... execution continues here ...
|
||||
}
|
||||
```
|
||||
|
||||
* `FAIL( [streamable expression] )`
|
||||
|
||||
`FAIL` is morally equivalent with `INFO( [streamable expression] ); REQUIRE( false );`.
|
||||
|
||||
_In practice, `FAIL` is usually used to stop executing test that is currently
|
||||
known to be broken, but has to be fixed later._
|
||||
|
||||
```cpp
|
||||
TEST_CASE( "FAIL showcase" ) {
|
||||
FAIL( "This test case causes segfault, which breaks CI." );
|
||||
// ... this will not be executed ...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
@@ -25,7 +25,8 @@ _section description_ can be used to provide long form description
|
||||
of a section while keeping the _section name_ short for use with the
|
||||
[`-c` command line parameter](command-line.md#specify-the-section-to-run).
|
||||
|
||||
**Test names must be unique within the Catch executable.**
|
||||
**The combination of test names and tags must be unique within the Catch2
|
||||
executable.**
|
||||
|
||||
For examples see the [Tutorial](tutorial.md#top)
|
||||
|
||||
@@ -68,7 +69,8 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
|
||||
|
||||
* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers.
|
||||
|
||||
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped), as a tag to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
||||
* `[#<filename>]` - these tags are added to test cases when you run Catch2
|
||||
with [`-#` or `--filenames-as-tags`](command-line.md#filenames-as-tags).
|
||||
|
||||
* `[@<alias>]` - tag aliases all begin with `@` (see below).
|
||||
|
||||
@@ -167,7 +169,11 @@ Other than the additional prefixes and the formatting in the console reporter th
|
||||
|
||||
In addition to `TEST_CASE`s, Catch2 also supports test cases parametrised
|
||||
by types, in the form of `TEMPLATE_TEST_CASE`,
|
||||
`TEMPLATE_PRODUCT_TEST_CASE` and `TEMPLATE_LIST_TEST_CASE`.
|
||||
`TEMPLATE_PRODUCT_TEST_CASE` and `TEMPLATE_LIST_TEST_CASE`. These macros
|
||||
are defined in the `catch_template_test_macros.hpp` header, so compiling
|
||||
the code examples below also requires
|
||||
`#include <catch2/catch_template_test_macros.hpp>`.
|
||||
|
||||
|
||||
* **TEMPLATE_TEST_CASE(** _test name_ , _tags_, _type1_, _type2_, ..., _typen_ **)**
|
||||
|
||||
@@ -289,7 +295,9 @@ TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside std
|
||||
In addition to [type parametrised test cases](#type-parametrised-test-cases) Catch2 also supports
|
||||
signature base parametrised test cases, in form of `TEMPLATE_TEST_CASE_SIG` and `TEMPLATE_PRODUCT_TEST_CASE_SIG`.
|
||||
These test cases have similar syntax like [type parametrised test cases](#type-parametrised-test-cases), with one
|
||||
additional positional argument which specifies the signature.
|
||||
additional positional argument which specifies the signature. These macros are defined in the
|
||||
`catch_template_test_macros.hpp` header, so compiling the code examples below also requires
|
||||
`#include <catch2/catch_template_test_macros.hpp>`.
|
||||
|
||||
### Signature
|
||||
Signature has some strict rules for these tests cases to work properly:
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
project(
|
||||
'catch2',
|
||||
'cpp',
|
||||
version: '3.2.1', # CML version placeholder, don't delete
|
||||
version: '3.3.2', # CML version placeholder, don't delete
|
||||
license: 'BSL-1.0',
|
||||
meson_version: '>=0.50.0',
|
||||
)
|
||||
|
@@ -39,7 +39,7 @@ set(BENCHMARK_FILES ${BENCHMARK_HEADERS} ${BENCHMARK_SOURCES})
|
||||
|
||||
|
||||
set(IMPL_HEADERS
|
||||
"${CMAKE_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
"${PROJECT_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
${SOURCES_DIR}/catch_user_config.hpp.in
|
||||
${SOURCES_DIR}/catch_all.hpp
|
||||
${SOURCES_DIR}/catch_approx.hpp
|
||||
@@ -88,6 +88,7 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/internal/catch_floating_point_helpers.hpp
|
||||
${SOURCES_DIR}/internal/catch_getenv.hpp
|
||||
${SOURCES_DIR}/internal/catch_istream.hpp
|
||||
${SOURCES_DIR}/internal/catch_is_permutation.hpp
|
||||
${SOURCES_DIR}/internal/catch_lazy_expr.hpp
|
||||
${SOURCES_DIR}/internal/catch_leak_detector.hpp
|
||||
${SOURCES_DIR}/internal/catch_list.hpp
|
||||
@@ -252,6 +253,7 @@ set(MATCHER_HEADERS
|
||||
${SOURCES_DIR}/matchers/catch_matchers_all.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_container_properties.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_contains.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_range_equals.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_exception.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_floating_point.hpp
|
||||
${SOURCES_DIR}/matchers/catch_matchers_predicate.hpp
|
||||
@@ -321,7 +323,7 @@ set(ALL_FILES
|
||||
)
|
||||
|
||||
set(FILTERED_FILES ${ALL_FILES})
|
||||
list(REMOVE_ITEM FILTERED_FILES "${CMAKE_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp")
|
||||
list(REMOVE_ITEM FILTERED_FILES "${PROJECT_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp")
|
||||
source_group(
|
||||
TREE ${SOURCES_DIR}
|
||||
PREFIX sources
|
||||
@@ -329,7 +331,7 @@ source_group(
|
||||
)
|
||||
source_group("generated headers"
|
||||
FILES
|
||||
"${CMAKE_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
"${PROJECT_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
)
|
||||
|
||||
add_library(Catch2 ${ALL_FILES})
|
||||
@@ -372,13 +374,13 @@ target_compile_features(Catch2
|
||||
|
||||
configure_file(
|
||||
"${SOURCES_DIR}/catch_user_config.hpp.in"
|
||||
"${CMAKE_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
"${PROJECT_BINARY_DIR}/generated-includes/catch2/catch_user_config.hpp"
|
||||
)
|
||||
|
||||
target_include_directories(Catch2
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${SOURCES_DIR}/..>
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/generated-includes>
|
||||
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/generated-includes>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
@@ -426,7 +428,7 @@ if (NOT_SUBPROJECT)
|
||||
install(
|
||||
DIRECTORY
|
||||
"${SOURCES_DIR}"
|
||||
"${CMAKE_BINARY_DIR}/generated-includes/catch2" # Also install the generated header
|
||||
"${PROJECT_BINARY_DIR}/generated-includes/catch2" # Also install the generated header
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
FILES_MATCHING
|
||||
@@ -447,7 +449,7 @@ if (CATCH_BUILD_EXAMPLES OR CATCH_BUILD_EXTRA_TESTS)
|
||||
target_include_directories(Catch2_buildall_interface
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${SOURCES_DIR}/..>
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/generated-includes>
|
||||
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/generated-includes>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
target_compile_definitions(Catch2_buildall_interface
|
||||
@@ -487,12 +489,10 @@ set(CATCH_WARNING_TARGETS ${CATCH_WARNING_TARGETS} PARENT_SCOPE)
|
||||
# so we want to check & warn users if they do this. However, we won't abort
|
||||
# the configuration step so that we don't have to also provide an override.
|
||||
if (BUILD_SHARED_LIBS)
|
||||
if (MSVC)
|
||||
set_target_properties(Catch2 Catch2WithMain
|
||||
PROPERTIES
|
||||
WINDOWS_EXPORT_ALL_SYMBOLS ON
|
||||
)
|
||||
endif()
|
||||
set_target_properties(Catch2 Catch2WithMain
|
||||
PROPERTIES
|
||||
WINDOWS_EXPORT_ALL_SYMBOLS ON
|
||||
)
|
||||
|
||||
get_target_property(_VisPreset Catch2 CXX_VISIBILITY_PRESET)
|
||||
if (NOT MSVC AND _VisPreset STREQUAL "hidden")
|
||||
|
@@ -64,7 +64,7 @@ namespace Catch {
|
||||
});
|
||||
|
||||
BenchmarkInfo info {
|
||||
name,
|
||||
CATCH_MOVE(name),
|
||||
plan.estimated_duration.count(),
|
||||
plan.iterations_per_sample,
|
||||
cfg->benchmarkSamples(),
|
||||
@@ -80,7 +80,7 @@ namespace Catch {
|
||||
});
|
||||
|
||||
auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
|
||||
BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
|
||||
BenchmarkStats<FloatDuration<Clock>> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
|
||||
getResultCapture().benchmarkEnded(stats);
|
||||
} CATCH_CATCH_ANON (TestFailureException) {
|
||||
getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr);
|
||||
|
@@ -70,6 +70,7 @@
|
||||
#include <catch2/internal/catch_fatal_condition_handler.hpp>
|
||||
#include <catch2/internal/catch_floating_point_helpers.hpp>
|
||||
#include <catch2/internal/catch_getenv.hpp>
|
||||
#include <catch2/internal/catch_is_permutation.hpp>
|
||||
#include <catch2/internal/catch_istream.hpp>
|
||||
#include <catch2/internal/catch_lazy_expr.hpp>
|
||||
#include <catch2/internal/catch_leak_detector.hpp>
|
||||
|
@@ -7,6 +7,7 @@
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/catch_assertion_result.hpp>
|
||||
#include <catch2/internal/catch_reusable_string_stream.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -26,9 +27,9 @@ namespace Catch {
|
||||
return reconstructedExpression;
|
||||
}
|
||||
|
||||
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
|
||||
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData&& data )
|
||||
: m_info( info ),
|
||||
m_resultData( data )
|
||||
m_resultData( CATCH_MOVE(data) )
|
||||
{}
|
||||
|
||||
// Result was a success
|
||||
@@ -67,16 +68,15 @@ namespace Catch {
|
||||
}
|
||||
|
||||
std::string AssertionResult::getExpressionInMacro() const {
|
||||
std::string expr;
|
||||
if( m_info.macroName.empty() )
|
||||
expr = static_cast<std::string>(m_info.capturedExpression);
|
||||
else {
|
||||
expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
|
||||
expr += m_info.macroName;
|
||||
expr += "( ";
|
||||
expr += m_info.capturedExpression;
|
||||
expr += " )";
|
||||
if ( m_info.macroName.empty() ) {
|
||||
return static_cast<std::string>( m_info.capturedExpression );
|
||||
}
|
||||
std::string expr;
|
||||
expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
|
||||
expr += m_info.macroName;
|
||||
expr += "( ";
|
||||
expr += m_info.capturedExpression;
|
||||
expr += " )";
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ namespace Catch {
|
||||
class AssertionResult {
|
||||
public:
|
||||
AssertionResult() = delete;
|
||||
AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
|
||||
AssertionResult( AssertionInfo const& info, AssertionResultData&& data );
|
||||
|
||||
bool isOk() const;
|
||||
bool succeeded() const;
|
||||
|
@@ -19,8 +19,8 @@ namespace Catch {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ScopedMessage::ScopedMessage( MessageBuilder const& builder ):
|
||||
m_info( builder.m_info ) {
|
||||
ScopedMessage::ScopedMessage( MessageBuilder&& builder ):
|
||||
m_info( CATCH_MOVE(builder.m_info) ) {
|
||||
m_info.message = builder.m_stream.str();
|
||||
getResultCapture().pushScopedMessage( m_info );
|
||||
}
|
||||
|
@@ -39,11 +39,10 @@ namespace Catch {
|
||||
ResultWas::OfType type ):
|
||||
m_info(macroName, lineInfo, type) {}
|
||||
|
||||
|
||||
template<typename T>
|
||||
MessageBuilder& operator << ( T const& value ) {
|
||||
MessageBuilder&& operator << ( T const& value ) && {
|
||||
m_stream << value;
|
||||
return *this;
|
||||
return CATCH_MOVE(*this);
|
||||
}
|
||||
|
||||
MessageInfo m_info;
|
||||
@@ -51,7 +50,7 @@ namespace Catch {
|
||||
|
||||
class ScopedMessage {
|
||||
public:
|
||||
explicit ScopedMessage( MessageBuilder const& builder );
|
||||
explicit ScopedMessage( MessageBuilder&& builder );
|
||||
ScopedMessage( ScopedMessage& duplicate ) = delete;
|
||||
ScopedMessage( ScopedMessage&& old ) noexcept;
|
||||
~ScopedMessage();
|
||||
@@ -98,7 +97,10 @@ namespace Catch {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
|
||||
Catch::Capturer varName( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
|
||||
Catch::Capturer varName( macroName##_catch_sr, \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
Catch::ResultWas::Info, \
|
||||
#__VA_ARGS__##_catch_sr ); \
|
||||
varName.captureValues( 0, __VA_ARGS__ )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -341,6 +341,12 @@ namespace Catch {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ( totals.testCases.total() > 0 &&
|
||||
totals.testCases.total() == totals.testCases.skipped
|
||||
&& !m_config->zeroTestsCountAsSuccess() ) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Note that on unices only the lower 8 bits are usually used, clamping
|
||||
// the return value to 255 prevents false negative when some multiple
|
||||
// of 256 tests has failed
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
@@ -102,6 +103,7 @@
|
||||
#define CATCH_FAIL( ... ) (void)(0)
|
||||
#define CATCH_FAIL_CHECK( ... ) (void)(0)
|
||||
#define CATCH_SUCCEED( ... ) (void)(0)
|
||||
#define CATCH_SKIP( ... ) (void)(0)
|
||||
|
||||
#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
|
||||
#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
|
||||
@@ -146,6 +148,7 @@
|
||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
@@ -198,6 +201,7 @@
|
||||
#define FAIL( ... ) (void)(0)
|
||||
#define FAIL_CHECK( ... ) (void)(0)
|
||||
#define SUCCEED( ... ) (void)(0)
|
||||
#define SKIP( ... ) (void)(0)
|
||||
|
||||
#define STATIC_REQUIRE( ... ) (void)(0)
|
||||
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
|
||||
|
@@ -14,6 +14,7 @@ namespace Catch {
|
||||
diff.passed = passed - other.passed;
|
||||
diff.failed = failed - other.failed;
|
||||
diff.failedButOk = failedButOk - other.failedButOk;
|
||||
diff.skipped = skipped - other.skipped;
|
||||
return diff;
|
||||
}
|
||||
|
||||
@@ -21,14 +22,15 @@ namespace Catch {
|
||||
passed += other.passed;
|
||||
failed += other.failed;
|
||||
failedButOk += other.failedButOk;
|
||||
skipped += other.skipped;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::uint64_t Counts::total() const {
|
||||
return passed + failed + failedButOk;
|
||||
return passed + failed + failedButOk + skipped;
|
||||
}
|
||||
bool Counts::allPassed() const {
|
||||
return failed == 0 && failedButOk == 0;
|
||||
return failed == 0 && failedButOk == 0 && skipped == 0;
|
||||
}
|
||||
bool Counts::allOk() const {
|
||||
return failed == 0;
|
||||
@@ -53,6 +55,8 @@ namespace Catch {
|
||||
++diff.testCases.failed;
|
||||
else if( diff.assertions.failedButOk > 0 )
|
||||
++diff.testCases.failedButOk;
|
||||
else if ( diff.assertions.skipped > 0 )
|
||||
++ diff.testCases.skipped;
|
||||
else
|
||||
++diff.testCases.passed;
|
||||
return diff;
|
||||
|
@@ -23,6 +23,7 @@ namespace Catch {
|
||||
std::uint64_t passed = 0;
|
||||
std::uint64_t failed = 0;
|
||||
std::uint64_t failedButOk = 0;
|
||||
std::uint64_t skipped = 0;
|
||||
};
|
||||
|
||||
struct Totals {
|
||||
|
@@ -36,7 +36,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 2, 1, "", 0 );
|
||||
static Version version( 3, 3, 2, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 2
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
#define CATCH_VERSION_MINOR 3
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
@@ -27,9 +27,16 @@ namespace Detail {
|
||||
|
||||
GeneratorUntypedBase::~GeneratorUntypedBase() = default;
|
||||
|
||||
auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
|
||||
IGeneratorTracker* acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) {
|
||||
return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
|
||||
}
|
||||
|
||||
IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo lineInfo,
|
||||
GeneratorBasePtr&& generator ) {
|
||||
return getResultCapture().createGeneratorTracker(
|
||||
generatorName, lineInfo, CATCH_MOVE( generator ) );
|
||||
}
|
||||
|
||||
} // namespace Generators
|
||||
} // namespace Catch
|
||||
|
@@ -14,7 +14,6 @@
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_unique_name.hpp>
|
||||
#include <catch2/internal/catch_preprocessor.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
@@ -204,37 +203,47 @@ namespace Detail {
|
||||
return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... );
|
||||
}
|
||||
|
||||
auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
|
||||
IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo const& lineInfo );
|
||||
IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo lineInfo,
|
||||
GeneratorBasePtr&& generator );
|
||||
|
||||
template<typename L>
|
||||
// Note: The type after -> is weird, because VS2015 cannot parse
|
||||
// the expression used in the typedef inside, when it is in
|
||||
// return type. Yeah.
|
||||
auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
|
||||
auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type {
|
||||
using UnderlyingType = typename decltype(generatorExpression())::type;
|
||||
|
||||
IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
|
||||
if (!tracker.hasGenerator()) {
|
||||
tracker.setGenerator(Catch::Detail::make_unique<Generators<UnderlyingType>>(generatorExpression()));
|
||||
IGeneratorTracker* tracker = acquireGeneratorTracker( generatorName, lineInfo );
|
||||
// Creation of tracker is delayed after generator creation, so
|
||||
// that constructing generator can fail without breaking everything.
|
||||
if (!tracker) {
|
||||
tracker = createGeneratorTracker(
|
||||
generatorName,
|
||||
lineInfo,
|
||||
Catch::Detail::make_unique<Generators<UnderlyingType>>(
|
||||
generatorExpression() ) );
|
||||
}
|
||||
|
||||
auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
|
||||
auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker->getGenerator() );
|
||||
return generator.get();
|
||||
}
|
||||
|
||||
} // namespace Generators
|
||||
} // namespace Catch
|
||||
|
||||
#define CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL( ... ) #__VA_ARGS__##_catch_sr
|
||||
#define CATCH_INTERNAL_GENERATOR_STRINGIZE(...) CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL(__VA_ARGS__)
|
||||
|
||||
#define GENERATE( ... ) \
|
||||
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
[ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||
#define GENERATE_COPY( ... ) \
|
||||
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
[=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||
#define GENERATE_REF( ... ) \
|
||||
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
[&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_result_type.hpp>
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -33,16 +34,29 @@ namespace Catch {
|
||||
template <typename Duration = std::chrono::duration<double, std::nano>>
|
||||
struct BenchmarkStats;
|
||||
|
||||
namespace Generators {
|
||||
class GeneratorUntypedBase;
|
||||
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
|
||||
}
|
||||
|
||||
|
||||
class IResultCapture {
|
||||
public:
|
||||
virtual ~IResultCapture();
|
||||
|
||||
virtual bool sectionStarted( SectionInfo const& sectionInfo,
|
||||
Counts& assertions ) = 0;
|
||||
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
|
||||
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
|
||||
virtual bool sectionStarted( StringRef sectionName,
|
||||
SourceLineInfo const& sectionLineInfo,
|
||||
Counts& assertions ) = 0;
|
||||
virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0;
|
||||
virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0;
|
||||
|
||||
virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
|
||||
virtual IGeneratorTracker*
|
||||
acquireGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo const& lineInfo ) = 0;
|
||||
virtual IGeneratorTracker*
|
||||
createGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo lineInfo,
|
||||
Generators::GeneratorBasePtr&& generator ) = 0;
|
||||
|
||||
virtual void benchmarkPreparing( StringRef name ) = 0;
|
||||
virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
|
||||
@@ -52,7 +66,7 @@ namespace Catch {
|
||||
virtual void pushScopedMessage( MessageInfo const& message ) = 0;
|
||||
virtual void popScopedMessage( MessageInfo const& message ) = 0;
|
||||
|
||||
virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
|
||||
virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0;
|
||||
|
||||
virtual void handleFatalErrorCondition( StringRef message ) = 0;
|
||||
|
||||
|
@@ -60,18 +60,17 @@ namespace Catch {
|
||||
// Copy message into messages list.
|
||||
// !TBD This should have been done earlier, somewhere
|
||||
MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
|
||||
builder << assertionResult.getMessage();
|
||||
builder.m_info.message = builder.m_stream.str();
|
||||
builder.m_info.message = static_cast<std::string>(assertionResult.getMessage());
|
||||
|
||||
infoMessages.push_back( builder.m_info );
|
||||
infoMessages.push_back( CATCH_MOVE(builder.m_info) );
|
||||
}
|
||||
}
|
||||
|
||||
SectionStats::SectionStats( SectionInfo const& _sectionInfo,
|
||||
SectionStats::SectionStats( SectionInfo&& _sectionInfo,
|
||||
Counts const& _assertions,
|
||||
double _durationInSeconds,
|
||||
bool _missingAssertions )
|
||||
: sectionInfo( _sectionInfo ),
|
||||
: sectionInfo( CATCH_MOVE(_sectionInfo) ),
|
||||
assertions( _assertions ),
|
||||
durationInSeconds( _durationInSeconds ),
|
||||
missingAssertions( _missingAssertions )
|
||||
@@ -80,13 +79,13 @@ namespace Catch {
|
||||
|
||||
TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
|
||||
Totals const& _totals,
|
||||
std::string const& _stdOut,
|
||||
std::string const& _stdErr,
|
||||
std::string&& _stdOut,
|
||||
std::string&& _stdErr,
|
||||
bool _aborting )
|
||||
: testInfo( &_testInfo ),
|
||||
totals( _totals ),
|
||||
stdOut( _stdOut ),
|
||||
stdErr( _stdErr ),
|
||||
stdOut( CATCH_MOVE(_stdOut) ),
|
||||
stdErr( CATCH_MOVE(_stdErr) ),
|
||||
aborting( _aborting )
|
||||
{}
|
||||
|
||||
|
@@ -78,7 +78,7 @@ namespace Catch {
|
||||
};
|
||||
|
||||
struct SectionStats {
|
||||
SectionStats( SectionInfo const& _sectionInfo,
|
||||
SectionStats( SectionInfo&& _sectionInfo,
|
||||
Counts const& _assertions,
|
||||
double _durationInSeconds,
|
||||
bool _missingAssertions );
|
||||
@@ -92,8 +92,8 @@ namespace Catch {
|
||||
struct TestCaseStats {
|
||||
TestCaseStats( TestCaseInfo const& _testInfo,
|
||||
Totals const& _totals,
|
||||
std::string const& _stdOut,
|
||||
std::string const& _stdErr,
|
||||
std::string&& _stdOut,
|
||||
std::string&& _stdErr,
|
||||
bool _aborting );
|
||||
|
||||
TestCaseInfo const * testInfo;
|
||||
@@ -242,7 +242,12 @@ namespace Catch {
|
||||
*/
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
||||
|
||||
//! Called with test cases that are skipped due to the test run aborting
|
||||
/**
|
||||
* Called with test cases that are skipped due to the test run aborting.
|
||||
* NOT called for test cases that are explicitly skipped using the `SKIP` macro.
|
||||
*
|
||||
* Deprecated - will be removed in the next major release.
|
||||
*/
|
||||
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
|
||||
|
||||
//! Called if a fatal error (signal/structured exception) occured
|
||||
|
@@ -50,6 +50,13 @@ namespace Catch {
|
||||
if (m_reaction.shouldThrow) {
|
||||
throw_test_failure_exception();
|
||||
}
|
||||
if ( m_reaction.shouldSkip ) {
|
||||
#if !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS )
|
||||
throw Catch::TestSkipException();
|
||||
#else
|
||||
CATCH_ERROR( "Explicitly skipping tests during runtime requires exceptions" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
void AssertionHandler::setCompleted() {
|
||||
m_completed = true;
|
||||
|
@@ -22,6 +22,7 @@ namespace Catch {
|
||||
struct AssertionReaction {
|
||||
bool shouldDebugBreak = false;
|
||||
bool shouldThrow = false;
|
||||
bool shouldSkip = false;
|
||||
};
|
||||
|
||||
class AssertionHandler {
|
||||
|
@@ -41,7 +41,7 @@
|
||||
|
||||
// Only GCC compiler should be used in this block, so other compilers trying to
|
||||
// mask themselves as GCC should be ignored.
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) && !defined(__NVCOMPILER)
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
|
||||
|
||||
@@ -60,10 +60,21 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__NVCOMPILER)
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "diag push" )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "diag pop" )
|
||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress declared_but_not_referenced" )
|
||||
#endif
|
||||
|
||||
#if defined(__CUDACC__) && !defined(__clang__)
|
||||
# ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
|
||||
// New pragmas introduced in CUDA 11.5+
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
|
||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
|
||||
# else
|
||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress 177" )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// clang-cl defines _MSC_VER as well as __clang__, which could cause the
|
||||
@@ -181,8 +192,14 @@
|
||||
// Visual C++
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
|
||||
// We want to defer to nvcc-specific warning suppression if we are compiled
|
||||
// with nvcc masquerading for MSVC.
|
||||
# if !defined( __CUDACC__ )
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
__pragma( warning( push ) )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
__pragma( warning( pop ) )
|
||||
# endif
|
||||
|
||||
// Universal Windows platform does not support SEH
|
||||
// Or console colours (or console at all...)
|
||||
|
@@ -47,6 +47,7 @@ namespace Catch {
|
||||
|
||||
Error = BrightRed,
|
||||
Success = Green,
|
||||
Skip = LightGrey,
|
||||
|
||||
OriginalExpression = Cyan,
|
||||
ReconstructedExpression = BrightYellow,
|
||||
|
@@ -19,7 +19,10 @@ namespace Catch {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
|
||||
#elif defined(__aarch64__)
|
||||
#define CATCH_TRAP() __asm__(".inst 0xd43e0000")
|
||||
#define CATCH_TRAP() __asm__(".inst 0xd43e0000")
|
||||
#elif defined(__POWERPC__)
|
||||
#define CATCH_TRAP() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ) /* NOLINT */
|
||||
#endif
|
||||
|
||||
#elif defined(CATCH_PLATFORM_IPHONE)
|
||||
|
@@ -44,6 +44,9 @@ namespace Catch {
|
||||
catch( TestFailureException& ) {
|
||||
std::rethrow_exception(std::current_exception());
|
||||
}
|
||||
catch( TestSkipException& ) {
|
||||
std::rethrow_exception(std::current_exception());
|
||||
}
|
||||
catch( std::exception const& ex ) {
|
||||
return ex.what();
|
||||
}
|
||||
|
138
src/catch2/internal/catch_is_permutation.hpp
Normal file
138
src/catch2/internal/catch_is_permutation.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#ifndef CATCH_IS_PERMUTATION_HPP_INCLUDED
|
||||
#define CATCH_IS_PERMUTATION_HPP_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
|
||||
template <typename ForwardIter,
|
||||
typename Sentinel,
|
||||
typename T,
|
||||
typename Comparator>
|
||||
ForwardIter find_sentinel( ForwardIter start,
|
||||
Sentinel sentinel,
|
||||
T const& value,
|
||||
Comparator cmp ) {
|
||||
while ( start != sentinel ) {
|
||||
if ( cmp( *start, value ) ) { break; }
|
||||
++start;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
template <typename ForwardIter,
|
||||
typename Sentinel,
|
||||
typename T,
|
||||
typename Comparator>
|
||||
std::ptrdiff_t count_sentinel( ForwardIter start,
|
||||
Sentinel sentinel,
|
||||
T const& value,
|
||||
Comparator cmp ) {
|
||||
std::ptrdiff_t count = 0;
|
||||
while ( start != sentinel ) {
|
||||
if ( cmp( *start, value ) ) { ++count; }
|
||||
++start;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename ForwardIter, typename Sentinel>
|
||||
std::enable_if_t<!std::is_same<ForwardIter, Sentinel>::value,
|
||||
std::ptrdiff_t>
|
||||
sentinel_distance( ForwardIter iter, const Sentinel sentinel ) {
|
||||
std::ptrdiff_t dist = 0;
|
||||
while ( iter != sentinel ) {
|
||||
++iter;
|
||||
++dist;
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
template <typename ForwardIter>
|
||||
std::ptrdiff_t sentinel_distance( ForwardIter first,
|
||||
ForwardIter last ) {
|
||||
return std::distance( first, last );
|
||||
}
|
||||
|
||||
template <typename ForwardIter1,
|
||||
typename Sentinel1,
|
||||
typename ForwardIter2,
|
||||
typename Sentinel2,
|
||||
typename Comparator>
|
||||
bool check_element_counts( ForwardIter1 first_1,
|
||||
const Sentinel1 end_1,
|
||||
ForwardIter2 first_2,
|
||||
const Sentinel2 end_2,
|
||||
Comparator cmp ) {
|
||||
auto cursor = first_1;
|
||||
while ( cursor != end_1 ) {
|
||||
if ( find_sentinel( first_1, cursor, *cursor, cmp ) ==
|
||||
cursor ) {
|
||||
// we haven't checked this element yet
|
||||
const auto count_in_range_2 =
|
||||
count_sentinel( first_2, end_2, *cursor, cmp );
|
||||
// Not a single instance in 2nd range, so it cannot be a
|
||||
// permutation of 1st range
|
||||
if ( count_in_range_2 == 0 ) { return false; }
|
||||
|
||||
const auto count_in_range_1 =
|
||||
count_sentinel( cursor, end_1, *cursor, cmp );
|
||||
if ( count_in_range_1 != count_in_range_2 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
++cursor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ForwardIter1,
|
||||
typename Sentinel1,
|
||||
typename ForwardIter2,
|
||||
typename Sentinel2,
|
||||
typename Comparator>
|
||||
bool is_permutation( ForwardIter1 first_1,
|
||||
const Sentinel1 end_1,
|
||||
ForwardIter2 first_2,
|
||||
const Sentinel2 end_2,
|
||||
Comparator cmp ) {
|
||||
// TODO: no optimization for stronger iterators, because we would also have to constrain on sentinel vs not sentinel types
|
||||
// TODO: Comparator has to be "both sides", e.g. a == b => b == a
|
||||
// This skips shared prefix of the two ranges
|
||||
while (first_1 != end_1 && first_2 != end_2 && cmp(*first_1, *first_2)) {
|
||||
++first_1;
|
||||
++first_2;
|
||||
}
|
||||
|
||||
// We need to handle case where at least one of the ranges has no more elements
|
||||
if (first_1 == end_1 || first_2 == end_2) {
|
||||
return first_1 == end_1 && first_2 == end_2;
|
||||
}
|
||||
|
||||
// pair counting is n**2, so we pay linear walk to compare the sizes first
|
||||
auto dist_1 = sentinel_distance( first_1, end_1 );
|
||||
auto dist_2 = sentinel_distance( first_2, end_2 );
|
||||
|
||||
if (dist_1 != dist_2) { return false; }
|
||||
|
||||
// Since we do not try to handle stronger iterators pair (e.g.
|
||||
// bidir) optimally, the only thing left to do is to check counts in
|
||||
// the remaining ranges.
|
||||
return check_element_counts( first_1, end_1, first_2, end_2, cmp );
|
||||
}
|
||||
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_IS_PERMUTATION_HPP_INCLUDED
|
@@ -6,12 +6,12 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#include <catch2/internal/catch_parse_numbers.hpp>
|
||||
|
||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||
#include <catch2/internal/catch_parse_numbers.hpp>
|
||||
#include <catch2/internal/catch_string_manip.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -39,11 +39,14 @@ namespace Catch {
|
||||
return {};
|
||||
}
|
||||
return static_cast<unsigned int>(ret);
|
||||
} CATCH_CATCH_ANON( std::exception const& ) {
|
||||
// There was a larger issue with the input, e.g. the parsed
|
||||
// number would be too large to fit within ull.
|
||||
return {};
|
||||
}
|
||||
CATCH_CATCH_ANON( std::invalid_argument const& ) {
|
||||
// no conversion could be performed
|
||||
}
|
||||
CATCH_CATCH_ANON( std::out_of_range const& ) {
|
||||
// the input does not fit into an unsigned long long
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Catch
|
||||
|
@@ -16,6 +16,8 @@ namespace Catch {
|
||||
Ok = 0,
|
||||
Info = 1,
|
||||
Warning = 2,
|
||||
// TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit?
|
||||
ExplicitSkip = 4,
|
||||
|
||||
FailureBit = 0x10,
|
||||
|
||||
|
@@ -29,12 +29,12 @@ namespace Catch {
|
||||
struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
|
||||
GeneratorBasePtr m_generator;
|
||||
|
||||
GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( nameAndLocation, ctx, parent )
|
||||
GeneratorTracker( TestCaseTracking::NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent )
|
||||
{}
|
||||
~GeneratorTracker() override;
|
||||
|
||||
static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
|
||||
static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocationRef const& nameAndLocation ) {
|
||||
GeneratorTracker* tracker;
|
||||
|
||||
ITracker& currentTracker = ctx.currentTracker();
|
||||
@@ -61,18 +61,14 @@ namespace Catch {
|
||||
assert( childTracker->isGeneratorTracker() );
|
||||
tracker = static_cast<GeneratorTracker*>( childTracker );
|
||||
} else {
|
||||
auto newTracker =
|
||||
Catch::Detail::make_unique<GeneratorTracker>(
|
||||
nameAndLocation, ctx, ¤tTracker );
|
||||
tracker = newTracker.get();
|
||||
currentTracker.addChild( CATCH_MOVE(newTracker) );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( !tracker->isComplete() ) {
|
||||
tracker->open();
|
||||
}
|
||||
|
||||
return *tracker;
|
||||
return tracker;
|
||||
}
|
||||
|
||||
// TrackerBase interface
|
||||
@@ -141,6 +137,7 @@ namespace Catch {
|
||||
// has a side-effect, where it consumes generator's current
|
||||
// value, but we do not want to invoke the side-effect if
|
||||
// this generator is still waiting for any child to start.
|
||||
assert( m_generator && "Tracker without generator" );
|
||||
if ( should_wait_for_child ||
|
||||
( m_runState == CompletedSuccessfully &&
|
||||
m_generator->countedNext() ) ) {
|
||||
@@ -179,13 +176,8 @@ namespace Catch {
|
||||
Totals RunContext::runTest(TestCaseHandle const& testCase) {
|
||||
const Totals prevTotals = m_totals;
|
||||
|
||||
std::string redirectedCout;
|
||||
std::string redirectedCerr;
|
||||
|
||||
auto const& testInfo = testCase.getTestCaseInfo();
|
||||
|
||||
m_reporter->testCaseStarting(testInfo);
|
||||
|
||||
m_activeTestCase = &testCase;
|
||||
|
||||
|
||||
@@ -227,9 +219,11 @@ namespace Catch {
|
||||
seedRng( *m_config );
|
||||
|
||||
uint64_t testRuns = 0;
|
||||
std::string redirectedCout;
|
||||
std::string redirectedCerr;
|
||||
do {
|
||||
m_trackerContext.startCycle();
|
||||
m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
|
||||
m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocationRef(testInfo.name, testInfo.lineInfo));
|
||||
|
||||
m_reporter->testCasePartialStarting(testInfo, testRuns);
|
||||
|
||||
@@ -240,7 +234,7 @@ namespace Catch {
|
||||
redirectedCerr += oneRunCerr;
|
||||
|
||||
const auto singleRunTotals = m_totals.delta(beforeRunTotals);
|
||||
auto statsForOneRun = TestCaseStats(testInfo, singleRunTotals, oneRunCout, oneRunCerr, aborting());
|
||||
auto statsForOneRun = TestCaseStats(testInfo, singleRunTotals, CATCH_MOVE(oneRunCout), CATCH_MOVE(oneRunCerr), aborting());
|
||||
|
||||
m_reporter->testCasePartialEnded(statsForOneRun, testRuns);
|
||||
++testRuns;
|
||||
@@ -255,8 +249,8 @@ namespace Catch {
|
||||
m_totals.testCases += deltaTotals.testCases;
|
||||
m_reporter->testCaseEnded(TestCaseStats(testInfo,
|
||||
deltaTotals,
|
||||
redirectedCout,
|
||||
redirectedCerr,
|
||||
CATCH_MOVE(redirectedCout),
|
||||
CATCH_MOVE(redirectedCerr),
|
||||
aborting()));
|
||||
|
||||
m_activeTestCase = nullptr;
|
||||
@@ -270,6 +264,9 @@ namespace Catch {
|
||||
if (result.getResultType() == ResultWas::Ok) {
|
||||
m_totals.assertions.passed++;
|
||||
m_lastAssertionPassed = true;
|
||||
} else if (result.getResultType() == ResultWas::ExplicitSkip) {
|
||||
m_totals.assertions.skipped++;
|
||||
m_lastAssertionPassed = true;
|
||||
} else if (!result.succeeded()) {
|
||||
m_lastAssertionPassed = false;
|
||||
if (result.isOk()) {
|
||||
@@ -297,12 +294,17 @@ namespace Catch {
|
||||
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
|
||||
}
|
||||
|
||||
bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
|
||||
ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
|
||||
bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) {
|
||||
ITracker& sectionTracker =
|
||||
SectionTracker::acquire( m_trackerContext,
|
||||
TestCaseTracking::NameAndLocationRef(
|
||||
sectionName, sectionLineInfo ) );
|
||||
|
||||
if (!sectionTracker.isOpen())
|
||||
return false;
|
||||
m_activeSections.push_back(§ionTracker);
|
||||
|
||||
SectionInfo sectionInfo( sectionLineInfo, static_cast<std::string>(sectionName) );
|
||||
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
|
||||
|
||||
m_reporter->sectionStarting(sectionInfo);
|
||||
@@ -311,14 +313,39 @@ namespace Catch {
|
||||
|
||||
return true;
|
||||
}
|
||||
auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
|
||||
IGeneratorTracker*
|
||||
RunContext::acquireGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo const& lineInfo ) {
|
||||
using namespace Generators;
|
||||
GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
|
||||
TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
|
||||
GeneratorTracker* tracker = GeneratorTracker::acquire(
|
||||
m_trackerContext,
|
||||
TestCaseTracking::NameAndLocationRef(
|
||||
generatorName, lineInfo ) );
|
||||
m_lastAssertionInfo.lineInfo = lineInfo;
|
||||
return tracker;
|
||||
}
|
||||
|
||||
IGeneratorTracker* RunContext::createGeneratorTracker(
|
||||
StringRef generatorName,
|
||||
SourceLineInfo lineInfo,
|
||||
Generators::GeneratorBasePtr&& generator ) {
|
||||
|
||||
auto nameAndLoc = TestCaseTracking::NameAndLocation( static_cast<std::string>( generatorName ), lineInfo );
|
||||
auto& currentTracker = m_trackerContext.currentTracker();
|
||||
assert(
|
||||
currentTracker.nameAndLocation() != nameAndLoc &&
|
||||
"Trying to create tracker for a genreator that already has one" );
|
||||
|
||||
auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>(
|
||||
CATCH_MOVE(nameAndLoc), m_trackerContext, ¤tTracker );
|
||||
auto ret = newTracker.get();
|
||||
currentTracker.addChild( CATCH_MOVE( newTracker ) );
|
||||
|
||||
ret->setGenerator( CATCH_MOVE( generator ) );
|
||||
ret->open();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RunContext::testForMissingAssertions(Counts& assertions) {
|
||||
if (assertions.total() != 0)
|
||||
return false;
|
||||
@@ -331,7 +358,7 @@ namespace Catch {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
|
||||
void RunContext::sectionEnded(SectionEndInfo&& endInfo) {
|
||||
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
|
||||
bool missingAssertions = testForMissingAssertions(assertions);
|
||||
|
||||
@@ -340,19 +367,20 @@ namespace Catch {
|
||||
m_activeSections.pop_back();
|
||||
}
|
||||
|
||||
m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
|
||||
m_reporter->sectionEnded(SectionStats(CATCH_MOVE(endInfo.sectionInfo), assertions, endInfo.durationInSeconds, missingAssertions));
|
||||
m_messages.clear();
|
||||
m_messageScopes.clear();
|
||||
}
|
||||
|
||||
void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
|
||||
if (m_unfinishedSections.empty())
|
||||
void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) {
|
||||
if ( m_unfinishedSections.empty() ) {
|
||||
m_activeSections.back()->fail();
|
||||
else
|
||||
} else {
|
||||
m_activeSections.back()->close();
|
||||
}
|
||||
m_activeSections.pop_back();
|
||||
|
||||
m_unfinishedSections.push_back(endInfo);
|
||||
m_unfinishedSections.push_back(CATCH_MOVE(endInfo));
|
||||
}
|
||||
|
||||
void RunContext::benchmarkPreparing( StringRef name ) {
|
||||
@@ -376,8 +404,8 @@ namespace Catch {
|
||||
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
|
||||
}
|
||||
|
||||
void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
|
||||
m_messageScopes.emplace_back( builder );
|
||||
void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) {
|
||||
m_messageScopes.emplace_back( CATCH_MOVE(builder) );
|
||||
}
|
||||
|
||||
std::string RunContext::getCurrentTestName() const {
|
||||
@@ -402,7 +430,7 @@ namespace Catch {
|
||||
// Instead, fake a result data.
|
||||
AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
|
||||
tempResult.message = static_cast<std::string>(message);
|
||||
AssertionResult result(m_lastAssertionInfo, tempResult);
|
||||
AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult));
|
||||
|
||||
assertionEnded(result);
|
||||
|
||||
@@ -414,7 +442,7 @@ namespace Catch {
|
||||
|
||||
Counts assertions;
|
||||
assertions.failed = 1;
|
||||
SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
|
||||
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, 0, false);
|
||||
m_reporter->sectionEnded(testCaseSectionStats);
|
||||
|
||||
auto const& testInfo = m_activeTestCase->getTestCaseInfo();
|
||||
@@ -475,6 +503,8 @@ namespace Catch {
|
||||
duration = timer.getElapsedSeconds();
|
||||
} CATCH_CATCH_ANON (TestFailureException&) {
|
||||
// This just means the test was aborted due to failure
|
||||
} CATCH_CATCH_ANON (TestSkipException&) {
|
||||
// This just means the test was explicitly skipped
|
||||
} CATCH_CATCH_ALL {
|
||||
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
|
||||
// are reported without translation at the point of origin.
|
||||
@@ -491,7 +521,7 @@ namespace Catch {
|
||||
m_messages.clear();
|
||||
m_messageScopes.clear();
|
||||
|
||||
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
||||
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions);
|
||||
m_reporter->sectionEnded(testCaseSectionStats);
|
||||
}
|
||||
|
||||
@@ -515,7 +545,7 @@ namespace Catch {
|
||||
itEnd = m_unfinishedSections.rend();
|
||||
it != itEnd;
|
||||
++it)
|
||||
sectionEnded(*it);
|
||||
sectionEnded(CATCH_MOVE(*it));
|
||||
m_unfinishedSections.clear();
|
||||
}
|
||||
|
||||
@@ -551,7 +581,7 @@ namespace Catch {
|
||||
m_lastAssertionInfo = info;
|
||||
AssertionResultData data( resultType, LazyExpression( negated ) );
|
||||
|
||||
AssertionResult assertionResult{ info, data };
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
|
||||
assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
|
||||
|
||||
assertionEnded( assertionResult );
|
||||
@@ -569,10 +599,16 @@ namespace Catch {
|
||||
|
||||
AssertionResultData data( resultType, LazyExpression( false ) );
|
||||
data.message = static_cast<std::string>(message);
|
||||
AssertionResult assertionResult{ m_lastAssertionInfo, data };
|
||||
AssertionResult assertionResult{ m_lastAssertionInfo,
|
||||
CATCH_MOVE( data ) };
|
||||
assertionEnded( assertionResult );
|
||||
if( !assertionResult.isOk() )
|
||||
if ( !assertionResult.isOk() ) {
|
||||
populateReaction( reaction );
|
||||
} else if ( resultType == ResultWas::ExplicitSkip ) {
|
||||
// TODO: Need to handle this explicitly, as ExplicitSkip is
|
||||
// considered "OK"
|
||||
reaction.shouldSkip = true;
|
||||
}
|
||||
}
|
||||
void RunContext::handleUnexpectedExceptionNotThrown(
|
||||
AssertionInfo const& info,
|
||||
@@ -590,7 +626,7 @@ namespace Catch {
|
||||
|
||||
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
|
||||
data.message = message;
|
||||
AssertionResult assertionResult{ info, data };
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE(data) };
|
||||
assertionEnded( assertionResult );
|
||||
populateReaction( reaction );
|
||||
}
|
||||
@@ -603,11 +639,12 @@ namespace Catch {
|
||||
void RunContext::handleIncomplete(
|
||||
AssertionInfo const& info
|
||||
) {
|
||||
using namespace std::string_literals;
|
||||
m_lastAssertionInfo = info;
|
||||
|
||||
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
|
||||
data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
|
||||
AssertionResult assertionResult{ info, data };
|
||||
data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"s;
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
|
||||
assertionEnded( assertionResult );
|
||||
}
|
||||
void RunContext::handleNonExpr(
|
||||
@@ -618,7 +655,7 @@ namespace Catch {
|
||||
m_lastAssertionInfo = info;
|
||||
|
||||
AssertionResultData data( resultType, LazyExpression( false ) );
|
||||
AssertionResult assertionResult{ info, data };
|
||||
AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
|
||||
assertionEnded( assertionResult );
|
||||
|
||||
if( !assertionResult.isOk() )
|
||||
|
@@ -68,12 +68,21 @@ namespace Catch {
|
||||
ResultWas::OfType resultType,
|
||||
AssertionReaction &reaction ) override;
|
||||
|
||||
bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
|
||||
bool sectionStarted( StringRef sectionName,
|
||||
SourceLineInfo const& sectionLineInfo,
|
||||
Counts& assertions ) override;
|
||||
|
||||
void sectionEnded( SectionEndInfo const& endInfo ) override;
|
||||
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
|
||||
void sectionEnded( SectionEndInfo&& endInfo ) override;
|
||||
void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
|
||||
|
||||
IGeneratorTracker*
|
||||
acquireGeneratorTracker( StringRef generatorName,
|
||||
SourceLineInfo const& lineInfo ) override;
|
||||
IGeneratorTracker* createGeneratorTracker(
|
||||
StringRef generatorName,
|
||||
SourceLineInfo lineInfo,
|
||||
Generators::GeneratorBasePtr&& generator ) override;
|
||||
|
||||
auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
|
||||
|
||||
void benchmarkPreparing( StringRef name ) override;
|
||||
void benchmarkStarting( BenchmarkInfo const& info ) override;
|
||||
@@ -83,7 +92,7 @@ namespace Catch {
|
||||
void pushScopedMessage( MessageInfo const& message ) override;
|
||||
void popScopedMessage( MessageInfo const& message ) override;
|
||||
|
||||
void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
|
||||
void emplaceUnscopedMessage( MessageBuilder&& builder ) override;
|
||||
|
||||
std::string getCurrentTestName() const override;
|
||||
|
||||
|
@@ -15,7 +15,7 @@ namespace Catch {
|
||||
Section::Section( SectionInfo&& info ):
|
||||
m_info( CATCH_MOVE( info ) ),
|
||||
m_sectionIncluded(
|
||||
getResultCapture().sectionStarted( m_info, m_assertions ) ) {
|
||||
getResultCapture().sectionStarted( m_info.name, m_info.lineInfo, m_assertions ) ) {
|
||||
// Non-"included" sections will not use the timing information
|
||||
// anyway, so don't bother with the potential syscall.
|
||||
if (m_sectionIncluded) {
|
||||
@@ -23,13 +23,31 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
Section::Section( SourceLineInfo const& _lineInfo,
|
||||
StringRef _name,
|
||||
const char* const ):
|
||||
m_info( { "invalid", static_cast<std::size_t>( -1 ) }, std::string{} ),
|
||||
m_sectionIncluded(
|
||||
getResultCapture().sectionStarted( _name, _lineInfo, m_assertions ) ) {
|
||||
// We delay initialization the SectionInfo member until we know
|
||||
// this section needs it, so we avoid allocating std::string for name.
|
||||
// We also delay timer start to avoid the potential syscall unless we
|
||||
// will actually use the result.
|
||||
if ( m_sectionIncluded ) {
|
||||
m_info.name = static_cast<std::string>( _name );
|
||||
m_info.lineInfo = _lineInfo;
|
||||
m_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
Section::~Section() {
|
||||
if( m_sectionIncluded ) {
|
||||
SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
|
||||
if( uncaught_exceptions() )
|
||||
getResultCapture().sectionEndedEarly( endInfo );
|
||||
else
|
||||
getResultCapture().sectionEnded( endInfo );
|
||||
SectionEndInfo endInfo{ CATCH_MOVE(m_info), m_assertions, m_timer.getElapsedSeconds() };
|
||||
if ( uncaught_exceptions() ) {
|
||||
getResultCapture().sectionEndedEarly( CATCH_MOVE(endInfo) );
|
||||
} else {
|
||||
getResultCapture().sectionEnded( CATCH_MOVE( endInfo ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,9 @@ namespace Catch {
|
||||
class Section : Detail::NonCopyable {
|
||||
public:
|
||||
Section( SectionInfo&& info );
|
||||
Section( SourceLineInfo const& _lineInfo,
|
||||
StringRef _name,
|
||||
const char* const = nullptr );
|
||||
~Section();
|
||||
|
||||
// This indicates whether the section should be executed or not
|
||||
@@ -38,7 +41,7 @@ namespace Catch {
|
||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
|
@@ -17,10 +17,6 @@ namespace Catch {
|
||||
: StringRef( rawChars, std::strlen(rawChars) )
|
||||
{}
|
||||
|
||||
auto StringRef::operator == ( StringRef other ) const noexcept -> bool {
|
||||
return m_size == other.m_size
|
||||
&& (std::memcmp( m_start, other.m_start, m_size ) == 0);
|
||||
}
|
||||
|
||||
bool StringRef::operator<(StringRef rhs) const noexcept {
|
||||
if (m_size < rhs.m_size) {
|
||||
|
@@ -13,6 +13,8 @@
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
/// A non-owning string class (similar to the forthcoming std::string_view)
|
||||
@@ -49,7 +51,10 @@ namespace Catch {
|
||||
}
|
||||
|
||||
public: // operators
|
||||
auto operator == ( StringRef other ) const noexcept -> bool;
|
||||
auto operator == ( StringRef other ) const noexcept -> bool {
|
||||
return m_size == other.m_size
|
||||
&& (std::memcmp( m_start, other.m_start, m_size ) == 0);
|
||||
}
|
||||
auto operator != (StringRef other) const noexcept -> bool {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
@@ -181,7 +181,7 @@
|
||||
void reg_tests() { \
|
||||
size_t index = 0; \
|
||||
using expander = size_t[]; \
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
|
||||
} \
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
|
||||
@@ -316,7 +316,7 @@
|
||||
void reg_tests(){\
|
||||
size_t index = 0;\
|
||||
using expander = size_t[];\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
|
@@ -22,8 +22,8 @@
|
||||
namespace Catch {
|
||||
namespace TestCaseTracking {
|
||||
|
||||
NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
|
||||
: name( _name ),
|
||||
NameAndLocation::NameAndLocation( std::string&& _name, SourceLineInfo const& _location )
|
||||
: name( CATCH_MOVE(_name) ),
|
||||
location( _location )
|
||||
{}
|
||||
|
||||
@@ -38,14 +38,17 @@ namespace TestCaseTracking {
|
||||
m_children.push_back( CATCH_MOVE(child) );
|
||||
}
|
||||
|
||||
ITracker* ITracker::findChild( NameAndLocation const& nameAndLocation ) {
|
||||
ITracker* ITracker::findChild( NameAndLocationRef const& nameAndLocation ) {
|
||||
auto it = std::find_if(
|
||||
m_children.begin(),
|
||||
m_children.end(),
|
||||
[&nameAndLocation]( ITrackerPtr const& tracker ) {
|
||||
return tracker->nameAndLocation().location ==
|
||||
nameAndLocation.location &&
|
||||
tracker->nameAndLocation().name == nameAndLocation.name;
|
||||
auto const& tnameAndLoc = tracker->nameAndLocation();
|
||||
if ( tnameAndLoc.location.line !=
|
||||
nameAndLocation.location.line ) {
|
||||
return false;
|
||||
}
|
||||
return tnameAndLoc == nameAndLocation;
|
||||
} );
|
||||
return ( it != m_children.end() ) ? it->get() : nullptr;
|
||||
}
|
||||
@@ -53,10 +56,6 @@ namespace TestCaseTracking {
|
||||
bool ITracker::isSectionTracker() const { return false; }
|
||||
bool ITracker::isGeneratorTracker() const { return false; }
|
||||
|
||||
bool ITracker::isSuccessfullyCompleted() const {
|
||||
return m_runState == CompletedSuccessfully;
|
||||
}
|
||||
|
||||
bool ITracker::isOpen() const {
|
||||
return m_runState != NotStarted && !isComplete();
|
||||
}
|
||||
@@ -83,16 +82,6 @@ namespace TestCaseTracking {
|
||||
return *m_rootTracker;
|
||||
}
|
||||
|
||||
void TrackerContext::endRun() {
|
||||
m_rootTracker.reset();
|
||||
m_currentTracker = nullptr;
|
||||
m_runState = NotStarted;
|
||||
}
|
||||
|
||||
void TrackerContext::startCycle() {
|
||||
m_currentTracker = m_rootTracker.get();
|
||||
m_runState = Executing;
|
||||
}
|
||||
void TrackerContext::completeCycle() {
|
||||
m_runState = CompletedCycle;
|
||||
}
|
||||
@@ -100,16 +89,13 @@ namespace TestCaseTracking {
|
||||
bool TrackerContext::completedCycle() const {
|
||||
return m_runState == CompletedCycle;
|
||||
}
|
||||
ITracker& TrackerContext::currentTracker() {
|
||||
return *m_currentTracker;
|
||||
}
|
||||
void TrackerContext::setCurrentTracker( ITracker* tracker ) {
|
||||
m_currentTracker = tracker;
|
||||
}
|
||||
|
||||
|
||||
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
|
||||
ITracker(nameAndLocation, parent),
|
||||
TrackerBase::TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
|
||||
ITracker(CATCH_MOVE(nameAndLocation), parent),
|
||||
m_ctx( ctx )
|
||||
{}
|
||||
|
||||
@@ -169,13 +155,14 @@ namespace TestCaseTracking {
|
||||
m_ctx.setCurrentTracker( this );
|
||||
}
|
||||
|
||||
SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( nameAndLocation, ctx, parent ),
|
||||
m_trimmed_name(trim(nameAndLocation.name))
|
||||
SectionTracker::SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent ),
|
||||
m_trimmed_name(trim(StringRef(ITracker::nameAndLocation().name)))
|
||||
{
|
||||
if( parent ) {
|
||||
while( !parent->isSectionTracker() )
|
||||
while ( !parent->isSectionTracker() ) {
|
||||
parent = parent->parent();
|
||||
}
|
||||
|
||||
SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
|
||||
addNextFilters( parentSection.m_filters );
|
||||
@@ -195,24 +182,30 @@ namespace TestCaseTracking {
|
||||
|
||||
bool SectionTracker::isSectionTracker() const { return true; }
|
||||
|
||||
SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
|
||||
SectionTracker* section;
|
||||
SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocationRef const& nameAndLocation ) {
|
||||
SectionTracker* tracker;
|
||||
|
||||
ITracker& currentTracker = ctx.currentTracker();
|
||||
if ( ITracker* childTracker =
|
||||
currentTracker.findChild( nameAndLocation ) ) {
|
||||
assert( childTracker );
|
||||
assert( childTracker->isSectionTracker() );
|
||||
section = static_cast<SectionTracker*>( childTracker );
|
||||
tracker = static_cast<SectionTracker*>( childTracker );
|
||||
} else {
|
||||
auto newSection = Catch::Detail::make_unique<SectionTracker>(
|
||||
nameAndLocation, ctx, ¤tTracker );
|
||||
section = newSection.get();
|
||||
currentTracker.addChild( CATCH_MOVE( newSection ) );
|
||||
auto newTracker = Catch::Detail::make_unique<SectionTracker>(
|
||||
NameAndLocation{ static_cast<std::string>(nameAndLocation.name),
|
||||
nameAndLocation.location },
|
||||
ctx,
|
||||
¤tTracker );
|
||||
tracker = newTracker.get();
|
||||
currentTracker.addChild( CATCH_MOVE( newTracker ) );
|
||||
}
|
||||
if( !ctx.completedCycle() )
|
||||
section->tryOpen();
|
||||
return *section;
|
||||
|
||||
if ( !ctx.completedCycle() ) {
|
||||
tracker->tryOpen();
|
||||
}
|
||||
|
||||
return *tracker;
|
||||
}
|
||||
|
||||
void SectionTracker::tryOpen() {
|
||||
@@ -233,10 +226,6 @@ namespace TestCaseTracking {
|
||||
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
|
||||
}
|
||||
|
||||
std::vector<StringRef> const& SectionTracker::getFilters() const {
|
||||
return m_filters;
|
||||
}
|
||||
|
||||
StringRef SectionTracker::trimmedName() const {
|
||||
return m_trimmed_name;
|
||||
}
|
||||
|
@@ -22,10 +22,49 @@ namespace TestCaseTracking {
|
||||
std::string name;
|
||||
SourceLineInfo location;
|
||||
|
||||
NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
|
||||
NameAndLocation( std::string&& _name, SourceLineInfo const& _location );
|
||||
friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
|
||||
return lhs.name == rhs.name
|
||||
&& lhs.location == rhs.location;
|
||||
// This is a very cheap check that should have a very high hit rate.
|
||||
// If we get to SourceLineInfo::operator==, we will redo it, but the
|
||||
// cost of repeating is trivial at that point (we will be paying
|
||||
// multiple strcmp/memcmps at that point).
|
||||
if ( lhs.location.line != rhs.location.line ) { return false; }
|
||||
return lhs.name == rhs.name && lhs.location == rhs.location;
|
||||
}
|
||||
friend bool operator!=(NameAndLocation const& lhs,
|
||||
NameAndLocation const& rhs) {
|
||||
return !( lhs == rhs );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a variant of `NameAndLocation` that does not own the name string
|
||||
*
|
||||
* This avoids extra allocations when trying to locate a tracker by its
|
||||
* name and location, as long as we make sure that trackers only keep
|
||||
* around the owning variant.
|
||||
*/
|
||||
struct NameAndLocationRef {
|
||||
StringRef name;
|
||||
SourceLineInfo location;
|
||||
|
||||
constexpr NameAndLocationRef( StringRef name_,
|
||||
SourceLineInfo location_ ):
|
||||
name( name_ ), location( location_ ) {}
|
||||
|
||||
friend bool operator==( NameAndLocation const& lhs,
|
||||
NameAndLocationRef const& rhs ) {
|
||||
// This is a very cheap check that should have a very high hit rate.
|
||||
// If we get to SourceLineInfo::operator==, we will redo it, but the
|
||||
// cost of repeating is trivial at that point (we will be paying
|
||||
// multiple strcmp/memcmps at that point).
|
||||
if ( lhs.location.line != rhs.location.line ) { return false; }
|
||||
return StringRef( lhs.name ) == rhs.name &&
|
||||
lhs.location == rhs.location;
|
||||
}
|
||||
friend bool operator==( NameAndLocationRef const& lhs,
|
||||
NameAndLocation const& rhs ) {
|
||||
return rhs == lhs;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,8 +92,8 @@ namespace TestCaseTracking {
|
||||
CycleState m_runState = NotStarted;
|
||||
|
||||
public:
|
||||
ITracker( NameAndLocation const& nameAndLoc, ITracker* parent ):
|
||||
m_nameAndLocation( nameAndLoc ),
|
||||
ITracker( NameAndLocation&& nameAndLoc, ITracker* parent ):
|
||||
m_nameAndLocation( CATCH_MOVE(nameAndLoc) ),
|
||||
m_parent( parent )
|
||||
{}
|
||||
|
||||
@@ -75,7 +114,9 @@ namespace TestCaseTracking {
|
||||
//! Returns true if tracker run to completion (successfully or not)
|
||||
virtual bool isComplete() const = 0;
|
||||
//! Returns true if tracker run to completion succesfully
|
||||
bool isSuccessfullyCompleted() const;
|
||||
bool isSuccessfullyCompleted() const {
|
||||
return m_runState == CompletedSuccessfully;
|
||||
}
|
||||
//! Returns true if tracker has started but hasn't been completed
|
||||
bool isOpen() const;
|
||||
//! Returns true iff tracker has started
|
||||
@@ -93,7 +134,7 @@ namespace TestCaseTracking {
|
||||
*
|
||||
* Returns nullptr if not found.
|
||||
*/
|
||||
ITracker* findChild( NameAndLocation const& nameAndLocation );
|
||||
ITracker* findChild( NameAndLocationRef const& nameAndLocation );
|
||||
//! Have any children been added?
|
||||
bool hasChildren() const {
|
||||
return !m_children.empty();
|
||||
@@ -134,13 +175,15 @@ namespace TestCaseTracking {
|
||||
public:
|
||||
|
||||
ITracker& startRun();
|
||||
void endRun();
|
||||
|
||||
void startCycle();
|
||||
void startCycle() {
|
||||
m_currentTracker = m_rootTracker.get();
|
||||
m_runState = Executing;
|
||||
}
|
||||
void completeCycle();
|
||||
|
||||
bool completedCycle() const;
|
||||
ITracker& currentTracker();
|
||||
ITracker& currentTracker() { return *m_currentTracker; }
|
||||
void setCurrentTracker( ITracker* tracker );
|
||||
};
|
||||
|
||||
@@ -150,7 +193,7 @@ namespace TestCaseTracking {
|
||||
TrackerContext& m_ctx;
|
||||
|
||||
public:
|
||||
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
||||
TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
||||
|
||||
bool isComplete() const override;
|
||||
|
||||
@@ -166,22 +209,26 @@ namespace TestCaseTracking {
|
||||
|
||||
class SectionTracker : public TrackerBase {
|
||||
std::vector<StringRef> m_filters;
|
||||
std::string m_trimmed_name;
|
||||
// Note that lifetime-wise we piggy back off the name stored in the `ITracker` parent`.
|
||||
// Currently it allocates owns the name, so this is safe. If it is later refactored
|
||||
// to not own the name, the name still has to outlive the `ITracker` parent, so
|
||||
// this should still be safe.
|
||||
StringRef m_trimmed_name;
|
||||
public:
|
||||
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
||||
SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
||||
|
||||
bool isSectionTracker() const override;
|
||||
|
||||
bool isComplete() const override;
|
||||
|
||||
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
|
||||
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocationRef const& nameAndLocation );
|
||||
|
||||
void tryOpen();
|
||||
|
||||
void addInitialFilters( std::vector<std::string> const& filters );
|
||||
void addNextFilters( std::vector<StringRef> const& filters );
|
||||
//! Returns filters active in this tracker
|
||||
std::vector<StringRef> const& getFilters() const;
|
||||
std::vector<StringRef> const& getFilters() const { return m_filters; }
|
||||
//! Returns whitespace-trimmed name of the tracked section
|
||||
StringRef trimmedName() const;
|
||||
};
|
||||
|
@@ -20,6 +20,9 @@ namespace Catch {
|
||||
*/
|
||||
[[noreturn]] void throw_test_failure_exception();
|
||||
|
||||
//! Used to signal that the remainder of a test should be skipped
|
||||
struct TestSkipException{};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
|
||||
|
@@ -23,9 +23,9 @@
|
||||
#if !defined(CATCH_CONFIG_DISABLE)
|
||||
|
||||
#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
|
||||
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
|
||||
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__##_catch_sr
|
||||
#else
|
||||
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
|
||||
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"_catch_sr
|
||||
#endif
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
|
||||
|
@@ -78,7 +78,7 @@ struct AutoReg : Detail::NonCopyable {
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||
namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
static void TestName()
|
||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||
@@ -89,7 +89,13 @@ struct AutoReg : Detail::NonCopyable {
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||
namespace { \
|
||||
const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
|
||||
Catch::makeTestInvoker( &QualifiedMethod ), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
"&" #QualifiedMethod##_catch_sr, \
|
||||
Catch::NameAndTags{ __VA_ARGS__ } ); \
|
||||
} /* NOLINT */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -101,7 +107,11 @@ struct AutoReg : Detail::NonCopyable {
|
||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
|
||||
void test(); \
|
||||
}; \
|
||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||
const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
|
||||
Catch::makeTestInvoker( &TestName::test ), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
#ClassName##_catch_sr, \
|
||||
Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||
} \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
void TestName::test()
|
||||
|
@@ -221,10 +221,8 @@ namespace Catch {
|
||||
token.erase(token.begin());
|
||||
if (m_exclusion) {
|
||||
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::TagPattern>(".", m_substring));
|
||||
m_currentFilter.m_forbidden.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||
} else {
|
||||
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::TagPattern>(".", m_substring));
|
||||
m_currentFilter.m_required.emplace_back(Detail::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||
}
|
||||
}
|
||||
if (m_exclusion) {
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <catch2/internal/catch_enforce.hpp>
|
||||
#include <catch2/internal/catch_xmlwriter.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <type_traits>
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include <catch2/matchers/catch_matchers_predicate.hpp>
|
||||
#include <catch2/matchers/catch_matchers_quantifiers.hpp>
|
||||
#include <catch2/matchers/catch_matchers_range_equals.hpp>
|
||||
#include <catch2/matchers/catch_matchers_string.hpp>
|
||||
#include <catch2/matchers/catch_matchers_templated.hpp>
|
||||
#include <catch2/matchers/catch_matchers_vector.hpp>
|
||||
|
@@ -33,13 +33,11 @@ namespace Catch {
|
||||
}
|
||||
|
||||
template <typename RangeLike>
|
||||
bool match(RangeLike&& rng) const {
|
||||
using std::begin; using std::end;
|
||||
|
||||
return end(rng) != std::find_if(begin(rng), end(rng),
|
||||
[&](auto const& elem) {
|
||||
return m_eq(elem, m_desired);
|
||||
});
|
||||
bool match( RangeLike&& rng ) const {
|
||||
for ( auto&& elem : rng ) {
|
||||
if ( m_eq( elem, m_desired ) ) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -91,7 +89,7 @@ namespace Catch {
|
||||
/**
|
||||
* Creates a matcher that checks whether a range contains a specific element.
|
||||
*
|
||||
* Uses `eq` to do the comparisons
|
||||
* Uses `eq` to do the comparisons, the element is provided on the rhs
|
||||
*/
|
||||
template <typename T, typename Equality>
|
||||
ContainsElementMatcher<T, Equality> Contains(T&& elem, Equality&& eq) {
|
||||
|
@@ -29,6 +29,32 @@ public:
|
||||
//! Creates a matcher that checks whether a std derived exception has the provided message
|
||||
ExceptionMessageMatcher Message(std::string const& message);
|
||||
|
||||
template <typename StringMatcherType>
|
||||
class ExceptionMessageMatchesMatcher final
|
||||
: public MatcherBase<std::exception> {
|
||||
StringMatcherType m_matcher;
|
||||
|
||||
public:
|
||||
ExceptionMessageMatchesMatcher( StringMatcherType matcher ):
|
||||
m_matcher( CATCH_MOVE( matcher ) ) {}
|
||||
|
||||
bool match( std::exception const& ex ) const override {
|
||||
return m_matcher.match( ex.what() );
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return " matches \"" + m_matcher.describe() + '"';
|
||||
}
|
||||
};
|
||||
|
||||
//! Creates a matcher that checks whether a message from an std derived
|
||||
//! exception matches a provided matcher
|
||||
template <typename StringMatcherType>
|
||||
ExceptionMessageMatchesMatcher<StringMatcherType>
|
||||
MessageMatches( StringMatcherType&& matcher ) {
|
||||
return { CATCH_FORWARD( matcher ) };
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
|
@@ -225,5 +225,17 @@ WithinRelMatcher WithinRel(float target) {
|
||||
}
|
||||
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
bool IsNaNMatcher::match( double const& matchee ) const {
|
||||
return std::isnan( matchee );
|
||||
}
|
||||
|
||||
std::string IsNaNMatcher::describe() const {
|
||||
using namespace std::string_literals;
|
||||
return "is NaN"s;
|
||||
}
|
||||
|
||||
IsNaNMatcher IsNaN() { return IsNaNMatcher(); }
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
@@ -27,6 +27,11 @@ namespace Matchers {
|
||||
double m_margin;
|
||||
};
|
||||
|
||||
//! Creates a matcher that accepts numbers within certain range of target
|
||||
WithinAbsMatcher WithinAbs( double target, double margin );
|
||||
|
||||
|
||||
|
||||
class WithinUlpsMatcher final : public MatcherBase<double> {
|
||||
public:
|
||||
WithinUlpsMatcher( double target,
|
||||
@@ -40,6 +45,13 @@ namespace Matchers {
|
||||
Detail::FloatingPointKind m_type;
|
||||
};
|
||||
|
||||
//! Creates a matcher that accepts doubles within certain ULP range of target
|
||||
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
|
||||
//! Creates a matcher that accepts floats within certain ULP range of target
|
||||
WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
|
||||
|
||||
|
||||
|
||||
// Given IEEE-754 format for floats and doubles, we can assume
|
||||
// that float -> double promotion is lossless. Given this, we can
|
||||
// assume that if we do the standard relative comparison of
|
||||
@@ -56,13 +68,6 @@ namespace Matchers {
|
||||
double m_epsilon;
|
||||
};
|
||||
|
||||
//! Creates a matcher that accepts doubles within certain ULP range of target
|
||||
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
|
||||
//! Creates a matcher that accepts floats within certain ULP range of target
|
||||
WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
|
||||
//! Creates a matcher that accepts numbers within certain range of target
|
||||
WithinAbsMatcher WithinAbs(double target, double margin);
|
||||
|
||||
//! Creates a matcher that accepts doubles within certain relative range of target
|
||||
WithinRelMatcher WithinRel(double target, double eps);
|
||||
//! Creates a matcher that accepts doubles within 100*DBL_EPS relative range of target
|
||||
@@ -72,6 +77,17 @@ namespace Matchers {
|
||||
//! Creates a matcher that accepts floats within 100*FLT_EPS relative range of target
|
||||
WithinRelMatcher WithinRel(float target);
|
||||
|
||||
|
||||
|
||||
class IsNaNMatcher final : public MatcherBase<double> {
|
||||
public:
|
||||
IsNaNMatcher() = default;
|
||||
bool match( double const& matchee ) const override;
|
||||
std::string describe() const override;
|
||||
};
|
||||
|
||||
IsNaNMatcher IsNaN();
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
|
144
src/catch2/matchers/catch_matchers_range_equals.hpp
Normal file
144
src/catch2/matchers/catch_matchers_range_equals.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
|
||||
#define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_is_permutation.hpp>
|
||||
#include <catch2/matchers/catch_matchers_templated.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
/**
|
||||
* Matcher for checking that an element contains the same
|
||||
* elements in the same order
|
||||
*/
|
||||
template <typename TargetRangeLike, typename Equality>
|
||||
class RangeEqualsMatcher final : public MatcherGenericBase {
|
||||
TargetRangeLike m_desired;
|
||||
Equality m_predicate;
|
||||
|
||||
public:
|
||||
template <typename TargetRangeLike2, typename Equality2>
|
||||
RangeEqualsMatcher( TargetRangeLike2&& range,
|
||||
Equality2&& predicate ):
|
||||
m_desired( CATCH_FORWARD( range ) ),
|
||||
m_predicate( CATCH_FORWARD( predicate ) ) {}
|
||||
|
||||
template <typename RangeLike>
|
||||
bool match( RangeLike&& rng ) const {
|
||||
auto rng_start = begin( rng );
|
||||
const auto rng_end = end( rng );
|
||||
auto target_start = begin( m_desired );
|
||||
const auto target_end = end( m_desired );
|
||||
|
||||
while (rng_start != rng_end && target_start != target_end) {
|
||||
if (!m_predicate(*rng_start, *target_start)) {
|
||||
return false;
|
||||
}
|
||||
++rng_start;
|
||||
++target_start;
|
||||
}
|
||||
return rng_start == rng_end && target_start == target_end;
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return "elements are " + Catch::Detail::stringify( m_desired );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher for checking that an element contains the same
|
||||
* elements (but not necessarily in the same order)
|
||||
*/
|
||||
template <typename TargetRangeLike, typename Equality>
|
||||
class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
|
||||
TargetRangeLike m_desired;
|
||||
Equality m_predicate;
|
||||
|
||||
public:
|
||||
template <typename TargetRangeLike2, typename Equality2>
|
||||
UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
|
||||
Equality2&& predicate ):
|
||||
m_desired( CATCH_FORWARD( range ) ),
|
||||
m_predicate( CATCH_FORWARD( predicate ) ) {}
|
||||
|
||||
template <typename RangeLike>
|
||||
bool match( RangeLike&& rng ) const {
|
||||
using std::begin;
|
||||
using std::end;
|
||||
return Catch::Detail::is_permutation( begin( m_desired ),
|
||||
end( m_desired ),
|
||||
begin( rng ),
|
||||
end( rng ),
|
||||
m_predicate );
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return "unordered elements are " +
|
||||
::Catch::Detail::stringify( m_desired );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a matcher that checks if all elements in a range are equal
|
||||
* to all elements in another range.
|
||||
*
|
||||
* Uses `std::equal_to` to do the comparison
|
||||
*/
|
||||
template <typename RangeLike>
|
||||
std::enable_if_t<!Detail::is_matcher<RangeLike>::value,
|
||||
RangeEqualsMatcher<RangeLike, std::equal_to<>>>
|
||||
RangeEquals( RangeLike&& range ) {
|
||||
return { CATCH_FORWARD( range ), std::equal_to<>{} };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that checks if all elements in a range are equal
|
||||
* to all elements in another range.
|
||||
*
|
||||
* Uses to provided predicate `predicate` to do the comparisons
|
||||
*/
|
||||
template <typename RangeLike, typename Equality>
|
||||
RangeEqualsMatcher<RangeLike, Equality>
|
||||
RangeEquals( RangeLike&& range, Equality&& predicate ) {
|
||||
return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that checks if all elements in a range are equal
|
||||
* to all elements in another range, in some permutation
|
||||
*
|
||||
* Uses `std::equal_to` to do the comparison
|
||||
*/
|
||||
template <typename RangeLike>
|
||||
std::enable_if_t<
|
||||
!Detail::is_matcher<RangeLike>::value,
|
||||
UnorderedRangeEqualsMatcher<RangeLike, std::equal_to<>>>
|
||||
UnorderedRangeEquals( RangeLike&& range ) {
|
||||
return { CATCH_FORWARD( range ), std::equal_to<>{} };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that checks if all elements in a range are equal
|
||||
* to all elements in another range, in some permuation.
|
||||
*
|
||||
* Uses to provided predicate `predicate` to do the comparisons
|
||||
*/
|
||||
template <typename RangeLike, typename Equality>
|
||||
UnorderedRangeEqualsMatcher<RangeLike, Equality>
|
||||
UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) {
|
||||
return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
|
||||
}
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
|
@@ -93,6 +93,7 @@ internal_headers = [
|
||||
'internal/catch_floating_point_helpers.hpp',
|
||||
'internal/catch_getenv.hpp',
|
||||
'internal/catch_istream.hpp',
|
||||
'internal/catch_is_permutation.hpp',
|
||||
'internal/catch_lazy_expr.hpp',
|
||||
'internal/catch_leak_detector.hpp',
|
||||
'internal/catch_list.hpp',
|
||||
|
@@ -17,7 +17,9 @@ namespace Catch {
|
||||
void AutomakeReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
|
||||
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
|
||||
m_stream << ":test-result: ";
|
||||
if (_testCaseStats.totals.assertions.allPassed()) {
|
||||
if ( _testCaseStats.totals.testCases.skipped > 0 ) {
|
||||
m_stream << "SKIP";
|
||||
} else if (_testCaseStats.totals.assertions.allPassed()) {
|
||||
m_stream << "PASS";
|
||||
} else if (_testCaseStats.totals.assertions.allOk()) {
|
||||
m_stream << "XFAIL";
|
||||
|
@@ -105,6 +105,11 @@ public:
|
||||
printIssue("explicitly");
|
||||
printRemainingMessages(Colour::None);
|
||||
break;
|
||||
case ResultWas::ExplicitSkip:
|
||||
printResultType(Colour::Skip, "skipped"_sr);
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
@@ -187,7 +192,7 @@ private:
|
||||
private:
|
||||
std::ostream& stream;
|
||||
AssertionResult const& result;
|
||||
std::vector<MessageInfo> messages;
|
||||
std::vector<MessageInfo> const& messages;
|
||||
std::vector<MessageInfo>::const_iterator itMessage;
|
||||
bool printInfoMessages;
|
||||
ColourImpl* colourImpl;
|
||||
@@ -220,7 +225,7 @@ private:
|
||||
|
||||
// Drop out if result was successful and we're not printing those
|
||||
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
|
||||
if( result.getResultType() != ResultWas::Warning )
|
||||
if( result.getResultType() != ResultWas::Warning && result.getResultType() != ResultWas::ExplicitSkip )
|
||||
return;
|
||||
printInfoMessages = false;
|
||||
}
|
||||
|
@@ -51,7 +51,6 @@ public:
|
||||
stats(_stats),
|
||||
result(_stats.assertionResult),
|
||||
colour(Colour::None),
|
||||
message(result.getMessage()),
|
||||
messages(_stats.infoMessages),
|
||||
colourImpl(colourImpl_),
|
||||
printInfoMessages(_printInfoMessages) {
|
||||
@@ -60,10 +59,10 @@ public:
|
||||
colour = Colour::Success;
|
||||
passOrFail = "PASSED"_sr;
|
||||
//if( result.hasMessage() )
|
||||
if (_stats.infoMessages.size() == 1)
|
||||
messageLabel = "with message";
|
||||
if (_stats.infoMessages.size() > 1)
|
||||
messageLabel = "with messages";
|
||||
if (messages.size() == 1)
|
||||
messageLabel = "with message"_sr;
|
||||
if (messages.size() > 1)
|
||||
messageLabel = "with messages"_sr;
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
if (result.isOk()) {
|
||||
@@ -73,43 +72,57 @@ public:
|
||||
colour = Colour::Error;
|
||||
passOrFail = "FAILED"_sr;
|
||||
}
|
||||
if (_stats.infoMessages.size() == 1)
|
||||
messageLabel = "with message";
|
||||
if (_stats.infoMessages.size() > 1)
|
||||
messageLabel = "with messages";
|
||||
if (messages.size() == 1)
|
||||
messageLabel = "with message"_sr;
|
||||
if (messages.size() > 1)
|
||||
messageLabel = "with messages"_sr;
|
||||
break;
|
||||
case ResultWas::ThrewException:
|
||||
colour = Colour::Error;
|
||||
passOrFail = "FAILED"_sr;
|
||||
messageLabel = "due to unexpected exception with ";
|
||||
if (_stats.infoMessages.size() == 1)
|
||||
messageLabel += "message";
|
||||
if (_stats.infoMessages.size() > 1)
|
||||
messageLabel += "messages";
|
||||
// todo switch
|
||||
switch (messages.size()) { case 0:
|
||||
messageLabel = "due to unexpected exception with "_sr;
|
||||
break;
|
||||
case 1:
|
||||
messageLabel = "due to unexpected exception with message"_sr;
|
||||
break;
|
||||
default:
|
||||
messageLabel = "due to unexpected exception with messages"_sr;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
colour = Colour::Error;
|
||||
passOrFail = "FAILED"_sr;
|
||||
messageLabel = "due to a fatal error condition";
|
||||
messageLabel = "due to a fatal error condition"_sr;
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
colour = Colour::Error;
|
||||
passOrFail = "FAILED"_sr;
|
||||
messageLabel = "because no exception was thrown where one was expected";
|
||||
messageLabel = "because no exception was thrown where one was expected"_sr;
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
messageLabel = "info";
|
||||
messageLabel = "info"_sr;
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
messageLabel = "warning";
|
||||
messageLabel = "warning"_sr;
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
passOrFail = "FAILED"_sr;
|
||||
colour = Colour::Error;
|
||||
if (_stats.infoMessages.size() == 1)
|
||||
messageLabel = "explicitly with message";
|
||||
if (_stats.infoMessages.size() > 1)
|
||||
messageLabel = "explicitly with messages";
|
||||
if (messages.size() == 1)
|
||||
messageLabel = "explicitly with message"_sr;
|
||||
if (messages.size() > 1)
|
||||
messageLabel = "explicitly with messages"_sr;
|
||||
break;
|
||||
case ResultWas::ExplicitSkip:
|
||||
colour = Colour::Skip;
|
||||
passOrFail = "SKIPPED"_sr;
|
||||
if (messages.size() == 1)
|
||||
messageLabel = "explicitly with message"_sr;
|
||||
if (messages.size() > 1)
|
||||
messageLabel = "explicitly with messages"_sr;
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
@@ -173,9 +186,8 @@ private:
|
||||
AssertionResult const& result;
|
||||
Colour::Code colour;
|
||||
StringRef passOrFail;
|
||||
std::string messageLabel;
|
||||
std::string message;
|
||||
std::vector<MessageInfo> messages;
|
||||
StringRef messageLabel;
|
||||
std::vector<MessageInfo> const& messages;
|
||||
ColourImpl* colourImpl;
|
||||
bool printInfoMessages;
|
||||
};
|
||||
@@ -185,13 +197,16 @@ std::size_t makeRatio( std::uint64_t number, std::uint64_t total ) {
|
||||
return (ratio == 0 && number > 0) ? 1 : static_cast<std::size_t>(ratio);
|
||||
}
|
||||
|
||||
std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
|
||||
if (i > j && i > k)
|
||||
std::size_t&
|
||||
findMax( std::size_t& i, std::size_t& j, std::size_t& k, std::size_t& l ) {
|
||||
if (i > j && i > k && i > l)
|
||||
return i;
|
||||
else if (j > k)
|
||||
else if (j > k && j > l)
|
||||
return j;
|
||||
else
|
||||
else if (k > l)
|
||||
return k;
|
||||
else
|
||||
return l;
|
||||
}
|
||||
|
||||
enum class Justification { Left, Right };
|
||||
@@ -400,7 +415,8 @@ void ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
|
||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if (!includeResults && result.getResultType() != ResultWas::Warning)
|
||||
// TODO: Make configurable whether skips should be printed
|
||||
if (!includeResults && result.getResultType() != ResultWas::Warning && result.getResultType() != ResultWas::ExplicitSkip)
|
||||
return;
|
||||
|
||||
lazyPrint();
|
||||
@@ -603,10 +619,11 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
|
||||
std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
|
||||
std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
|
||||
std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
|
||||
while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
|
||||
findMax(failedRatio, failedButOkRatio, passedRatio)++;
|
||||
std::size_t skippedRatio = makeRatio(totals.testCases.skipped, totals.testCases.total());
|
||||
while (failedRatio + failedButOkRatio + passedRatio + skippedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
|
||||
findMax(failedRatio, failedButOkRatio, passedRatio, skippedRatio)++;
|
||||
while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
|
||||
findMax(failedRatio, failedButOkRatio, passedRatio)--;
|
||||
findMax(failedRatio, failedButOkRatio, passedRatio, skippedRatio)--;
|
||||
|
||||
m_stream << m_colour->guardColour( Colour::Error )
|
||||
<< std::string( failedRatio, '=' )
|
||||
@@ -619,6 +636,8 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
|
||||
m_stream << m_colour->guardColour( Colour::Success )
|
||||
<< std::string( passedRatio, '=' );
|
||||
}
|
||||
m_stream << m_colour->guardColour( Colour::Skip )
|
||||
<< std::string( skippedRatio, '=' );
|
||||
} else {
|
||||
m_stream << m_colour->guardColour( Colour::Warning )
|
||||
<< std::string( CATCH_CONFIG_CONSOLE_WIDTH - 1, '=' );
|
||||
|
@@ -70,7 +70,8 @@ namespace Catch {
|
||||
|
||||
void
|
||||
CumulativeReporterBase::sectionStarting( SectionInfo const& sectionInfo ) {
|
||||
SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
|
||||
// We need a copy, because SectionStats expect to take ownership
|
||||
SectionStats incompleteStats( SectionInfo(sectionInfo), Counts(), 0, false );
|
||||
SectionNode* node;
|
||||
if ( m_sectionStack.empty() ) {
|
||||
if ( !m_rootSection ) {
|
||||
|
@@ -316,15 +316,22 @@ namespace Catch {
|
||||
}
|
||||
|
||||
std::vector<SummaryColumn> columns;
|
||||
// Don't include "skipped assertions" in total count
|
||||
const auto totalAssertionCount =
|
||||
totals.assertions.total() - totals.assertions.skipped;
|
||||
columns.push_back( SummaryColumn( "", Colour::None )
|
||||
.addRow( totals.testCases.total() )
|
||||
.addRow( totals.assertions.total() ) );
|
||||
.addRow( totalAssertionCount ) );
|
||||
columns.push_back( SummaryColumn( "passed", Colour::Success )
|
||||
.addRow( totals.testCases.passed )
|
||||
.addRow( totals.assertions.passed ) );
|
||||
columns.push_back( SummaryColumn( "failed", Colour::ResultError )
|
||||
.addRow( totals.testCases.failed )
|
||||
.addRow( totals.assertions.failed ) );
|
||||
columns.push_back( SummaryColumn( "skipped", Colour::Skip )
|
||||
.addRow( totals.testCases.skipped )
|
||||
// Don't print "skipped assertions"
|
||||
.addRow( 0 ) );
|
||||
columns.push_back(
|
||||
SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
|
||||
.addRow( totals.testCases.failedButOk )
|
||||
|
@@ -132,6 +132,7 @@ namespace Catch {
|
||||
xml.writeAttribute( "name"_sr, stats.runInfo.name );
|
||||
xml.writeAttribute( "errors"_sr, unexpectedExceptions );
|
||||
xml.writeAttribute( "failures"_sr, stats.totals.assertions.failed-unexpectedExceptions );
|
||||
xml.writeAttribute( "skipped"_sr, stats.totals.assertions.skipped );
|
||||
xml.writeAttribute( "tests"_sr, stats.totals.assertions.total() );
|
||||
xml.writeAttribute( "hostname"_sr, "tbd"_sr ); // !TBD
|
||||
if( m_config->showDurations() == ShowDurations::Never )
|
||||
@@ -244,7 +245,8 @@ namespace Catch {
|
||||
|
||||
void JunitReporter::writeAssertion( AssertionStats const& stats ) {
|
||||
AssertionResult const& result = stats.assertionResult;
|
||||
if( !result.isOk() ) {
|
||||
if ( !result.isOk() ||
|
||||
result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
std::string elementName;
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::ThrewException:
|
||||
@@ -256,7 +258,9 @@ namespace Catch {
|
||||
case ResultWas::DidntThrowException:
|
||||
elementName = "failure";
|
||||
break;
|
||||
|
||||
case ResultWas::ExplicitSkip:
|
||||
elementName = "skipped";
|
||||
break;
|
||||
// We should never see these here:
|
||||
case ResultWas::Info:
|
||||
case ResultWas::Warning:
|
||||
@@ -274,7 +278,9 @@ namespace Catch {
|
||||
xml.writeAttribute( "type"_sr, result.getTestMacroName() );
|
||||
|
||||
ReusableStringStream rss;
|
||||
if (stats.totals.assertions.total() > 0) {
|
||||
if ( result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
rss << "SKIPPED\n";
|
||||
} else {
|
||||
rss << "FAILED" << ":\n";
|
||||
if (result.hasExpression()) {
|
||||
rss << " ";
|
||||
@@ -285,8 +291,6 @@ namespace Catch {
|
||||
rss << "with expansion:\n";
|
||||
rss << TextFlow::Column(result.getExpandedExpression()).indent(2) << '\n';
|
||||
}
|
||||
} else {
|
||||
rss << '\n';
|
||||
}
|
||||
|
||||
if( !result.getMessage().empty() )
|
||||
|
@@ -118,7 +118,7 @@ namespace Catch {
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
namespace { \
|
||||
Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
|
||||
catch_internal_RegistrarFor )( #listenerType ); \
|
||||
catch_internal_RegistrarFor )( #listenerType##_catch_sr ); \
|
||||
} \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
|
@@ -40,7 +40,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void SonarQubeReporter::writeRun( TestRunNode const& runNode ) {
|
||||
std::map<std::string, std::vector<TestCaseNode const*>> testsPerFile;
|
||||
std::map<StringRef, std::vector<TestCaseNode const*>> testsPerFile;
|
||||
|
||||
for ( auto const& child : runNode.children ) {
|
||||
testsPerFile[child->value.testInfo->lineInfo.file].push_back(
|
||||
@@ -52,7 +52,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
void SonarQubeReporter::writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes) {
|
||||
void SonarQubeReporter::writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes) {
|
||||
XmlWriter::ScopedElement e = xml.scopedElement("file");
|
||||
xml.writeAttribute("path"_sr, filename);
|
||||
|
||||
@@ -97,7 +97,8 @@ namespace Catch {
|
||||
|
||||
void SonarQubeReporter::writeAssertion(AssertionStats const& stats, bool okToFail) {
|
||||
AssertionResult const& result = stats.assertionResult;
|
||||
if (!result.isOk()) {
|
||||
if ( !result.isOk() ||
|
||||
result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
std::string elementName;
|
||||
if (okToFail) {
|
||||
elementName = "skipped";
|
||||
@@ -108,15 +109,13 @@ namespace Catch {
|
||||
elementName = "error";
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
elementName = "failure";
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
elementName = "failure";
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
elementName = "failure";
|
||||
break;
|
||||
|
||||
case ResultWas::ExplicitSkip:
|
||||
elementName = "skipped";
|
||||
break;
|
||||
// We should never see these here:
|
||||
case ResultWas::Info:
|
||||
case ResultWas::Warning:
|
||||
@@ -136,7 +135,9 @@ namespace Catch {
|
||||
xml.writeAttribute("message"_sr, messageRss.str());
|
||||
|
||||
ReusableStringStream textRss;
|
||||
if (stats.totals.assertions.total() > 0) {
|
||||
if ( result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
textRss << "SKIPPED\n";
|
||||
} else {
|
||||
textRss << "FAILED:\n";
|
||||
if (result.hasExpression()) {
|
||||
textRss << '\t' << result.getExpressionInMacro() << '\n';
|
||||
|
@@ -41,7 +41,7 @@ namespace Catch {
|
||||
|
||||
void writeRun( TestRunNode const& groupNode );
|
||||
|
||||
void writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes);
|
||||
void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes);
|
||||
|
||||
void writeTestCase(TestCaseNode const& testCaseNode);
|
||||
|
||||
|
@@ -100,6 +100,12 @@ namespace Catch {
|
||||
printIssue("explicitly"_sr);
|
||||
printRemainingMessages(Colour::None);
|
||||
break;
|
||||
case ResultWas::ExplicitSkip:
|
||||
printResultType(tapPassedString);
|
||||
printIssue(" # SKIP"_sr);
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
@@ -178,7 +184,7 @@ namespace Catch {
|
||||
private:
|
||||
std::ostream& stream;
|
||||
AssertionResult const& result;
|
||||
std::vector<MessageInfo> messages;
|
||||
std::vector<MessageInfo> const& messages;
|
||||
std::vector<MessageInfo>::const_iterator itMessage;
|
||||
bool printInfoMessages;
|
||||
std::size_t counter;
|
||||
|
@@ -59,7 +59,8 @@ namespace Catch {
|
||||
|
||||
void TeamCityReporter::assertionEnded(AssertionStats const& assertionStats) {
|
||||
AssertionResult const& result = assertionStats.assertionResult;
|
||||
if (!result.isOk()) {
|
||||
if ( !result.isOk() ||
|
||||
result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
|
||||
ReusableStringStream msg;
|
||||
if (!m_headerPrintedForThisSection)
|
||||
@@ -84,6 +85,9 @@ namespace Catch {
|
||||
case ResultWas::ExplicitFailure:
|
||||
msg << "explicit failure";
|
||||
break;
|
||||
case ResultWas::ExplicitSkip:
|
||||
msg << "explicit skip";
|
||||
break;
|
||||
|
||||
// We shouldn't get here because of the isOk() test
|
||||
case ResultWas::Ok:
|
||||
@@ -111,18 +115,16 @@ namespace Catch {
|
||||
" " << result.getExpandedExpression() << '\n';
|
||||
}
|
||||
|
||||
if (currentTestCaseInfo->okToFail()) {
|
||||
if ( result.getResultType() == ResultWas::ExplicitSkip ) {
|
||||
m_stream << "##teamcity[testIgnored";
|
||||
} else if ( currentTestCaseInfo->okToFail() ) {
|
||||
msg << "- failure ignore as test marked as 'ok to fail'\n";
|
||||
m_stream << "##teamcity[testIgnored"
|
||||
<< " name='" << escape(currentTestCaseInfo->name) << '\''
|
||||
<< " message='" << escape(msg.str()) << '\''
|
||||
<< "]\n";
|
||||
m_stream << "##teamcity[testIgnored";
|
||||
} else {
|
||||
m_stream << "##teamcity[testFailed"
|
||||
<< " name='" << escape(currentTestCaseInfo->name) << '\''
|
||||
<< " message='" << escape(msg.str()) << '\''
|
||||
<< "]\n";
|
||||
m_stream << "##teamcity[testFailed";
|
||||
}
|
||||
m_stream << " name='" << escape( currentTestCaseInfo->name ) << '\''
|
||||
<< " message='" << escape( msg.str() ) << '\'' << "]\n";
|
||||
}
|
||||
m_stream.flush();
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ namespace Catch {
|
||||
void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
|
||||
StreamingReporterBase::testCaseStarting(testInfo);
|
||||
m_xml.startElement( "TestCase" )
|
||||
.writeAttribute( "name"_sr, trim( testInfo.name ) )
|
||||
.writeAttribute( "name"_sr, trim( StringRef(testInfo.name) ) )
|
||||
.writeAttribute( "tags"_sr, testInfo.tagsAsString() );
|
||||
|
||||
writeSourceInfo( testInfo.lineInfo );
|
||||
@@ -80,7 +80,7 @@ namespace Catch {
|
||||
StreamingReporterBase::sectionStarting( sectionInfo );
|
||||
if( m_sectionDepth++ > 0 ) {
|
||||
m_xml.startElement( "Section" )
|
||||
.writeAttribute( "name"_sr, trim( sectionInfo.name ) );
|
||||
.writeAttribute( "name"_sr, trim( StringRef(sectionInfo.name) ) );
|
||||
writeSourceInfo( sectionInfo.lineInfo );
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
@@ -108,9 +108,10 @@ namespace Catch {
|
||||
}
|
||||
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if( !includeResults && result.getResultType() != ResultWas::Warning )
|
||||
if ( !includeResults && result.getResultType() != ResultWas::Warning &&
|
||||
result.getResultType() != ResultWas::ExplicitSkip ) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Print the expression if there is one.
|
||||
if( result.hasExpression() ) {
|
||||
@@ -153,6 +154,12 @@ namespace Catch {
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
case ResultWas::ExplicitSkip:
|
||||
m_xml.startElement( "Skip" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -163,15 +170,18 @@ namespace Catch {
|
||||
|
||||
void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
|
||||
StreamingReporterBase::sectionEnded( sectionStats );
|
||||
if( --m_sectionDepth > 0 ) {
|
||||
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
|
||||
e.writeAttribute( "successes"_sr, sectionStats.assertions.passed );
|
||||
e.writeAttribute( "failures"_sr, sectionStats.assertions.failed );
|
||||
e.writeAttribute( "expectedFailures"_sr, sectionStats.assertions.failedButOk );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
e.writeAttribute( "durationInSeconds"_sr, sectionStats.durationInSeconds );
|
||||
if ( --m_sectionDepth > 0 ) {
|
||||
{
|
||||
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
|
||||
e.writeAttribute( "successes"_sr, sectionStats.assertions.passed );
|
||||
e.writeAttribute( "failures"_sr, sectionStats.assertions.failed );
|
||||
e.writeAttribute( "expectedFailures"_sr, sectionStats.assertions.failedButOk );
|
||||
e.writeAttribute( "skipped"_sr, sectionStats.assertions.skipped > 0 );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
e.writeAttribute( "durationInSeconds"_sr, sectionStats.durationInSeconds );
|
||||
}
|
||||
// Ends assertion tag
|
||||
m_xml.endElement();
|
||||
}
|
||||
}
|
||||
@@ -180,14 +190,14 @@ namespace Catch {
|
||||
StreamingReporterBase::testCaseEnded( testCaseStats );
|
||||
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
|
||||
e.writeAttribute( "success"_sr, testCaseStats.totals.assertions.allOk() );
|
||||
e.writeAttribute( "skips"_sr, testCaseStats.totals.assertions.skipped );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
e.writeAttribute( "durationInSeconds"_sr, m_testCaseTimer.getElapsedSeconds() );
|
||||
|
||||
if( !testCaseStats.stdOut.empty() )
|
||||
m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
|
||||
m_xml.scopedElement( "StdOut" ).writeText( trim( StringRef(testCaseStats.stdOut) ), XmlFormatting::Newline );
|
||||
if( !testCaseStats.stdErr.empty() )
|
||||
m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
|
||||
m_xml.scopedElement( "StdErr" ).writeText( trim( StringRef(testCaseStats.stdErr) ), XmlFormatting::Newline );
|
||||
|
||||
m_xml.endElement();
|
||||
}
|
||||
@@ -197,11 +207,13 @@ namespace Catch {
|
||||
m_xml.scopedElement( "OverallResults" )
|
||||
.writeAttribute( "successes"_sr, testRunStats.totals.assertions.passed )
|
||||
.writeAttribute( "failures"_sr, testRunStats.totals.assertions.failed )
|
||||
.writeAttribute( "expectedFailures"_sr, testRunStats.totals.assertions.failedButOk );
|
||||
.writeAttribute( "expectedFailures"_sr, testRunStats.totals.assertions.failedButOk )
|
||||
.writeAttribute( "skips"_sr, testRunStats.totals.assertions.skipped );
|
||||
m_xml.scopedElement( "OverallResultsCases")
|
||||
.writeAttribute( "successes"_sr, testRunStats.totals.testCases.passed )
|
||||
.writeAttribute( "failures"_sr, testRunStats.totals.testCases.failed )
|
||||
.writeAttribute( "expectedFailures"_sr, testRunStats.totals.testCases.failedButOk );
|
||||
.writeAttribute( "expectedFailures"_sr, testRunStats.totals.testCases.failedButOk )
|
||||
.writeAttribute( "skips"_sr, testRunStats.totals.testCases.skipped );
|
||||
m_xml.endElement();
|
||||
}
|
||||
|
||||
|
@@ -77,6 +77,7 @@ endif(MSVC) #Temporary workaround
|
||||
# Please keep these ordered alphabetically
|
||||
set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/TestRegistrations.cpp
|
||||
${SELF_TEST_DIR}/IntrospectiveTests/Algorithms.tests.cpp
|
||||
${SELF_TEST_DIR}/IntrospectiveTests/Clara.tests.cpp
|
||||
${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
|
||||
${SELF_TEST_DIR}/IntrospectiveTests/CmdLineHelpers.tests.cpp
|
||||
@@ -116,6 +117,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/UsageTests/Generators.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/Skip.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/ToStringByte.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
|
||||
${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
|
||||
@@ -133,6 +135,7 @@ set(TEST_SOURCES
|
||||
|
||||
set(TEST_HEADERS
|
||||
${SELF_TEST_DIR}/helpers/parse_test_spec.hpp
|
||||
${SELF_TEST_DIR}/helpers/range_test_helpers.hpp
|
||||
${SELF_TEST_DIR}/helpers/type_with_lit_0_comparisons.hpp
|
||||
)
|
||||
|
||||
@@ -272,6 +275,10 @@ add_test(NAME TestSpecs::OverrideFailureWithNoMatchedTests
|
||||
COMMAND $<TARGET_FILE:SelfTest> "___nonexistent_test___" --allow-running-no-tests
|
||||
)
|
||||
|
||||
add_test(NAME TestSpecs::OverrideAllSkipFailure
|
||||
COMMAND $<TARGET_FILE:SelfTest> "tests can be skipped dynamically at runtime" --allow-running-no-tests
|
||||
)
|
||||
|
||||
add_test(NAME TestSpecs::NonMatchingTestSpecIsRoundTrippable
|
||||
COMMAND $<TARGET_FILE:SelfTest> Tracker, "this test does not exist" "[nor does this tag]"
|
||||
)
|
||||
|
@@ -488,15 +488,32 @@ set_tests_properties(TestSpecs::EmptySpecWithNoTestsFails
|
||||
PROPERTIES
|
||||
WILL_FAIL ON
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME TestSpecs::OverrideFailureWithEmptySpec
|
||||
COMMAND $<TARGET_FILE:NoTests> --allow-running-no-tests
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME List::Listeners::WorksWithoutRegisteredListeners
|
||||
COMMAND $<TARGET_FILE:NoTests> --list-listeners
|
||||
)
|
||||
|
||||
|
||||
add_executable(AllSkipped ${TESTS_DIR}/X93-AllSkipped.cpp)
|
||||
target_link_libraries(AllSkipped PRIVATE Catch2::Catch2WithMain)
|
||||
|
||||
add_test(
|
||||
NAME TestSpecs::SkippingAllTestsFails
|
||||
COMMAND $<TARGET_FILE:AllSkipped>
|
||||
)
|
||||
set_tests_properties(TestSpecs::SkippingAllTestsFails
|
||||
PROPERTIES
|
||||
WILL_FAIL ON
|
||||
)
|
||||
|
||||
set( EXTRA_TEST_BINARIES
|
||||
AllSkipped
|
||||
PrefixedMacros
|
||||
DisabledMacros
|
||||
DisabledExceptions-DefaultHandler
|
||||
|
16
tests/ExtraTests/X93-AllSkipped.cpp
Normal file
16
tests/ExtraTests/X93-AllSkipped.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE( "this test case is being skipped" ) { SKIP(); }
|
||||
|
||||
TEST_CASE( "all sections in this test case are being skipped" ) {
|
||||
SECTION( "A" ) { SKIP(); }
|
||||
SECTION( "B" ) { SKIP(); }
|
||||
}
|
@@ -25,6 +25,7 @@ Nor would this
|
||||
:test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0
|
||||
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - double
|
||||
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - float
|
||||
:test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort
|
||||
:test-result: XFAIL #748 - captures with unexpected exceptions
|
||||
:test-result: PASS #809
|
||||
:test-result: PASS #833
|
||||
@@ -142,6 +143,7 @@ Nor would this
|
||||
:test-result: PASS Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified
|
||||
:test-result: FAIL Exception matchers that fail
|
||||
:test-result: PASS Exception matchers that succeed
|
||||
:test-result: PASS Exception message can be matched
|
||||
:test-result: PASS Exception messages can be tested for
|
||||
:test-result: PASS Exceptions matchers
|
||||
:test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||
@@ -149,6 +151,7 @@ Nor would this
|
||||
:test-result: FAIL FAIL does not require an argument
|
||||
:test-result: FAIL FAIL_CHECK does not abort the test
|
||||
:test-result: PASS Factorials are computed
|
||||
:test-result: PASS Filter generator throws exception for empty generator
|
||||
:test-result: PASS Floating point matchers: double
|
||||
:test-result: PASS Floating point matchers: float
|
||||
:test-result: PASS Generators -- adapters
|
||||
@@ -268,6 +271,7 @@ Message from section two
|
||||
:test-result: FAIL Thrown string literals are translated
|
||||
:test-result: PASS Tracker
|
||||
:test-result: PASS Trim strings
|
||||
:test-result: PASS Type conversions of RangeEquals and similar
|
||||
:test-result: FAIL Unexpected exceptions can be translated
|
||||
:test-result: PASS Upcasting special member functions
|
||||
:test-result: PASS Usage of AllMatch range matcher
|
||||
@@ -276,6 +280,8 @@ Message from section two
|
||||
:test-result: PASS Usage of AnyTrue range matcher
|
||||
:test-result: PASS Usage of NoneMatch range matcher
|
||||
:test-result: PASS Usage of NoneTrue range matcher
|
||||
:test-result: PASS Usage of RangeEquals range matcher
|
||||
:test-result: PASS Usage of UnorderedRangeEquals range matcher
|
||||
:test-result: PASS Usage of the SizeIs range matcher
|
||||
:test-result: PASS Use a custom approx
|
||||
:test-result: PASS Variadic macros
|
||||
@@ -296,6 +302,7 @@ Message from section two
|
||||
:test-result: PASS X/level/1/b
|
||||
:test-result: PASS XmlEncode
|
||||
:test-result: PASS XmlWriter writes boolean attributes as true/false
|
||||
:test-result: SKIP a succeeding test can still be skipped
|
||||
:test-result: PASS analyse no analysis
|
||||
:test-result: PASS array<int, N> -> toString
|
||||
:test-result: PASS benchmark function call
|
||||
@@ -308,10 +315,14 @@ Message from section two
|
||||
:test-result: PASS comparisons between const int variables
|
||||
:test-result: PASS comparisons between int variables
|
||||
:test-result: PASS convertToBits
|
||||
:test-result: SKIP dynamic skipping works with generators
|
||||
:test-result: PASS empty tags are not allowed
|
||||
:test-result: PASS erfc_inv
|
||||
:test-result: PASS estimate_clock_resolution
|
||||
:test-result: PASS even more nested SECTION tests
|
||||
:test-result: XFAIL failed assertions before SKIP cause test case to fail
|
||||
:test-result: XFAIL failing for some generator values causes entire test case to fail
|
||||
:test-result: XFAIL failing in some unskipped sections causes entire test case to fail
|
||||
:test-result: FAIL first tag
|
||||
loose text artifact
|
||||
:test-result: FAIL has printf
|
||||
@@ -330,6 +341,10 @@ loose text artifact
|
||||
:test-result: FAIL mix info, unscoped info and warning
|
||||
:test-result: FAIL more nested SECTION tests
|
||||
:test-result: PASS nested SECTION tests
|
||||
a!
|
||||
b1!
|
||||
!
|
||||
:test-result: FAIL nested sections can be skipped dynamically at runtime
|
||||
:test-result: PASS non streamable - with conv. op
|
||||
:test-result: PASS non-copyable objects
|
||||
:test-result: PASS normal_cdf
|
||||
@@ -351,9 +366,11 @@ loose text artifact
|
||||
:test-result: PASS run_for_at_least, chronometer
|
||||
:test-result: PASS run_for_at_least, int
|
||||
:test-result: FAIL second tag
|
||||
:test-result: SKIP sections can be skipped dynamically at runtime
|
||||
:test-result: FAIL send a single char to INFO
|
||||
:test-result: FAIL sends information to INFO
|
||||
:test-result: PASS shortened hide tags are split apart
|
||||
:test-result: SKIP skipped tests can optionally provide a reason
|
||||
:test-result: PASS splitString
|
||||
:test-result: FAIL stacks unscoped info in loops
|
||||
:test-result: PASS startsWith
|
||||
@@ -375,6 +392,7 @@ loose text artifact
|
||||
:test-result: PASS strlen3
|
||||
:test-result: PASS tables
|
||||
:test-result: PASS tags with dots in later positions are not parsed as hidden
|
||||
:test-result: SKIP tests can be skipped dynamically at runtime
|
||||
:test-result: FAIL thrown std::strings are translated
|
||||
:test-result: PASS toString on const wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on const wchar_t pointer returns the string contents
|
||||
|
@@ -23,6 +23,7 @@
|
||||
:test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0
|
||||
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - double
|
||||
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - float
|
||||
:test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort
|
||||
:test-result: XFAIL #748 - captures with unexpected exceptions
|
||||
:test-result: PASS #809
|
||||
:test-result: PASS #833
|
||||
@@ -140,6 +141,7 @@
|
||||
:test-result: PASS Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified
|
||||
:test-result: FAIL Exception matchers that fail
|
||||
:test-result: PASS Exception matchers that succeed
|
||||
:test-result: PASS Exception message can be matched
|
||||
:test-result: PASS Exception messages can be tested for
|
||||
:test-result: PASS Exceptions matchers
|
||||
:test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||
@@ -147,6 +149,7 @@
|
||||
:test-result: FAIL FAIL does not require an argument
|
||||
:test-result: FAIL FAIL_CHECK does not abort the test
|
||||
:test-result: PASS Factorials are computed
|
||||
:test-result: PASS Filter generator throws exception for empty generator
|
||||
:test-result: PASS Floating point matchers: double
|
||||
:test-result: PASS Floating point matchers: float
|
||||
:test-result: PASS Generators -- adapters
|
||||
@@ -261,6 +264,7 @@
|
||||
:test-result: FAIL Thrown string literals are translated
|
||||
:test-result: PASS Tracker
|
||||
:test-result: PASS Trim strings
|
||||
:test-result: PASS Type conversions of RangeEquals and similar
|
||||
:test-result: FAIL Unexpected exceptions can be translated
|
||||
:test-result: PASS Upcasting special member functions
|
||||
:test-result: PASS Usage of AllMatch range matcher
|
||||
@@ -269,6 +273,8 @@
|
||||
:test-result: PASS Usage of AnyTrue range matcher
|
||||
:test-result: PASS Usage of NoneMatch range matcher
|
||||
:test-result: PASS Usage of NoneTrue range matcher
|
||||
:test-result: PASS Usage of RangeEquals range matcher
|
||||
:test-result: PASS Usage of UnorderedRangeEquals range matcher
|
||||
:test-result: PASS Usage of the SizeIs range matcher
|
||||
:test-result: PASS Use a custom approx
|
||||
:test-result: PASS Variadic macros
|
||||
@@ -289,6 +295,7 @@
|
||||
:test-result: PASS X/level/1/b
|
||||
:test-result: PASS XmlEncode
|
||||
:test-result: PASS XmlWriter writes boolean attributes as true/false
|
||||
:test-result: SKIP a succeeding test can still be skipped
|
||||
:test-result: PASS analyse no analysis
|
||||
:test-result: PASS array<int, N> -> toString
|
||||
:test-result: PASS benchmark function call
|
||||
@@ -301,10 +308,14 @@
|
||||
:test-result: PASS comparisons between const int variables
|
||||
:test-result: PASS comparisons between int variables
|
||||
:test-result: PASS convertToBits
|
||||
:test-result: SKIP dynamic skipping works with generators
|
||||
:test-result: PASS empty tags are not allowed
|
||||
:test-result: PASS erfc_inv
|
||||
:test-result: PASS estimate_clock_resolution
|
||||
:test-result: PASS even more nested SECTION tests
|
||||
:test-result: XFAIL failed assertions before SKIP cause test case to fail
|
||||
:test-result: XFAIL failing for some generator values causes entire test case to fail
|
||||
:test-result: XFAIL failing in some unskipped sections causes entire test case to fail
|
||||
:test-result: FAIL first tag
|
||||
:test-result: FAIL has printf
|
||||
:test-result: PASS is_unary_function
|
||||
@@ -322,6 +333,7 @@
|
||||
:test-result: FAIL mix info, unscoped info and warning
|
||||
:test-result: FAIL more nested SECTION tests
|
||||
:test-result: PASS nested SECTION tests
|
||||
:test-result: FAIL nested sections can be skipped dynamically at runtime
|
||||
:test-result: PASS non streamable - with conv. op
|
||||
:test-result: PASS non-copyable objects
|
||||
:test-result: PASS normal_cdf
|
||||
@@ -343,9 +355,11 @@
|
||||
:test-result: PASS run_for_at_least, chronometer
|
||||
:test-result: PASS run_for_at_least, int
|
||||
:test-result: FAIL second tag
|
||||
:test-result: SKIP sections can be skipped dynamically at runtime
|
||||
:test-result: FAIL send a single char to INFO
|
||||
:test-result: FAIL sends information to INFO
|
||||
:test-result: PASS shortened hide tags are split apart
|
||||
:test-result: SKIP skipped tests can optionally provide a reason
|
||||
:test-result: PASS splitString
|
||||
:test-result: FAIL stacks unscoped info in loops
|
||||
:test-result: PASS startsWith
|
||||
@@ -367,6 +381,7 @@
|
||||
:test-result: PASS strlen3
|
||||
:test-result: PASS tables
|
||||
:test-result: PASS tags with dots in later positions are not parsed as hidden
|
||||
:test-result: SKIP tests can be skipped dynamically at runtime
|
||||
:test-result: FAIL thrown std::strings are translated
|
||||
:test-result: PASS toString on const wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on const wchar_t pointer returns the string contents
|
||||
|
@@ -84,6 +84,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smalles
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00])
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
|
||||
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
||||
@@ -572,6 +573,10 @@ Matchers.tests.cpp:<line number>: failed: throwsSpecialException( 3 ), SpecialEx
|
||||
Matchers.tests.cpp:<line number>: failed: throwsSpecialException( 4 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 1 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 2 ), SpecialException, ExceptionMatcher{ 2 } for: SpecialException::what special exception has value of 2
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) for: DerivedException::what matches "starts with: "Derived""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) for: DerivedException::what matches "ends with: "::what""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) for: DerivedException::what matches "not starts with: "::what""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) for: SpecialException::what matches "starts with: "Special""
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive)
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected"
|
||||
@@ -594,6 +599,7 @@ Misc.tests.cpp:<line number>: passed: Factorial(1) == 1 for: 1 == 1
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(2) == 2 for: 2 == 2
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(3) == 6 for: 6 == 6
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(10) == 3628800 for: 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
|
||||
Matchers.tests.cpp:<line number>: passed: 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other
|
||||
@@ -623,6 +629,7 @@ Matchers.tests.cpp:<line number>: passed: WithinULP( 1., 0 )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., 0. )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., -0.2 ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., 1. ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !IsNaN() for: 1.0 not is NaN
|
||||
Matchers.tests.cpp:<line number>: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other
|
||||
@@ -655,6 +662,7 @@ Matchers.tests.cpp:<line number>: passed: WithinULP( 1.f, static_cast<uint64_t>(
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, 0.f )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, -0.2f ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, 1.f ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !IsNaN() for: 1.0 not is NaN
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
@@ -1855,6 +1863,23 @@ There is no extra whitespace here
|
||||
StringManip.tests.cpp:<line number>: passed: trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here
|
||||
==
|
||||
There is no extra whitespace here
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( c_array ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( c_array ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_3, !RangeEquals( array_int_4 ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_3, !UnorderedRangeEquals( array_int_4 ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: with 1 message: 'ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess( list_char_a )'
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( list_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( list_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, !RangeEquals( vector_char_b ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, !UnorderedRangeEquals( vector_char_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: a, !RangeEquals( b ) for: { 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: a, UnorderedRangeEquals( b ) for: { 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14'
|
||||
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
|
||||
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
|
||||
@@ -1960,6 +1985,38 @@ MatchersRanges.tests.cpp:<line number>: passed: mocked.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked.m_derefed[3]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked.m_derefed[4]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, RangeEquals( empty_vector ) for: { } elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, !RangeEquals( non_empty_vector ) for: { } not elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_vector, !RangeEquals( empty_vector ) for: { 1 } not elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_array, RangeEquals( non_empty_array ) for: { 1 } elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, RangeEquals( array_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !RangeEquals( array_b ) for: { 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !RangeEquals( array_c ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !RangeEquals( vector_b ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( vector_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !RangeEquals( vector_b, close_enough ) for: { 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, RangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) for: { 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1, !RangeEquals( arr ) for: { 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[0] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked1.m_derefed[3]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1, RangeEquals( arr ) for: { 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[0] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[3] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, UnorderedRangeEquals( empty_vector ) for: { } unordered elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, !UnorderedRangeEquals( non_empty_vector ) for: { } not unordered elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_vector, !UnorderedRangeEquals( empty_vector ) for: { 1 } not unordered elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_array, UnorderedRangeEquals( non_empty_array ) for: { 1 } unordered elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, UnorderedRangeEquals( array_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !UnorderedRangeEquals( array_b ) for: { 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !UnorderedRangeEquals( vector_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) for: { 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !UnorderedRangeEquals( vector_b, close_enough ) for: { 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, UnorderedRangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(0) for: { } has size == 0
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, !SizeIs(2) for: { } not has size == 2
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(Lt(2)) for: { } size matches is less than 2
|
||||
@@ -2056,6 +2113,8 @@ Xml.tests.cpp:<line number>: passed: encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F
|
||||
Xml.tests.cpp:<line number>: passed: stream.str(), ContainsSubstring(R"(attr1="true")") && ContainsSubstring(R"(attr2="false")") for: "<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Element1 attr1="true" attr2="false"/>
|
||||
" ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.point.count() == 23 for: 23.0 == 23
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.lower_bound.count() == 23 for: 23.0 == 23
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.upper_bound.count() == 23 for: 23.0 == 23
|
||||
@@ -2145,6 +2204,9 @@ FloatingPoint.tests.cpp:<line number>: passed: convertToBits( -0. ) == ( 1ULL <<
|
||||
9223372036854775808 (0x<hex digits>)
|
||||
FloatingPoint.tests.cpp:<line number>: passed: convertToBits( std::numeric_limits<float>::denorm_min() ) == 1 for: 1 == 1
|
||||
FloatingPoint.tests.cpp:<line number>: passed: convertToBits( std::numeric_limits<double>::denorm_min() ) == 1 for: 1 == 1
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 41'
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 43'
|
||||
Tag.tests.cpp:<line number>: passed: Catch::TestCaseInfo("", { "test with an empty tag", "[]" }, dummySourceLineInfo)
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: erfc_inv(1.103560) == Approx(-0.09203687623843015) for: -0.0920368762 == Approx( -0.0920368762 )
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: erfc_inv(1.067400) == Approx(-0.05980291115763361) for: -0.0598029112 == Approx( -0.0598029112 )
|
||||
@@ -2154,6 +2216,14 @@ InternalBenchmark.tests.cpp:<line number>: passed: res.outliers.total() == 0 for
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: failed: 3 == 4
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
loose text artifact
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value'
|
||||
@@ -2211,6 +2281,10 @@ Misc.tests.cpp:<line number>: passed: a < b for: 1 < 2
|
||||
Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
|
||||
Misc.tests.cpp:<line number>: passed: b != a for: 2 != 1
|
||||
Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
|
||||
a!
|
||||
b1!
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
!
|
||||
Tricky.tests.cpp:<line number>: passed: s == "7" for: "7" == "7"
|
||||
Tricky.tests.cpp:<line number>: passed: ti == typeid(int) for: {?} == {?}
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: normal_cdf(0.000000) == Approx(0.50000000000000000) for: 0.5 == Approx( 0.5 )
|
||||
@@ -2295,9 +2369,13 @@ InternalBenchmark.tests.cpp:<line number>: passed: x >= old_x for: 128 >= 64
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.elapsed >= time for: 128 ns >= 100 ns
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.result == Timing.iterations + 17 for: 145 == 145
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.iterations >= time.count() for: 128 >= 100
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
|
||||
Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags, VectorContains( Tag( "magic-tag" ) ) && VectorContains( Tag( "."_catch_sr ) ) for: { {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 43'
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}) for: { abc } Equals: { abc }
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}) for: { abc, def } Equals: { abc, def }
|
||||
@@ -2363,6 +2441,7 @@ Generators.tests.cpp:<line number>: passed: strlen(std::get<0>(data)) == static_
|
||||
Generators.tests.cpp:<line number>: passed: strlen(std::get<0>(data)) == static_cast<size_t>(std::get<1>(data)) for: 6 == 6
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags.size() == 1 for: 1 == 1
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags[0].original == "magic.tag"_catch_sr for: magic.tag == magic.tag
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'Why would you throw a std::string?'
|
||||
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
|
||||
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
|
||||
@@ -2459,7 +2538,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
test cases: 394 | 304 passed | 83 failed | 7 failed as expected
|
||||
assertions: 2159 | 1989 passed | 143 failed | 27 failed as expected
|
||||
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
||||
|
@@ -82,6 +82,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smalles
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00])
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
|
||||
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
|
||||
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
|
||||
@@ -570,6 +571,10 @@ Matchers.tests.cpp:<line number>: failed: throwsSpecialException( 3 ), SpecialEx
|
||||
Matchers.tests.cpp:<line number>: failed: throwsSpecialException( 4 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 1 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 2 ), SpecialException, ExceptionMatcher{ 2 } for: SpecialException::what special exception has value of 2
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) for: DerivedException::what matches "starts with: "Derived""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) for: DerivedException::what matches "ends with: "::what""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) for: DerivedException::what matches "not starts with: "::what""
|
||||
Matchers.tests.cpp:<line number>: passed: throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) for: SpecialException::what matches "starts with: "Special""
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) for: "expected exception" equals: "expected exception" (case insensitive)
|
||||
Exception.tests.cpp:<line number>: passed: thisThrows(), StartsWith( "expected" ) for: "expected exception" starts with: "expected"
|
||||
@@ -592,6 +597,7 @@ Misc.tests.cpp:<line number>: passed: Factorial(1) == 1 for: 1 == 1
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(2) == 2 for: 2 == 2
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(3) == 6 for: 6 == 6
|
||||
Misc.tests.cpp:<line number>: passed: Factorial(10) == 3628800 for: 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
|
||||
Matchers.tests.cpp:<line number>: passed: 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other
|
||||
@@ -621,6 +627,7 @@ Matchers.tests.cpp:<line number>: passed: WithinULP( 1., 0 )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., 0. )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., -0.2 ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1., 1. ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !IsNaN() for: 1.0 not is NaN
|
||||
Matchers.tests.cpp:<line number>: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other
|
||||
Matchers.tests.cpp:<line number>: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other
|
||||
@@ -653,6 +660,7 @@ Matchers.tests.cpp:<line number>: passed: WithinULP( 1.f, static_cast<uint64_t>(
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, 0.f )
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, -0.2f ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: WithinRel( 1.f, 1.f ), std::domain_error
|
||||
Matchers.tests.cpp:<line number>: passed: 1., !IsNaN() for: 1.0 not is NaN
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
@@ -1848,6 +1856,23 @@ There is no extra whitespace here
|
||||
StringManip.tests.cpp:<line number>: passed: trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here
|
||||
==
|
||||
There is no extra whitespace here
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( c_array ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( c_array ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_3, !RangeEquals( array_int_4 ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_3, !UnorderedRangeEquals( array_int_4 ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: with 1 message: 'ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess( list_char_a )'
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, RangeEquals( list_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_int_a, UnorderedRangeEquals( list_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, !RangeEquals( vector_char_b ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_int_a, !UnorderedRangeEquals( vector_char_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: a, !RangeEquals( b ) for: { 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: a, UnorderedRangeEquals( b ) for: { 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14'
|
||||
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
|
||||
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
|
||||
@@ -1953,6 +1978,38 @@ MatchersRanges.tests.cpp:<line number>: passed: mocked.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked.m_derefed[3]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked.m_derefed[4]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, RangeEquals( empty_vector ) for: { } elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, !RangeEquals( non_empty_vector ) for: { } not elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_vector, !RangeEquals( empty_vector ) for: { 1 } not elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_array, RangeEquals( non_empty_array ) for: { 1 } elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, RangeEquals( array_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !RangeEquals( array_b ) for: { 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !RangeEquals( array_c ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !RangeEquals( vector_b ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( vector_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !RangeEquals( vector_b, close_enough ) for: { 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, RangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) for: { 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1, !RangeEquals( arr ) for: { 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[0] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: !(mocked1.m_derefed[3]) for: !false
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1, RangeEquals( arr ) for: { 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[0] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[1] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[2] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: mocked1.m_derefed[3] for: true
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, UnorderedRangeEquals( empty_vector ) for: { } unordered elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vector, !UnorderedRangeEquals( non_empty_vector ) for: { } not unordered elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_vector, !UnorderedRangeEquals( empty_vector ) for: { 1 } not unordered elements are { }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: non_empty_array, UnorderedRangeEquals( non_empty_array ) for: { 1 } unordered elements are { 1 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, UnorderedRangeEquals( array_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: array_a, !UnorderedRangeEquals( array_b ) for: { 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !UnorderedRangeEquals( vector_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) for: { 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: vector_a, !UnorderedRangeEquals( vector_b, close_enough ) for: { 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: needs_adl1, UnorderedRangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(0) for: { } has size == 0
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, !SizeIs(2) for: { } not has size == 2
|
||||
MatchersRanges.tests.cpp:<line number>: passed: empty_vec, SizeIs(Lt(2)) for: { } size matches is less than 2
|
||||
@@ -2049,6 +2106,8 @@ Xml.tests.cpp:<line number>: passed: encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F
|
||||
Xml.tests.cpp:<line number>: passed: stream.str(), ContainsSubstring(R"(attr1="true")") && ContainsSubstring(R"(attr2="false")") for: "<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Element1 attr1="true" attr2="false"/>
|
||||
" ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.point.count() == 23 for: 23.0 == 23
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.lower_bound.count() == 23 for: 23.0 == 23
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: analysis.mean.upper_bound.count() == 23 for: 23.0 == 23
|
||||
@@ -2138,6 +2197,9 @@ FloatingPoint.tests.cpp:<line number>: passed: convertToBits( -0. ) == ( 1ULL <<
|
||||
9223372036854775808 (0x<hex digits>)
|
||||
FloatingPoint.tests.cpp:<line number>: passed: convertToBits( std::numeric_limits<float>::denorm_min() ) == 1 for: 1 == 1
|
||||
FloatingPoint.tests.cpp:<line number>: passed: convertToBits( std::numeric_limits<double>::denorm_min() ) == 1 for: 1 == 1
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 41'
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 43'
|
||||
Tag.tests.cpp:<line number>: passed: Catch::TestCaseInfo("", { "test with an empty tag", "[]" }, dummySourceLineInfo)
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: erfc_inv(1.103560) == Approx(-0.09203687623843015) for: -0.0920368762 == Approx( -0.0920368762 )
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: erfc_inv(1.067400) == Approx(-0.05980291115763361) for: -0.0598029112 == Approx( -0.0598029112 )
|
||||
@@ -2147,6 +2209,14 @@ InternalBenchmark.tests.cpp:<line number>: passed: res.outliers.total() == 0 for
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: failed: 3 == 4
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: failed: explicitly
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary2)>::value'
|
||||
Clara.tests.cpp:<line number>: passed: with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary3)>::value'
|
||||
@@ -2203,6 +2273,7 @@ Misc.tests.cpp:<line number>: passed: a < b for: 1 < 2
|
||||
Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
|
||||
Misc.tests.cpp:<line number>: passed: b != a for: 2 != 1
|
||||
Misc.tests.cpp:<line number>: passed: a != b for: 1 != 2
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Tricky.tests.cpp:<line number>: passed: s == "7" for: "7" == "7"
|
||||
Tricky.tests.cpp:<line number>: passed: ti == typeid(int) for: {?} == {?}
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: normal_cdf(0.000000) == Approx(0.50000000000000000) for: 0.5 == Approx( 0.5 )
|
||||
@@ -2287,9 +2358,13 @@ InternalBenchmark.tests.cpp:<line number>: passed: x >= old_x for: 128 >= 64
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.elapsed >= time for: 128 ns >= 100 ns
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.result == Timing.iterations + 17 for: 145 == 145
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: Timing.iterations >= time.count() for: 128 >= 100
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Skip.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
|
||||
Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags, VectorContains( Tag( "magic-tag" ) ) && VectorContains( Tag( "."_catch_sr ) ) for: { {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
Skip.tests.cpp:<line number>: skipped: 'skipping because answer = 43'
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}) for: { abc } Equals: { abc }
|
||||
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}) for: { abc, def } Equals: { abc, def }
|
||||
@@ -2355,6 +2430,7 @@ Generators.tests.cpp:<line number>: passed: strlen(std::get<0>(data)) == static_
|
||||
Generators.tests.cpp:<line number>: passed: strlen(std::get<0>(data)) == static_cast<size_t>(std::get<1>(data)) for: 6 == 6
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags.size() == 1 for: 1 == 1
|
||||
Tag.tests.cpp:<line number>: passed: testcase.tags[0].original == "magic.tag"_catch_sr for: magic.tag == magic.tag
|
||||
Skip.tests.cpp:<line number>: skipped:
|
||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'Why would you throw a std::string?'
|
||||
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
|
||||
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
|
||||
@@ -2451,7 +2527,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
|
||||
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
test cases: 394 | 304 passed | 83 failed | 7 failed as expected
|
||||
assertions: 2159 | 1989 passed | 143 failed | 27 failed as expected
|
||||
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
||||
|
@@ -27,6 +27,16 @@ Tricky.tests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
1514
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#2615 - Throwing in constructor generator fails test case but does not abort
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
failure to init
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
@@ -1164,6 +1174,14 @@ Exception.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
unexpected exception
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
a succeeding test can still be skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
checkedElse, failing
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1186,6 +1204,87 @@ Misc.tests.cpp:<line number>: FAILED:
|
||||
with expansion:
|
||||
false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 41
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failed assertions before SKIP cause test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
CHECK( 3 == 4 )
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
loose text artifact
|
||||
-------------------------------------------------------------------------------
|
||||
just failure
|
||||
@@ -1304,6 +1403,19 @@ Misc.tests.cpp:<line number>: FAILED:
|
||||
with expansion:
|
||||
1 == 2
|
||||
|
||||
a!
|
||||
b1!
|
||||
-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
B
|
||||
B2
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
!
|
||||
-------------------------------------------------------------------------------
|
||||
not prints unscoped info from previous failures
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1338,6 +1450,15 @@ Message.tests.cpp:<line number>: FAILED:
|
||||
with message:
|
||||
this SHOULD be seen only ONCE
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
send a single char to INFO
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1361,6 +1482,16 @@ with messages:
|
||||
hi
|
||||
i := 7
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
skipped tests can optionally provide a reason
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
stacks unscoped info in loops
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1383,6 +1514,14 @@ with messages:
|
||||
5
|
||||
6
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
tests can be skipped dynamically at runtime
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
thrown std::strings are translated
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1394,6 +1533,6 @@ due to unexpected exception with message:
|
||||
Why would you throw a std::string?
|
||||
|
||||
===============================================================================
|
||||
test cases: 394 | 318 passed | 69 failed | 7 failed as expected
|
||||
assertions: 2144 | 1989 passed | 128 failed | 27 failed as expected
|
||||
test cases: 409 | 323 passed | 69 failed | 6 skipped | 11 failed as expected
|
||||
assertions: 2209 | 2049 passed | 128 failed | 32 failed as expected
|
||||
|
||||
|
@@ -761,6 +761,16 @@ with expansion:
|
||||
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
|
||||
00000000e+00])
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#2615 - Throwing in constructor generator fails test case but does not abort
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
failure to init
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
@@ -4282,6 +4292,32 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
SpecialException::what special exception has value of 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception message can be matched
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "starts with: "Derived""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "ends with: "::what""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "not starts with: "::what""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) )
|
||||
with expansion:
|
||||
SpecialException::what matches "starts with: "Special""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception messages can be tested for
|
||||
exact match
|
||||
@@ -4441,6 +4477,15 @@ Misc.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Filter generator throws exception for empty generator
|
||||
-------------------------------------------------------------------------------
|
||||
GeneratorsImpl.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
Relative
|
||||
@@ -4626,6 +4671,18 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( WithinRel( 1., 1. ), std::domain_error )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
IsNaN
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1., !IsNaN() )
|
||||
with expansion:
|
||||
1.0 not is NaN
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
Relative
|
||||
@@ -4819,6 +4876,18 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( WithinRel( 1.f, 1.f ), std::domain_error )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
IsNaN
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1., !IsNaN() )
|
||||
with expansion:
|
||||
1.0 not is NaN
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators -- adapters
|
||||
Filtering by predicate
|
||||
@@ -13072,6 +13141,154 @@ with expansion:
|
||||
==
|
||||
There is no extra whitespace here
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( c_array ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( c_array ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types (differ in array N)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_3, !RangeEquals( array_int_4 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_3, !UnorderedRangeEquals( array_int_4 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types and value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers, one random access, one not
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess(
|
||||
list_char_a )
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( list_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( list_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Value type
|
||||
Two equal containers of different value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, RangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, UnorderedRangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Value type
|
||||
Two non-equal containers of different value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, !RangeEquals( vector_char_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, !UnorderedRangeEquals( vector_char_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Ranges with begin that needs ADL
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( a, !RangeEquals( b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( a, UnorderedRangeEquals( b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, RangeEquals( array_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Unexpected exceptions can be translated
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -13931,6 +14148,324 @@ MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
!false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container matches empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, RangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ } elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container does not match non-empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, !RangeEquals( non_empty_vector ) )
|
||||
with expansion:
|
||||
{ } not elements are { 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_vector, !RangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ 1 } not elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal 1-length non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_array, RangeEquals( non_empty_array ) )
|
||||
with expansion:
|
||||
{ 1 } elements are { 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, RangeEquals( array_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, non-equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !RangeEquals( array_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !RangeEquals( array_c ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two non-equal-sized, non-empty containers (with same first elements)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !RangeEquals( vector_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, RangeEquals( vector_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Custom predicate
|
||||
Two non-equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !RangeEquals( vector_b, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Ranges that need ADL begin/end
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, RangeEquals( needs_adl2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Check short-circuiting behaviour
|
||||
Check short-circuits on failure
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( mocked1, !RangeEquals( arr ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[0] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[1] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[2] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_FALSE( mocked1.m_derefed[3] )
|
||||
with expansion:
|
||||
!false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Check short-circuiting behaviour
|
||||
All elements are checked on success
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( mocked1, RangeEquals( arr ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[0] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[1] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[2] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[3] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container matches empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, UnorderedRangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ } unordered elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container does not match non-empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, !UnorderedRangeEquals( non_empty_vector ) )
|
||||
with expansion:
|
||||
{ } not unordered elements are { 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_vector, !UnorderedRangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ 1 } not unordered elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal 1-length non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_array, UnorderedRangeEquals( non_empty_array ) )
|
||||
with expansion:
|
||||
{ 1 } unordered elements are { 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, UnorderedRangeEquals( array_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, non-equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !UnorderedRangeEquals( array_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two non-equal-sized, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !UnorderedRangeEquals( vector_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Custom predicate
|
||||
Two non-equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !UnorderedRangeEquals( vector_b, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Ranges that need ADL begin/end
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, UnorderedRangeEquals( needs_adl2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of the SizeIs range matcher
|
||||
Some with stdlib containers
|
||||
@@ -14633,6 +15168,16 @@ with expansion:
|
||||
<Element1 attr1="true" attr2="false"/>
|
||||
" ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
a succeeding test can still be skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
analyse no analysis
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15178,6 +15723,34 @@ FloatingPoint.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 41
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
empty tags are not allowed
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15253,6 +15826,67 @@ Misc.tests.cpp:<line number>
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failed assertions before SKIP cause test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
CHECK( 3 == 4 )
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
first tag
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15749,6 +16383,40 @@ Misc.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
1 != 2
|
||||
|
||||
a-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
A
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
|
||||
No assertions in section 'A'
|
||||
|
||||
!
|
||||
b1-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
B
|
||||
B1
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
|
||||
No assertions in section 'B1'
|
||||
|
||||
!
|
||||
-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
B
|
||||
B2
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
!
|
||||
-------------------------------------------------------------------------------
|
||||
non streamable - with conv. op
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16350,6 +17018,33 @@ Misc.tests.cpp:<line number>
|
||||
|
||||
No assertions in test case 'second tag'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
also not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
send a single char to INFO
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16384,6 +17079,16 @@ Tag.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
{ {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
skipped tests can optionally provide a reason
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
splitString
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16811,6 +17516,14 @@ Tag.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
magic.tag == magic.tag
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
tests can be skipped dynamically at runtime
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
thrown std::strings are translated
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -17518,6 +18231,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 394 | 304 passed | 83 failed | 7 failed as expected
|
||||
assertions: 2159 | 1989 passed | 143 failed | 27 failed as expected
|
||||
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
@@ -759,6 +759,16 @@ with expansion:
|
||||
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
|
||||
00000000e+00])
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#2615 - Throwing in constructor generator fails test case but does not abort
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
failure to init
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
@@ -4280,6 +4290,32 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
SpecialException::what special exception has value of 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception message can be matched
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "starts with: "Derived""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "ends with: "::what""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) )
|
||||
with expansion:
|
||||
DerivedException::what matches "not starts with: "::what""
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_MATCHES( throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) )
|
||||
with expansion:
|
||||
SpecialException::what matches "starts with: "Special""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception messages can be tested for
|
||||
exact match
|
||||
@@ -4439,6 +4475,15 @@ Misc.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Filter generator throws exception for empty generator
|
||||
-------------------------------------------------------------------------------
|
||||
GeneratorsImpl.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
Relative
|
||||
@@ -4624,6 +4669,18 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( WithinRel( 1., 1. ), std::domain_error )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
IsNaN
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1., !IsNaN() )
|
||||
with expansion:
|
||||
1.0 not is NaN
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
Relative
|
||||
@@ -4817,6 +4874,18 @@ Matchers.tests.cpp:<line number>: PASSED:
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( WithinRel( 1.f, 1.f ), std::domain_error )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
IsNaN
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1., !IsNaN() )
|
||||
with expansion:
|
||||
1.0 not is NaN
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators -- adapters
|
||||
Filtering by predicate
|
||||
@@ -13065,6 +13134,154 @@ with expansion:
|
||||
==
|
||||
There is no extra whitespace here
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( c_array ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( c_array ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types (differ in array N)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_3, !RangeEquals( array_int_4 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_3, !UnorderedRangeEquals( array_int_4 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers of different container types and value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Container conversions
|
||||
Two equal containers, one random access, one not
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess(
|
||||
list_char_a )
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, RangeEquals( list_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_int_a, UnorderedRangeEquals( list_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Value type
|
||||
Two equal containers of different value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, RangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, UnorderedRangeEquals( vector_char_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Value type
|
||||
Two non-equal containers of different value types
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, !RangeEquals( vector_char_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_int_a, !UnorderedRangeEquals( vector_char_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Ranges with begin that needs ADL
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( a, !RangeEquals( b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( a, UnorderedRangeEquals( b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Type conversions of RangeEquals and similar
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, RangeEquals( array_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Unexpected exceptions can be translated
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -13924,6 +14141,324 @@ MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
!false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container matches empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, RangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ } elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container does not match non-empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, !RangeEquals( non_empty_vector ) )
|
||||
with expansion:
|
||||
{ } not elements are { 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_vector, !RangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ 1 } not elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal 1-length non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_array, RangeEquals( non_empty_array ) )
|
||||
with expansion:
|
||||
{ 1 } elements are { 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, RangeEquals( array_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, non-equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !RangeEquals( array_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !RangeEquals( array_c ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Basic usage
|
||||
Two non-equal-sized, non-empty containers (with same first elements)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !RangeEquals( vector_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, RangeEquals( vector_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Custom predicate
|
||||
Two non-equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !RangeEquals( vector_b, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Ranges that need ADL begin/end
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, RangeEquals( needs_adl2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Check short-circuiting behaviour
|
||||
Check short-circuits on failure
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( mocked1, !RangeEquals( arr ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[0] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[1] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[2] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_FALSE( mocked1.m_derefed[3] )
|
||||
with expansion:
|
||||
!false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of RangeEquals range matcher
|
||||
Check short-circuiting behaviour
|
||||
All elements are checked on success
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( mocked1, RangeEquals( arr ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[0] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[1] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[2] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( mocked1.m_derefed[3] )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container matches empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, UnorderedRangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ } unordered elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Empty container does not match non-empty container
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( empty_vector, !UnorderedRangeEquals( non_empty_vector ) )
|
||||
with expansion:
|
||||
{ } not unordered elements are { 1 }
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_vector, !UnorderedRangeEquals( empty_vector ) )
|
||||
with expansion:
|
||||
{ 1 } not unordered elements are { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal 1-length non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( non_empty_array, UnorderedRangeEquals( non_empty_array ) )
|
||||
with expansion:
|
||||
{ 1 } unordered elements are { 1 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, UnorderedRangeEquals( array_a ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two equal-sized, non-equal, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( array_a, !UnorderedRangeEquals( array_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Basic usage
|
||||
Two non-equal-sized, non-empty containers
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !UnorderedRangeEquals( vector_b ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Custom predicate
|
||||
Two equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Custom predicate
|
||||
Two non-equal non-empty containers (close enough)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
CHECK_THAT( vector_a, !UnorderedRangeEquals( vector_b, close_enough ) )
|
||||
with expansion:
|
||||
{ 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of UnorderedRangeEquals range matcher
|
||||
Ranges that need ADL begin/end
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersRanges.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersRanges.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( needs_adl1, UnorderedRangeEquals( needs_adl2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Usage of the SizeIs range matcher
|
||||
Some with stdlib containers
|
||||
@@ -14626,6 +15161,16 @@ with expansion:
|
||||
<Element1 attr1="true" attr2="false"/>
|
||||
" ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
a succeeding test can still be skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
analyse no analysis
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15171,6 +15716,34 @@ FloatingPoint.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 41
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
dynamic skipping works with generators
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
empty tags are not allowed
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15246,6 +15819,67 @@ Misc.tests.cpp:<line number>
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failed assertions before SKIP cause test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
CHECK( 3 == 4 )
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing for some generator values causes entire test case to fail
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
failing in some unskipped sections causes entire test case to fail
|
||||
not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
first tag
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -15741,6 +16375,37 @@ Misc.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
1 != 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
A
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
|
||||
No assertions in section 'A'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
B
|
||||
B1
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
|
||||
No assertions in section 'B1'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
nested sections can be skipped dynamically at runtime
|
||||
B
|
||||
B2
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
non streamable - with conv. op
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16342,6 +17007,33 @@ Misc.tests.cpp:<line number>
|
||||
|
||||
No assertions in test case 'second tag'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
sections can be skipped dynamically at runtime
|
||||
also not skipped
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
send a single char to INFO
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16376,6 +17068,16 @@ Tag.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
{ {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
skipped tests can optionally provide a reason
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
skipping because answer = 43
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
splitString
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16803,6 +17505,14 @@ Tag.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
magic.tag == magic.tag
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
tests can be skipped dynamically at runtime
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
thrown std::strings are translated
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -17510,6 +18220,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 394 | 304 passed | 83 failed | 7 failed as expected
|
||||
assertions: 2159 | 1989 passed | 143 failed | 27 failed as expected
|
||||
test cases: 409 | 309 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
assertions: 2226 | 2049 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
@@ -761,6 +761,16 @@ with expansion:
|
||||
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
|
||||
00000000e+00])
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#2615 - Throwing in constructor generator fails test case but does not abort
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
failure to init
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#748 - captures with unexpected exceptions
|
||||
outside assertions
|
||||
@@ -941,6 +951,6 @@ Condition.tests.cpp:<line number>: FAILED:
|
||||
CHECK( true != true )
|
||||
|
||||
===============================================================================
|
||||
test cases: 32 | 27 passed | 3 failed | 2 failed as expected
|
||||
assertions: 101 | 94 passed | 4 failed | 3 failed as expected
|
||||
test cases: 33 | 27 passed | 3 failed | 3 failed as expected
|
||||
assertions: 102 | 94 passed | 4 failed | 4 failed as expected
|
||||
|
||||
|
@@ -6,3 +6,6 @@ A string sent to stderr via clog
|
||||
Message from section one
|
||||
Message from section two
|
||||
loose text artifact
|
||||
a!
|
||||
b1!
|
||||
!
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,8 @@ ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0
|
||||
ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
|
||||
# #2152 - ULP checks between differently signed values were wrong - float
|
||||
ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
|
||||
# #2615 - Throwing in constructor generator fails test case but does not abort
|
||||
not ok {test-number} - unexpected exception with message: 'failure to init'
|
||||
# #748 - captures with unexpected exceptions
|
||||
not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||
# #748 - captures with unexpected exceptions
|
||||
@@ -1076,6 +1078,14 @@ not ok {test-number} - throwsSpecialException( 4 ), SpecialException, ExceptionM
|
||||
ok {test-number} - throwsSpecialException( 1 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
# Exception matchers that succeed
|
||||
ok {test-number} - throwsSpecialException( 2 ), SpecialException, ExceptionMatcher{ 2 } for: SpecialException::what special exception has value of 2
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) for: DerivedException::what matches "starts with: "Derived""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) for: DerivedException::what matches "ends with: "::what""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) for: DerivedException::what matches "not starts with: "::what""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) for: SpecialException::what matches "starts with: "Special""
|
||||
# Exception messages can be tested for
|
||||
ok {test-number} - thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||
# Exception messages can be tested for
|
||||
@@ -1120,6 +1130,8 @@ ok {test-number} - Factorial(2) == 2 for: 2 == 2
|
||||
ok {test-number} - Factorial(3) == 6 for: 6 == 6
|
||||
# Factorials are computed
|
||||
ok {test-number} - Factorial(10) == 3628800 for: 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
# Filter generator throws exception for empty generator
|
||||
ok {test-number} - filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other
|
||||
# Floating point matchers: double
|
||||
@@ -1178,6 +1190,8 @@ ok {test-number} - WithinRel( 1., 0. )
|
||||
ok {test-number} - WithinRel( 1., -0.2 ), std::domain_error
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - WithinRel( 1., 1. ), std::domain_error
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
|
||||
# Floating point matchers: float
|
||||
@@ -1242,6 +1256,8 @@ ok {test-number} - WithinRel( 1.f, 0.f )
|
||||
ok {test-number} - WithinRel( 1.f, -0.2f ), std::domain_error
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - WithinRel( 1.f, 1.f ), std::domain_error
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
|
||||
# Generators -- adapters
|
||||
ok {test-number} - i % 2 == 0 for: 0 == 0
|
||||
# Generators -- adapters
|
||||
@@ -3215,6 +3231,40 @@ ok {test-number} - trim(StringRef(leading_whitespace)) == StringRef(no_whitespac
|
||||
ok {test-number} - trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace) for: There is no extra whitespace here == There is no extra whitespace here
|
||||
# Trim strings
|
||||
ok {test-number} - trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here == There is no extra whitespace here
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( c_array ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( c_array ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_3, !RangeEquals( array_int_4 ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_3, !UnorderedRangeEquals( array_int_4 ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - with 1 message: 'ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess( list_char_a )'
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( list_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( list_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, !RangeEquals( vector_char_b ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, !UnorderedRangeEquals( vector_char_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - a, !RangeEquals( b ) for: { 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - a, UnorderedRangeEquals( b ) for: { 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
# Unexpected exceptions can be translated
|
||||
not ok {test-number} - unexpected exception with message: '3.14'
|
||||
# Upcasting special member functions
|
||||
@@ -3425,6 +3475,70 @@ ok {test-number} - mocked.m_derefed[2] for: true
|
||||
ok {test-number} - !(mocked.m_derefed[3]) for: !false
|
||||
# Usage of NoneTrue range matcher
|
||||
ok {test-number} - !(mocked.m_derefed[4]) for: !false
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - empty_vector, RangeEquals( empty_vector ) for: { } elements are { }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - empty_vector, !RangeEquals( non_empty_vector ) for: { } not elements are { 1 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - non_empty_vector, !RangeEquals( empty_vector ) for: { 1 } not elements are { }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - non_empty_array, RangeEquals( non_empty_array ) for: { 1 } elements are { 1 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, RangeEquals( array_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, !RangeEquals( array_b ) for: { 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, !RangeEquals( array_c ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, !RangeEquals( vector_b ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, RangeEquals( vector_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, !RangeEquals( vector_b, close_enough ) for: { 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, RangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) for: { 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1, !RangeEquals( arr ) for: { 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[0] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[1] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[2] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - !(mocked1.m_derefed[3]) for: !false
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1, RangeEquals( arr ) for: { 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[0] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[1] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[2] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[3] for: true
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - empty_vector, UnorderedRangeEquals( empty_vector ) for: { } unordered elements are { }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - empty_vector, !UnorderedRangeEquals( non_empty_vector ) for: { } not unordered elements are { 1 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - non_empty_vector, !UnorderedRangeEquals( empty_vector ) for: { 1 } not unordered elements are { }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - non_empty_array, UnorderedRangeEquals( non_empty_array ) for: { 1 } unordered elements are { 1 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - array_a, UnorderedRangeEquals( array_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - array_a, !UnorderedRangeEquals( array_b ) for: { 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, !UnorderedRangeEquals( vector_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) for: { 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, !UnorderedRangeEquals( vector_b, close_enough ) for: { 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, UnorderedRangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
# Usage of the SizeIs range matcher
|
||||
ok {test-number} - empty_vec, SizeIs(0) for: { } has size == 0
|
||||
# Usage of the SizeIs range matcher
|
||||
@@ -3601,6 +3715,10 @@ ok {test-number} - encode( "[\x01]" ) == "[\\x01]" for: "[\x01]" == "[\x01]"
|
||||
ok {test-number} - encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F]" == "[\x7F]"
|
||||
# XmlWriter writes boolean attributes as true/false
|
||||
ok {test-number} - stream.str(), ContainsSubstring(R"(attr1="true")") && ContainsSubstring(R"(attr2="false")") for: "<?xml version="1.0" encoding="UTF-8"?> <Element1 attr1="true" attr2="false"/> " ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
# a succeeding test can still be skipped
|
||||
ok {test-number} -
|
||||
# a succeeding test can still be skipped
|
||||
ok {test-number} - # SKIP
|
||||
# analyse no analysis
|
||||
ok {test-number} - analysis.mean.point.count() == 23 for: 23.0 == 23
|
||||
# analyse no analysis
|
||||
@@ -3771,6 +3889,12 @@ ok {test-number} - convertToBits( -0. ) == ( 1ULL << 63 ) for: 92233720368547758
|
||||
ok {test-number} - convertToBits( std::numeric_limits<float>::denorm_min() ) == 1 for: 1 == 1
|
||||
# convertToBits
|
||||
ok {test-number} - convertToBits( std::numeric_limits<double>::denorm_min() ) == 1 for: 1 == 1
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} - # SKIP 'skipping because answer = 41'
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} -
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} - # SKIP 'skipping because answer = 43'
|
||||
# empty tags are not allowed
|
||||
ok {test-number} - Catch::TestCaseInfo("", { "test with an empty tag", "[]" }, dummySourceLineInfo)
|
||||
# erfc_inv
|
||||
@@ -3789,6 +3913,22 @@ ok {test-number} -
|
||||
ok {test-number} -
|
||||
# even more nested SECTION tests
|
||||
ok {test-number} -
|
||||
# failed assertions before SKIP cause test case to fail
|
||||
not ok {test-number} - 3 == 4
|
||||
# failed assertions before SKIP cause test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing for some generator values causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
# failing for some generator values causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing for some generator values causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
# failing for some generator values causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing in some unskipped sections causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing in some unskipped sections causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
loose text artifact
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
@@ -3898,6 +4038,11 @@ ok {test-number} - a != b for: 1 != 2
|
||||
ok {test-number} - b != a for: 2 != 1
|
||||
# nested SECTION tests
|
||||
ok {test-number} - a != b for: 1 != 2
|
||||
a!
|
||||
b1!
|
||||
# nested sections can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
!
|
||||
# non streamable - with conv. op
|
||||
ok {test-number} - s == "7" for: "7" == "7"
|
||||
# non-copyable objects
|
||||
@@ -4062,12 +4207,20 @@ ok {test-number} - Timing.elapsed >= time for: 128 ns >= 100 ns
|
||||
ok {test-number} - Timing.result == Timing.iterations + 17 for: 145 == 145
|
||||
# run_for_at_least, int
|
||||
ok {test-number} - Timing.iterations >= time.count() for: 128 >= 100
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} -
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} -
|
||||
# send a single char to INFO
|
||||
not ok {test-number} - false with 1 message: '3'
|
||||
# sends information to INFO
|
||||
not ok {test-number} - false with 2 messages: 'hi' and 'i := 7'
|
||||
# shortened hide tags are split apart
|
||||
ok {test-number} - testcase.tags, VectorContains( Tag( "magic-tag" ) ) && VectorContains( Tag( "."_catch_sr ) ) for: { {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
# skipped tests can optionally provide a reason
|
||||
ok {test-number} - # SKIP 'skipping because answer = 43'
|
||||
# splitString
|
||||
ok {test-number} - splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
|
||||
# splitString
|
||||
@@ -4150,6 +4303,8 @@ ok {test-number} - strlen(std::get<0>(data)) == static_cast<size_t>(std::get<1>(
|
||||
ok {test-number} - testcase.tags.size() == 1 for: 1 == 1
|
||||
# tags with dots in later positions are not parsed as hidden
|
||||
ok {test-number} - testcase.tags[0].original == "magic.tag"_catch_sr for: magic.tag == magic.tag
|
||||
# tests can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
# thrown std::strings are translated
|
||||
not ok {test-number} - unexpected exception with message: 'Why would you throw a std::string?'
|
||||
# toString on const wchar_t const pointer returns the string contents
|
||||
@@ -4322,5 +4477,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..2159
|
||||
1..2237
|
||||
|
||||
|
@@ -162,6 +162,8 @@ ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0
|
||||
ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
|
||||
# #2152 - ULP checks between differently signed values were wrong - float
|
||||
ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
|
||||
# #2615 - Throwing in constructor generator fails test case but does not abort
|
||||
not ok {test-number} - unexpected exception with message: 'failure to init'
|
||||
# #748 - captures with unexpected exceptions
|
||||
not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
|
||||
# #748 - captures with unexpected exceptions
|
||||
@@ -1074,6 +1076,14 @@ not ok {test-number} - throwsSpecialException( 4 ), SpecialException, ExceptionM
|
||||
ok {test-number} - throwsSpecialException( 1 ), SpecialException, ExceptionMatcher{ 1 } for: SpecialException::what special exception has value of 1
|
||||
# Exception matchers that succeed
|
||||
ok {test-number} - throwsSpecialException( 2 ), SpecialException, ExceptionMatcher{ 2 } for: SpecialException::what special exception has value of 2
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( StartsWith( "Derived" ) ) for: DerivedException::what matches "starts with: "Derived""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( EndsWith( "::what" ) ) for: DerivedException::what matches "ends with: "::what""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsDerivedException(), DerivedException, MessageMatches( !StartsWith( "::what" ) ) for: DerivedException::what matches "not starts with: "::what""
|
||||
# Exception message can be matched
|
||||
ok {test-number} - throwsSpecialException( 2 ), SpecialException, MessageMatches( StartsWith( "Special" ) ) for: SpecialException::what matches "starts with: "Special""
|
||||
# Exception messages can be tested for
|
||||
ok {test-number} - thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
|
||||
# Exception messages can be tested for
|
||||
@@ -1118,6 +1128,8 @@ ok {test-number} - Factorial(2) == 2 for: 2 == 2
|
||||
ok {test-number} - Factorial(3) == 6 for: 6 == 6
|
||||
# Factorials are computed
|
||||
ok {test-number} - Factorial(10) == 3628800 for: 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
# Filter generator throws exception for empty generator
|
||||
ok {test-number} - filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other
|
||||
# Floating point matchers: double
|
||||
@@ -1176,6 +1188,8 @@ ok {test-number} - WithinRel( 1., 0. )
|
||||
ok {test-number} - WithinRel( 1., -0.2 ), std::domain_error
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - WithinRel( 1., 1. ), std::domain_error
|
||||
# Floating point matchers: double
|
||||
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other
|
||||
# Floating point matchers: float
|
||||
@@ -1240,6 +1254,8 @@ ok {test-number} - WithinRel( 1.f, 0.f )
|
||||
ok {test-number} - WithinRel( 1.f, -0.2f ), std::domain_error
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - WithinRel( 1.f, 1.f ), std::domain_error
|
||||
# Floating point matchers: float
|
||||
ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN
|
||||
# Generators -- adapters
|
||||
ok {test-number} - i % 2 == 0 for: 0 == 0
|
||||
# Generators -- adapters
|
||||
@@ -3208,6 +3224,40 @@ ok {test-number} - trim(StringRef(leading_whitespace)) == StringRef(no_whitespac
|
||||
ok {test-number} - trim(StringRef(trailing_whitespace)) == StringRef(no_whitespace) for: There is no extra whitespace here == There is no extra whitespace here
|
||||
# Trim strings
|
||||
ok {test-number} - trim(StringRef(whitespace_at_both_ends)) == StringRef(no_whitespace) for: There is no extra whitespace here == There is no extra whitespace here
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( c_array ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( c_array ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_3, !RangeEquals( array_int_4 ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_3, !UnorderedRangeEquals( array_int_4 ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - with 1 message: 'ContainerIsRandomAccess( array_int_a ) != ContainerIsRandomAccess( list_char_a )'
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, RangeEquals( list_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - array_int_a, UnorderedRangeEquals( list_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, RangeEquals( vector_char_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, UnorderedRangeEquals( vector_char_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, !RangeEquals( vector_char_b ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_int_a, !UnorderedRangeEquals( vector_char_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 2 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - a, !RangeEquals( b ) for: { 1, 2, 3 } not elements are { 3, 2, 1 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - a, UnorderedRangeEquals( b ) for: { 1, 2, 3 } unordered elements are { 3, 2, 1 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
# Type conversions of RangeEquals and similar
|
||||
ok {test-number} - vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
|
||||
# Unexpected exceptions can be translated
|
||||
not ok {test-number} - unexpected exception with message: '3.14'
|
||||
# Upcasting special member functions
|
||||
@@ -3418,6 +3468,70 @@ ok {test-number} - mocked.m_derefed[2] for: true
|
||||
ok {test-number} - !(mocked.m_derefed[3]) for: !false
|
||||
# Usage of NoneTrue range matcher
|
||||
ok {test-number} - !(mocked.m_derefed[4]) for: !false
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - empty_vector, RangeEquals( empty_vector ) for: { } elements are { }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - empty_vector, !RangeEquals( non_empty_vector ) for: { } not elements are { 1 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - non_empty_vector, !RangeEquals( empty_vector ) for: { 1 } not elements are { }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - non_empty_array, RangeEquals( non_empty_array ) for: { 1 } elements are { 1 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, RangeEquals( array_a ) for: { 1, 2, 3 } elements are { 1, 2, 3 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, !RangeEquals( array_b ) for: { 1, 2, 3 } not elements are { 2, 2, 3 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - array_a, !RangeEquals( array_c ) for: { 1, 2, 3 } not elements are { 1, 2, 2 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, !RangeEquals( vector_b ) for: { 1, 2, 3 } not elements are { 1, 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, RangeEquals( vector_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - vector_a, !RangeEquals( vector_b, close_enough ) for: { 1, 2, 3 } not elements are { 3, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, RangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } elements are { 1, 2, 3, 4, 5 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, RangeEquals( needs_adl3, []( int l, int r ) { return l + 1 == r; } ) for: { 1, 2, 3, 4, 5 } elements are { 2, 3, 4, 5, 6 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1, !RangeEquals( arr ) for: { 1, 2, 3, 4 } not elements are { 1, 2, 4, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[0] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[1] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[2] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - !(mocked1.m_derefed[3]) for: !false
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1, RangeEquals( arr ) for: { 1, 2, 3, 4 } elements are { 1, 2, 3, 4 }
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[0] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[1] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[2] for: true
|
||||
# Usage of RangeEquals range matcher
|
||||
ok {test-number} - mocked1.m_derefed[3] for: true
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - empty_vector, UnorderedRangeEquals( empty_vector ) for: { } unordered elements are { }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - empty_vector, !UnorderedRangeEquals( non_empty_vector ) for: { } not unordered elements are { 1 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - non_empty_vector, !UnorderedRangeEquals( empty_vector ) for: { 1 } not unordered elements are { }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - non_empty_array, UnorderedRangeEquals( non_empty_array ) for: { 1 } unordered elements are { 1 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - array_a, UnorderedRangeEquals( array_a ) for: { 1, 2, 3 } unordered elements are { 1, 2, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - array_a, !UnorderedRangeEquals( array_b ) for: { 1, 2, 3 } not unordered elements are { 2, 2, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, !UnorderedRangeEquals( vector_b ) for: { 1, 2, 3 } not unordered elements are { 1, 2, 3, 4 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, UnorderedRangeEquals( vector_a_plus_1, close_enough ) for: { 1, 10, 20 } unordered elements are { 11, 21, 2 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - vector_a, !UnorderedRangeEquals( vector_b, close_enough ) for: { 1, 10, 21 } not unordered elements are { 11, 21, 3 }
|
||||
# Usage of UnorderedRangeEquals range matcher
|
||||
ok {test-number} - needs_adl1, UnorderedRangeEquals( needs_adl2 ) for: { 1, 2, 3, 4, 5 } unordered elements are { 1, 2, 3, 4, 5 }
|
||||
# Usage of the SizeIs range matcher
|
||||
ok {test-number} - empty_vec, SizeIs(0) for: { } has size == 0
|
||||
# Usage of the SizeIs range matcher
|
||||
@@ -3594,6 +3708,10 @@ ok {test-number} - encode( "[\x01]" ) == "[\\x01]" for: "[\x01]" == "[\x01]"
|
||||
ok {test-number} - encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F]" == "[\x7F]"
|
||||
# XmlWriter writes boolean attributes as true/false
|
||||
ok {test-number} - stream.str(), ContainsSubstring(R"(attr1="true")") && ContainsSubstring(R"(attr2="false")") for: "<?xml version="1.0" encoding="UTF-8"?> <Element1 attr1="true" attr2="false"/> " ( contains: "attr1="true"" and contains: "attr2="false"" )
|
||||
# a succeeding test can still be skipped
|
||||
ok {test-number} -
|
||||
# a succeeding test can still be skipped
|
||||
ok {test-number} - # SKIP
|
||||
# analyse no analysis
|
||||
ok {test-number} - analysis.mean.point.count() == 23 for: 23.0 == 23
|
||||
# analyse no analysis
|
||||
@@ -3764,6 +3882,12 @@ ok {test-number} - convertToBits( -0. ) == ( 1ULL << 63 ) for: 92233720368547758
|
||||
ok {test-number} - convertToBits( std::numeric_limits<float>::denorm_min() ) == 1 for: 1 == 1
|
||||
# convertToBits
|
||||
ok {test-number} - convertToBits( std::numeric_limits<double>::denorm_min() ) == 1 for: 1 == 1
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} - # SKIP 'skipping because answer = 41'
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} -
|
||||
# dynamic skipping works with generators
|
||||
ok {test-number} - # SKIP 'skipping because answer = 43'
|
||||
# empty tags are not allowed
|
||||
ok {test-number} - Catch::TestCaseInfo("", { "test with an empty tag", "[]" }, dummySourceLineInfo)
|
||||
# erfc_inv
|
||||
@@ -3782,6 +3906,22 @@ ok {test-number} -
|
||||
ok {test-number} -
|
||||
# even more nested SECTION tests
|
||||
ok {test-number} -
|
||||
# failed assertions before SKIP cause test case to fail
|
||||
not ok {test-number} - 3 == 4
|
||||
# failed assertions before SKIP cause test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing for some generator values causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
# failing for some generator values causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing for some generator values causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
# failing for some generator values causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing in some unskipped sections causes entire test case to fail
|
||||
ok {test-number} - # SKIP
|
||||
# failing in some unskipped sections causes entire test case to fail
|
||||
not ok {test-number} - explicitly
|
||||
# is_unary_function
|
||||
ok {test-number} - with 1 message: 'Catch::Clara::Detail::is_unary_function<decltype(unary1)>::value'
|
||||
# is_unary_function
|
||||
@@ -3890,6 +4030,8 @@ ok {test-number} - a != b for: 1 != 2
|
||||
ok {test-number} - b != a for: 2 != 1
|
||||
# nested SECTION tests
|
||||
ok {test-number} - a != b for: 1 != 2
|
||||
# nested sections can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
# non streamable - with conv. op
|
||||
ok {test-number} - s == "7" for: "7" == "7"
|
||||
# non-copyable objects
|
||||
@@ -4054,12 +4196,20 @@ ok {test-number} - Timing.elapsed >= time for: 128 ns >= 100 ns
|
||||
ok {test-number} - Timing.result == Timing.iterations + 17 for: 145 == 145
|
||||
# run_for_at_least, int
|
||||
ok {test-number} - Timing.iterations >= time.count() for: 128 >= 100
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} -
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
# sections can be skipped dynamically at runtime
|
||||
ok {test-number} -
|
||||
# send a single char to INFO
|
||||
not ok {test-number} - false with 1 message: '3'
|
||||
# sends information to INFO
|
||||
not ok {test-number} - false with 2 messages: 'hi' and 'i := 7'
|
||||
# shortened hide tags are split apart
|
||||
ok {test-number} - testcase.tags, VectorContains( Tag( "magic-tag" ) ) && VectorContains( Tag( "."_catch_sr ) ) for: { {?}, {?} } ( Contains: {?} and Contains: {?} )
|
||||
# skipped tests can optionally provide a reason
|
||||
ok {test-number} - # SKIP 'skipping because answer = 43'
|
||||
# splitString
|
||||
ok {test-number} - splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
|
||||
# splitString
|
||||
@@ -4142,6 +4292,8 @@ ok {test-number} - strlen(std::get<0>(data)) == static_cast<size_t>(std::get<1>(
|
||||
ok {test-number} - testcase.tags.size() == 1 for: 1 == 1
|
||||
# tags with dots in later positions are not parsed as hidden
|
||||
ok {test-number} - testcase.tags[0].original == "magic.tag"_catch_sr for: magic.tag == magic.tag
|
||||
# tests can be skipped dynamically at runtime
|
||||
ok {test-number} - # SKIP
|
||||
# thrown std::strings are translated
|
||||
not ok {test-number} - unexpected exception with message: 'Why would you throw a std::string?'
|
||||
# toString on const wchar_t const pointer returns the string contents
|
||||
@@ -4314,5 +4466,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..2159
|
||||
1..2237
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user