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)
endif()
project(Catch2 LANGUAGES CXX VERSION 2.7.0)
project(Catch2 LANGUAGES CXX VERSION 2.7.1)
# Provide path for scripts
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://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)
[![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)
<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!
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)
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?

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).
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:
@@ -61,7 +61,7 @@ Catch provides a way to perform tolerant comparisons of floating point values th
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:
```cpp
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
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
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>`
* `take(count, GeneratorWrapper<T>&&)` for `TakeGenerator<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`)
* `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>`
* `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
@@ -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
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
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
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);
}
```

View File

@@ -17,6 +17,7 @@
- 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 variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp)
- Generators: [Use custom variable capture in generator expressions](../examples/311-Gen-CustomCapture.cpp)
## Planned

View File

@@ -100,7 +100,7 @@ public:
// 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
// preceded by the value under test).
virtual std::string describe() const {
virtual std::string describe() const override {
std::ostringstream ss;
ss << "is between " << m_begin << " and " << m_end;
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
### [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)
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 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 is a code for multi-scale, multi-physics problems in astrophysics and gravitational physics.

View File

@@ -2,6 +2,7 @@
# Release notes
**Contents**<br>
[2.7.1](#271)<br>
[2.7.0](#270)<br>
[2.6.1](#261)<br>
[2.6.0](#260)<br>
@@ -21,6 +22,19 @@
[Older versions](#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
### Improvements

View File

@@ -23,7 +23,7 @@ The full source for Catch2, including test projects, documentation, and other th
## 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.
@@ -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?
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)).
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.
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++
SECTION( "reserving bigger changes capacity but not size" ) {

View File

@@ -8,41 +8,6 @@
#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",
"[generator][example][advanced]") {
// 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
// auto number = GENERATE(take(50, random(r.first, r.second)));
// We have to manually register the generators instead
// Notice that we are using value capture in the lambda, to avoid lifetime issues
auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO,
[=]{
using namespace Catch::Generators;
return makeGenerators(take(50, random(std::get<0>(r), std::get<1>(r))));
}
);
// auto number = GENERATE(take(50, random(std::get<0>(r), std::get<1>(r))));
// GENERATE_COPY copies all variables mentioned inside the expression
// thus this will work.
auto number = GENERATE_COPY(take(50, random(std::get<0>(r), std::get<1>(r))));
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
301-Gen-MapTypeConversion.cpp
310-Gen-VariablesInGenerators.cpp
311-Gen-CustomCapture.cpp
)
# main-s for reporter-specific test sources:

View File

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

View File

@@ -82,7 +82,7 @@ namespace Catch {
std::string getProcessName() 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;
virtual TestSpec const& testSpec() const override;

View File

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

View File

@@ -201,7 +201,10 @@ namespace Generators {
} // namespace Catch
#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

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) {
return GeneratorWrapper<T>(
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>(
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 TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual std::vector<std::string> const& getTestsOrTags() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0;

View File

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

View File

@@ -75,6 +75,12 @@ namespace Catch {
else if( prop == TestCaseInfo::None )
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 );
tag.clear();
inTag = false;

View File

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

View File

@@ -41,6 +41,20 @@ namespace Catch {
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)
:StreamingReporterBase(_config) {}

View File

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

View File

@@ -441,6 +441,10 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
stream << std::endl;
StreamingReporterBase::testRunEnded(_testRunStats);
}
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
StreamingReporterBase::testRunStarting(_testInfo);
printTestFilters();
}
void ConsoleReporter::lazyPrint() {
@@ -622,6 +626,11 @@ void ConsoleReporter::printSummaryDivider() {
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)
} // end namespace Catch

View File

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

View File

@@ -76,8 +76,17 @@ namespace Catch {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo );
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 ) {
xml.startElement( "properties" );
xml.scopedElement( "property" )
.writeAttribute( "name", "random-seed" )
.writeAttribute( "value", m_config->rngSeed() );

View File

@@ -55,6 +55,8 @@ namespace Catch {
m_xml.startElement( "Catch" );
if( !m_config->name().empty() )
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 )
m_xml.scopedElement( "Randomness" )
.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/GeneratorsImpl.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/Xml.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: 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: 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.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() == 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.next()) for: !false
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"
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"
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'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception'
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;
}
"
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
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
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
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
Redefined at: file:10" contains: "10"
TagAlias.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 ) )
TagAlias.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 ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
Tag.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( "@no square bracket at start]", "", 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.capacity() >= 5 for: 5 >= 5
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"
Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
Tag.tests.cpp:<line number>: passed: testcase.tags, 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 4 to 6...' and '4' and '5' and '6'
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
Nor would this
@@ -1264,6 +1265,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 255 | 189 passed | 62 failed | 4 failed as expected
assertions: 1393 | 1250 passed | 122 failed | 21 failed as expected
test cases: 257 | 191 passed | 62 failed | 4 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.
@@ -3040,6 +3041,45 @@ Generators -- adapters
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:
REQUIRE( i.size() == 1 )
with expansion:
@@ -3675,7 +3715,44 @@ with expansion:
-------------------------------------------------------------------------------
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>
...............................................................................
@@ -4621,6 +4698,182 @@ Exception.tests.cpp:<line number>: FAILED:
with expansion:
"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
-------------------------------------------------------------------------------
@@ -7239,31 +7492,31 @@ with expansion:
Tag alias can be registered against tag patterns
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]" ) )
with expansion:
"error: tag alias, '[@zzz]' already registered.
First seen at: file:2
Redefined at: file:10" contains: "[@zzz]"
TagAlias.tests.cpp:<line number>: PASSED:
Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "file" ) )
with expansion:
"error: tag alias, '[@zzz]' already registered.
First seen at: file:2
Redefined at: file:10" contains: "file"
TagAlias.tests.cpp:<line number>: PASSED:
Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "2" ) )
with expansion:
"error: tag alias, '[@zzz]' already registered.
First seen at: file:2
Redefined at: file:10" contains: "2"
TagAlias.tests.cpp:<line number>: PASSED:
Tag.tests.cpp:<line number>: PASSED:
CHECK_THAT( what, Contains( "10" ) )
with expansion:
"error: tag alias, '[@zzz]' already registered.
@@ -7274,19 +7527,19 @@ with expansion:
Tag alias can be registered against tag patterns
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 ) ) )
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 ) ) )
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 ) ) )
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 ) ) )
-------------------------------------------------------------------------------
@@ -10008,6 +10261,17 @@ with messages:
hi
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
-------------------------------------------------------------------------------
@@ -10849,6 +11113,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 255 | 174 passed | 77 failed | 4 failed as expected
assertions: 1409 | 1250 passed | 138 failed | 21 failed as expected
test cases: 257 | 176 passed | 77 failed | 4 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.

View File

@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
<property name="random-seed" value="1"/>
</properties>
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="#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}"/>
@@ -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/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 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/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}"/>
@@ -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/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/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/Actual repeat" 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>
</failure>
</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="Non-std exceptions can be translated" time="{duration}">
<error type="TEST_CASE">
@@ -978,6 +982,7 @@ i := 7
Message.tests.cpp:<line number>
</failure>
</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}">
<failure message="false" type="CHECK">
Count 1 to 3...

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Catch name="<exe-name>">
<Catch name="<exe-name>" filters="~[!nonportable]~[!benchmark]~[approvals]">
<Randomness seed="1"/>
<Group name="<exe-name>">
<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>
<OverallResult success="true"/>
</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" >
<Expression success="false" type="CHECK_THROWS_MATCHES" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original>
@@ -3736,6 +3736,48 @@ Nor would this
</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="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" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
<Original>
@@ -4461,7 +4503,58 @@ Nor would this
</Section>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</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" >
<Original>
gen.get() == 2.0
@@ -5768,7 +5861,7 @@ Nor would this
</Expression>
<OverallResult success="true"/>
</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" >
<Original>
testStringForMatching(), (Contains("string") || Contains("different")) &amp;&amp; Contains("random")
@@ -5790,7 +5883,7 @@ Nor would this
</Expression>
<OverallResult success="true"/>
</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" >
<Original>
testStringForMatching(), !Contains("substring")
@@ -5820,6 +5913,137 @@ Nor would this
</Expression>
<OverallResult success="false"/>
</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" >
<Warning>
This one ran
@@ -8112,7 +8336,7 @@ Nor would this
</Expression>
<OverallResult success="false"/>
</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" >
<Original>
testStringForMatching(), Matches("this STRING contains 'abc' as a substring")
@@ -9093,9 +9317,9 @@ Message from section two
</Expression>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Tag alias can be registered against tag patterns" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" >
<Section name="The same tag alias can only be registered once" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" >
<Expression success="true" type="CHECK_THAT" 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/Tag.tests.cpp" >
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original>
what, Contains( "[@zzz]" )
</Original>
@@ -9105,7 +9329,7 @@ Message from section two
Redefined at: file:10" contains: "[@zzz]"
</Expanded>
</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>
what, Contains( "file" )
</Original>
@@ -9115,7 +9339,7 @@ Message from section two
Redefined at: file:10" contains: "file"
</Expanded>
</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>
what, Contains( "2" )
</Original>
@@ -9125,7 +9349,7 @@ Message from section two
Redefined at: file:10" contains: "2"
</Expanded>
</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>
what, Contains( "10" )
</Original>
@@ -9137,8 +9361,8 @@ Message from section two
</Expression>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<Section name="Tag aliases must be of the form [@name]" filename="projects/<exe-name>/IntrospectiveTests/TagAlias.tests.cpp" >
<Expression success="true" type="CHECK_THROWS" 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/Tag.tests.cpp" >
<Original>
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original>
@@ -9146,7 +9370,7 @@ Message from section two
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded>
</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>
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original>
@@ -9154,7 +9378,7 @@ Message from section two
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded>
</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>
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Original>
@@ -9162,7 +9386,7 @@ Message from section two
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
</Expanded>
</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>
registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
</Original>
@@ -12259,6 +12483,17 @@ loose text artifact
</Expression>
<OverallResult success="false"/>
</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" >
<Info>
Count 1 to 3...
@@ -13153,7 +13388,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1250" failures="139" expectedFailures="21"/>
<OverallResults successes="1276" failures="139" expectedFailures="21"/>
</Group>
<OverallResults successes="1250" failures="138" expectedFailures="21"/>
<OverallResults successes="1276" failures="138" expectedFailures="21"/>
</Catch>

View File

@@ -68,7 +68,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
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 }));
REQUIRE(gen.get() == 2.0);
REQUIRE(gen.next());
@@ -77,6 +77,15 @@ TEST_CASE("Generators internals", "[generators][internals]") {
REQUIRE(gen.get() == 6.0);
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("Singular repeat") {
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 ) ) );
}
}
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 })));
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") {
// 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
}
}
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
* Generated: 2019-03-07 21:34:30.252164
* Catch v2.7.1
* Generated: 2019-04-05 18:22:37.720122
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
@@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 0
#define CATCH_VERSION_PATCH 1
#ifdef __clang__
# pragma clang system_header
@@ -3686,7 +3686,11 @@ namespace Generators {
} // namespace Catch
#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
// 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) {
return GeneratorWrapper<T>(
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>(
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 TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual std::vector<std::string> const& getTestsOrTags() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0;
@@ -4352,7 +4369,7 @@ namespace Catch {
arcSafeRelease( m_substr );
}
bool match( NSString* arg ) const override {
bool match( NSString* const& str ) const override {
return false;
}
@@ -4362,7 +4379,7 @@ namespace Catch {
struct Equals : StringHolder {
Equals( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override {
bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr];
}
@@ -4375,7 +4392,7 @@ namespace Catch {
struct Contains : StringHolder {
Contains( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const {
bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound;
}
@@ -4388,7 +4405,7 @@ namespace Catch {
struct StartsWith : StringHolder {
StartsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override {
bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0;
}
@@ -4400,7 +4417,7 @@ namespace Catch {
struct EndsWith : StringHolder {
EndsWith( NSString* substr ) : StringHolder( substr ){}
bool match( NSString* str ) const override {
bool match( NSString* const& str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
}
@@ -4708,7 +4725,7 @@ namespace Catch {
std::string getProcessName() 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;
virtual TestSpec const& testSpec() const override;
@@ -5082,6 +5099,8 @@ namespace Catch {
// Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration );
std::string serializeFilters( std::vector<std::string> const& container );
template<typename DerivedT>
struct StreamingReporterBase : IStreamingReporter {
@@ -5109,6 +5128,7 @@ namespace Catch {
void testRunStarting(TestRunInfo const& _testRunInfo) override {
currentTestRunInfo = _testRunInfo;
}
void testGroupStarting(GroupInfo const& _groupInfo) override {
currentGroupInfo = _groupInfo;
}
@@ -5521,7 +5541,7 @@ namespace Catch {
void testCaseEnded(TestCaseStats const& _testCaseStats) override;
void testGroupEnded(TestGroupStats const& _testGroupStats) override;
void testRunEnded(TestRunStats const& _testRunStats) override;
void testRunStarting(TestRunInfo const& _testRunInfo) override;
private:
void lazyPrint();
@@ -5543,6 +5563,7 @@ namespace Catch {
void printTotalsDivider(Totals const& totals);
void printSummaryDivider();
void printTestFilters();
private:
bool m_headerPrinted = false;
@@ -8660,10 +8681,10 @@ namespace Catch {
// Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently.
static SignalDefs signalDefs[] = {
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
{ static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
{ static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
{ static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
{ static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
};
LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
@@ -11657,6 +11678,12 @@ namespace Catch {
else if( prop == TestCaseInfo::None )
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 );
tag.clear();
inTag = false;
@@ -12665,7 +12692,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 2, 7, 0, "", 0 );
static Version version( 2, 7, 1, "", 0 );
return version;
}
@@ -13022,6 +13049,21 @@ namespace Catch {
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)
:StreamingReporterBase(_config) {}
@@ -13746,6 +13788,10 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
stream << std::endl;
StreamingReporterBase::testRunEnded(_testRunStats);
}
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
StreamingReporterBase::testRunStarting(_testInfo);
printTestFilters();
}
void ConsoleReporter::lazyPrint() {
@@ -13927,6 +13973,11 @@ void ConsoleReporter::printSummaryDivider() {
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)
} // end namespace Catch
@@ -14000,8 +14051,17 @@ namespace Catch {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo );
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 ) {
xml.startElement( "properties" );
xml.scopedElement( "property" )
.writeAttribute( "name", "random-seed" )
.writeAttribute( "value", m_config->rngSeed() );
@@ -14357,6 +14417,8 @@ namespace Catch {
m_xml.startElement( "Catch" );
if( !m_config->name().empty() )
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 )
m_xml.scopedElement( "Randomness" )
.writeAttribute( "seed", m_config->rngSeed() );