mirror of
https://github.com/catchorg/Catch2.git
synced 2025-01-15 22:58:02 +00:00
Compare commits
16 Commits
db1a0465dc
...
ae1d21315c
Author | SHA1 | Date | |
---|---|---|---|
|
ae1d21315c | ||
|
6a2c025bfc | ||
|
2441c2faab | ||
|
442283ee11 | ||
|
3f81dd753a | ||
|
f8794634c2 | ||
|
d6b2a3793b | ||
|
548de655fd | ||
|
89f18f15ca | ||
|
3c7e737a7b | ||
|
e880da93bd | ||
|
3e01d4b239 | ||
|
06c32862b3 | ||
|
ab520f4e97 | ||
|
32617f42d0 | ||
|
17c4b2d093 |
@ -35,6 +35,7 @@ FAQ:
|
||||
Other:
|
||||
* [Why Catch?](why-catch.md#top)
|
||||
* [Open Source Projects using Catch](opensource-users.md#top)
|
||||
* [Commercial Projects using Catch](commercial-users.md#top)
|
||||
* [Contributing](contributing.md#top)
|
||||
* [Release Notes](release-notes.md#top)
|
||||
* [Deprecations and incoming changes](deprecations.md#top)
|
||||
|
@ -24,6 +24,7 @@
|
||||
[Specify the number of resamples for bootstrapping](#specify-the-number-of-resamples-for-bootstrapping)<br>
|
||||
[Specify the confidence-interval for bootstrapping](#specify-the-confidence-interval-for-bootstrapping)<br>
|
||||
[Disable statistical analysis of collected benchmark samples](#disable-statistical-analysis-of-collected-benchmark-samples)<br>
|
||||
[Specify the amount of time in milliseconds spent on warming up each test](#specify-the-amount-of-time-in-milliseconds-spent-on-warming-up-each-test)<br>
|
||||
[Usage](#usage)<br>
|
||||
[Specify the section to run](#specify-the-section-to-run)<br>
|
||||
[Filenames as tags](#filenames-as-tags)<br>
|
||||
@ -64,6 +65,7 @@ Click one of the following links to take you straight to that option - or scroll
|
||||
<a href="#benchmark-resamples"> ` --benchmark-resamples`</a><br />
|
||||
<a href="#benchmark-confidence-interval"> ` --benchmark-confidence-interval`</a><br />
|
||||
<a href="#benchmark-no-analysis"> ` --benchmark-no-analysis`</a><br />
|
||||
<a href="#benchmark-warmup-time"> ` --benchmark-warmup-time`</a><br />
|
||||
<a href="#use-colour"> ` --use-colour`</a><br />
|
||||
|
||||
</br>
|
||||
@ -269,7 +271,7 @@ See [The LibIdentify repo for more information and examples](https://github.com/
|
||||
|
||||
<a id="wait-for-keypress"></a>
|
||||
## Wait for key before continuing
|
||||
<pre>--wait-for-keypress <start|exit|both></pre>
|
||||
<pre>--wait-for-keypress <never|start|exit|both></pre>
|
||||
|
||||
Will cause the executable to print a message and wait until the return/ enter key is pressed before continuing -
|
||||
either before running any tests, after running all tests - or both, depending on the argument.
|
||||
@ -317,6 +319,14 @@ Must be between 0 and 1 and defaults to 0.95.
|
||||
When this flag is specified no bootstrapping or any other statistical analysis is performed.
|
||||
Instead the user code is only measured and the plain mean from the samples is reported.
|
||||
|
||||
<a id="benchmark-warmup-time"></a>
|
||||
## Specify the amount of time in milliseconds spent on warming up each test
|
||||
<pre>--benchmark-warmup-time</pre>
|
||||
|
||||
> [Introduced](https://github.com/catchorg/Catch2/pull/1844) in Catch X.Y.Z.
|
||||
|
||||
Configure the amount of time spent warming up each test.
|
||||
|
||||
<a id="usage"></a>
|
||||
## Usage
|
||||
<pre>-h, -?, --help</pre>
|
||||
|
@ -17,4 +17,4 @@ fact then please let us know - either directly, via a PR or
|
||||
- NASA
|
||||
- [Inscopix Inc.](https://www.inscopix.com/)
|
||||
- [Makimo](https://makimo.pl/)
|
||||
- [UX3D] (https://ux3d.io)
|
||||
- [UX3D](https://ux3d.io)
|
||||
|
@ -16,6 +16,7 @@
|
||||
[Windows header clutter](#windows-header-clutter)<br>
|
||||
[Enabling stringification](#enabling-stringification)<br>
|
||||
[Disabling exceptions](#disabling-exceptions)<br>
|
||||
[Overriding Catch's debug break (`-b`)](#overriding-catchs-debug-break--b)<br>
|
||||
|
||||
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
|
||||
|
||||
@ -249,6 +250,18 @@ namespace Catch {
|
||||
}
|
||||
```
|
||||
|
||||
## Overriding Catch's debug break (`-b`)
|
||||
|
||||
> [Introduced](https://github.com/catchorg/Catch2/pull/1846) in Catch X.Y.Z.
|
||||
|
||||
You can override Catch2's break-into-debugger code by defining the
|
||||
`CATCH_BREAK_INTO_DEBUGGER()` macro. This can be used if e.g. Catch2 does
|
||||
not know your platform, or your platform is misdetected.
|
||||
|
||||
The macro will be used as is, that is, `CATCH_BREAK_INTO_DEBUGGER();`
|
||||
must compile and must break into debugger.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@ -9,6 +9,35 @@ either of these is a breaking change, and thus will not happen until
|
||||
at least the next major release.
|
||||
|
||||
|
||||
### Composing lvalues of already composed matchers
|
||||
|
||||
Because a significant bug in this use case has persisted for 2+ years
|
||||
without a bug report, and to simplify the implementation, code that
|
||||
composes lvalues of composed matchers will not compile. That is,
|
||||
this code will no longer work:
|
||||
|
||||
```cpp
|
||||
auto m1 = Contains("string");
|
||||
auto m2 = Contains("random");
|
||||
auto composed1 = m1 || m2;
|
||||
auto m3 = Contains("different");
|
||||
auto composed2 = composed1 || m3;
|
||||
REQUIRE_THAT(foo(), !composed1);
|
||||
REQUIRE_THAT(foo(), composed2);
|
||||
```
|
||||
|
||||
Instead you will have to write this:
|
||||
|
||||
```cpp
|
||||
auto m1 = Contains("string");
|
||||
auto m2 = Contains("random");
|
||||
auto m3 = Contains("different");
|
||||
REQUIRE_THAT(foo(), !(m1 || m2));
|
||||
REQUIRE_THAT(foo(), m1 || m2 || m3);
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Planned changes
|
||||
|
||||
### `CHECKED_IF` and `CHECKED_ELSE`
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[2.11.1](#2111)<br>
|
||||
[2.11.0](#2110)<br>
|
||||
[2.10.2](#2102)<br>
|
||||
[2.10.1](#2101)<br>
|
||||
@ -63,6 +64,22 @@
|
||||
* `CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER` no longer exists.
|
||||
* `StringMaker` specializations for <chrono> are always provided
|
||||
|
||||
|
||||
|
||||
## 2.11.1
|
||||
|
||||
### Improvements
|
||||
* Breaking into debugger is supported on iOS (#1817)
|
||||
* `google-build-using-namespace` clang-tidy warning is suppressed (#1799)
|
||||
|
||||
### Fixes
|
||||
* Clang on Windows is no longer assumed to implement MSVC's traditional preprocessor (#1806)
|
||||
* `ObjectStorage` now behaves properly in `const` contexts (#1820)
|
||||
* `GENERATE_COPY(a, b)` now compiles properly (#1809, #1815)
|
||||
* Some more cleanups in the benchmarking support
|
||||
|
||||
|
||||
|
||||
## 2.11.0
|
||||
|
||||
### Improvements
|
||||
|
@ -30,7 +30,7 @@ std::ostream& operator<<(std::ostream& out, Catch::Tag t) {
|
||||
template< typename T >
|
||||
std::ostream& operator<<( std::ostream& os, std::vector<T> const& v ) {
|
||||
os << "{ ";
|
||||
for ( auto x : v )
|
||||
for ( const auto& x : v )
|
||||
os << x << ", ";
|
||||
return os << "}";
|
||||
}
|
||||
@ -63,7 +63,7 @@ void print( std::ostream& os, int const level, Catch::MessageInfo const& info )
|
||||
|
||||
void print( std::ostream& os, int const level, std::string const& title, std::vector<Catch::MessageInfo> const& v ) {
|
||||
os << ws(level ) << title << ":\n";
|
||||
for ( auto x : v )
|
||||
for ( const auto& x : v )
|
||||
{
|
||||
os << ws(level+1) << "{\n";
|
||||
print( os, level+2, x );
|
||||
|
@ -18,7 +18,7 @@ class out_buff : public std::stringbuf {
|
||||
public:
|
||||
out_buff(std::FILE* stream):m_stream(stream) {}
|
||||
~out_buff();
|
||||
int sync() {
|
||||
int sync() override {
|
||||
int ret = 0;
|
||||
for (unsigned char c : str()) {
|
||||
if (putc(c, m_stream) == EOF) {
|
||||
|
17
projects/ExtraTests/X12-CustomDebugBreakMacro.cpp
Normal file
17
projects/ExtraTests/X12-CustomDebugBreakMacro.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// X12-CustomDebugBreakMacro.cpp
|
||||
// Test that user-defined `CATCH_BREAK_INTO_DEBUGGER` is respected and used.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void custom_debug_break() {
|
||||
std::cerr << "Pretty please, break into debugger\n";
|
||||
}
|
||||
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() custom_debug_break()
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE("Failing test that breaks into debugger", "[macros]") {
|
||||
REQUIRE(1 == 2);
|
||||
}
|
@ -77,6 +77,7 @@ set(INTERNAL_HEADERS
|
||||
${SOURCES_DIR}/catch_matchers_floating.h
|
||||
${SOURCES_DIR}/catch_matchers_generic.hpp
|
||||
${SOURCES_DIR}/catch_matchers_string.h
|
||||
${SOURCES_DIR}/catch_matchers_templates.hpp
|
||||
${SOURCES_DIR}/catch_matchers_vector.h
|
||||
${SOURCES_DIR}/catch_message.h
|
||||
${SOURCES_DIR}/catch_meta.hpp
|
||||
@ -159,6 +160,7 @@ set(IMPL_SOURCES
|
||||
${SOURCES_DIR}/catch_matchers_floating.cpp
|
||||
${SOURCES_DIR}/catch_matchers_generic.cpp
|
||||
${SOURCES_DIR}/catch_matchers_string.cpp
|
||||
${SOURCES_DIR}/catch_matchers_templates.cpp
|
||||
${SOURCES_DIR}/catch_message.cpp
|
||||
${SOURCES_DIR}/catch_output_redirect.cpp
|
||||
${SOURCES_DIR}/catch_registry_hub.cpp
|
||||
|
@ -44,10 +44,10 @@ namespace Catch {
|
||||
template <typename Clock>
|
||||
ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
|
||||
auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
|
||||
auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
|
||||
auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
|
||||
auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
|
||||
int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
|
||||
return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
|
||||
return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
|
||||
}
|
||||
|
||||
template <typename Clock = default_clock>
|
||||
|
@ -17,7 +17,7 @@ namespace Catch {
|
||||
// the Equals matcher (so the header does not mention matchers)
|
||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
|
||||
std::string exceptionMessage = Catch::translateActiveException();
|
||||
MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
|
||||
MatchExpr<std::string, StringMatcher const&> expr( std::move(exceptionMessage), matcher, matcherString );
|
||||
handler.handleExpr( expr );
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,13 @@ namespace Catch {
|
||||
|
||||
template<typename ArgT, typename MatcherT>
|
||||
class MatchExpr : public ITransientExpression {
|
||||
ArgT const& m_arg;
|
||||
ArgT && m_arg;
|
||||
MatcherT m_matcher;
|
||||
StringRef m_matcherString;
|
||||
public:
|
||||
MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
|
||||
: ITransientExpression{ true, matcher.match( arg ) },
|
||||
m_arg( arg ),
|
||||
MatchExpr( ArgT && arg, MatcherT const& matcher, StringRef const& matcherString )
|
||||
: ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose
|
||||
m_arg( std::forward<ArgT>(arg) ),
|
||||
m_matcher( matcher ),
|
||||
m_matcherString( matcherString )
|
||||
{}
|
||||
@ -42,8 +42,8 @@ namespace Catch {
|
||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
|
||||
|
||||
template<typename ArgT, typename MatcherT>
|
||||
auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
|
||||
return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
|
||||
auto makeMatchExpr( ArgT && arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
|
||||
return MatchExpr<ArgT, MatcherT>( std::forward<ArgT>(arg), matcher, matcherString );
|
||||
}
|
||||
|
||||
} // namespace Catch
|
||||
|
@ -50,14 +50,13 @@ namespace Catch {
|
||||
if( !startsWith( line, '"' ) )
|
||||
line = '"' + line + '"';
|
||||
config.testsOrTags.push_back( line );
|
||||
config.testsOrTags.push_back( "," );
|
||||
|
||||
config.testsOrTags.emplace_back( "," );
|
||||
}
|
||||
}
|
||||
//Remove comma in the end
|
||||
if(!config.testsOrTags.empty())
|
||||
config.testsOrTags.erase( config.testsOrTags.end()-1 );
|
||||
|
||||
|
||||
return ParserResult::ok( ParseResultType::Matched );
|
||||
};
|
||||
auto const setTestOrder = [&]( std::string const& order ) {
|
||||
@ -92,14 +91,16 @@ namespace Catch {
|
||||
};
|
||||
auto const setWaitForKeypress = [&]( std::string const& keypress ) {
|
||||
auto keypressLc = toLower( keypress );
|
||||
if( keypressLc == "start" )
|
||||
if (keypressLc == "never")
|
||||
config.waitForKeypress = WaitForKeypress::Never;
|
||||
else if( keypressLc == "start" )
|
||||
config.waitForKeypress = WaitForKeypress::BeforeStart;
|
||||
else if( keypressLc == "exit" )
|
||||
config.waitForKeypress = WaitForKeypress::BeforeExit;
|
||||
else if( keypressLc == "both" )
|
||||
config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
|
||||
else
|
||||
return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
|
||||
return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
|
||||
return ParserResult::ok( ParseResultType::Matched );
|
||||
};
|
||||
auto const setVerbosity = [&]( std::string const& verbosity ) {
|
||||
@ -196,7 +197,7 @@ namespace Catch {
|
||||
| Opt( config.libIdentify )
|
||||
["--libidentify"]
|
||||
( "report name and version according to libidentify standard" )
|
||||
| Opt( setWaitForKeypress, "start|exit|both" )
|
||||
| Opt( setWaitForKeypress, "never|start|exit|both" )
|
||||
["--wait-for-keypress"]
|
||||
( "waits for a keypress before exiting" )
|
||||
| Opt( config.benchmarkSamples, "samples" )
|
||||
@ -211,7 +212,10 @@ namespace Catch {
|
||||
| Opt( config.benchmarkNoAnalysis )
|
||||
["--benchmark-no-analysis"]
|
||||
( "perform only measurements; do not perform any analysis" )
|
||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||
| Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
|
||||
["--benchmark-warmup-time"]
|
||||
( "amount of time in milliseconds spent on warming up each test (default: 100)" )
|
||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||
( "which test or tests to use" );
|
||||
|
||||
return cli;
|
||||
|
@ -203,7 +203,7 @@
|
||||
#define CATCH_CONFIG_COLOUR_NONE
|
||||
#endif
|
||||
|
||||
#if defined(__UCLIBC__)
|
||||
#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
|
||||
#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
|
||||
#endif
|
||||
|
||||
|
@ -75,10 +75,11 @@ namespace Catch {
|
||||
bool Config::showInvisibles() const { return m_data.showInvisibles; }
|
||||
Verbosity Config::verbosity() const { return m_data.verbosity; }
|
||||
|
||||
bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
|
||||
int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
|
||||
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
|
||||
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
|
||||
bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
|
||||
int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
|
||||
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
|
||||
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
|
||||
std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
|
||||
|
||||
IStream const* Config::openStream() {
|
||||
return Catch::makeStream(m_data.outputFilename);
|
||||
|
@ -43,6 +43,7 @@ namespace Catch {
|
||||
unsigned int benchmarkSamples = 100;
|
||||
double benchmarkConfidenceInterval = 0.95;
|
||||
unsigned int benchmarkResamples = 100000;
|
||||
std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
|
||||
|
||||
Verbosity verbosity = Verbosity::Normal;
|
||||
WarnAbout::What warnings = WarnAbout::Nothing;
|
||||
@ -108,6 +109,7 @@ namespace Catch {
|
||||
int benchmarkSamples() const override;
|
||||
double benchmarkConfidenceInterval() const override;
|
||||
unsigned int benchmarkResamples() const override;
|
||||
std::chrono::milliseconds benchmarkWarmupTime() const override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace Catch {
|
||||
};
|
||||
|
||||
struct NoColourImpl : IColourImpl {
|
||||
void use( Colour::Code ) {}
|
||||
void use( Colour::Code ) override {}
|
||||
|
||||
static IColourImpl* instance() {
|
||||
static NoColourImpl s_instance;
|
||||
@ -208,13 +208,13 @@ namespace Catch {
|
||||
namespace Catch {
|
||||
|
||||
Colour::Colour( Code _colourCode ) { use( _colourCode ); }
|
||||
Colour::Colour( Colour&& rhs ) noexcept {
|
||||
m_moved = rhs.m_moved;
|
||||
rhs.m_moved = true;
|
||||
Colour::Colour( Colour&& other ) noexcept {
|
||||
m_moved = other.m_moved;
|
||||
other.m_moved = true;
|
||||
}
|
||||
Colour& Colour::operator=( Colour&& rhs ) noexcept {
|
||||
m_moved = rhs.m_moved;
|
||||
rhs.m_moved = true;
|
||||
Colour& Colour::operator=( Colour&& other ) noexcept {
|
||||
m_moved = other.m_moved;
|
||||
other.m_moved = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ namespace Catch {
|
||||
// However, under some conditions it does happen (see #1626),
|
||||
// and this change is small enough that we can let practicality
|
||||
// triumph over purity in this case.
|
||||
if (impl != NULL) {
|
||||
if (impl != nullptr) {
|
||||
impl->use( _colourCode );
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,10 @@ namespace Catch {
|
||||
#define CATCH_TRAP() __asm__("int $3")
|
||||
#elif defined(__aarch64__)
|
||||
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
||||
#elif defined(__arm__)
|
||||
#elif defined(__arm__) && !defined(__thumb__)
|
||||
#define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
|
||||
#elif defined(__arm__) && defined(__thumb__)
|
||||
#define CATCH_TRAP() __asm__(".inst 0xde01")
|
||||
#endif
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
@ -48,10 +50,12 @@ namespace Catch {
|
||||
#define CATCH_TRAP() DebugBreak()
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_TRAP
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{}()
|
||||
#ifndef CATCH_BREAK_INTO_DEBUGGER
|
||||
#ifdef CATCH_TRAP
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() []{}()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
||||
|
@ -9,10 +9,11 @@
|
||||
#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_session.h>
|
||||
#include <catch2/catch_platform.h>
|
||||
|
||||
#ifndef __OBJC__
|
||||
|
||||
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
|
||||
#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
|
||||
// Standard C/C++ Win32 Unicode wmain entry point
|
||||
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
|
||||
#else
|
||||
|
@ -60,7 +60,7 @@ namespace Catch {
|
||||
assert( valueNames.size() == values.size() );
|
||||
std::size_t i = 0;
|
||||
for( auto value : values )
|
||||
enumInfo->m_values.push_back({ value, valueNames[i++] });
|
||||
enumInfo->m_values.emplace_back(value, valueNames[i++]);
|
||||
|
||||
return enumInfo;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <catch2/catch_common.h>
|
||||
#include <catch2/catch_option.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -81,6 +82,7 @@ namespace Catch {
|
||||
virtual int benchmarkSamples() const = 0;
|
||||
virtual double benchmarkConfidenceInterval() const = 0;
|
||||
virtual unsigned int benchmarkResamples() const = 0;
|
||||
virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
|
||||
};
|
||||
|
||||
using IConfigPtr = std::shared_ptr<IConfig const>;
|
||||
|
@ -91,9 +91,10 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
@ -124,9 +125,10 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
|
@ -59,16 +59,8 @@ namespace {
|
||||
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
|
||||
}
|
||||
|
||||
} //end anonymous namespace
|
||||
|
||||
#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
// The long double overload is currently unused
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
float nextafter(float x, float y) {
|
||||
return ::nextafterf(x, y);
|
||||
}
|
||||
@ -77,18 +69,8 @@ namespace {
|
||||
return ::nextafter(x, y);
|
||||
}
|
||||
|
||||
long double nextafter(long double x, long double y) {
|
||||
return ::nextafterl(x, y);
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename FP>
|
||||
FP step(FP start, FP direction, uint64_t steps) {
|
||||
for (uint64_t i = 0; i < steps; ++i) {
|
||||
|
32
src/catch2/catch_matchers_templates.cpp
Normal file
32
src/catch2/catch_matchers_templates.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <catch2/catch_matchers_templates.hpp>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
MatcherGenericBase::~MatcherGenericBase() {}
|
||||
|
||||
std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end) {
|
||||
std::string description;
|
||||
std::size_t combined_size = 4;
|
||||
for ( auto desc = descriptions_begin; desc != descriptions_end; ++desc ) {
|
||||
combined_size += desc->size();
|
||||
}
|
||||
combined_size += (descriptions_end - descriptions_begin - 1) * combine.size();
|
||||
|
||||
description.reserve(combined_size);
|
||||
|
||||
description += "( ";
|
||||
bool first = true;
|
||||
for( auto desc = descriptions_begin; desc != descriptions_end; ++desc ) {
|
||||
if( first )
|
||||
first = false;
|
||||
else
|
||||
description += combine;
|
||||
description += *desc;
|
||||
}
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
}
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
262
src/catch2/catch_matchers_templates.hpp
Normal file
262
src/catch2/catch_matchers_templates.hpp
Normal file
@ -0,0 +1,262 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_common.h>
|
||||
#include <catch2/catch_matchers.h>
|
||||
#include <catch2/catch_stringref.h>
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
template<typename... MatcherTs> struct MatchAllOfGeneric;
|
||||
template<typename... MatcherTs> struct MatchAnyOfGeneric;
|
||||
template<typename MatcherT> struct MatchNotOfGeneric;
|
||||
|
||||
struct MatcherGenericBase : MatcherUntypedBase {
|
||||
virtual ~MatcherGenericBase();
|
||||
};
|
||||
|
||||
template<std::size_t N, std::size_t M>
|
||||
std::array<void const*, N + M> array_cat(std::array<void const*, N> && lhs, std::array<void const*, M> && rhs) {
|
||||
std::array<void const*, N + M> arr{};
|
||||
std::copy_n(lhs.begin(), N, arr.begin());
|
||||
std::copy_n(rhs.begin(), M, arr.begin() + N);
|
||||
return arr;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
std::array<void const*, N+1> array_cat(std::array<void const*, N> && lhs, void const* rhs) {
|
||||
std::array<void const*, N+1> arr{};
|
||||
std::copy_n(lhs.begin(), N, arr.begin());
|
||||
arr[N] = rhs;
|
||||
return arr;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
std::array<void const*, N+1> array_cat(void const* lhs, std::array<void const*, N> && rhs) {
|
||||
std::array<void const*, N+1> arr{lhs};
|
||||
std::copy_n(rhs.begin(), N, arr.begin() + 1);
|
||||
return arr;
|
||||
}
|
||||
|
||||
#ifdef CATCH_CPP17_OR_GREATER
|
||||
|
||||
using std::conjunction;
|
||||
|
||||
#else // CATCH_CPP17_OR_GREATER
|
||||
|
||||
template<typename... Cond>
|
||||
struct conjunction : std::true_type {};
|
||||
|
||||
template<typename Cond, typename... Rest>
|
||||
struct conjunction<Cond, Rest...> : std::integral_constant<bool, Cond::value && conjunction<Rest...>::value> {};
|
||||
|
||||
#endif // CATCH_CPP17_OR_GREATER
|
||||
|
||||
template<typename T>
|
||||
using is_generic_matcher = std::is_base_of<
|
||||
Catch::Matchers::Impl::MatcherGenericBase,
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type
|
||||
>;
|
||||
|
||||
template<typename... Ts>
|
||||
using are_generic_matchers = conjunction<is_generic_matcher<Ts>...>;
|
||||
|
||||
template<typename T>
|
||||
using is_matcher = std::is_base_of<
|
||||
Catch::Matchers::Impl::MatcherUntypedBase,
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type
|
||||
>;
|
||||
|
||||
|
||||
template<std::size_t N, typename Arg>
|
||||
bool match_all_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
|
||||
bool match_all_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
|
||||
return static_cast<T const*>(matchers[Idx])->match(arg) && match_all_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
|
||||
}
|
||||
|
||||
|
||||
template<std::size_t N, typename Arg>
|
||||
bool match_any_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
|
||||
bool match_any_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
|
||||
return static_cast<T const*>(matchers[Idx])->match(arg) || match_any_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
|
||||
}
|
||||
|
||||
std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end);
|
||||
|
||||
template<typename... MatcherTs, std::size_t... Idx>
|
||||
std::string describe_multi_matcher(StringRef combine, std::array<void const*, sizeof...(MatcherTs)> const& matchers, std::index_sequence<Idx...>) {
|
||||
std::array<std::string, sizeof...(MatcherTs)> descriptions {{
|
||||
static_cast<MatcherTs const*>(matchers[Idx])->toString()...
|
||||
}};
|
||||
|
||||
return describe_multi_matcher(combine, descriptions.data(), descriptions.data() + descriptions.size());
|
||||
}
|
||||
|
||||
|
||||
template<typename... MatcherTs>
|
||||
struct MatchAllOfGeneric : MatcherGenericBase {
|
||||
MatchAllOfGeneric(MatcherTs const&... matchers) : m_matchers{std::addressof(matchers)...} {}
|
||||
explicit MatchAllOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
|
||||
|
||||
template<typename Arg>
|
||||
bool match(Arg&& arg) const {
|
||||
return match_all_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return describe_multi_matcher<MatcherTs...>(" and "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
|
||||
}
|
||||
|
||||
std::array<void const*, sizeof...(MatcherTs)> m_matchers;
|
||||
};
|
||||
|
||||
|
||||
template<typename... MatcherTs>
|
||||
struct MatchAnyOfGeneric : MatcherGenericBase {
|
||||
MatchAnyOfGeneric(MatcherTs const&... matchers) : m_matchers{std::addressof(matchers)...} {}
|
||||
explicit MatchAnyOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
|
||||
|
||||
template<typename Arg>
|
||||
bool match(Arg&& arg) const {
|
||||
return match_any_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return describe_multi_matcher<MatcherTs...>(" or "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
|
||||
}
|
||||
|
||||
std::array<void const*, sizeof...(MatcherTs)> m_matchers;
|
||||
};
|
||||
|
||||
|
||||
template<typename MatcherT>
|
||||
struct MatchNotOfGeneric : MatcherGenericBase {
|
||||
explicit MatchNotOfGeneric(MatcherT const& matcher) : m_matcher{matcher} {}
|
||||
|
||||
template<typename Arg>
|
||||
bool match(Arg&& arg) const {
|
||||
return !m_matcher.match(arg);
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return "not " + m_matcher.toString();
|
||||
}
|
||||
|
||||
MatcherT const& m_matcher;
|
||||
};
|
||||
|
||||
// compose only generic matchers
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
typename std::enable_if<is_generic_matcher<MatcherT>::value, MatchNotOfGeneric<MatcherT>>::type
|
||||
operator ! (MatcherT const& matcher) {
|
||||
return MatchNotOfGeneric<MatcherT>{matcher};
|
||||
}
|
||||
|
||||
|
||||
// compose mixed generic and non-generic matchers
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename ArgRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
template<typename ArgLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
|
||||
// avoid deep nesting of matcher templates
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator && (MatchAllOfGeneric<MatchersLHS...> && lhs, MatchAllOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>{array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator && (MatchAllOfGeneric<MatchersLHS...> && lhs, MatcherRHS const& rhs) {
|
||||
return MatchAllOfGeneric<MatchersLHS..., MatcherRHS>{array_cat(std::move(lhs.m_matchers), static_cast<void const*>(&rhs))};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<is_matcher<MatcherLHS>::value, MatchAllOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator && (MatcherLHS const& lhs, MatchAllOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAllOfGeneric<MatcherLHS, MatchersRHS...>{array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename... MatchersRHS>
|
||||
MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>
|
||||
operator || (MatchAnyOfGeneric<MatchersLHS...> && lhs, MatchAnyOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>{array_cat(std::move(lhs.m_matchers), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename... MatchersLHS, typename MatcherRHS>
|
||||
typename std::enable_if<is_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
operator || (MatchAnyOfGeneric<MatchersLHS...> && lhs, MatcherRHS const& rhs) {
|
||||
return MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>{array_cat(std::move(lhs.m_matchers), static_cast<void const*>(std::addressof(rhs)))};
|
||||
}
|
||||
|
||||
template<typename MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<is_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
operator || (MatcherLHS const& lhs, MatchAnyOfGeneric<MatchersRHS...> && rhs) {
|
||||
return MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>{array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
MatcherT const& operator ! (MatchNotOfGeneric<MatcherT> const& matcher) {
|
||||
return matcher.m_matcher;
|
||||
}
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherGenericBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif //TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
|
@ -111,7 +111,7 @@ namespace Catch {
|
||||
pos = skipq(pos, c);
|
||||
break;
|
||||
case ',':
|
||||
if (start != pos && openings.size() == 0) {
|
||||
if (start != pos && openings.empty()) {
|
||||
m_messages.emplace_back(macroName, lineInfo, resultType);
|
||||
m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
|
||||
m_messages.back().message += " := ";
|
||||
@ -119,7 +119,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(openings.size() == 0 && "Mismatched openings");
|
||||
assert(openings.empty() && "Mismatched openings");
|
||||
m_messages.emplace_back(macroName, lineInfo, resultType);
|
||||
m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
|
||||
m_messages.back().message += " := ";
|
||||
|
@ -204,11 +204,11 @@ namespace Catch {
|
||||
char **utf8Argv = new char *[ argc ];
|
||||
|
||||
for ( int i = 0; i < argc; ++i ) {
|
||||
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
|
||||
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
|
||||
|
||||
utf8Argv[ i ] = new char[ bufSize ];
|
||||
|
||||
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
|
||||
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
|
||||
}
|
||||
|
||||
int returnCode = applyCommandLine( argc, utf8Argv );
|
||||
|
@ -224,8 +224,8 @@ namespace TestCaseTracking {
|
||||
void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
|
||||
if( !filters.empty() ) {
|
||||
m_filters.reserve( m_filters.size() + filters.size() + 2 );
|
||||
m_filters.push_back(""); // Root - should never be consulted
|
||||
m_filters.push_back(""); // Test Case - not a section filter
|
||||
m_filters.emplace_back(""); // Root - should never be consulted
|
||||
m_filters.emplace_back(""); // Test Case - not a section filter
|
||||
m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include <iomanip>
|
||||
#include <type_traits>
|
||||
|
||||
using uchar = unsigned char;
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
@ -87,7 +85,7 @@ namespace {
|
||||
// (see: http://www.w3.org/TR/xml/#syntax)
|
||||
|
||||
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
|
||||
uchar c = m_str[idx];
|
||||
unsigned char c = m_str[idx];
|
||||
switch (c) {
|
||||
case '<': os << "<"; break;
|
||||
case '&': os << "&"; break;
|
||||
@ -147,7 +145,7 @@ namespace {
|
||||
bool valid = true;
|
||||
uint32_t value = headerValue(c);
|
||||
for (std::size_t n = 1; n < encBytes; ++n) {
|
||||
uchar nc = m_str[idx + n];
|
||||
unsigned char nc = m_str[idx + n];
|
||||
valid &= ((nc & 0xC0) == 0x80);
|
||||
value = (value << 6) | (nc & 0x3F);
|
||||
}
|
||||
|
@ -228,11 +228,7 @@ namespace Catch {
|
||||
elementName = "error";
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
elementName = "failure";
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
elementName = "failure";
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
elementName = "failure";
|
||||
break;
|
||||
|
@ -142,6 +142,14 @@ if (MSVC)
|
||||
add_test(NAME WindowsHeader COMMAND WindowsHeader -r compact)
|
||||
endif()
|
||||
|
||||
add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
|
||||
add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)
|
||||
set_tests_properties(
|
||||
DebugBreakMacros
|
||||
PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "Pretty please, break into debugger"
|
||||
)
|
||||
|
||||
set( EXTRA_TEST_BINARIES
|
||||
PrefixedMacros
|
||||
DisabledMacros
|
||||
@ -150,6 +158,7 @@ set( EXTRA_TEST_BINARIES
|
||||
FallbackStringifier
|
||||
DisableStringification
|
||||
BenchmarkingMacros
|
||||
DebugBreakMacros
|
||||
)
|
||||
|
||||
# Shared config
|
||||
|
@ -85,6 +85,13 @@ Nor would this
|
||||
:test-result: PASS CAPTURE parses string and character constants
|
||||
:test-result: PASS Capture and info messages
|
||||
:test-result: PASS Character pretty printing
|
||||
:test-result: PASS Combining MatchAllOfGeneric does not nest
|
||||
:test-result: PASS Combining MatchAnyOfGeneric does not nest
|
||||
:test-result: PASS Combining MatchNotOfGeneric does not nest
|
||||
:test-result: PASS Combining concrete matchers does not use templated matchers
|
||||
:test-result: PASS Combining only templated matchers
|
||||
:test-result: PASS Combining templated and concrete matchers
|
||||
:test-result: PASS Combining templated matchers
|
||||
:test-result: PASS Commas in various macros are allowed
|
||||
:test-result: PASS Comparing function pointers
|
||||
:test-result: PASS Comparison ops
|
||||
@ -92,6 +99,7 @@ Nor would this
|
||||
:test-result: PASS Comparisons between ints where one side is computed
|
||||
:test-result: PASS Comparisons between unsigned ints and negative signed ints match c++ standard behaviour
|
||||
:test-result: PASS Comparisons with int literals don't warn when mixing signed/ unsigned
|
||||
:test-result: PASS Composed matchers are distinct
|
||||
:test-result: FAIL Contains string matcher
|
||||
:test-result: PASS Copy and then generate a range
|
||||
:test-result: FAIL Custom exceptions can be translated when testing for nothrow
|
||||
@ -147,6 +155,7 @@ Nor would this
|
||||
:test-result: PASS Ordering comparison checks that should succeed
|
||||
:test-result: PASS Our PCG implementation provides expected results for known seeds
|
||||
:test-result: FAIL Output from all sections is reported
|
||||
:test-result: PASS Overloaded comma or address-of operators are not used
|
||||
:test-result: PASS Parse test names and tags
|
||||
:test-result: PASS Pointers can be compared to null
|
||||
:test-result: PASS Precision of floating point stringification can be set
|
||||
|
@ -263,6 +263,37 @@ ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 2 == 2
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 3 == 3
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 5 == 5
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() && MatcherB() && MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() && MatcherB() && MatcherC() && MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 and equals: true )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() || MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() || MatcherC() || MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 or equals: true )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 0, !MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!MatcherA()), MatcherA const& >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, !!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 0, !!!MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(!!!!MatcherA()), MatcherA const & >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, !!!!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))), Catch::Matchers::Impl::MatchAnyOf<std::string> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() && MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric<MatcherB>> >::value'
|
||||
Matchers.tests.cpp:<line number>: passed: 1, MatcherA() || !MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or not equals: (long long) 1 )
|
||||
Matchers.tests.cpp:<line number>: passed: vec, Predicate<std::vector<int>>([](auto const& vec) { return std::all_of(vec.begin(), vec.end(), [](int elem) { return elem % 2 == 1; }); }, "All elements are odd") && !EqualsRange(a) for: { 1, 3, 5 } ( matches predicate: "All elements are odd" and not Equals: { 5, 3, 1 } )
|
||||
Matchers.tests.cpp:<line number>: passed: str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
Matchers.tests.cpp:<line number>: passed: str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar")) for: "foobar" ( Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } or ( starts with: "foo" and ends with: "bar" ) )
|
||||
Matchers.tests.cpp:<line number>: passed: str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr) for: "foobar" ( ( starts with: "foo" and ends with: "bar" ) or Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } )
|
||||
Matchers.tests.cpp:<line number>: passed: container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c) for: { 1, 2, 3 } ( Equals: { 1, 2, 3 } or Equals: { 0, 1, 2 } or Equals: { 4, 5, 6 } )
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
|
||||
Tricky.tests.cpp:<line number>: passed: std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
|
||||
@ -313,6 +344,8 @@ Condition.tests.cpp:<line number>: passed: 4 == ul for: 4 == 4
|
||||
Condition.tests.cpp:<line number>: passed: 5 == c for: 5 == 5
|
||||
Condition.tests.cpp:<line number>: passed: 6 == uc for: 6 == 6
|
||||
Condition.tests.cpp:<line number>: passed: (std::numeric_limits<uint32_t>::max)() > ul for: 4294967295 (0x<hex digits>) > 4
|
||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching2(), !composed1 for: "some completely different text that contains one common word" not ( contains: "string" or contains: "random" )
|
||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching2(), composed2 for: "some completely different text that contains one common word" ( contains: "string" or contains: "random" or contains: "different" )
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive)
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("STRING") for: "this string contains 'abc' as a substring" contains: "STRING"
|
||||
Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
|
||||
@ -883,6 +916,10 @@ RandomNumberGeneration.tests.cpp:<line number>: passed: rng() == 0x<hex digits>
|
||||
4261393167 (0x<hex digits>)
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section one'
|
||||
Message.tests.cpp:<line number>: failed: explicitly with 1 message: 'Message from section two'
|
||||
Matchers.tests.cpp:<line number>: passed: (EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed
|
||||
Matchers.tests.cpp:<line number>: passed: &EvilMatcher(), EvilAddressOfOperatorUsed
|
||||
Matchers.tests.cpp:<line number>: passed: EvilMatcher() || EvilMatcher() && !EvilMatcher()
|
||||
Matchers.tests.cpp:<line number>: passed: (EvilMatcher() && EvilMatcher()) || !EvilMatcher()
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.hasFilters() == false for: false == false
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *tcA ) == false for: false == false
|
||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *tcB ) == false for: false == false
|
||||
@ -1087,6 +1124,16 @@ CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-x", "2"}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.abortAfter == 2 for: 2 == 2
|
||||
CmdLine.tests.cpp:<line number>: passed: !result for: true
|
||||
CmdLine.tests.cpp:<line number>: passed: result.errorMessage(), Contains("convert") && Contains("oops") for: "Unable to convert 'oops' to destination type" ( contains: "convert" and contains: "oops" )
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.waitForKeypress == std::get<1>(input) for: 0 == 0
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.waitForKeypress == std::get<1>(input) for: 1 == 1
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.waitForKeypress == std::get<1>(input) for: 2 == 2
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.waitForKeypress == std::get<1>(input) for: 3 == 3
|
||||
CmdLine.tests.cpp:<line number>: passed: !result for: true
|
||||
CmdLine.tests.cpp:<line number>: passed: result.errorMessage(), Contains("never") && Contains("both") for: "keypress argument must be one of: never, start, exit or both. 'sometimes' not recognised" ( contains: "never" and contains: "both" )
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-e"}) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.noThrow for: true
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--nothrow"}) for: {?}
|
||||
@ -1117,6 +1164,8 @@ CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-confid
|
||||
CmdLine.tests.cpp:<line number>: passed: config.benchmarkConfidenceInterval == Catch::Approx(0.99) for: 0.99 == Approx( 0.99 )
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-no-analysis" }) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.benchmarkNoAnalysis for: true
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse({ "test", "--benchmark-warmup-time=10" }) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.benchmarkWarmupTime == 10 for: 10 == 10
|
||||
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 3 >= 1
|
||||
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 2 >= 1
|
||||
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 1 >= 1
|
||||
|
@ -1380,6 +1380,6 @@ due to unexpected exception with message:
|
||||
Why would you throw a std::string?
|
||||
|
||||
===============================================================================
|
||||
test cases: 320 | 246 passed | 70 failed | 4 failed as expected
|
||||
assertions: 1792 | 1640 passed | 131 failed | 21 failed as expected
|
||||
test cases: 329 | 255 passed | 70 failed | 4 failed as expected
|
||||
assertions: 1841 | 1689 passed | 131 failed | 21 failed as expected
|
||||
|
||||
|
@ -2116,6 +2116,217 @@ ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
5 == 5
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining MatchAllOfGeneric does not nest
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::
|
||||
Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() && MatcherB() && MatcherC() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T)
|
||||
1 )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()),
|
||||
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC,
|
||||
MatcherD> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() && MatcherB() && MatcherC() && MatcherD() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T)
|
||||
1 and equals: true )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining MatchAnyOfGeneric does not nest
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::
|
||||
Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() || MatcherB() || MatcherC() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1
|
||||
)
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()),
|
||||
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC,
|
||||
MatcherD> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() || MatcherB() || MatcherC() || MatcherD() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1
|
||||
or equals: true )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining MatchNotOfGeneric does not nest
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric
|
||||
<MatcherA> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 0, !MatcherA() )
|
||||
with expansion:
|
||||
0 not equals: (int) 1 or (float) 1.0f
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(!!MatcherA()), MatcherA const& >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, !!MatcherA() )
|
||||
with expansion:
|
||||
1 equals: (int) 1 or (float) 1.0f
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Impl::
|
||||
MatchNotOfGeneric<MatcherA> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 0, !!!MatcherA() )
|
||||
with expansion:
|
||||
0 not equals: (int) 1 or (float) 1.0f
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(!!!!MatcherA()), MatcherA const & >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, !!!!MatcherA() )
|
||||
with expansion:
|
||||
1 equals: (int) 1 or (float) 1.0f
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining concrete matchers does not use templated matchers
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith
|
||||
("bar") && !EndsWith("foo"))), Catch::Matchers::Impl::MatchAnyOf<std::string>
|
||||
>::value
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining only templated matchers
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Impl::
|
||||
MatchAnyOfGeneric<MatcherA, MatcherB> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() || MatcherB() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Impl::
|
||||
MatchAllOfGeneric<MatcherA, MatcherB> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() && MatcherB() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Impl::
|
||||
MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric
|
||||
<MatcherB>> >::value
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( 1, MatcherA() || !MatcherB() )
|
||||
with expansion:
|
||||
1 ( equals: (int) 1 or (float) 1.0f or not equals: (long long) 1 )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining templated and concrete matchers
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( vec, Predicate<std::vector<int>>([](auto const& vec) { return std::all_of(vec.begin(), vec.end(), [](int elem) { return elem % 2 == 1; }); }, "All elements are odd") && !EqualsRange(a) )
|
||||
with expansion:
|
||||
{ 1, 3, 5 } ( matches predicate: "All elements are odd" and not Equals: { 5,
|
||||
3, 1 } )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar") )
|
||||
with expansion:
|
||||
"foobar" ( starts with: "foo" and Equals: { 'f', 'o', 'o', 'b', 'a', 'r' }
|
||||
and ends with: "bar" )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar") )
|
||||
with expansion:
|
||||
"foobar" ( starts with: "foo" and not Equals: { 'o', 'o', 'f', 'b', 'a', 'r'
|
||||
} and ends with: "bar" )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar") )
|
||||
with expansion:
|
||||
"foobar" ( Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and starts with: "foo"
|
||||
and ends with: "bar" )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar") )
|
||||
with expansion:
|
||||
"foobar" ( not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and starts with:
|
||||
"foo" and ends with: "bar" )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar")) )
|
||||
with expansion:
|
||||
"foobar" ( Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } or ( starts with: "foo"
|
||||
and ends with: "bar" ) )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr) )
|
||||
with expansion:
|
||||
"foobar" ( ( starts with: "foo" and ends with: "bar" ) or Equals: { 'o', 'o',
|
||||
'f', 'b', 'a', 'r' } )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Combining templated matchers
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } ( Equals: { 1, 2, 3 } or Equals: { 0, 1, 2 } or Equals: { 4, 5, 6
|
||||
} )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Commas in various macros are allowed
|
||||
-------------------------------------------------------------------------------
|
||||
@ -2399,6 +2610,24 @@ Condition.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
4294967295 (0x<hex digits>) > 4
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Composed matchers are distinct
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( testStringForMatching2(), !composed1 )
|
||||
with expansion:
|
||||
"some completely different text that contains one common word" not (
|
||||
contains: "string" or contains: "random" )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( testStringForMatching2(), composed2 )
|
||||
with expansion:
|
||||
"some completely different text that contains one common word" ( contains:
|
||||
"string" or contains: "random" or contains: "different" )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Contains string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
@ -6414,6 +6643,24 @@ Message.tests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
Message from section two
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Overloaded comma or address-of operators are not used
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( (EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THROWS_AS( &EvilMatcher(), EvilAddressOfOperatorUsed )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_NOTHROW( EvilMatcher() || EvilMatcher() && !EvilMatcher() )
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_NOTHROW( (EvilMatcher() && EvilMatcher()) || !EvilMatcher() )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Parse test names and tags
|
||||
Empty test spec should have no filters
|
||||
@ -7825,6 +8072,102 @@ with expansion:
|
||||
"Unable to convert 'oops' to destination type" ( contains: "convert" and
|
||||
contains: "oops" )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
abort
|
||||
wait-for-keypress
|
||||
Accepted options
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.waitForKeypress == std::get<1>(input) )
|
||||
with expansion:
|
||||
0 == 0
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
abort
|
||||
wait-for-keypress
|
||||
Accepted options
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.waitForKeypress == std::get<1>(input) )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
abort
|
||||
wait-for-keypress
|
||||
Accepted options
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.waitForKeypress == std::get<1>(input) )
|
||||
with expansion:
|
||||
2 == 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
abort
|
||||
wait-for-keypress
|
||||
Accepted options
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.waitForKeypress == std::get<1>(input) )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
abort
|
||||
wait-for-keypress
|
||||
invalid options are reported
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( !result )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( result.errorMessage(), Contains("never") && Contains("both") )
|
||||
with expansion:
|
||||
"keypress argument must be one of: never, start, exit or both. 'sometimes'
|
||||
not recognised" ( contains: "never" and contains: "both" )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
nothrow
|
||||
@ -8055,7 +8398,7 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
Benchmark options
|
||||
resamples
|
||||
confidence-interval
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
@ -8073,7 +8416,7 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
Benchmark options
|
||||
resamples
|
||||
no-analysis
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
@ -8088,6 +8431,24 @@ CmdLine.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
Benchmark options
|
||||
warmup-time
|
||||
-------------------------------------------------------------------------------
|
||||
CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
CHECK( cli.parse({ "test", "--benchmark-warmup-time=10" }) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.benchmarkWarmupTime == 10 )
|
||||
with expansion:
|
||||
10 == 10
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Product with differing arities - std::tuple<int, double, float>
|
||||
-------------------------------------------------------------------------------
|
||||
@ -14053,6 +14414,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 320 | 230 passed | 86 failed | 4 failed as expected
|
||||
assertions: 1809 | 1640 passed | 148 failed | 21 failed as expected
|
||||
test cases: 329 | 239 passed | 86 failed | 4 failed as expected
|
||||
assertions: 1858 | 1689 passed | 148 failed | 21 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="17" failures="132" tests="1810" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="17" failures="132" tests="1859" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<properties>
|
||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
|
||||
<property name="random-seed" value="1"/>
|
||||
@ -350,6 +350,13 @@ Exception.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Character pretty printing/General chars" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Character pretty printing/Low ASCII" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchAllOfGeneric does not nest" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchAnyOfGeneric does not nest" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining MatchNotOfGeneric does not nest" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining concrete matchers does not use templated matchers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining only templated matchers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining templated and concrete matchers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Combining templated matchers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Commas in various macros are allowed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Comparing function pointers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Comparison ops" time="{duration}"/>
|
||||
@ -357,6 +364,7 @@ Exception.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Comparisons between ints where one side is computed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Comparisons with int literals don't warn when mixing signed/ unsigned" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Composed matchers are distinct" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Contains string matcher" time="{duration}">
|
||||
<failure message="testStringForMatching(), Contains("not there", Catch::CaseSensitive::No)" type="CHECK_THAT">
|
||||
FAILED:
|
||||
@ -950,6 +958,7 @@ Message from section two
|
||||
Message.tests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Overloaded comma or address-of operators are not used" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/Empty test spec should have no filters" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/Test spec from empty string should have no filters" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/Test spec from just a comma should have no filters" time="{duration}"/>
|
||||
@ -1004,6 +1013,8 @@ Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/-a aborts after first failure" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/-x 2 aborts after two failures" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/-x must be numeric" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/wait-for-keypress/Accepted options" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/wait-for-keypress/invalid options are reported" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/nothrow/-e" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/nothrow/--nothrow" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/output filename/-o filename" time="{duration}"/>
|
||||
@ -1016,8 +1027,9 @@ Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/use-colour/error" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/samples" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/resamples" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/confidence-interval" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/no-analysis" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Process can be configured on command line/Benchmark options/warmup-time" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple<int, double, float>" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple<int, double>" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple<int>" time="{duration}"/>
|
||||
|
@ -52,6 +52,8 @@
|
||||
<testCase name="Process can be configured on command line/abort/-a aborts after first failure" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/abort/-x 2 aborts after two failures" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/abort/-x must be numeric" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/abort/wait-for-keypress/Accepted options" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/abort/wait-for-keypress/invalid options are reported" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/nothrow/-e" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/nothrow/--nothrow" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/output filename/-o filename" duration="{duration}"/>
|
||||
@ -64,8 +66,9 @@
|
||||
<testCase name="Process can be configured on command line/use-colour/error" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/samples" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/resamples" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/confidence-interval" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/no-analysis" duration="{duration}"/>
|
||||
<testCase name="Process can be configured on command line/Benchmark options/warmup-time" duration="{duration}"/>
|
||||
<testCase name="Test with special, characters "in name" duration="{duration}"/>
|
||||
</file>
|
||||
<file path="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp">
|
||||
@ -915,6 +918,14 @@ Exception.tests.cpp:<line number>
|
||||
<file path="tests/<exe-name>/UsageTests/Matchers.tests.cpp">
|
||||
<testCase name="Arbitrary predicate matcher/Function pointer" duration="{duration}"/>
|
||||
<testCase name="Arbitrary predicate matcher/Lambdas + different type" duration="{duration}"/>
|
||||
<testCase name="Combining MatchAllOfGeneric does not nest" duration="{duration}"/>
|
||||
<testCase name="Combining MatchAnyOfGeneric does not nest" duration="{duration}"/>
|
||||
<testCase name="Combining MatchNotOfGeneric does not nest" duration="{duration}"/>
|
||||
<testCase name="Combining concrete matchers does not use templated matchers" duration="{duration}"/>
|
||||
<testCase name="Combining only templated matchers" duration="{duration}"/>
|
||||
<testCase name="Combining templated and concrete matchers" duration="{duration}"/>
|
||||
<testCase name="Combining templated matchers" duration="{duration}"/>
|
||||
<testCase name="Composed matchers are distinct" duration="{duration}"/>
|
||||
<testCase name="Contains string matcher" duration="{duration}">
|
||||
<failure message="CHECK_THAT(testStringForMatching(), Contains("not there", Catch::CaseSensitive::No))">
|
||||
FAILED:
|
||||
@ -1042,6 +1053,7 @@ with expansion:
|
||||
Matchers.tests.cpp:<line number>
|
||||
</failure>
|
||||
</testCase>
|
||||
<testCase name="Overloaded comma or address-of operators are not used" duration="{duration}"/>
|
||||
<testCase name="Predicate matcher can accept const char*" duration="{duration}"/>
|
||||
<testCase name="Regex string matcher" duration="{duration}">
|
||||
<failure message="CHECK_THAT(testStringForMatching(), Matches("this STRING contains 'abc' as a substring"))">
|
||||
|
@ -524,6 +524,68 @@ ok {test-number} - c == i for: 3 == 3
|
||||
ok {test-number} - c == i for: 4 == 4
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 5 == 5
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC> >::value'
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
ok {test-number} - 1, MatcherA() && MatcherB() && MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 )
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
# Combining MatchAllOfGeneric does not nest
|
||||
ok {test-number} - 1, MatcherA() && MatcherB() && MatcherC() && MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 and equals: true )
|
||||
# Combining MatchAnyOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC> >::value'
|
||||
# Combining MatchAnyOfGeneric does not nest
|
||||
ok {test-number} - 1, MatcherA() || MatcherB() || MatcherC() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 )
|
||||
# Combining MatchAnyOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD> >::value'
|
||||
# Combining MatchAnyOfGeneric does not nest
|
||||
ok {test-number} - 1, MatcherA() || MatcherB() || MatcherC() || MatcherD() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 or equals: true )
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - 0, !MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(!!MatcherA()), MatcherA const& >::value'
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - 1, !!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA> >::value'
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - 0, !!!MatcherA() for: 0 not equals: (int) 1 or (float) 1.0f
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(!!!!MatcherA()), MatcherA const & >::value'
|
||||
# Combining MatchNotOfGeneric does not nest
|
||||
ok {test-number} - 1, !!!!MatcherA() for: 1 equals: (int) 1 or (float) 1.0f
|
||||
# Combining concrete matchers does not use templated matchers
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))), Catch::Matchers::Impl::MatchAnyOf<std::string> >::value'
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB> >::value'
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - 1, MatcherA() || MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 )
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB> >::value'
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - 1, MatcherA() && MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 )
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric<MatcherB>> >::value'
|
||||
# Combining only templated matchers
|
||||
ok {test-number} - 1, MatcherA() || !MatcherB() for: 1 ( equals: (int) 1 or (float) 1.0f or not equals: (long long) 1 )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - vec, Predicate<std::vector<int>>([](auto const& vec) { return std::all_of(vec.begin(), vec.end(), [](int elem) { return elem % 2 == 1; }); }, "All elements are odd") && !EqualsRange(a) for: { 1, 3, 5 } ( matches predicate: "All elements are odd" and not Equals: { 5, 3, 1 } )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar") for: "foobar" ( starts with: "foo" and not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar") for: "foobar" ( not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar")) for: "foobar" ( Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } or ( starts with: "foo" and ends with: "bar" ) )
|
||||
# Combining templated and concrete matchers
|
||||
ok {test-number} - str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr) for: "foobar" ( ( starts with: "foo" and ends with: "bar" ) or Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } )
|
||||
# Combining templated matchers
|
||||
ok {test-number} - container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c) for: { 1, 2, 3 } ( Equals: { 1, 2, 3 } or Equals: { 0, 1, 2 } or Equals: { 4, 5, 6 } )
|
||||
# Commas in various macros are allowed
|
||||
ok {test-number} - std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
|
||||
# Commas in various macros are allowed
|
||||
@ -624,6 +686,10 @@ ok {test-number} - 5 == c for: 5 == 5
|
||||
ok {test-number} - 6 == uc for: 6 == 6
|
||||
# Comparisons with int literals don't warn when mixing signed/ unsigned
|
||||
ok {test-number} - (std::numeric_limits<uint32_t>::max)() > ul for: 4294967295 (0x<hex digits>) > 4
|
||||
# Composed matchers are distinct
|
||||
ok {test-number} - testStringForMatching2(), !composed1 for: "some completely different text that contains one common word" not ( contains: "string" or contains: "random" )
|
||||
# Composed matchers are distinct
|
||||
ok {test-number} - testStringForMatching2(), composed2 for: "some completely different text that contains one common word" ( contains: "string" or contains: "random" or contains: "different" )
|
||||
# Contains string matcher
|
||||
not ok {test-number} - testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive)
|
||||
# Contains string matcher
|
||||
@ -1688,6 +1754,14 @@ ok {test-number} - rng() == 0x<hex digits> for: 4261393167 (0x<hex digits>) == 4
|
||||
not ok {test-number} - explicitly with 1 message: 'Message from section one'
|
||||
# Output from all sections is reported
|
||||
not ok {test-number} - explicitly with 1 message: 'Message from section two'
|
||||
# Overloaded comma or address-of operators are not used
|
||||
ok {test-number} - (EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed
|
||||
# Overloaded comma or address-of operators are not used
|
||||
ok {test-number} - &EvilMatcher(), EvilAddressOfOperatorUsed
|
||||
# Overloaded comma or address-of operators are not used
|
||||
ok {test-number} - EvilMatcher() || EvilMatcher() && !EvilMatcher()
|
||||
# Overloaded comma or address-of operators are not used
|
||||
ok {test-number} - (EvilMatcher() && EvilMatcher()) || !EvilMatcher()
|
||||
# Parse test names and tags
|
||||
ok {test-number} - spec.hasFilters() == false for: false == false
|
||||
# Parse test names and tags
|
||||
@ -2097,6 +2171,26 @@ ok {test-number} - !result for: true
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - result.errorMessage(), Contains("convert") && Contains("oops") for: "Unable to convert 'oops' to destination type" ( contains: "convert" and contains: "oops" )
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.waitForKeypress == std::get<1>(input) for: 0 == 0
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.waitForKeypress == std::get<1>(input) for: 1 == 1
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.waitForKeypress == std::get<1>(input) for: 2 == 2
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.waitForKeypress == std::get<1>(input) for: 3 == 3
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - !result for: true
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - result.errorMessage(), Contains("never") && Contains("both") for: "keypress argument must be one of: never, start, exit or both. 'sometimes' not recognised" ( contains: "never" and contains: "both" )
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({"test", "-e"}) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.noThrow for: true
|
||||
@ -2156,6 +2250,10 @@ ok {test-number} - config.benchmarkConfidenceInterval == Catch::Approx(0.99) for
|
||||
ok {test-number} - cli.parse({ "test", "--benchmark-no-analysis" }) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.benchmarkNoAnalysis for: true
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - cli.parse({ "test", "--benchmark-warmup-time=10" }) for: {?}
|
||||
# Process can be configured on command line
|
||||
ok {test-number} - config.benchmarkWarmupTime == 10 for: 10 == 10
|
||||
# Product with differing arities - std::tuple<int, double, float>
|
||||
ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 3 >= 1
|
||||
# Product with differing arities - std::tuple<int, double>
|
||||
@ -3610,5 +3708,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..1801
|
||||
1..1850
|
||||
|
||||
|
@ -203,6 +203,20 @@ Exception.tests.cpp:<line number>|nunexpected exception with message:|n "unexpe
|
||||
##teamcity[testFinished name='Capture and info messages' duration="{duration}"]
|
||||
##teamcity[testStarted name='Character pretty printing']
|
||||
##teamcity[testFinished name='Character pretty printing' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining MatchAllOfGeneric does not nest']
|
||||
##teamcity[testFinished name='Combining MatchAllOfGeneric does not nest' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining MatchAnyOfGeneric does not nest']
|
||||
##teamcity[testFinished name='Combining MatchAnyOfGeneric does not nest' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining MatchNotOfGeneric does not nest']
|
||||
##teamcity[testFinished name='Combining MatchNotOfGeneric does not nest' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining concrete matchers does not use templated matchers']
|
||||
##teamcity[testFinished name='Combining concrete matchers does not use templated matchers' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining only templated matchers']
|
||||
##teamcity[testFinished name='Combining only templated matchers' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining templated and concrete matchers']
|
||||
##teamcity[testFinished name='Combining templated and concrete matchers' duration="{duration}"]
|
||||
##teamcity[testStarted name='Combining templated matchers']
|
||||
##teamcity[testFinished name='Combining templated matchers' duration="{duration}"]
|
||||
##teamcity[testStarted name='Commas in various macros are allowed']
|
||||
##teamcity[testFinished name='Commas in various macros are allowed' duration="{duration}"]
|
||||
##teamcity[testStarted name='Comparing function pointers']
|
||||
@ -217,6 +231,8 @@ Exception.tests.cpp:<line number>|nunexpected exception with message:|n "unexpe
|
||||
##teamcity[testFinished name='Comparisons between unsigned ints and negative signed ints match c++ standard behaviour' duration="{duration}"]
|
||||
##teamcity[testStarted name='Comparisons with int literals don|'t warn when mixing signed/ unsigned']
|
||||
##teamcity[testFinished name='Comparisons with int literals don|'t warn when mixing signed/ unsigned' duration="{duration}"]
|
||||
##teamcity[testStarted name='Composed matchers are distinct']
|
||||
##teamcity[testFinished name='Composed matchers are distinct' duration="{duration}"]
|
||||
##teamcity[testStarted name='Contains string matcher']
|
||||
Matchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )|nwith expansion:|n "this string contains |'abc|' as a substring" contains: "not there" (case insensitive)|n']
|
||||
Matchers.tests.cpp:<line number>|nexpression failed|n CHECK_THAT( testStringForMatching(), Contains("STRING") )|nwith expansion:|n "this string contains |'abc|' as a substring" contains: "STRING"|n']
|
||||
@ -395,6 +411,8 @@ Condition.tests.cpp:<line number>|nexpression failed|n CHECK( data.str_hello <=
|
||||
Message.tests.cpp:<line number>|nexplicit failure with message:|n "Message from section one"']
|
||||
Message.tests.cpp:<line number>|nexplicit failure with message:|n "Message from section two"']
|
||||
##teamcity[testFinished name='Output from all sections is reported' duration="{duration}"]
|
||||
##teamcity[testStarted name='Overloaded comma or address-of operators are not used']
|
||||
##teamcity[testFinished name='Overloaded comma or address-of operators are not used' duration="{duration}"]
|
||||
##teamcity[testStarted name='Parse test names and tags']
|
||||
##teamcity[testFinished name='Parse test names and tags' duration="{duration}"]
|
||||
##teamcity[testStarted name='Pointers can be compared to null']
|
||||
|
@ -2417,6 +2417,179 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining MatchAllOfGeneric does not nest" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() && MatcherB() && MatcherC()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() && MatcherB() && MatcherC() && MatcherD()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 and equals: (T) 1 and equals: true )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining MatchAnyOfGeneric does not nest" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() || MatcherB() || MatcherC()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() || MatcherB() || MatcherC() || MatcherD()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 or equals: (T) 1 or equals: true )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining MatchNotOfGeneric does not nest" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
0, !MatcherA()
|
||||
</Original>
|
||||
<Expanded>
|
||||
0 not equals: (int) 1 or (float) 1.0f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, !!MatcherA()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 equals: (int) 1 or (float) 1.0f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
0, !!!MatcherA()
|
||||
</Original>
|
||||
<Expanded>
|
||||
0 not equals: (int) 1 or (float) 1.0f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, !!!!MatcherA()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 equals: (int) 1 or (float) 1.0f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining concrete matchers does not use templated matchers" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining only templated matchers" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() || MatcherB()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f or equals: (long long) 1 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() && MatcherB()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f and equals: (long long) 1 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
1, MatcherA() || !MatcherB()
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ( equals: (int) 1 or (float) 1.0f or not equals: (long long) 1 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining templated and concrete matchers" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
vec, Predicate<std::vector<int>>([](auto const& vec) { return std::all_of(vec.begin(), vec.end(), [](int elem) { return elem % 2 == 1; }); }, "All elements are odd") && !EqualsRange(a)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1, 3, 5 } ( matches predicate: "All elements are odd" and not Equals: { 5, 3, 1 } )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( starts with: "foo" and Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( starts with: "foo" and not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and ends with: "bar" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( Equals: { 'f', 'o', 'o', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( not Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } and starts with: "foo" and ends with: "bar" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar"))
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } or ( starts with: "foo" and ends with: "bar" ) )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr)
|
||||
</Original>
|
||||
<Expanded>
|
||||
"foobar" ( ( starts with: "foo" and ends with: "bar" ) or Equals: { 'o', 'o', 'f', 'b', 'a', 'r' } )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Combining templated matchers" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1, 2, 3 } ( Equals: { 1, 2, 3 } or Equals: { 0, 1, 2 } or Equals: { 4, 5, 6 } )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Commas in various macros are allowed" filename="tests/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||
<Original>
|
||||
@ -2838,6 +3011,25 @@ Nor would this
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Composed matchers are distinct" tags="[composed][matchers]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching2(), !composed1
|
||||
</Original>
|
||||
<Expanded>
|
||||
"some completely different text that contains one common word" not ( contains: "string" or contains: "random" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching2(), composed2
|
||||
</Original>
|
||||
<Expanded>
|
||||
"some completely different text that contains one common word" ( contains: "string" or contains: "random" or contains: "different" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Contains string matcher" tags="[.][failing][matchers]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="false" type="CHECK_THAT" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
@ -8025,6 +8217,41 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="Overloaded comma or address-of operators are not used" tags="[matchers][templated]" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THROWS_AS" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
(EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed
|
||||
</Original>
|
||||
<Expanded>
|
||||
(EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THROWS_AS" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
&EvilMatcher(), EvilAddressOfOperatorUsed
|
||||
</Original>
|
||||
<Expanded>
|
||||
&EvilMatcher(), EvilAddressOfOperatorUsed
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_NOTHROW" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
EvilMatcher() || EvilMatcher() && !EvilMatcher()
|
||||
</Original>
|
||||
<Expanded>
|
||||
EvilMatcher() || EvilMatcher() && !EvilMatcher()
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_NOTHROW" filename="tests/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
(EvilMatcher() && EvilMatcher()) || !EvilMatcher()
|
||||
</Original>
|
||||
<Expanded>
|
||||
(EvilMatcher() && EvilMatcher()) || !EvilMatcher()
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Parse test names and tags" tags="[command-line][test-spec]" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="Empty test spec should have no filters" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
@ -9865,6 +10092,131 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="abort" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="wait-for-keypress" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="Accepted options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({"test", "--wait-for-keypress", std::get<0>(input)})
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.waitForKeypress == std::get<1>(input)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0 == 0
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="abort" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="wait-for-keypress" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="Accepted options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({"test", "--wait-for-keypress", std::get<0>(input)})
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.waitForKeypress == std::get<1>(input)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 == 1
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="abort" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="wait-for-keypress" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="Accepted options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({"test", "--wait-for-keypress", std::get<0>(input)})
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.waitForKeypress == std::get<1>(input)
|
||||
</Original>
|
||||
<Expanded>
|
||||
2 == 2
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="abort" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="wait-for-keypress" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="Accepted options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({"test", "--wait-for-keypress", std::get<0>(input)})
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.waitForKeypress == std::get<1>(input)
|
||||
</Original>
|
||||
<Expanded>
|
||||
3 == 3
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="abort" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="wait-for-keypress" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="invalid options are reported" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
!result
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
result.errorMessage(), Contains("never") && Contains("both")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"keypress argument must be one of: never, start, exit or both. 'sometimes' not recognised" ( contains: "never" and contains: "both" )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="nothrow" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="-e" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
@ -10146,7 +10498,7 @@ Nor would this
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Benchmark options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="resamples" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="confidence-interval" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({ "test", "--benchmark-confidence-interval=0.99" })
|
||||
@ -10168,7 +10520,7 @@ Nor would this
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Benchmark options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="resamples" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="no-analysis" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({ "test", "--benchmark-no-analysis" })
|
||||
@ -10189,6 +10541,28 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Benchmark options" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Section name="warmup-time" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse({ "test", "--benchmark-warmup-time=10" })
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.benchmarkWarmupTime == 10
|
||||
</Original>
|
||||
<Expanded>
|
||||
10 == 10
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Product with differing arities - std::tuple<int, double, float>" tags="[product][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
@ -16909,7 +17283,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="1640" failures="149" expectedFailures="21"/>
|
||||
<OverallResults successes="1689" failures="149" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="1640" failures="148" expectedFailures="21"/>
|
||||
<OverallResults successes="1689" failures="148" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <catch2/catch_test_case_info.h>
|
||||
#include <catch2/catch_config.hpp>
|
||||
#include <catch2/catch_commandline.h>
|
||||
#include <catch2/catch_generators.hpp>
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||
@ -410,7 +411,31 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
||||
CHECK(!result);
|
||||
REQUIRE_THAT(result.errorMessage(), Contains("convert") && Contains("oops"));
|
||||
}
|
||||
|
||||
SECTION("wait-for-keypress") {
|
||||
SECTION("Accepted options") {
|
||||
using tuple_type = std::tuple<char const*, Catch::WaitForKeypress::When>;
|
||||
auto input = GENERATE(table<char const*, Catch::WaitForKeypress::When>({
|
||||
tuple_type{"never", Catch::WaitForKeypress::Never},
|
||||
tuple_type{"start", Catch::WaitForKeypress::BeforeStart},
|
||||
tuple_type{"exit", Catch::WaitForKeypress::BeforeExit},
|
||||
tuple_type{"both", Catch::WaitForKeypress::BeforeStartAndExit},
|
||||
}));
|
||||
CHECK(cli.parse({"test", "--wait-for-keypress", std::get<0>(input)}));
|
||||
|
||||
REQUIRE(config.waitForKeypress == std::get<1>(input));
|
||||
}
|
||||
|
||||
SECTION("invalid options are reported") {
|
||||
auto result = cli.parse({"test", "--wait-for-keypress", "sometimes"});
|
||||
CHECK(!result);
|
||||
|
||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
|
||||
REQUIRE_THAT(result.errorMessage(), Contains("never") && Contains("both"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("nothrow") {
|
||||
SECTION("-e") {
|
||||
@ -497,17 +522,23 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
||||
REQUIRE(config.benchmarkResamples == 20000);
|
||||
}
|
||||
|
||||
SECTION("resamples") {
|
||||
SECTION("confidence-interval") {
|
||||
CHECK(cli.parse({ "test", "--benchmark-confidence-interval=0.99" }));
|
||||
|
||||
REQUIRE(config.benchmarkConfidenceInterval == Catch::Approx(0.99));
|
||||
}
|
||||
|
||||
SECTION("resamples") {
|
||||
SECTION("no-analysis") {
|
||||
CHECK(cli.parse({ "test", "--benchmark-no-analysis" }));
|
||||
|
||||
REQUIRE(config.benchmarkNoAnalysis);
|
||||
}
|
||||
|
||||
SECTION("warmup-time") {
|
||||
CHECK(cli.parse({ "test", "--benchmark-warmup-time=10" }));
|
||||
|
||||
REQUIRE(config.benchmarkWarmupTime == 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,12 @@
|
||||
#include <catch2/catch_matchers_generic.hpp>
|
||||
#include <catch2/catch_matchers_string.h>
|
||||
#include <catch2/catch_matchers_vector.h>
|
||||
#include <catch2/catch_matchers_templates.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
@ -554,6 +556,312 @@ namespace { namespace MatchersTests {
|
||||
REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, Message("SpecialException::what"));
|
||||
}
|
||||
|
||||
TEST_CASE("Composed matchers are distinct", "[matchers][composed]") {
|
||||
auto m1 = Contains("string");
|
||||
auto m2 = Contains("random");
|
||||
auto composed1 = m1 || m2;
|
||||
auto m3 = Contains("different");
|
||||
auto composed2 = composed1 || m3;
|
||||
REQUIRE_THAT(testStringForMatching2(), !composed1);
|
||||
REQUIRE_THAT(testStringForMatching2(), composed2);
|
||||
}
|
||||
|
||||
|
||||
template<typename Range>
|
||||
struct EqualsRangeMatcher : Catch::MatcherGenericBase {
|
||||
|
||||
EqualsRangeMatcher(Range const& range) : range{ range } {}
|
||||
|
||||
template<typename OtherRange>
|
||||
bool match(OtherRange const& other) const {
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
return std::equal(begin(range), end(range), begin(other), end(other));
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return "Equals: " + Catch::rangeToString(range);
|
||||
}
|
||||
|
||||
private:
|
||||
Range const& range;
|
||||
};
|
||||
|
||||
template<typename Range>
|
||||
auto EqualsRange(const Range& range) -> EqualsRangeMatcher<Range> {
|
||||
return EqualsRangeMatcher<Range>{range};
|
||||
}
|
||||
|
||||
TEST_CASE("Combining templated matchers", "[matchers][templated]") {
|
||||
std::array<int, 3> container{{ 1,2,3 }};
|
||||
|
||||
std::array<int, 3> a{{ 1,2,3 }};
|
||||
std::vector<int> b{ 0,1,2 };
|
||||
std::list<int> c{ 4,5,6 };
|
||||
|
||||
REQUIRE_THAT(container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c));
|
||||
}
|
||||
|
||||
TEST_CASE("Combining templated and concrete matchers", "[matchers][templated]") {
|
||||
using namespace Catch::Matchers;
|
||||
std::vector<int> vec{ 1, 3, 5 };
|
||||
|
||||
std::array<int, 3> a{{ 5, 3, 1 }};
|
||||
|
||||
REQUIRE_THAT(vec,
|
||||
Predicate<std::vector<int>>([](auto const& vec) {
|
||||
return std::all_of(vec.begin(), vec.end(), [](int elem) {
|
||||
return elem % 2 == 1;
|
||||
});
|
||||
}, "All elements are odd") &&
|
||||
!EqualsRange(a));
|
||||
|
||||
const std::string str = "foobar";
|
||||
const std::array<char, 6> arr{{ 'f', 'o', 'o', 'b', 'a', 'r' }};
|
||||
const std::array<char, 6> bad_arr{{ 'o', 'o', 'f', 'b', 'a', 'r' }};
|
||||
|
||||
using Catch::Matchers::StartsWith;
|
||||
using Catch::Matchers::EndsWith;
|
||||
|
||||
REQUIRE_THAT(str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar"));
|
||||
REQUIRE_THAT(str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar"));
|
||||
|
||||
REQUIRE_THAT(str, EqualsRange(arr) && StartsWith("foo") && EndsWith("bar"));
|
||||
REQUIRE_THAT(str, !EqualsRange(bad_arr) && StartsWith("foo") && EndsWith("bar"));
|
||||
|
||||
REQUIRE_THAT(str, EqualsRange(bad_arr) || (StartsWith("foo") && EndsWith("bar")));
|
||||
REQUIRE_THAT(str, (StartsWith("foo") && EndsWith("bar")) || EqualsRange(bad_arr));
|
||||
}
|
||||
|
||||
TEST_CASE("Combining concrete matchers does not use templated matchers", "[matchers][templated]") {
|
||||
using Catch::Matchers::StartsWith;
|
||||
using Catch::Matchers::EndsWith;
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))),
|
||||
Catch::Matchers::Impl::MatchAnyOf<std::string>
|
||||
>::value);
|
||||
}
|
||||
|
||||
struct MatcherA : Catch::MatcherGenericBase {
|
||||
std::string describe() const override { return "equals: (int) 1 or (float) 1.0f"; }
|
||||
bool match(int i) const { return i == 1; }
|
||||
bool match(float f) const { return f == 1.0f; }
|
||||
};
|
||||
|
||||
struct MatcherB : Catch::MatcherGenericBase {
|
||||
std::string describe() const override { return "equals: (long long) 1"; }
|
||||
bool match(long long l) const { return l == 1ll; }
|
||||
};
|
||||
|
||||
struct MatcherC : Catch::MatcherGenericBase {
|
||||
std::string describe() const override { return "equals: (T) 1"; }
|
||||
template<typename T>
|
||||
bool match(T t) const { return t == T{1}; }
|
||||
};
|
||||
|
||||
struct MatcherD : Catch::MatcherGenericBase {
|
||||
std::string describe() const override { return "equals: true"; }
|
||||
bool match(bool b) const { return b == true; }
|
||||
};
|
||||
|
||||
TEST_CASE("Combining only templated matchers", "[matchers][templated]") {
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() || MatcherB()),
|
||||
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() || MatcherB());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() && MatcherB()),
|
||||
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() && MatcherB());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() || !MatcherB()),
|
||||
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric<MatcherB>>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() || !MatcherB());
|
||||
}
|
||||
|
||||
TEST_CASE("Combining MatchAnyOfGeneric does not nest", "[matchers][templated]") {
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() || MatcherB() || MatcherC()),
|
||||
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() || MatcherB() || MatcherC());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()),
|
||||
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() || MatcherB() || MatcherC() || MatcherD());
|
||||
}
|
||||
|
||||
TEST_CASE("Combining MatchAllOfGeneric does not nest", "[matchers][templated]") {
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() && MatcherB() && MatcherC()),
|
||||
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() && MatcherB() && MatcherC());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()),
|
||||
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, MatcherA() && MatcherB() && MatcherC() && MatcherD());
|
||||
}
|
||||
|
||||
TEST_CASE("Combining MatchNotOfGeneric does not nest", "[matchers][templated]") {
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(!MatcherA()),
|
||||
Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(0, !MatcherA());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(!!MatcherA()),
|
||||
MatcherA const&
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, !!MatcherA());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(!!!MatcherA()),
|
||||
Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA>
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(0, !!!MatcherA());
|
||||
|
||||
STATIC_REQUIRE(std::is_same<
|
||||
decltype(!!!!MatcherA()),
|
||||
MatcherA const &
|
||||
>::value);
|
||||
|
||||
REQUIRE_THAT(1, !!!!MatcherA());
|
||||
}
|
||||
|
||||
struct EvilAddressOfOperatorUsed : std::exception {
|
||||
EvilAddressOfOperatorUsed() {}
|
||||
const char* what() const noexcept override {
|
||||
return "overloaded address-of operator of matcher was used instead of std::addressof";
|
||||
}
|
||||
};
|
||||
|
||||
struct EvilCommaOperatorUsed : std::exception {
|
||||
EvilCommaOperatorUsed() {}
|
||||
const char* what() const noexcept override {
|
||||
return "overloaded comma operator of matcher was used";
|
||||
}
|
||||
};
|
||||
|
||||
struct EvilMatcher : Catch::MatcherGenericBase {
|
||||
std::string describe() const override {
|
||||
return "equals: 45";
|
||||
}
|
||||
|
||||
bool match(int i) const {
|
||||
return i == 45;
|
||||
}
|
||||
|
||||
EvilMatcher const* operator& () const {
|
||||
throw EvilAddressOfOperatorUsed();
|
||||
}
|
||||
|
||||
int operator,(EvilMatcher const&) const {
|
||||
throw EvilCommaOperatorUsed();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("Overloaded comma or address-of operators are not used", "[matchers][templated]") {
|
||||
REQUIRE_THROWS_AS((EvilMatcher(), EvilMatcher()), EvilCommaOperatorUsed);
|
||||
REQUIRE_THROWS_AS(&EvilMatcher(), EvilAddressOfOperatorUsed);
|
||||
REQUIRE_NOTHROW(EvilMatcher() || EvilMatcher() && !EvilMatcher());
|
||||
REQUIRE_NOTHROW((EvilMatcher() && EvilMatcher()) || !EvilMatcher());
|
||||
}
|
||||
|
||||
struct ImmovableMatcher : Catch::MatcherGenericBase {
|
||||
ImmovableMatcher() = default;
|
||||
ImmovableMatcher(ImmovableMatcher const&) = delete;
|
||||
ImmovableMatcher(ImmovableMatcher &&) = delete;
|
||||
ImmovableMatcher& operator=(ImmovableMatcher const&) = delete;
|
||||
ImmovableMatcher& operator=(ImmovableMatcher &&) = delete;
|
||||
|
||||
std::string describe() const override {
|
||||
return "always false";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool match(T&&) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct MatcherWasMovedOrCopied : std::exception {
|
||||
MatcherWasMovedOrCopied() {}
|
||||
const char* what() const noexcept override {
|
||||
return "attempted to copy or move a matcher";
|
||||
}
|
||||
};
|
||||
|
||||
struct ThrowOnCopyOrMoveMatcher : Catch::MatcherGenericBase {
|
||||
ThrowOnCopyOrMoveMatcher() = default;
|
||||
[[noreturn]]
|
||||
ThrowOnCopyOrMoveMatcher(ThrowOnCopyOrMoveMatcher const&) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
[[noreturn]]
|
||||
ThrowOnCopyOrMoveMatcher(ThrowOnCopyOrMoveMatcher &&) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
ThrowOnCopyOrMoveMatcher& operator=(ThrowOnCopyOrMoveMatcher const&) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
ThrowOnCopyOrMoveMatcher& operator=(ThrowOnCopyOrMoveMatcher &&) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
return "always false";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool match(T&&) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("Matchers are not moved or copied", "[matchers][templated][approvals]") {
|
||||
REQUIRE_NOTHROW((ThrowOnCopyOrMoveMatcher() && ThrowOnCopyOrMoveMatcher()) || !ThrowOnCopyOrMoveMatcher());
|
||||
}
|
||||
|
||||
TEST_CASE("Immovable matchers can be used", "[matchers][templated][approvals]") {
|
||||
REQUIRE_THAT(123, (ImmovableMatcher() && ImmovableMatcher()) || !ImmovableMatcher());
|
||||
}
|
||||
|
||||
struct ReferencingMatcher : Catch::MatcherGenericBase {
|
||||
std::string describe() const override {
|
||||
return "takes reference";
|
||||
}
|
||||
bool match(int& i) const {
|
||||
return i == 22;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("Matchers can take references", "[matchers][templated][approvals]") {
|
||||
REQUIRE_THAT(22, ReferencingMatcher{});
|
||||
}
|
||||
|
||||
} } // namespace MatchersTests
|
||||
|
||||
#ifdef __clang__
|
||||
|
@ -17,9 +17,9 @@ TEST_CASE( "vector<string> -> toString", "[toString][vector]" )
|
||||
{
|
||||
std::vector<std::string> vv;
|
||||
REQUIRE( ::Catch::Detail::stringify(vv) == "{ }" );
|
||||
vv.push_back( "hello" );
|
||||
vv.emplace_back( "hello" );
|
||||
REQUIRE( ::Catch::Detail::stringify(vv) == "{ \"hello\" }" );
|
||||
vv.push_back( "world" );
|
||||
vv.emplace_back( "world" );
|
||||
REQUIRE( ::Catch::Detail::stringify(vv) == "{ \"hello\", \"world\" }" );
|
||||
}
|
||||
|
||||
@ -83,4 +83,4 @@ TEST_CASE( "array<int, N> -> toString", "[toString][containers][array]" ) {
|
||||
REQUIRE( Catch::Detail::stringify( oneValue ) == "{ 42 }" );
|
||||
std::array<int, 2> twoValues = {{ 42, 250 }};
|
||||
REQUIRE( Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" );
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user