Compare commits

..

19 Commits

Author SHA1 Message Date
Martin Hořeňovský
b9dd1936e5 v2.7.1 2019-04-08 13:38:00 +02:00
Martin Hořeňovský
293d617c49 Merge pull request #1592 from robinlinden/fix-cmake-integration-typo
Use correct filename in CMake integration docs
2019-04-08 13:20:41 +02:00
Robin Lindén
7be35af167 Use correct filename in CMake integration docs 2019-04-07 15:41:34 +02:00
Martin Hořeňovský
08147a23f9 Fix ObjC matchers
Closes #1571
2019-04-03 20:32:11 +02:00
Ziv Shahaf
8af8704089 support for printing test filters (PR #1585) 2019-04-03 20:24:52 +02:00
Martin Hořeňovský
3816e99d0c Add GENERATE_COPY and GENERATE_VAR capturing generator macros 2019-03-31 14:11:10 +02:00
Martin Hořeňovský
b77cec05c0 Fix test tag parsing to split [.foo] into [.][foo] 2019-03-29 10:48:56 +01:00
Omer Ozarslan
54089c4c8c Deducing return type of map generator helper (#1576)
* Deduce map return type implicitly

Giving the first template argument to map generator function to deduce
return type is now optional even if the return type is different from
the type generated by mapped generator.
2019-03-24 15:44:22 +01:00
Martin Hořeňovský
296d447452 Merge pull request #1575 from alabuzhev/warning_ntstatus
Suppress warning caused by ntstatus.h inclusion
2019-03-20 15:22:27 +01:00
Alex Alabuzhev
0531965349 Suppress warning caused by ntstatus.h inclusion 2019-03-19 23:57:56 +00:00
Tadeusz Puźniakowski
a1cdff4f18 raspigcd - opensource-users
Added raspigcd that uses Catch2 for tests
2019-03-19 20:35:59 +01:00
Steve Hollasch
4611125801 generators.md: fix extraneous back tick in doc 2019-03-14 09:14:02 +01:00
Clare Macrae
e509012e64 Update blog URL and fic typos in tutorial.md 2019-03-09 18:02:29 +01:00
Clare Macrae
448825db03 Readability improvements for assertions.md 2019-03-09 18:02:29 +01:00
Clare Macrae
0fff8e7791 Add ApprovalTests.cpp to list of open source users 2019-03-09 18:02:29 +01:00
Martin Hořeňovský
68a3c129ac Merge pull request #1562 from claremacrae/patch-2
Update url of blog post
2019-03-09 17:35:08 +01:00
Martin Hořeňovský
1ce5ec9b74 Merge pull request #1565 from inobelar/patch-1
Added override keyword near IntRange::describe() method
2019-03-09 17:33:42 +01:00
Yurii Nakonechnyi
37a4e32319 Added override keyword near IntRange::describe() method 2019-03-09 15:05:27 +02:00
Clare Macrae
0424c9a62c Update url of blog post 2019-03-08 08:56:00 +00:00
39 changed files with 908 additions and 147 deletions

View File

@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON) set(NOT_SUBPROJECT ON)
endif() endif()
project(Catch2 LANGUAGES CXX VERSION 2.7.0) project(Catch2 LANGUAGES CXX VERSION 2.7.1)
# Provide path for scripts # Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")

View File

@@ -5,17 +5,17 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2) [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2) [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2) [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/byNJIivVphHo170P) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/ZFBZ5XbLA9F1gzKi)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.7.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a> <a href="https://github.com/catchorg/Catch2/releases/download/v2.7.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released! ## Catch2 is released!
If you've been using an earlier version of Catch, please see the If you've been using an earlier version of Catch, please see the
Breaking Changes section of [the release notes](https://github.com/catchorg/Catch2/releases/tag/v2.0.1) Breaking Changes section of [the release notes](https://github.com/catchorg/Catch2/releases/tag/v2.0.1)
before moving to Catch2. You might also like to read [this blog post](http://www.levelofindirection.com/journal/2017/11/3/catch2-released.html) for more details. before moving to Catch2. You might also like to read [this blog post](https://levelofindirection.com/blog/catch2-released.html) for more details.
## What's the Catch? ## What's the Catch?

View File

@@ -10,7 +10,7 @@
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc). Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxiliary macros as well. We'll describe all of these here. Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there is a rich set of auxiliary macros as well. We'll describe all of these here.
Most of these macros come in two forms: Most of these macros come in two forms:
@@ -61,7 +61,7 @@ Catch provides a way to perform tolerant comparisons of floating point values th
REQUIRE( performComputation() == Approx( 2.1 ) ); REQUIRE( performComputation() == Approx( 2.1 ) );
``` ```
Catch also provides a UDL for `Approx`; `_a`. It resides in Catch also provides a user-defined literal for `Approx`; `_a`. It resides in
the `Catch::literals` namespace and can be used like so: the `Catch::literals` namespace and can be used like so:
```cpp ```cpp
using namespace Catch::literals; using namespace Catch::literals;

View File

@@ -48,7 +48,7 @@ If Catch2 has been installed in system, both of these can be used after
doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
to your CMake module path. to your CMake module path.
### `Catch.cmake` and `AddCatchTests.cmake` ### `Catch.cmake` and `CatchAddTests.cmake`
`Catch.cmake` provides function `catch_discover_tests` to get tests from `Catch.cmake` provides function `catch_discover_tests` to get tests from
a target. This function works by running the resulting executable with a target. This function works by running the resulting executable with

View File

@@ -57,11 +57,11 @@ type, making their usage much nicer. These are
* `filter(predicate, GeneratorWrapper<T>&&)` for `FilterGenerator<T, Predicate>` * `filter(predicate, GeneratorWrapper<T>&&)` for `FilterGenerator<T, Predicate>`
* `take(count, GeneratorWrapper<T>&&)` for `TakeGenerator<T>` * `take(count, GeneratorWrapper<T>&&)` for `TakeGenerator<T>`
* `repeat(repeats, GeneratorWrapper<T>&&)` for `RepeatGenerator<T>` * `repeat(repeats, GeneratorWrapper<T>&&)` for `RepeatGenerator<T>`
* `map(func, GeneratorWrapper<T>&&)` for `MapGenerator<T, T, Func>` (map `T` to `T`) * `map(func, GeneratorWrapper<T>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`, deduced from `Func`)
* `map<T>(func, GeneratorWrapper<U>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`) * `map<T>(func, GeneratorWrapper<U>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`)
* `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>` * `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>`
* `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator` * `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
* `range(start, end)` for `RangeGenerator<T>` with a step size of `1` * `range(start, end)` for `RangeGenerator<T>` with a step size of `1`
* `range(start, end, step)` for `RangeGenerator<T>` with a custom step size * `range(start, end, step)` for `RangeGenerator<T>` with a custom step size
@@ -90,7 +90,11 @@ used with other generators as arguments, such as `auto i = GENERATE(0, 2,
take(100, random(300, 3000)));`. This is useful e.g. if you know that take(100, random(300, 3000)));`. This is useful e.g. if you know that
specific inputs are problematic and want to test them separately/first. specific inputs are problematic and want to test them separately/first.
**For safety reasons, you cannot use variables inside the `GENERATE` macro.** **For safety reasons, you cannot use variables inside the `GENERATE` macro.
This is done because the generator expression _will_ outlive the outside
scope and thus capturing references is dangerous. If you need to use
variables inside the generator expression, make sure you thought through
the lifetime implications and use `GENERATE_COPY` or `GENERATE_REF`.**
You can also override the inferred type by using `as<type>` as the first You can also override the inferred type by using `as<type>` as the first
argument to the macro. This can be useful when dealing with string literals, argument to the macro. This can be useful when dealing with string literals,
@@ -98,7 +102,7 @@ if you want them to come out as `std::string`:
```cpp ```cpp
TEST_CASE("type conversion", "[generators]") { TEST_CASE("type conversion", "[generators]") {
auto str = GENERATE(as<std::string>{}, "a", "bb", "ccc");` auto str = GENERATE(as<std::string>{}, "a", "bb", "ccc");
REQUIRE(str.size() > 0); REQUIRE(str.size() > 0);
} }
``` ```

View File

@@ -17,6 +17,7 @@
- Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp) - Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp)
- Generators: [Use map to convert types in GENERATE expression](../examples/301-Gen-MapTypeConversion.cpp) - Generators: [Use map to convert types in GENERATE expression](../examples/301-Gen-MapTypeConversion.cpp)
- Generators: [Use variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp) - Generators: [Use variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp)
- Generators: [Use custom variable capture in generator expressions](../examples/311-Gen-CustomCapture.cpp)
## Planned ## Planned

View File

@@ -100,7 +100,7 @@ public:
// include any provided data (the begin/ end in this case) and // include any provided data (the begin/ end in this case) and
// be written as if it were stating a fact (in the output it will be // be written as if it were stating a fact (in the output it will be
// preceded by the value under test). // preceded by the value under test).
virtual std::string describe() const { virtual std::string describe() const override {
std::ostringstream ss; std::ostringstream ss;
ss << "is between " << m_begin << " and " << m_end; ss << "is between " << m_begin << " and " << m_end;
return ss.str(); return ss.str();

View File

@@ -17,6 +17,9 @@ Listing a project here does not imply endorsement and the plan is to keep these
## Libraries & Frameworks ## Libraries & Frameworks
### [ApprovalTests.cpp](https://github.com/approvals/ApprovalTests.cpp)
C++11 implementation of Approval Tests, for quick, convenient testing of legacy code.
### [Azmq](https://github.com/zeromq/azmq) ### [Azmq](https://github.com/zeromq/azmq)
Boost Asio style bindings for ZeroMQ. Boost Asio style bindings for ZeroMQ.
@@ -100,6 +103,9 @@ MAME originally stood for Multiple Arcade Machine Emulator.
### [Newsbeuter](https://github.com/akrennmair/newsbeuter) ### [Newsbeuter](https://github.com/akrennmair/newsbeuter)
Newsbeuter is an open-source RSS/Atom feed reader for text terminals. Newsbeuter is an open-source RSS/Atom feed reader for text terminals.
### [raspigcd](https://github.com/pantadeusz/raspigcd)
Low level CLI app and library for execution of GCODE on Raspberry Pi without any additional microcontrolers (just RPi + Stepsticks).
### [SpECTRE](https://github.com/sxs-collaboration/spectre) ### [SpECTRE](https://github.com/sxs-collaboration/spectre)
SpECTRE is a code for multi-scale, multi-physics problems in astrophysics and gravitational physics. SpECTRE is a code for multi-scale, multi-physics problems in astrophysics and gravitational physics.

View File

@@ -2,6 +2,7 @@
# Release notes # Release notes
**Contents**<br> **Contents**<br>
[2.7.1](#271)<br>
[2.7.0](#270)<br> [2.7.0](#270)<br>
[2.6.1](#261)<br> [2.6.1](#261)<br>
[2.6.0](#260)<br> [2.6.0](#260)<br>
@@ -21,6 +22,19 @@
[Older versions](#older-versions)<br> [Older versions](#older-versions)<br>
[Even Older versions](#even-older-versions)<br> [Even Older versions](#even-older-versions)<br>
## 2.7.1
### Improvements
* Reporters now print out the filters applied to test cases (#1550, #1585)
* Added `GENERATE_COPY` and `GENERATE_VAR` macros that can use variables inside the generator expression
* Because of the significant danger of lifetime issues, the default `GENERATE` macro still does not allow variables
* The `map` generator helper now deduces the mapped return type (#1576)
### Fixes
* Fixed ObjC++ compilation (#1571)
* Fixed test tag parsing so that `[.foo]` is now parsed as `[.][foo]`.
* Suppressed warning caused by the Windows headers defining SE codes in different manners (#1575)
## 2.7.0 ## 2.7.0
### Improvements ### Improvements

View File

@@ -23,7 +23,7 @@ The full source for Catch2, including test projects, documentation, and other th
## Where to put it? ## Where to put it?
Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html). Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](https://levelofindirection.com/blog/unit-testing-in-cpp-and-objective-c-just-got-ridiculously-easier-still.html).
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary. The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
@@ -103,7 +103,7 @@ Of course there are still more issues to deal with. For example we'll hit proble
### What did we do here? ### What did we do here?
Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take moment to consider those before we move on. Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take a moment to consider those before we move on.
1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md#top). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md#top)). 1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md#top). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md#top)).
2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see <a href="#test-cases-and-sections">Test cases and Sections</a>, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md#top) for more information on running tests. 2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see <a href="#test-cases-and-sections">Test cases and Sections</a>, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md#top) for more information on running tests.
@@ -159,7 +159,7 @@ This works because the ```SECTION``` macro contains an if statement that calls b
So far so good - this is already an improvement on the setup/teardown approach because now we see our setup code inline and use the stack. So far so good - this is already an improvement on the setup/teardown approach because now we see our setup code inline and use the stack.
The power of sections really shows, however, when we need to execute a sequence of, checked, operations. Continuing the vector example, we might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing. We can do that, naturally, like so: The power of sections really shows, however, when we need to execute a sequence of checked operations. Continuing the vector example, we might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing. We can do that, naturally, like so:
```c++ ```c++
SECTION( "reserving bigger changes capacity but not size" ) { SECTION( "reserving bigger changes capacity but not size" ) {

View File

@@ -8,41 +8,6 @@
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include <random>
// Lets start by implementing a parametrizable double generator
class RandomDoubleGenerator : public Catch::Generators::IGenerator<double> {
std::minstd_rand m_rand;
std::uniform_real_distribution<> m_dist;
double current_number;
public:
RandomDoubleGenerator(double low, double high):
m_rand(std::random_device{}()),
m_dist(low, high)
{
static_cast<void>(next());
}
double const& get() const override;
bool next() override {
current_number = m_dist(m_rand);
return true;
}
};
// Avoids -Wweak-vtables
double const& RandomDoubleGenerator::get() const {
return current_number;
}
// Also provide a nice shortcut for creating the generator
Catch::Generators::GeneratorWrapper<double> random(double low, double high) {
return Catch::Generators::GeneratorWrapper<double>(std::unique_ptr<Catch::Generators::IGenerator<double>>(new RandomDoubleGenerator(low, high)));
}
TEST_CASE("Generate random doubles across different ranges", TEST_CASE("Generate random doubles across different ranges",
"[generator][example][advanced]") { "[generator][example][advanced]") {
// Workaround for old libstdc++ // Workaround for old libstdc++
@@ -55,16 +20,12 @@ TEST_CASE("Generate random doubles across different ranges",
})); }));
// This will not compile (intentionally), because it accesses a variable // This will not compile (intentionally), because it accesses a variable
// auto number = GENERATE(take(50, random(r.first, r.second))); // auto number = GENERATE(take(50, random(std::get<0>(r), std::get<1>(r))));
// We have to manually register the generators instead // GENERATE_COPY copies all variables mentioned inside the expression
// Notice that we are using value capture in the lambda, to avoid lifetime issues // thus this will work.
auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, auto number = GENERATE_COPY(take(50, random(std::get<0>(r), std::get<1>(r))));
[=]{
using namespace Catch::Generators;
return makeGenerators(take(50, random(std::get<0>(r), std::get<1>(r))));
}
);
REQUIRE(std::abs(number) > 0); REQUIRE(std::abs(number) > 0);
} }

View File

@@ -0,0 +1,41 @@
// 311-Gen-CustomCapture.cpp
// Shows how to provide custom capture list to the generator expression
// Note that using variables inside generators is dangerous and should
// be done only if you know what you are doing, because the generators
// _WILL_ outlive the variables. Also, even if you know what you are
// doing, you should probably use GENERATE_COPY or GENERATE_REF macros
// instead. However, if your use case requires having a
// per-variable custom capture list, this example shows how to achieve
// that.
#include <catch2/catch.hpp>
TEST_CASE("Generate random doubles across different ranges",
"[generator][example][advanced]") {
// Workaround for old libstdc++
using record = std::tuple<double, double>;
// Set up 3 ranges to generate numbers from
auto r1 = GENERATE(table<double, double>({
record{3, 4},
record{-4, -3},
record{10, 1000}
}));
auto r2(r1);
// This will take r1 by reference and r2 by value.
// Note that there are no advantages for doing so in this example,
// it is done only for expository purposes.
auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO,
[&r1, r2]{
using namespace Catch::Generators;
return makeGenerators(take(50, random(std::get<0>(r1), std::get<1>(r2))));
}
);
REQUIRE(std::abs(number) > 0);
}
// Compiling and running this file will result in 150 successful assertions

View File

@@ -47,6 +47,7 @@ set( SOURCES_IDIOMATIC_TESTS
300-Gen-OwnGenerator.cpp 300-Gen-OwnGenerator.cpp
301-Gen-MapTypeConversion.cpp 301-Gen-MapTypeConversion.cpp
310-Gen-VariablesInGenerators.cpp 310-Gen-VariablesInGenerators.cpp
311-Gen-CustomCapture.cpp
) )
# main-s for reporter-specific test sources: # main-s for reporter-specific test sources:

View File

@@ -11,7 +11,7 @@
#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 7 #define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 0 #define CATCH_VERSION_PATCH 1
#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header

View File

@@ -82,7 +82,7 @@ namespace Catch {
std::string getProcessName() const; std::string getProcessName() const;
std::string const& getReporterName() const; std::string const& getReporterName() const;
std::vector<std::string> const& getTestsOrTags() const; std::vector<std::string> const& getTestsOrTags() const override;
std::vector<std::string> const& getSectionsToRun() const override; std::vector<std::string> const& getSectionsToRun() const override;
virtual TestSpec const& testSpec() const override; virtual TestSpec const& testSpec() const override;

View File

@@ -37,10 +37,10 @@ namespace Catch {
// Windows can easily distinguish between SO and SigSegV, // Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently. // but SigInt, SigTerm, etc are handled differently.
static SignalDefs signalDefs[] = { static SignalDefs signalDefs[] = {
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
}; };
LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {

View File

@@ -201,7 +201,10 @@ namespace Generators {
} // namespace Catch } // namespace Catch
#define GENERATE( ... ) \ #define GENERATE( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
#define GENERATE_COPY( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
#define GENERATE_REF( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED

View File

@@ -169,16 +169,28 @@ namespace Generators {
} }
}; };
template <typename T, typename U, typename Func> #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
// replaced with std::invoke_result here. Also *_t format is preferred over
// typename *::type format.
template <typename Func, typename U>
using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
#else
template <typename Func, typename U>
using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
#endif
template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>( return GeneratorWrapper<T>(
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
); );
} }
template <typename T, typename Func>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<T>&& generator) { template <typename T, typename U, typename Func>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>( return GeneratorWrapper<T>(
pf::make_unique<MapGenerator<T, T, Func>>(std::forward<Func>(function), std::move(generator)) pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
); );
} }

View File

@@ -69,6 +69,7 @@ namespace Catch {
virtual ShowDurations::OrNot showDurations() const = 0; virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0; virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0; virtual bool hasTestFilters() const = 0;
virtual std::vector<std::string> const& getTestsOrTags() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0; virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0; virtual int benchmarkResolutionMultiple() const = 0;

View File

@@ -116,7 +116,7 @@ namespace Catch {
arcSafeRelease( m_substr ); arcSafeRelease( m_substr );
} }
bool match( NSString* arg ) const override { bool match( NSString* const& str ) const override {
return false; return false;
} }
@@ -126,7 +126,7 @@ namespace Catch {
struct Equals : StringHolder { struct Equals : StringHolder {
Equals( NSString* substr ) : StringHolder( substr ){} Equals( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr]; [str isEqualToString:m_substr];
} }
@@ -139,7 +139,7 @@ namespace Catch {
struct Contains : StringHolder { struct Contains : StringHolder {
Contains( NSString* substr ) : StringHolder( substr ){} Contains( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound; [str rangeOfString:m_substr].location != NSNotFound;
} }
@@ -152,7 +152,7 @@ namespace Catch {
struct StartsWith : StringHolder { struct StartsWith : StringHolder {
StartsWith( NSString* substr ) : StringHolder( substr ){} StartsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0; [str rangeOfString:m_substr].location == 0;
} }
@@ -164,7 +164,7 @@ namespace Catch {
struct EndsWith : StringHolder { struct EndsWith : StringHolder {
EndsWith( NSString* substr ) : StringHolder( substr ){} EndsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length]; [str rangeOfString:m_substr].location == [str length] - [m_substr length];
} }

View File

@@ -75,6 +75,12 @@ namespace Catch {
else if( prop == TestCaseInfo::None ) else if( prop == TestCaseInfo::None )
enforceNotReservedTag( tag, _lineInfo ); enforceNotReservedTag( tag, _lineInfo );
// Merged hide tags like `[.approvals]` should be added as
// `[.][approvals]`. The `[.]` is added at later point, so
// we only strip the prefix
if (startsWith(tag, '.') && tag.size() > 1) {
tag.erase(0, 1);
}
tags.push_back( tag ); tags.push_back( tag );
tag.clear(); tag.clear();
inTag = false; inTag = false;

View File

@@ -37,7 +37,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 7, 0, "", 0 ); static Version version( 2, 7, 1, "", 0 );
return version; return version;
} }

View File

@@ -41,6 +41,20 @@ namespace Catch {
return std::string(buffer); return std::string(buffer);
} }
std::string serializeFilters( std::vector<std::string> const& container ) {
ReusableStringStream oss;
bool first = true;
for (auto&& filter : container)
{
if (!first)
oss << ' ';
else
first = false;
oss << filter;
}
return oss.str();
}
TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
:StreamingReporterBase(_config) {} :StreamingReporterBase(_config) {}

View File

@@ -25,6 +25,8 @@ namespace Catch {
// Returns double formatted as %.3f (format expected on output) // Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration ); std::string getFormattedDuration( double duration );
std::string serializeFilters( std::vector<std::string> const& container );
template<typename DerivedT> template<typename DerivedT>
struct StreamingReporterBase : IStreamingReporter { struct StreamingReporterBase : IStreamingReporter {
@@ -52,6 +54,7 @@ namespace Catch {
void testRunStarting(TestRunInfo const& _testRunInfo) override { void testRunStarting(TestRunInfo const& _testRunInfo) override {
currentTestRunInfo = _testRunInfo; currentTestRunInfo = _testRunInfo;
} }
void testGroupStarting(GroupInfo const& _groupInfo) override { void testGroupStarting(GroupInfo const& _groupInfo) override {
currentGroupInfo = _groupInfo; currentGroupInfo = _groupInfo;
} }

View File

@@ -441,6 +441,10 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
stream << std::endl; stream << std::endl;
StreamingReporterBase::testRunEnded(_testRunStats); StreamingReporterBase::testRunEnded(_testRunStats);
} }
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
StreamingReporterBase::testRunStarting(_testInfo);
printTestFilters();
}
void ConsoleReporter::lazyPrint() { void ConsoleReporter::lazyPrint() {
@@ -622,6 +626,11 @@ void ConsoleReporter::printSummaryDivider() {
stream << getLineOfChars<'-'>() << '\n'; stream << getLineOfChars<'-'>() << '\n';
} }
void ConsoleReporter::printTestFilters() {
if (m_config->testSpec().hasFilters())
stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
}
CATCH_REGISTER_REPORTER("console", ConsoleReporter) CATCH_REGISTER_REPORTER("console", ConsoleReporter)
} // end namespace Catch } // end namespace Catch

View File

@@ -46,7 +46,7 @@ namespace Catch {
void testCaseEnded(TestCaseStats const& _testCaseStats) override; void testCaseEnded(TestCaseStats const& _testCaseStats) override;
void testGroupEnded(TestGroupStats const& _testGroupStats) override; void testGroupEnded(TestGroupStats const& _testGroupStats) override;
void testRunEnded(TestRunStats const& _testRunStats) override; void testRunEnded(TestRunStats const& _testRunStats) override;
void testRunStarting(TestRunInfo const& _testRunInfo) override;
private: private:
void lazyPrint(); void lazyPrint();
@@ -69,6 +69,7 @@ namespace Catch {
void printTotalsDivider(Totals const& totals); void printTotalsDivider(Totals const& totals);
void printSummaryDivider(); void printSummaryDivider();
void printTestFilters();
private: private:
bool m_headerPrinted = false; bool m_headerPrinted = false;

View File

@@ -76,8 +76,17 @@ namespace Catch {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo ); CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" ); xml.startElement( "testsuites" );
if ( m_config->hasTestFilters() || m_config->rngSeed() != 0 )
xml.startElement("properties");
if ( m_config->hasTestFilters() ) {
xml.scopedElement( "property" )
.writeAttribute( "name" , "filters" )
.writeAttribute( "value" , serializeFilters( m_config->getTestsOrTags() ) );
}
if( m_config->rngSeed() != 0 ) { if( m_config->rngSeed() != 0 ) {
xml.startElement( "properties" );
xml.scopedElement( "property" ) xml.scopedElement( "property" )
.writeAttribute( "name", "random-seed" ) .writeAttribute( "name", "random-seed" )
.writeAttribute( "value", m_config->rngSeed() ); .writeAttribute( "value", m_config->rngSeed() );

View File

@@ -55,6 +55,8 @@ namespace Catch {
m_xml.startElement( "Catch" ); m_xml.startElement( "Catch" );
if( !m_config->name().empty() ) if( !m_config->name().empty() )
m_xml.writeAttribute( "name", m_config->name() ); m_xml.writeAttribute( "name", m_config->name() );
if (m_config->testSpec().hasFilters())
m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
if( m_config->rngSeed() != 0 ) if( m_config->rngSeed() != 0 )
m_xml.scopedElement( "Randomness" ) m_xml.scopedElement( "Randomness" )
.writeAttribute( "seed", m_config->rngSeed() ); .writeAttribute( "seed", m_config->rngSeed() );

View File

@@ -19,7 +19,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/Tag.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp

View File

@@ -416,6 +416,9 @@ Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1 Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1 Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1 Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
Generators.tests.cpp:<line number>: passed: j > 0 for: 1 > 0 Generators.tests.cpp:<line number>: passed: j > 0 for: 1 > 0
Generators.tests.cpp:<line number>: passed: j > 0 for: 2 > 0 Generators.tests.cpp:<line number>: passed: j > 0 for: 2 > 0
Generators.tests.cpp:<line number>: passed: j > 0 for: 3 > 0 Generators.tests.cpp:<line number>: passed: j > 0 for: 3 > 0
@@ -495,6 +498,12 @@ GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 4.0 for: 4.0 == 4.0
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 6.0 for: 6.0 == 6.0 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 6.0 for: 6.0 == 6.0
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2.0 for: 2.0 == 2.0
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 4.0 for: 4.0 == 4.0
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 6.0 for: 6.0 == 6.0
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 3 for: 3 == 3 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1 GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
@@ -628,6 +637,22 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), !Contains("di
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring" Matchers.tests.cpp:<line number>: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring"
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception" Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
Exception.tests.cpp:<line number>: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail" Exception.tests.cpp:<line number>: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail"
Generators.tests.cpp:<line number>: passed: values > -6 for: 3 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 4 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 5 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 6 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: -5 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: -4 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 90 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 91 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 92 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 93 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 94 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 95 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 96 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 97 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 98 > -6
Generators.tests.cpp:<line number>: passed: values > -6 for: 99 > -6
Misc.tests.cpp:<line number>: warning: 'This one ran' Misc.tests.cpp:<line number>: warning: 'This one ran'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception' Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception'
Tricky.tests.cpp:<line number>: passed: True for: {?} Tricky.tests.cpp:<line number>: passed: True for: {?}
@@ -995,22 +1020,22 @@ Misc.tests.cpp:<line number>: failed: s1 == s2 for: "if ($b == 10) {
$a = 20; $a = 20;
} }
" "
TagAlias.tests.cpp:<line number>: passed: what, Contains( "[@zzz]" ) for: "error: tag alias, '[@zzz]' already registered. Tag.tests.cpp:<line number>: passed: what, Contains( "[@zzz]" ) for: "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "[@zzz]" Redefined at: file:10" contains: "[@zzz]"
TagAlias.tests.cpp:<line number>: passed: what, Contains( "file" ) for: "error: tag alias, '[@zzz]' already registered. Tag.tests.cpp:<line number>: passed: what, Contains( "file" ) for: "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "file" Redefined at: file:10" contains: "file"
TagAlias.tests.cpp:<line number>: passed: what, Contains( "2" ) for: "error: tag alias, '[@zzz]' already registered. Tag.tests.cpp:<line number>: passed: what, Contains( "2" ) for: "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "2" Redefined at: file:10" contains: "2"
TagAlias.tests.cpp:<line number>: passed: what, Contains( "10" ) for: "error: tag alias, '[@zzz]' already registered. Tag.tests.cpp:<line number>: passed: what, Contains( "10" ) for: "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "10" Redefined at: file:10" contains: "10"
TagAlias.tests.cpp:<line number>: passed: registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) Tag.tests.cpp:<line number>: passed: registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
TagAlias.tests.cpp:<line number>: passed: registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) Tag.tests.cpp:<line number>: passed: registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
TagAlias.tests.cpp:<line number>: passed: registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) Tag.tests.cpp:<line number>: passed: registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
TagAlias.tests.cpp:<line number>: passed: registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) Tag.tests.cpp:<line number>: passed: registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5 Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5 Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
Misc.tests.cpp:<line number>: passed: v.size() == 10 for: 10 == 10 Misc.tests.cpp:<line number>: passed: v.size() == 10 for: 10 == 10
@@ -1353,6 +1378,7 @@ String.tests.cpp:<line number>: passed: Catch::replaceInPlace( s, "'", "|'" ) fo
String.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t" String.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t"
Misc.tests.cpp:<line number>: failed: false with 1 message: '3' 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' Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
Tag.tests.cpp:<line number>: passed: testcase.tags, Catch::VectorContains(std::string("magic-tag")) && Catch::VectorContains(std::string(".")) for: { ".", "magic-tag" } ( Contains: "magic-tag" and Contains: "." )
Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 1 to 3...' and '1' and '2' and '3' Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 1 to 3...' and '1' and '2' and '3'
Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 4 to 6...' and '4' and '5' and '6' Message.tests.cpp:<line number>: failed: false with 4 messages: 'Count 4 to 6...' and '4' and '5' and '6'
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( emptyMap ) == "{ }" for: "{ }" == "{ }" ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( emptyMap ) == "{ }" for: "{ }" == "{ }"

View File

@@ -1,3 +1,4 @@
Filters: ~[!nonportable]~[!benchmark]~[approvals]
This would not be caught previously This would not be caught previously
Nor would this Nor would this
@@ -1264,6 +1265,6 @@ due to unexpected exception with message:
Why would you throw a std::string? Why would you throw a std::string?
=============================================================================== ===============================================================================
test cases: 255 | 189 passed | 62 failed | 4 failed as expected test cases: 257 | 191 passed | 62 failed | 4 failed as expected
assertions: 1393 | 1250 passed | 122 failed | 21 failed as expected assertions: 1419 | 1276 passed | 122 failed | 21 failed as expected

View File

@@ -1,3 +1,4 @@
Filters: ~[!nonportable]~[!benchmark]~[approvals]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<exe-name> is a <version> host application. <exe-name> is a <version> host application.
@@ -3040,6 +3041,45 @@ Generators -- adapters
Generators.tests.cpp:<line number> Generators.tests.cpp:<line number>
............................................................................... ...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( i.size() == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
Generators -- adapters
Transforming elements
Different deduced type
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( i.size() == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
Generators -- adapters
Transforming elements
Different deduced type
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( i.size() == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
Generators -- adapters
Transforming elements
Different deduced type
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED: Generators.tests.cpp:<line number>: PASSED:
REQUIRE( i.size() == 1 ) REQUIRE( i.size() == 1 )
with expansion: with expansion:
@@ -3675,7 +3715,44 @@ with expansion:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Generators internals Generators internals
Map Map with explicit return type
-------------------------------------------------------------------------------
GeneratorsImpl.tests.cpp:<line number>
...............................................................................
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( gen.get() == 2.0 )
with expansion:
2.0 == 2.0
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( gen.next() )
with expansion:
true
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( gen.get() == 4.0 )
with expansion:
4.0 == 4.0
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( gen.next() )
with expansion:
true
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( gen.get() == 6.0 )
with expansion:
6.0 == 6.0
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( gen.next() )
with expansion:
!false
-------------------------------------------------------------------------------
Generators internals
Map with deduced return type
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
GeneratorsImpl.tests.cpp:<line number> GeneratorsImpl.tests.cpp:<line number>
............................................................................... ...............................................................................
@@ -4621,6 +4698,182 @@ Exception.tests.cpp:<line number>: FAILED:
with expansion: with expansion:
"expected exception" equals: "should fail" "expected exception" equals: "should fail"
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
3 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
4 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
5 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
6 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
-5 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
-4 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
90 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
91 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
92 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
93 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
94 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
95 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
96 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
97 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
98 > -6
-------------------------------------------------------------------------------
Nested generators and captured variables
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: PASSED:
REQUIRE( values > -6 )
with expansion:
99 > -6
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Nice descriptive name Nice descriptive name
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -7239,31 +7492,31 @@ with expansion:
Tag alias can be registered against tag patterns Tag alias can be registered against tag patterns
The same tag alias can only be registered once The same tag alias can only be registered once
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
TagAlias.tests.cpp:<line number> Tag.tests.cpp:<line number>
............................................................................... ...............................................................................
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "[@zzz]" ) ) CHECK_THAT( what, Contains( "[@zzz]" ) )
with expansion: with expansion:
"error: tag alias, '[@zzz]' already registered. "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "[@zzz]" Redefined at: file:10" contains: "[@zzz]"
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "file" ) ) CHECK_THAT( what, Contains( "file" ) )
with expansion: with expansion:
"error: tag alias, '[@zzz]' already registered. "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "file" Redefined at: file:10" contains: "file"
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "2" ) ) CHECK_THAT( what, Contains( "2" ) )
with expansion: with expansion:
"error: tag alias, '[@zzz]' already registered. "error: tag alias, '[@zzz]' already registered.
First seen at: file:2 First seen at: file:2
Redefined at: file:10" contains: "2" Redefined at: file:10" contains: "2"
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "10" ) ) CHECK_THAT( what, Contains( "10" ) )
with expansion: with expansion:
"error: tag alias, '[@zzz]' already registered. "error: tag alias, '[@zzz]' already registered.
@@ -7274,19 +7527,19 @@ with expansion:
Tag alias can be registered against tag patterns Tag alias can be registered against tag patterns
Tag aliases must be of the form [@name] Tag aliases must be of the form [@name]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
TagAlias.tests.cpp:<line number> Tag.tests.cpp:<line number>
............................................................................... ...............................................................................
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) ) CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) )
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) )
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) ) CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) )
TagAlias.tests.cpp:<line number>: PASSED: Tag.tests.cpp:<line number>: PASSED:
CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ) CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) )
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -10008,6 +10261,17 @@ with messages:
hi hi
i := 7 i := 7
-------------------------------------------------------------------------------
shortened hide tags are split apart
-------------------------------------------------------------------------------
Tag.tests.cpp:<line number>
...............................................................................
Tag.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( testcase.tags, Catch::VectorContains(std::string("magic-tag")) && Catch::VectorContains(std::string(".")) )
with expansion:
{ ".", "magic-tag" } ( Contains: "magic-tag" and Contains: "." )
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
stacks unscoped info in loops stacks unscoped info in loops
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -10849,6 +11113,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED: Misc.tests.cpp:<line number>: PASSED:
=============================================================================== ===============================================================================
test cases: 255 | 174 passed | 77 failed | 4 failed as expected test cases: 257 | 176 passed | 77 failed | 4 failed as expected
assertions: 1409 | 1250 passed | 138 failed | 21 failed as expected assertions: 1435 | 1276 passed | 138 failed | 21 failed as expected

View File

@@ -1,3 +1,4 @@
Filters: ~[!nonportable]~[!benchmark]~[approvals]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<exe-name> is a <version> host application. <exe-name> is a <version> host application.

View File

@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuites> <testsuites>
<properties> <properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
<property name="random-seed" value="1"/> <property name="random-seed" value="1"/>
</properties> </properties>
loose text artifact loose text artifact
<testsuite name="<exe-name>" errors="17" failures="122" tests="1410" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testsuite name="<exe-name>" errors="17" failures="122" tests="1436" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/> <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
@@ -360,6 +361,7 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Shortening a range" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Shortening a range" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Same type" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Same type" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Different type" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Different type" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Different deduced type" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Repeating a generator" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Repeating a generator" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is divisible by chunk size" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is divisible by chunk size" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is not divisible by chunk size" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is not divisible by chunk size" time="{duration}"/>
@@ -373,7 +375,8 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Generators internals/Filter generator" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Filter generator" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take less" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take less" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take more" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take more" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Map" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Map with explicit return type" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Map with deduced return type" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Repeat/Singular repeat" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Repeat/Singular repeat" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Repeat/Actual repeat" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Repeat/Actual repeat" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Generators internals/Range/Positive auto step/Integer" time="{duration}"/> <testcase classname="<exe-name>.global" name="Generators internals/Range/Positive auto step/Integer" time="{duration}"/>
@@ -452,6 +455,7 @@ Matchers.tests.cpp:<line number>
Exception.tests.cpp:<line number> Exception.tests.cpp:<line number>
</failure> </failure>
</testcase> </testcase>
<testcase classname="<exe-name>.global" name="Nested generators and captured variables" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Nice descriptive name" time="{duration}"/> <testcase classname="<exe-name>.global" name="Nice descriptive name" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Non-std exceptions can be translated" time="{duration}"> <testcase classname="<exe-name>.global" name="Non-std exceptions can be translated" time="{duration}">
<error type="TEST_CASE"> <error type="TEST_CASE">
@@ -978,6 +982,7 @@ i := 7
Message.tests.cpp:<line number> Message.tests.cpp:<line number>
</failure> </failure>
</testcase> </testcase>
<testcase classname="<exe-name>.global" name="shortened hide tags are split apart" time="{duration}"/>
<testcase classname="<exe-name>.global" name="stacks unscoped info in loops" time="{duration}"> <testcase classname="<exe-name>.global" name="stacks unscoped info in loops" time="{duration}">
<failure message="false" type="CHECK"> <failure message="false" type="CHECK">
Count 1 to 3... Count 1 to 3...

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Catch name="<exe-name>"> <Catch name="<exe-name>" filters="~[!nonportable]~[!benchmark]~[approvals]">
<Randomness seed="1"/> <Randomness seed="1"/>
<Group name="<exe-name>"> <Group name="<exe-name>">
<TestCase name="# A test name that starts with a #" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" > <TestCase name="# A test name that starts with a #" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -2916,7 +2916,7 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="Exception matchers that fail" tags="[!throws][.][.failing][exceptions][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <TestCase name="Exception matchers that fail" tags="[!throws][.][exceptions][failing][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Section name="No exception" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Section name="No exception" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="false" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original> <Original>
@@ -3736,6 +3736,48 @@ Nor would this
</Section> </Section>
<OverallResults successes="1" failures="0" expectedFailures="0"/> <OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section> </Section>
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
i.size() == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
i.size() == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
i.size() == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Repeating a generator" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > <Section name="Repeating a generator" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original> <Original>
@@ -4461,7 +4503,58 @@ Nor would this
</Section> </Section>
<OverallResults successes="2" failures="0" expectedFailures="0"/> <OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section> </Section>
<Section name="Map" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" > <Section name="Map with explicit return type" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
gen.get() == 2.0
</Original>
<Expanded>
2.0 == 2.0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
gen.next()
</Original>
<Expanded>
true
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
gen.get() == 4.0
</Original>
<Expanded>
4.0 == 4.0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
gen.next()
</Original>
<Expanded>
true
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
gen.get() == 6.0
</Original>
<Expanded>
6.0 == 6.0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
!(gen.next())
</Original>
<Expanded>
!false
</Expanded>
</Expression>
<OverallResults successes="6" failures="0" expectedFailures="0"/>
</Section>
<Section name="Map with deduced return type" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" > <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original> <Original>
gen.get() == 2.0 gen.get() == 2.0
@@ -5768,7 +5861,7 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="Matchers can be composed with both &amp;&amp; and || - failing" tags="[.][.failing][matchers][operator&amp;&amp;][operators][operator||]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <TestCase name="Matchers can be composed with both &amp;&amp; and || - failing" tags="[.][failing][matchers][operator&amp;&amp;][operators][operator||]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original> <Original>
testStringForMatching(), (Contains("string") || Contains("different")) &amp;&amp; Contains("random") testStringForMatching(), (Contains("string") || Contains("different")) &amp;&amp; Contains("random")
@@ -5790,7 +5883,7 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="Matchers can be negated (Not) with the ! operator - failing" tags="[.][.failing][matchers][not][operators]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <TestCase name="Matchers can be negated (Not) with the ! operator - failing" tags="[.][failing][matchers][not][operators]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original> <Original>
testStringForMatching(), !Contains("substring") testStringForMatching(), !Contains("substring")
@@ -5820,6 +5913,137 @@ Nor would this
</Expression> </Expression>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="Nested generators and captured variables" tags="[generators]" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
3 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
4 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
5 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
6 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
-5 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
-4 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
90 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
91 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
92 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
93 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
94 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
95 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
96 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
97 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
98 > -6
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
values > -6
</Original>
<Expanded>
99 > -6
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Nice descriptive name" tags="[.][tag1][tag2][tag3]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" > <TestCase name="Nice descriptive name" tags="[.][tag1][tag2][tag3]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Warning> <Warning>
This one ran This one ran
@@ -8112,7 +8336,7 @@ Nor would this
</Expression> </Expression>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="Regex string matcher" tags="[.][.failing][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <TestCase name="Regex string matcher" tags="[.][failing][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original> <Original>
testStringForMatching(), Matches("this STRING contains 'abc' as a substring") testStringForMatching(), Matches("this STRING contains 'abc' as a substring")
@@ -9093,9 +9317,9 @@ Message from section two
</Expression> </Expression>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="Tag alias can be registered against tag patterns" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <TestCase name="Tag alias can be registered against tag patterns" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Section name="The same tag alias can only be registered once" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Section name="The same tag alias can only be registered once" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
what, Contains( "[@zzz]" ) what, Contains( "[@zzz]" )
</Original> </Original>
@@ -9105,7 +9329,7 @@ Message from section two
Redefined at: file:10" contains: "[@zzz]" Redefined at: file:10" contains: "[@zzz]"
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
what, Contains( "file" ) what, Contains( "file" )
</Original> </Original>
@@ -9115,7 +9339,7 @@ Message from section two
Redefined at: file:10" contains: "file" Redefined at: file:10" contains: "file"
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
what, Contains( "2" ) what, Contains( "2" )
</Original> </Original>
@@ -9125,7 +9349,7 @@ Message from section two
Redefined at: file:10" contains: "2" Redefined at: file:10" contains: "2"
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
what, Contains( "10" ) what, Contains( "10" )
</Original> </Original>
@@ -9137,8 +9361,8 @@ Message from section two
</Expression> </Expression>
<OverallResults successes="4" failures="0" expectedFailures="0"/> <OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section> </Section>
<Section name="Tag aliases must be of the form [@name]" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Section name="Tag aliases must be of the form [@name]" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original> </Original>
@@ -9146,7 +9370,7 @@ Message from section two
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original> </Original>
@@ -9154,7 +9378,7 @@ Message from section two
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original> </Original>
@@ -9162,7 +9386,7 @@ Message from section two
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded> </Expanded>
</Expression> </Expression>
<Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" > <Expression success="true" type="CHECK_THROWS" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original> <Original>
registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
</Original> </Original>
@@ -12259,6 +12483,17 @@ loose text artifact
</Expression> </Expression>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="shortened hide tags are split apart" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original>
testcase.tags, Catch::VectorContains(std::string("magic-tag")) &amp;&amp; Catch::VectorContains(std::string("."))
</Original>
<Expanded>
{ ".", "magic-tag" } ( Contains: "magic-tag" and Contains: "." )
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="stacks unscoped info in loops" tags="[.][failing][info][unscoped]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" > <TestCase name="stacks unscoped info in loops" tags="[.][failing][info][unscoped]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
<Info> <Info>
Count 1 to 3... Count 1 to 3...
@@ -13153,7 +13388,7 @@ loose text artifact
</Section> </Section>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<OverallResults successes="1250" failures="139" expectedFailures="21"/> <OverallResults successes="1276" failures="139" expectedFailures="21"/>
</Group> </Group>
<OverallResults successes="1250" failures="138" expectedFailures="21"/> <OverallResults successes="1276" failures="138" expectedFailures="21"/>
</Catch> </Catch>

View File

@@ -68,7 +68,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
REQUIRE_FALSE(gen.next()); REQUIRE_FALSE(gen.next());
} }
} }
SECTION("Map") { SECTION("Map with explicit return type") {
auto gen = map<double>([] (int i) {return 2.0 * i; }, values({ 1, 2, 3 })); auto gen = map<double>([] (int i) {return 2.0 * i; }, values({ 1, 2, 3 }));
REQUIRE(gen.get() == 2.0); REQUIRE(gen.get() == 2.0);
REQUIRE(gen.next()); REQUIRE(gen.next());
@@ -77,6 +77,15 @@ TEST_CASE("Generators internals", "[generators][internals]") {
REQUIRE(gen.get() == 6.0); REQUIRE(gen.get() == 6.0);
REQUIRE_FALSE(gen.next()); REQUIRE_FALSE(gen.next());
} }
SECTION("Map with deduced return type") {
auto gen = map([] (int i) {return 2.0 * i; }, values({ 1, 2, 3 }));
REQUIRE(gen.get() == 2.0);
REQUIRE(gen.next());
REQUIRE(gen.get() == 4.0);
REQUIRE(gen.next());
REQUIRE(gen.get() == 6.0);
REQUIRE_FALSE(gen.next());
}
SECTION("Repeat") { SECTION("Repeat") {
SECTION("Singular repeat") { SECTION("Singular repeat") {
auto gen = repeat(1, value(3)); auto gen = repeat(1, value(3));
@@ -207,3 +216,45 @@ TEST_CASE("Generators internals", "[generators][internals]") {
} }
} }
// todo: uncopyable type used in a generator
// idea: uncopyable tag type for a stupid generator
namespace {
struct non_copyable {
non_copyable() = default;
non_copyable(non_copyable const&) = delete;
non_copyable& operator=(non_copyable const&) = delete;
int value = -1;
};
// This class shows how to implement a simple generator for Catch tests
class TestGen : public Catch::Generators::IGenerator<int> {
int current_number;
public:
TestGen(non_copyable const& nc):
current_number(nc.value) {}
int const& get() const override;
bool next() override {
return false;
}
};
// Avoids -Wweak-vtables
int const& TestGen::get() const {
return current_number;
}
}
TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") {
auto value = GENERATE(take(10, random(0, 10)));
non_copyable nc; nc.value = value;
// neither `GENERATE_COPY` nor plain `GENERATE` would compile here
auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new TestGen(nc))));
REQUIRE(value == value2);
}

View File

@@ -40,3 +40,8 @@ TEST_CASE( "Tag alias can be registered against tag patterns" ) {
CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ); CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) );
} }
} }
TEST_CASE("shortened hide tags are split apart") {
auto testcase = Catch::makeTestCase(nullptr, "", {"fake test name", "[.magic-tag]"}, CATCH_INTERNAL_LINEINFO);
REQUIRE_THAT(testcase.tags, Catch::VectorContains(std::string("magic-tag")) && Catch::VectorContains(std::string(".")));
}

View File

@@ -144,6 +144,11 @@ TEST_CASE("Generators -- adapters", "[generators][generic]") {
auto i = GENERATE(map<std::string>([] (int val) { return std::to_string(val); }, values({ 1, 2, 3 }))); auto i = GENERATE(map<std::string>([] (int val) { return std::to_string(val); }, values({ 1, 2, 3 })));
REQUIRE(i.size() == 1); REQUIRE(i.size() == 1);
} }
SECTION("Different deduced type") {
// This takes a generator that returns ints and maps them into strings
auto i = GENERATE(map([] (int val) { return std::to_string(val); }, values({ 1, 2, 3 })));
REQUIRE(i.size() == 1);
}
} }
SECTION("Repeating a generator") { SECTION("Repeating a generator") {
// This will return values [1, 2, 3, 1, 2, 3] // This will return values [1, 2, 3, 1, 2, 3]
@@ -183,3 +188,21 @@ TEST_CASE("Random generator", "[generators][.][approvals]") {
static_cast<void>(val); // Silence VS 2015 unused variable warning static_cast<void>(val); // Silence VS 2015 unused variable warning
} }
} }
TEST_CASE("Nested generators and captured variables", "[generators]") {
// Workaround for old libstdc++
using record = std::tuple<int, int>;
// Set up 3 ranges to generate numbers from
auto extent = GENERATE(table<int, int>({
record{3, 7},
record{-5, -3},
record{90, 100}
}));
auto from = std::get<0>(extent);
auto to = std::get<1>(extent);
auto values = GENERATE_COPY(range(from, to));
REQUIRE(values > -6);
}

View File

@@ -1,6 +1,6 @@
/* /*
* Catch v2.7.0 * Catch v2.7.1
* Generated: 2019-03-07 21:34:30.252164 * Generated: 2019-04-05 18:22:37.720122
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
@@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 7 #define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 0 #define CATCH_VERSION_PATCH 1
#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header
@@ -3686,7 +3686,11 @@ namespace Generators {
} // namespace Catch } // namespace Catch
#define GENERATE( ... ) \ #define GENERATE( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
#define GENERATE_COPY( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
#define GENERATE_REF( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
// end catch_generators.hpp // end catch_generators.hpp
// start catch_generators_generic.hpp // start catch_generators_generic.hpp
@@ -3849,16 +3853,28 @@ namespace Generators {
} }
}; };
template <typename T, typename U, typename Func> #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
// replaced with std::invoke_result here. Also *_t format is preferred over
// typename *::type format.
template <typename Func, typename U>
using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
#else
template <typename Func, typename U>
using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
#endif
template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>( return GeneratorWrapper<T>(
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
); );
} }
template <typename T, typename Func>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<T>&& generator) { template <typename T, typename U, typename Func>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>( return GeneratorWrapper<T>(
pf::make_unique<MapGenerator<T, T, Func>>(std::forward<Func>(function), std::move(generator)) pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
); );
} }
@@ -4022,6 +4038,7 @@ namespace Catch {
virtual ShowDurations::OrNot showDurations() const = 0; virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0; virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0; virtual bool hasTestFilters() const = 0;
virtual std::vector<std::string> const& getTestsOrTags() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0; virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0; virtual int benchmarkResolutionMultiple() const = 0;
@@ -4352,7 +4369,7 @@ namespace Catch {
arcSafeRelease( m_substr ); arcSafeRelease( m_substr );
} }
bool match( NSString* arg ) const override { bool match( NSString* const& str ) const override {
return false; return false;
} }
@@ -4362,7 +4379,7 @@ namespace Catch {
struct Equals : StringHolder { struct Equals : StringHolder {
Equals( NSString* substr ) : StringHolder( substr ){} Equals( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr]; [str isEqualToString:m_substr];
} }
@@ -4375,7 +4392,7 @@ namespace Catch {
struct Contains : StringHolder { struct Contains : StringHolder {
Contains( NSString* substr ) : StringHolder( substr ){} Contains( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound; [str rangeOfString:m_substr].location != NSNotFound;
} }
@@ -4388,7 +4405,7 @@ namespace Catch {
struct StartsWith : StringHolder { struct StartsWith : StringHolder {
StartsWith( NSString* substr ) : StringHolder( substr ){} StartsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0; [str rangeOfString:m_substr].location == 0;
} }
@@ -4400,7 +4417,7 @@ namespace Catch {
struct EndsWith : StringHolder { struct EndsWith : StringHolder {
EndsWith( NSString* substr ) : StringHolder( substr ){} EndsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override { bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) && return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length]; [str rangeOfString:m_substr].location == [str length] - [m_substr length];
} }
@@ -4708,7 +4725,7 @@ namespace Catch {
std::string getProcessName() const; std::string getProcessName() const;
std::string const& getReporterName() const; std::string const& getReporterName() const;
std::vector<std::string> const& getTestsOrTags() const; std::vector<std::string> const& getTestsOrTags() const override;
std::vector<std::string> const& getSectionsToRun() const override; std::vector<std::string> const& getSectionsToRun() const override;
virtual TestSpec const& testSpec() const override; virtual TestSpec const& testSpec() const override;
@@ -5082,6 +5099,8 @@ namespace Catch {
// Returns double formatted as %.3f (format expected on output) // Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration ); std::string getFormattedDuration( double duration );
std::string serializeFilters( std::vector<std::string> const& container );
template<typename DerivedT> template<typename DerivedT>
struct StreamingReporterBase : IStreamingReporter { struct StreamingReporterBase : IStreamingReporter {
@@ -5109,6 +5128,7 @@ namespace Catch {
void testRunStarting(TestRunInfo const& _testRunInfo) override { void testRunStarting(TestRunInfo const& _testRunInfo) override {
currentTestRunInfo = _testRunInfo; currentTestRunInfo = _testRunInfo;
} }
void testGroupStarting(GroupInfo const& _groupInfo) override { void testGroupStarting(GroupInfo const& _groupInfo) override {
currentGroupInfo = _groupInfo; currentGroupInfo = _groupInfo;
} }
@@ -5521,7 +5541,7 @@ namespace Catch {
void testCaseEnded(TestCaseStats const& _testCaseStats) override; void testCaseEnded(TestCaseStats const& _testCaseStats) override;
void testGroupEnded(TestGroupStats const& _testGroupStats) override; void testGroupEnded(TestGroupStats const& _testGroupStats) override;
void testRunEnded(TestRunStats const& _testRunStats) override; void testRunEnded(TestRunStats const& _testRunStats) override;
void testRunStarting(TestRunInfo const& _testRunInfo) override;
private: private:
void lazyPrint(); void lazyPrint();
@@ -5543,6 +5563,7 @@ namespace Catch {
void printTotalsDivider(Totals const& totals); void printTotalsDivider(Totals const& totals);
void printSummaryDivider(); void printSummaryDivider();
void printTestFilters();
private: private:
bool m_headerPrinted = false; bool m_headerPrinted = false;
@@ -8660,10 +8681,10 @@ namespace Catch {
// Windows can easily distinguish between SO and SigSegV, // Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently. // but SigInt, SigTerm, etc are handled differently.
static SignalDefs signalDefs[] = { static SignalDefs signalDefs[] = {
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
}; };
LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
@@ -11657,6 +11678,12 @@ namespace Catch {
else if( prop == TestCaseInfo::None ) else if( prop == TestCaseInfo::None )
enforceNotReservedTag( tag, _lineInfo ); enforceNotReservedTag( tag, _lineInfo );
// Merged hide tags like `[.approvals]` should be added as
// `[.][approvals]`. The `[.]` is added at later point, so
// we only strip the prefix
if (startsWith(tag, '.') && tag.size() > 1) {
tag.erase(0, 1);
}
tags.push_back( tag ); tags.push_back( tag );
tag.clear(); tag.clear();
inTag = false; inTag = false;
@@ -12665,7 +12692,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 7, 0, "", 0 ); static Version version( 2, 7, 1, "", 0 );
return version; return version;
} }
@@ -13022,6 +13049,21 @@ namespace Catch {
return std::string(buffer); return std::string(buffer);
} }
std::string serializeFilters( std::vector<std::string> const& container ) {
ReusableStringStream oss;
bool first = true;
for (auto&& filter : container)
{
if (!first)
oss << ' ';
else
first = false;
oss << filter;
}
return oss.str();
}
TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
:StreamingReporterBase(_config) {} :StreamingReporterBase(_config) {}
@@ -13746,6 +13788,10 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
stream << std::endl; stream << std::endl;
StreamingReporterBase::testRunEnded(_testRunStats); StreamingReporterBase::testRunEnded(_testRunStats);
} }
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
StreamingReporterBase::testRunStarting(_testInfo);
printTestFilters();
}
void ConsoleReporter::lazyPrint() { void ConsoleReporter::lazyPrint() {
@@ -13927,6 +13973,11 @@ void ConsoleReporter::printSummaryDivider() {
stream << getLineOfChars<'-'>() << '\n'; stream << getLineOfChars<'-'>() << '\n';
} }
void ConsoleReporter::printTestFilters() {
if (m_config->testSpec().hasFilters())
stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
}
CATCH_REGISTER_REPORTER("console", ConsoleReporter) CATCH_REGISTER_REPORTER("console", ConsoleReporter)
} // end namespace Catch } // end namespace Catch
@@ -14000,8 +14051,17 @@ namespace Catch {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo ); CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" ); xml.startElement( "testsuites" );
if ( m_config->hasTestFilters() || m_config->rngSeed() != 0 )
xml.startElement("properties");
if ( m_config->hasTestFilters() ) {
xml.scopedElement( "property" )
.writeAttribute( "name" , "filters" )
.writeAttribute( "value" , serializeFilters( m_config->getTestsOrTags() ) );
}
if( m_config->rngSeed() != 0 ) { if( m_config->rngSeed() != 0 ) {
xml.startElement( "properties" );
xml.scopedElement( "property" ) xml.scopedElement( "property" )
.writeAttribute( "name", "random-seed" ) .writeAttribute( "name", "random-seed" )
.writeAttribute( "value", m_config->rngSeed() ); .writeAttribute( "value", m_config->rngSeed() );
@@ -14357,6 +14417,8 @@ namespace Catch {
m_xml.startElement( "Catch" ); m_xml.startElement( "Catch" );
if( !m_config->name().empty() ) if( !m_config->name().empty() )
m_xml.writeAttribute( "name", m_config->name() ); m_xml.writeAttribute( "name", m_config->name() );
if (m_config->testSpec().hasFilters())
m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
if( m_config->rngSeed() != 0 ) if( m_config->rngSeed() != 0 )
m_xml.scopedElement( "Randomness" ) m_xml.scopedElement( "Randomness" )
.writeAttribute( "seed", m_config->rngSeed() ); .writeAttribute( "seed", m_config->rngSeed() );