mirror of
https://github.com/catchorg/Catch2.git
synced 2025-10-15 16:25:31 +02:00
Compare commits
79 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 | ||
|
ab6c7375be | ||
|
24607694cb | ||
|
28e651f152 | ||
|
2d7be1f7de | ||
|
1f3b51e903 | ||
|
a20200be7e | ||
|
291c502f66 | ||
|
ae1644e7e9 |
@@ -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
|
||||
|
16
.github/workflows/linux-simple-builds.yml
vendored
16
.github/workflows/linux-simple-builds.yml
vendored
@@ -65,6 +65,22 @@ jobs:
|
||||
build_type: Release
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
- cxx: clang++-10
|
||||
build_type: Debug
|
||||
std: 20
|
||||
other_pkgs: clang-10
|
||||
- cxx: clang++-10
|
||||
build_type: Release
|
||||
std: 20
|
||||
other_pkgs: clang-10
|
||||
- cxx: g++-10
|
||||
build_type: Debug
|
||||
std: 20
|
||||
other_pkgs: g++-10
|
||||
- cxx: g++-10
|
||||
build_type: Release
|
||||
std: 20
|
||||
other_pkgs: g++-10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
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.0 # 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.
|
||||
|
||||
|
22
README.md
22
README.md
@@ -1,5 +1,5 @@
|
||||
<a id="top"></a>
|
||||

|
||||

|
||||
|
||||
[](https://github.com/catchorg/catch2/releases)
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/linux-simple-builds.yml)
|
||||
@@ -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.
|
||||
|
48
appveyor.yml
48
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"
|
||||
@@ -92,38 +75,9 @@ environment:
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
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
|
||||
configuration: Debug
|
BIN
data/artwork/catch2-logo-small-with-background.png
Normal file
BIN
data/artwork/catch2-logo-small-with-background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@@ -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,10 @@
|
||||
|
||||
# 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>
|
||||
[3.1.0](#310)<br>
|
||||
@@ -53,6 +57,74 @@
|
||||
|
||||
|
||||
|
||||
## 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
|
||||
* Fix the reworked decomposer to work with older (pre 9) GCC versions (#2571)
|
||||
* **This required more significant changes to properly support C++20, there might be bugs.**
|
||||
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### 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.0', # 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,9 +88,11 @@ 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
|
||||
${SOURCES_DIR}/internal/catch_logical_traits.hpp
|
||||
${SOURCES_DIR}/internal/catch_message_info.hpp
|
||||
${SOURCES_DIR}/internal/catch_meta.hpp
|
||||
${SOURCES_DIR}/internal/catch_move_and_forward.hpp
|
||||
@@ -251,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
|
||||
@@ -320,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
|
||||
@@ -328,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})
|
||||
@@ -371,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}>
|
||||
)
|
||||
|
||||
@@ -425,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
|
||||
@@ -446,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
|
||||
@@ -486,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,10 +70,12 @@
|
||||
#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>
|
||||
#include <catch2/internal/catch_list.hpp>
|
||||
#include <catch2/internal/catch_logical_traits.hpp>
|
||||
#include <catch2/internal/catch_message_info.hpp>
|
||||
#include <catch2/internal/catch_meta.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.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, 0, "", 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 0
|
||||
#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 {
|
||||
|
@@ -28,6 +28,13 @@ namespace Catch {
|
||||
# pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
#if defined( __clang__ )
|
||||
# pragma clang diagnostic push
|
||||
// Did you know that comparing floats with `0` directly
|
||||
// is super-duper dangerous in unevaluated context?
|
||||
# pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
#define CATCH_DEFINE_COMPARABLE_TRAIT( id, op ) \
|
||||
template <typename, typename, typename = void> \
|
||||
struct is_##id##_comparable : std::false_type {}; \
|
||||
@@ -56,6 +63,9 @@ namespace Catch {
|
||||
|
||||
#if defined( __GNUC__ ) && !defined( __clang__ )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined( __clang__ )
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -10,9 +10,9 @@
|
||||
|
||||
#include <catch2/catch_tostring.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_meta.hpp>
|
||||
#include <catch2/internal/catch_compare_traits.hpp>
|
||||
#include <catch2/internal/catch_test_failure_exception.hpp>
|
||||
#include <catch2/internal/catch_logical_traits.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <iosfwd>
|
||||
@@ -36,6 +36,9 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
template <typename T>
|
||||
struct always_false : std::false_type {};
|
||||
|
||||
class ITransientExpression {
|
||||
bool m_isBinaryExpression;
|
||||
bool m_result;
|
||||
@@ -165,112 +168,99 @@ namespace Catch {
|
||||
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t< \
|
||||
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT const&> { \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
std::is_arithmetic<RhsT>::value, \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
Detail::is_eq_0_comparable<LhsT>:: \
|
||||
value && /* We allow long because we want \
|
||||
`ptr op NULL to be accepted */ \
|
||||
( std::is_same<RhsT, int>::value || \
|
||||
std::is_same<RhsT, long>::value ), \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
if ( rhs != 0 ) { \
|
||||
throw_test_failure_exception(); \
|
||||
} \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
Detail::is_eq_0_comparable<LhsT>, \
|
||||
/* We allow long because we want `ptr op NULL` to be accepted */ \
|
||||
Detail::disjunction<std::is_same<RhsT, int>, \
|
||||
std::is_same<RhsT, long>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
if ( rhs != 0 ) { throw_test_failure_exception(); } \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
Detail::is_eq_0_comparable<RhsT>:: \
|
||||
value && /* We allow long because we want \
|
||||
`ptr op NULL` to be accepted */ \
|
||||
( std::is_same<LhsT, int>::value || \
|
||||
std::is_same<LhsT, long>::value ), \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
if ( lhs.m_lhs != 0 ) { \
|
||||
throw_test_failure_exception(); \
|
||||
} \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
Detail::is_eq_0_comparable<RhsT>, \
|
||||
/* We allow long because we want `ptr op NULL` to be accepted */ \
|
||||
Detail::disjunction<std::is_same<LhsT, int>, \
|
||||
std::is_same<LhsT, long>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
|
||||
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
}
|
||||
|
||||
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
|
||||
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( ne, != )
|
||||
|
||||
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t< \
|
||||
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||
int> = 0> \
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT const&> { \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
std::is_arithmetic<RhsT>::value, \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
Detail::is_##id##_0_comparable<LhsT>::value && \
|
||||
std::is_same<RhsT, int>::value, \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
if ( rhs != 0 ) { \
|
||||
throw_test_failure_exception(); \
|
||||
} \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
Detail::is_##id##_0_comparable<LhsT>, \
|
||||
std::is_same<RhsT, int>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
if ( rhs != 0 ) { throw_test_failure_exception(); } \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template < \
|
||||
typename RhsT, \
|
||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||
Detail::is_##id##_0_comparable<RhsT>::value && \
|
||||
std::is_same<LhsT, int>::value, \
|
||||
int> = 0> \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->BinaryExpr<LhsT, RhsT> { \
|
||||
if ( lhs.m_lhs != 0 ) { \
|
||||
throw_test_failure_exception(); \
|
||||
} \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
Detail::is_##id##_0_comparable<RhsT>, \
|
||||
std::is_same<LhsT, int>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
|
||||
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
}
|
||||
|
||||
@@ -282,15 +272,22 @@ namespace Catch {
|
||||
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
|
||||
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op) \
|
||||
template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0> \
|
||||
friend auto operator op ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> { \
|
||||
return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0> \
|
||||
friend auto operator op ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> { \
|
||||
return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
}
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t<std::is_arithmetic<RhsT>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
}
|
||||
|
||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
|
||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
|
||||
|
@@ -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
|
44
src/catch2/internal/catch_logical_traits.hpp
Normal file
44
src/catch2/internal/catch_logical_traits.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
// 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_LOGICAL_TRAITS_HPP_INCLUDED
|
||||
#define CATCH_LOGICAL_TRAITS_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
|
||||
#if defined( __cpp_lib_logical_traits ) && __cpp_lib_logical_traits >= 201510
|
||||
|
||||
using std::conjunction;
|
||||
using std::disjunction;
|
||||
using std::negation;
|
||||
|
||||
#else
|
||||
|
||||
template <class...> struct conjunction : std::true_type {};
|
||||
template <class B1> struct conjunction<B1> : B1 {};
|
||||
template <class B1, class... Bn>
|
||||
struct conjunction<B1, Bn...>
|
||||
: std::conditional_t<bool( B1::value ), conjunction<Bn...>, B1> {};
|
||||
|
||||
template <class...> struct disjunction : std::false_type {};
|
||||
template <class B1> struct disjunction<B1> : B1 {};
|
||||
template <class B1, class... Bn>
|
||||
struct disjunction<B1, Bn...>
|
||||
: std::conditional_t<bool( B1::value ), B1, disjunction<Bn...>> {};
|
||||
|
||||
template <class B>
|
||||
struct negation : std::integral_constant<bool, !bool(B::value)> {};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_LOGICAL_TRAITS_HPP_INCLUDED
|
@@ -11,10 +11,9 @@
|
||||
#include <type_traits>
|
||||
|
||||
namespace Catch {
|
||||
template<typename T>
|
||||
struct always_false : std::false_type {};
|
||||
template <typename>
|
||||
struct true_given : std::true_type {};
|
||||
|
||||
template <typename> struct true_given : std::true_type {};
|
||||
struct is_callable_tester {
|
||||
template <typename Fun, typename... Args>
|
||||
static true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
|
||||
|
@@ -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
|
@@ -11,6 +11,7 @@
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_logical_traits.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
@@ -56,20 +57,6 @@ namespace Matchers {
|
||||
return arr;
|
||||
}
|
||||
|
||||
#if defined( __cpp_lib_logical_traits ) && __cpp_lib_logical_traits >= 201510
|
||||
|
||||
using std::conjunction;
|
||||
|
||||
#else // __cpp_lib_logical_traits
|
||||
|
||||
template<typename... Cond>
|
||||
struct conjunction : std::true_type {};
|
||||
|
||||
template<typename Cond, typename... Rest>
|
||||
struct conjunction<Cond, Rest...> : std::integral_constant<bool, Cond::value && conjunction<Rest...>::value> {};
|
||||
|
||||
#endif // __cpp_lib_logical_traits
|
||||
|
||||
template<typename T>
|
||||
using is_generic_matcher = std::is_base_of<
|
||||
Catch::Matchers::MatcherGenericBase,
|
||||
@@ -77,7 +64,7 @@ namespace Matchers {
|
||||
>;
|
||||
|
||||
template<typename... Ts>
|
||||
using are_generic_matchers = conjunction<is_generic_matcher<Ts>...>;
|
||||
using are_generic_matchers = Catch::Detail::conjunction<is_generic_matcher<Ts>...>;
|
||||
|
||||
template<typename T>
|
||||
using is_matcher = std::is_base_of<
|
||||
|
@@ -93,9 +93,11 @@ 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',
|
||||
'internal/catch_logical_traits.hpp',
|
||||
'internal/catch_message_info.hpp',
|
||||
'internal/catch_meta.hpp',
|
||||
'internal/catch_move_and_forward.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
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user