Remove the ill-conceived compilation perf tests using real tests

This commit is contained in:
Martin Hořeňovský 2021-06-20 16:25:57 +02:00
parent 849002aec0
commit bf61a418cb
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
19 changed files with 2228 additions and 2276 deletions

View File

@ -2903,9 +2903,9 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype((MatcherA() && MatcherB()) && (MatcherC() && MatcherD
())), Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB,
MatcherC, MatcherD> >::value
std::is_same< decltype( ( MatcherA() && MatcherB() ) && ( MatcherC() &&
MatcherD() ) ), Catch::Matchers::Detail:: MatchAllOfGeneric<MatcherA,
MatcherB, MatcherC, MatcherD>>:: value
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1, ( MatcherA() && MatcherB() ) && ( MatcherC() && MatcherD() ) )
@ -2943,9 +2943,9 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype((MatcherA() || MatcherB()) || (MatcherC() || MatcherD
())), Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB,
MatcherC, MatcherD> >::value
std::is_same< decltype( ( MatcherA() || MatcherB() ) || ( MatcherC() ||
MatcherD() ) ), Catch::Matchers::Detail:: MatchAnyOfGeneric<MatcherA,
MatcherB, MatcherC, MatcherD>>:: value
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1, ( MatcherA() || MatcherB() ) || ( MatcherC() || MatcherD() ) )
@ -3005,9 +3005,9 @@ 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::Detail::MatchAnyOf<std::
string> >::value
std::is_same<decltype( StartsWith( "foo" ) || ( StartsWith( "bar" ) &&
EndsWith( "bar" ) && !EndsWith( "foo" ) ) ), Catch::Matchers::Detail::
MatchAnyOf<std::string>>::value
-------------------------------------------------------------------------------
Combining only templated matchers
@ -3037,8 +3037,8 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::MatchNotOfGeneric
std::is_same< decltype( MatcherA() || !MatcherB() ), Catch::Matchers::Detail:
:MatchAnyOfGeneric< MatcherA, Catch::Matchers::Detail::MatchNotOfGeneric
<MatcherB>>>::value
Matchers.tests.cpp:<line number>: PASSED:

View File

@ -1,13 +0,0 @@
// Include set of usage tests multiple times - for compile-time performance testing
// (do not run)
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"
#include "All.tests.cpp"

View File

@ -1,13 +0,0 @@
// Include set of usage tests multiple times - for compile-time performance testing
// (do not run)
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"
#include "10.tests.cpp"

View File

@ -1,15 +0,0 @@
// include set of usage tests into one file for compiler performance test purposes
// This whole file can now be included multiple times in 10.tests.cpp, and *that*
// file included multiple times (in 100.tests.cpp)
// Note that the intention is only for these files to be compiled. They will
// fail at runtime due to the re-user of test case names
#include "../UsageTests/Approx.tests.cpp"
#include "../UsageTests/BDD.tests.cpp"
#include "../UsageTests/Class.tests.cpp"
#include "../UsageTests/Compilation.tests.cpp"
#include "../UsageTests/Condition.tests.cpp"
#include "../UsageTests/Exception.tests.cpp"
#include "../UsageTests/Matchers.tests.cpp"
#include "../UsageTests/Misc.tests.cpp"

View File

@ -13,12 +13,8 @@
using Catch::Approx;
namespace { namespace ApproxTests {
#ifndef APPROX_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define APPROX_TEST_HELPERS_INCLUDED
inline double divide( double a, double b ) {
namespace {
static double divide(double a, double b) {
return a / b;
}
@ -30,11 +26,10 @@ namespace { namespace ApproxTests {
explicit operator double() const { return d_; }
};
inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
static std::ostream& operator<<(std::ostream& os, StrongDoubleTypedef td) {
return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
}
#endif
} // end unnamed namespace
using namespace Catch::literals;
@ -214,5 +209,3 @@ TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
REQUIRE(Approx(11.0) >= td);
}
}} // namespace ApproxTests

View File

@ -5,32 +5,23 @@
#include <catch2/catch_test_macros.hpp>
namespace { namespace BDDTests {
#ifndef BDD_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define BDD_TEST_HELPERS_INCLUDED
inline bool itDoesThis() { return true; }
inline bool itDoesThat() { return true; }
namespace {
static bool itDoesThis() { return true; }
static bool itDoesThat() { return true; }
// a trivial fixture example to support SCENARIO_METHOD tests
struct Fixture {
Fixture()
: d_counter(0) {
}
Fixture(): d_counter( 0 ) {}
int counter() {
return d_counter++;
}
int counter() { return d_counter++; }
int d_counter;
};
}
#endif
SCENARIO("Do that thing with the thing", "[Tags]") {
GIVEN("This stuff exists") {
@ -41,14 +32,17 @@ namespace { namespace BDDTests {
// do this
THEN("it should do this") {
REQUIRE(itDoesThis());
AND_THEN("do that")REQUIRE(itDoesThat());
AND_THEN("do that") {
REQUIRE(itDoesThat());
}
}
}
}
}
}
SCENARIO("Vector resizing affects size and capacity", "[vector][bdd][size][capacity]") {
SCENARIO( "Vector resizing affects size and capacity",
"[vector][bdd][size][capacity]" ) {
GIVEN( "an empty vector" ) {
std::vector<int> v;
REQUIRE( v.size() == 0 );
@ -61,7 +55,8 @@ namespace { namespace BDDTests {
AND_WHEN( "it is made smaller again" ) {
v.resize( 5 );
THEN("the size goes down but the capacity stays the same") {
THEN(
"the size goes down but the capacity stays the same" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
@ -83,10 +78,13 @@ namespace { namespace BDDTests {
"[very long tags][lots][long][tags][verbose]"
"[one very long tag name that should cause line wrapping writing out using the list command]"
"[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]") {
GIVEN("A section name that is so long that it cannot fit in a single console width")WHEN(
"The test headers are printed as part of the normal running of the scenario")THEN(
"The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent")SUCCEED(
"boo!");
GIVEN("A section name that is so long that it cannot fit in a single console width") {
WHEN("The test headers are printed as part of the normal running of the scenario") {
THEN("The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent") {
SUCCEED("boo!");
}
}
}
}
SCENARIO_METHOD(Fixture,
@ -103,5 +101,3 @@ namespace { namespace BDDTests {
}
}
}
}} // namespace BDDtests

View File

@ -7,68 +7,47 @@
#include <catch2/catch_template_test_macros.hpp>
#include <array>
namespace{ namespace ClassTests {
namespace {
#ifndef CLASS_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define CLASS_TEST_HELPERS_INCLUDED
class TestClass
{
class TestClass {
std::string s;
public:
TestClass()
: s( "hello" )
{}
TestClass(): s( "hello" ) {}
void succeedingCase()
{
REQUIRE( s == "hello" );
}
void failingCase()
{
REQUIRE( s == "world" );
}
void succeedingCase() { REQUIRE( s == "hello" ); }
void failingCase() { REQUIRE( s == "world" ); }
};
struct Fixture
{
struct Fixture {
Fixture(): m_a( 1 ) {}
int m_a;
};
template< typename T >
struct Template_Fixture {
template <typename T> struct Template_Fixture {
Template_Fixture(): m_a( 1 ) {}
T m_a;
};
template<typename T>
struct Template_Fixture_2 {
template <typename T> struct Template_Fixture_2 {
Template_Fixture_2() {}
T m_a;
};
template< typename T>
struct Template_Foo {
template <typename T> struct Template_Foo {
size_t size() { return 0; }
};
template< typename T, size_t V>
struct Template_Foo_2 {
template <typename T, size_t V> struct Template_Foo_2 {
size_t size() { return V; }
};
template <int V>
struct Nttp_Fixture{
int value = V;
};
#endif
template <int V> struct Nttp_Fixture { int value = V; };
} // end unnamed namespace
METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" )
METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" )
@ -129,7 +108,3 @@ namespace Inner
REQUIRE(Template_Fixture_2<TestType>{}.m_a.size() < 2);
}
}
}} // namespace ClassTests

View File

@ -33,11 +33,6 @@ std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
#include <cstring>
namespace { namespace CompilationTests {
#ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define COMPILATION_TEST_HELPERS_INCLUDED
// Comparison operators can return non-booleans.
// This is unusual, but should be supported.
struct logic_t {
@ -51,16 +46,6 @@ namespace { namespace CompilationTests {
};
// This is a minimal example for an issue we have found in 1.7.0
struct foo {
int i;
};
template<typename T>
bool operator==(const T &val, foo f) {
return val == f.i;
}
void throws_int(bool b) {
if (b) {
throw 1;
@ -79,8 +64,7 @@ namespace { namespace CompilationTests {
return true;
}
struct A {
};
struct A {};
std::ostream &operator<<(std::ostream &o, const A &) { return o << 0; }
@ -109,10 +93,18 @@ namespace { namespace CompilationTests {
template <typename, typename>
struct Fixture_1245 {};
#endif
// This is a minimal example for an issue we have found in 1.7.0
struct dummy_809 {
int i;
};
template<typename T>
bool operator==(const T& val, dummy_809 f) {
return val == f.i;
}
TEST_CASE("#809") {
foo f;
dummy_809 f;
f.i = 42;
REQUIRE(42 == f);
}
@ -129,8 +121,6 @@ namespace { namespace CompilationTests {
// Test containing example where original stream insertable check breaks compilation
TEST_CASE("#872") {
A dummy;
CAPTURE(dummy);
@ -214,7 +204,8 @@ namespace { namespace CompilationTests {
#pragma warning(pop)
#endif
TEST_CASE("#1319: Sections can have description (even if it is not saved", "[compilation]") {
TEST_CASE( "#1319: Sections can have description (even if it is not saved",
"[compilation]" ) {
SECTION( "SectionName", "This is a long form section description" ) {
SUCCEED();
}
@ -224,8 +215,6 @@ namespace { namespace CompilationTests {
REQUIRE([]() { return true; }());
}
}} // namespace CompilationTests
namespace {
struct HasBitOperators {
int value;

View File

@ -20,10 +20,7 @@ using Catch::Approx;
#include <limits>
#include <cstdint>
namespace { namespace ConditionTests {
#ifndef CONDITION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define CONDITION_TEST_HELPERS_INCLUDED
namespace {
struct TestData {
int int_seven = 7;
@ -41,10 +38,10 @@ struct TestDef {
}
};
inline const char* returnsConstNull(){ return nullptr; }
inline char* returnsNull(){ return nullptr; }
static const char* returnsConstNull() { return nullptr; }
static char* returnsNull() { return nullptr; }
#endif
} // end unnamed namespace
// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
// This allows us to see all results, even if an earlier check fails
@ -330,5 +327,3 @@ TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
CHECK( !(1 == 1) );
CHECK_FALSE( 1 == 1 );
}
}} // namespace ConditionTests

View File

@ -20,10 +20,7 @@
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif
namespace { namespace ExceptionTests {
#ifndef EXCEPTION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define EXCEPTION_TEST_HELPERS_INCLUDED
namespace {
int thisThrows() {
throw std::domain_error("expected exception");
@ -37,8 +34,7 @@ int thisDoesntThrow() {
class CustomException {
public:
explicit CustomException(const std::string& msg)
: m_msg( msg )
{}
: m_msg(msg) {}
std::string getMessage() const {
return m_msg;
@ -51,8 +47,7 @@ private:
class CustomStdException : public std::exception {
public:
explicit CustomStdException(const std::string& msg)
: m_msg( msg )
{}
: m_msg(msg) {}
~CustomStdException() noexcept override {}
std::string getMessage() const {
@ -67,7 +62,7 @@ private:
throw CustomException("custom exception - not std");
}
#endif
}
TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" ) {
REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
@ -198,8 +193,6 @@ TEST_CASE( "#748 - captures with unexpected exceptions", "[.][failing][!throws][
}
}
}} // namespace ExceptionTests
#ifdef __clang__
#pragma clang diagnostic pop
#endif

View File

@ -12,6 +12,7 @@
#include <catch2/matchers/catch_matchers_templated.hpp>
#include <algorithm>
#include <exception>
#include <cmath>
#include <list>
#include <sstream>
@ -22,29 +23,24 @@
# pragma clang diagnostic ignored "-Wpadded"
#endif
namespace { namespace MatchersTests {
namespace {
#ifndef MATCHERS_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define MATCHERS_TEST_HELPERS_INCLUDED
inline const char *testStringForMatching() {
static const char* testStringForMatching() {
return "this string contains 'abc' as a substring";
}
inline const char *testStringForMatching2() {
static const char* testStringForMatching2() {
return "some completely different text that contains one common word";
}
inline bool alwaysTrue(int) { return true; }
inline bool alwaysFalse(int) { return false; }
static bool alwaysTrue( int ) { return true; }
static bool alwaysFalse( int ) { return false; }
#ifdef _MSC_VER
#pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
# pragma warning( disable : 4702 ) // Unreachable code -- MSVC 19 (VS 2015)
// sees right through the indirection
#endif
#include <exception>
struct SpecialException : std::exception {
SpecialException( int i_ ): i( i_ ) {}
@ -61,25 +57,22 @@ namespace { namespace MatchersTests {
}
};
void doesNotThrow() {}
static void doesNotThrow() {}
[[noreturn]]
void throwsSpecialException(int i) {
[[noreturn]] static void throwsSpecialException( int i ) {
throw SpecialException{ i };
}
[[noreturn]]
void throwsAsInt(int i) {
throw i;
}
[[noreturn]] static void throwsAsInt( int i ) { throw i; }
[[noreturn]]
void throwsDerivedException() {
[[noreturn]] static void throwsDerivedException() {
throw DerivedException{};
}
class ExceptionMatcher : public Catch::Matchers::MatcherBase<SpecialException> {
class ExceptionMatcher
: public Catch::Matchers::MatcherBase<SpecialException> {
int m_expected;
public:
ExceptionMatcher( int i ): m_expected( i ) {}
@ -94,121 +87,133 @@ namespace { namespace MatchersTests {
}
};
#endif
using namespace Catch::Matchers;
#ifdef __DJGPP__
float nextafter(float from, float to)
{
static float nextafter( float from, float to ) {
return ::nextafterf( from, to );
}
double nextafter(double from, double to)
{
static double nextafter( double from, double to ) {
return ::nextafter( from, to );
}
#else
using std::nextafter;
#endif
} // end unnamed namespace
TEST_CASE( "String matchers", "[matchers]" ) {
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
REQUIRE_THAT(testStringForMatching(), Contains("string", Catch::CaseSensitive::No));
REQUIRE_THAT( testStringForMatching(),
Contains( "string", Catch::CaseSensitive::No ) );
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
CHECK_THAT(testStringForMatching(), Contains("aBC", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
Contains( "aBC", Catch::CaseSensitive::No ) );
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
CHECK_THAT(testStringForMatching(), StartsWith("THIS", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
StartsWith( "THIS", Catch::CaseSensitive::No ) );
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
CHECK_THAT(testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
EndsWith( " SuBsTrInG", Catch::CaseSensitive::No ) );
}
TEST_CASE( "Contains string matcher", "[.][failing][matchers]" ) {
CHECK_THAT(testStringForMatching(), Contains("not there", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
Contains( "not there", Catch::CaseSensitive::No ) );
CHECK_THAT( testStringForMatching(), Contains( "STRING" ) );
}
TEST_CASE( "StartsWith string matcher", "[.][failing][matchers]" ) {
CHECK_THAT( testStringForMatching(), StartsWith( "This String" ) );
CHECK_THAT(testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
StartsWith( "string", Catch::CaseSensitive::No ) );
}
TEST_CASE( "EndsWith string matcher", "[.][failing][matchers]" ) {
CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ) );
CHECK_THAT(testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
EndsWith( "this", Catch::CaseSensitive::No ) );
}
TEST_CASE( "Equals string matcher", "[.][failing][matchers]" ) {
CHECK_THAT(testStringForMatching(), Equals("this string contains 'ABC' as a substring"));
CHECK_THAT(testStringForMatching(), Equals("something else", Catch::CaseSensitive::No));
CHECK_THAT( testStringForMatching(),
Equals( "this string contains 'ABC' as a substring" ) );
CHECK_THAT( testStringForMatching(),
Equals( "something else", Catch::CaseSensitive::No ) );
}
TEST_CASE( "Equals", "[matchers]" ) {
CHECK_THAT(testStringForMatching(), Equals("this string contains 'abc' as a substring"));
CHECK_THAT( testStringForMatching(),
Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No));
Equals( "this string contains 'abc' as a substring" ) );
CHECK_THAT( testStringForMatching(),
Equals( "this string contains 'ABC' as a substring",
Catch::CaseSensitive::No ) );
}
// <regex> does not work in libstdc++ 4.8, so we have to enable these tests only when they
// are expected to pass and cannot have them in baselines
TEST_CASE("Regex string matcher -- libstdc++-4.8 workaround", "[matchers][approvals]") {
// This is fiiiine
// Taken from an answer at
// https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
#if (!defined(__GNUC__)) || \
(__cplusplus >= 201103L && \
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
(defined(_GLIBCXX_RELEASE) && \
_GLIBCXX_RELEASE > 4))))
// DJGPP meets the above condition but <regex> does not work properly anyway
TEST_CASE( "Regex string matcher -- libstdc++-4.8 workaround",
"[matchers][approvals]" ) {
// DJGPP has similar problem with its regex support as libstdc++ 4.8
#ifndef __DJGPP__
REQUIRE_THAT(testStringForMatching(), Matches("this string contains 'abc' as a substring"));
REQUIRE_THAT( testStringForMatching(),
Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No));
REQUIRE_THAT(testStringForMatching(), Matches("^this string contains 'abc' as a substring$"));
Matches( "this string contains 'abc' as a substring" ) );
REQUIRE_THAT( testStringForMatching(),
Matches( "this string CONTAINS 'abc' as a substring",
Catch::CaseSensitive::No ) );
REQUIRE_THAT( testStringForMatching(),
Matches( "^this string contains 'abc' as a substring$" ) );
REQUIRE_THAT( testStringForMatching(), Matches( "^.* 'abc' .*$" ) );
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No));
REQUIRE_THAT( testStringForMatching(),
Matches( "^.* 'ABC' .*$", Catch::CaseSensitive::No ) );
#endif
#endif
REQUIRE_THAT(testStringForMatching2(), !Matches("this string contains 'abc' as a substring"));
REQUIRE_THAT( testStringForMatching2(),
!Matches( "this string contains 'abc' as a substring" ) );
}
TEST_CASE( "Regex string matcher", "[matchers][.failing]" ) {
CHECK_THAT(testStringForMatching(), Matches("this STRING contains 'abc' as a substring"));
CHECK_THAT(testStringForMatching(), Matches("contains 'abc' as a substring"));
CHECK_THAT(testStringForMatching(), Matches("this string contains 'abc' as a"));
}
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]") {
CHECK_THAT( testStringForMatching(),
Contains("string") &&
Contains("abc") &&
Contains("substring") &&
Contains("contains"));
Matches( "this STRING contains 'abc' as a substring" ) );
CHECK_THAT( testStringForMatching(),
Matches( "contains 'abc' as a substring" ) );
CHECK_THAT( testStringForMatching(),
Matches( "this string contains 'abc' as a" ) );
}
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") {
CHECK_THAT(testStringForMatching(), Contains("string") || Contains("different") || Contains("random"));
CHECK_THAT(testStringForMatching2(), Contains("string") || Contains("different") || Contains("random"));
TEST_CASE( "Matchers can be (AllOf) composed with the && operator",
"[matchers][operators][operator&&]" ) {
CHECK_THAT( testStringForMatching(),
Contains( "string" ) && Contains( "abc" ) &&
Contains( "substring" ) && Contains( "contains" ) );
}
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") {
CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("substring"));
TEST_CASE( "Matchers can be (AnyOf) composed with the || operator",
"[matchers][operators][operator||]" ) {
CHECK_THAT( testStringForMatching(),
Contains( "string" ) || Contains( "different" ) ||
Contains( "random" ) );
CHECK_THAT( testStringForMatching2(),
Contains( "string" ) || Contains( "different" ) ||
Contains( "random" ) );
}
TEST_CASE( "Matchers can be composed with both && and ||",
"[matchers][operators][operator||][operator&&]" ) {
CHECK_THAT( testStringForMatching(),
( Contains( "string" ) || Contains( "different" ) ) &&
Contains( "substring" ) );
}
TEST_CASE( "Matchers can be composed with both && and || - failing",
"[matchers][operators][operator||][operator&&][.failing]" ) {
CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random"));
CHECK_THAT( testStringForMatching(),
( Contains( "string" ) || Contains( "different" ) ) &&
Contains( "random" ) );
}
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") {
TEST_CASE( "Matchers can be negated (Not) with the ! operator",
"[matchers][operators][not]" ) {
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
}
@ -217,9 +222,7 @@ namespace { namespace MatchersTests {
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
}
template<typename T>
struct CustomAllocator : private std::allocator<T>
{
template <typename T> struct CustomAllocator : private std::allocator<T> {
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T*;
@ -228,20 +231,17 @@ namespace { namespace MatchersTests {
using const_reference = const T&;
using value_type = T;
template<typename U>
struct rebind
{ using other = CustomAllocator<U>; };
template <typename U> struct rebind { using other = CustomAllocator<U>; };
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
CustomAllocator() = default;
CustomAllocator(const CustomAllocator& other)
: std::allocator<T>(other) { }
CustomAllocator( const CustomAllocator& other ):
std::allocator<T>( other ) {}
template<typename U>
CustomAllocator(const CustomAllocator<U>&) { }
template <typename U> CustomAllocator( const CustomAllocator<U>& ) {}
~CustomAllocator() = default;
@ -288,7 +288,9 @@ namespace { namespace MatchersTests {
SECTION( "Contains (vector)" ) {
CHECK_THAT( v, Contains( v2 ) );
CHECK_THAT( v, Contains<int>( { 1, 2 } ) );
CHECK_THAT(v5, (Contains<int, std::allocator<int>, CustomAllocator<int>>(v2)));
CHECK_THAT( v5,
( Contains<int, std::allocator<int>, CustomAllocator<int>>(
v2 ) ) );
v2.push_back( 3 ); // now exactly matches
CHECK_THAT( v, Contains( v2 ) );
@ -296,7 +298,9 @@ namespace { namespace MatchersTests {
CHECK_THAT( v, Contains( empty ) );
CHECK_THAT( empty, Contains( empty ) );
CHECK_THAT(v5, (Contains<int, std::allocator<int>, CustomAllocator<int>>(v2)));
CHECK_THAT( v5,
( Contains<int, std::allocator<int>, CustomAllocator<int>>(
v2 ) ) );
CHECK_THAT( v5, Contains( v6 ) );
}
SECTION( "Contains (element), composed" ) {
@ -315,7 +319,9 @@ namespace { namespace MatchersTests {
v2.push_back( 3 );
CHECK_THAT( v, Equals( v2 ) );
CHECK_THAT(v5, (Equals<int, std::allocator<int>, CustomAllocator<int>>(v2)));
CHECK_THAT(
v5,
( Equals<int, std::allocator<int>, CustomAllocator<int>>( v2 ) ) );
v6.push_back( 3 );
CHECK_THAT( v5, Equals( v6 ) );
@ -332,7 +338,10 @@ namespace { namespace MatchersTests {
std::reverse( begin( permuted ), end( permuted ) );
REQUIRE_THAT( permuted, UnorderedEquals( v ) );
CHECK_THAT(v5, (UnorderedEquals<int, std::allocator<int>, CustomAllocator<int>>(permuted)));
CHECK_THAT(
v5,
( UnorderedEquals<int, std::allocator<int>, CustomAllocator<int>>(
permuted ) ) );
auto v5_permuted = v5;
std::next_permutation( begin( v5_permuted ), end( v5_permuted ) );
@ -393,23 +402,35 @@ namespace { namespace MatchersTests {
}
}
TEST_CASE("Exception matchers that succeed", "[matchers][exceptions][!throws]") {
CHECK_THROWS_MATCHES(throwsSpecialException(1), SpecialException, ExceptionMatcher{1});
REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, ExceptionMatcher{2});
TEST_CASE( "Exception matchers that succeed",
"[matchers][exceptions][!throws]" ) {
CHECK_THROWS_MATCHES(
throwsSpecialException( 1 ), SpecialException, ExceptionMatcher{ 1 } );
REQUIRE_THROWS_MATCHES(
throwsSpecialException( 2 ), SpecialException, ExceptionMatcher{ 2 } );
}
TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") {
TEST_CASE( "Exception matchers that fail",
"[matchers][exceptions][!throws][.failing]" ) {
SECTION( "No exception" ) {
CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
CHECK_THROWS_MATCHES(
doesNotThrow(), SpecialException, ExceptionMatcher{ 1 } );
REQUIRE_THROWS_MATCHES(
doesNotThrow(), SpecialException, ExceptionMatcher{ 1 } );
}
SECTION( "Type mismatch" ) {
CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
CHECK_THROWS_MATCHES(
throwsAsInt( 1 ), SpecialException, ExceptionMatcher{ 1 } );
REQUIRE_THROWS_MATCHES(
throwsAsInt( 1 ), SpecialException, ExceptionMatcher{ 1 } );
}
SECTION( "Contents are wrong" ) {
CHECK_THROWS_MATCHES(throwsSpecialException(3), SpecialException, ExceptionMatcher{1});
REQUIRE_THROWS_MATCHES(throwsSpecialException(4), SpecialException, ExceptionMatcher{1});
CHECK_THROWS_MATCHES( throwsSpecialException( 3 ),
SpecialException,
ExceptionMatcher{ 1 } );
REQUIRE_THROWS_MATCHES( throwsSpecialException( 4 ),
SpecialException,
ExceptionMatcher{ 1 } );
}
}
@ -456,14 +477,16 @@ namespace { namespace MatchersTests {
SECTION( "Composed" ) {
REQUIRE_THAT( 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) );
REQUIRE_THAT( 1.f, WithinAbs( 2.f, 0.5 ) || WithinULP( 1.f, 0 ) );
REQUIRE_THAT(0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f));
REQUIRE_THAT( 0.0001f,
WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) );
}
SECTION( "Constructor validation" ) {
REQUIRE_NOTHROW( WithinAbs( 1.f, 0.f ) );
REQUIRE_THROWS_AS( WithinAbs( 1.f, -1.f ), std::domain_error );
REQUIRE_NOTHROW( WithinULP( 1.f, 0 ) );
REQUIRE_THROWS_AS(WithinULP(1.f, static_cast<uint64_t>(-1)), std::domain_error);
REQUIRE_THROWS_AS( WithinULP( 1.f, static_cast<uint64_t>( -1 ) ),
std::domain_error );
REQUIRE_NOTHROW( WithinRel( 1.f, 0.f ) );
REQUIRE_THROWS_AS( WithinRel( 1.f, -0.2f ), std::domain_error );
@ -526,7 +549,8 @@ namespace { namespace MatchersTests {
}
}
TEST_CASE("Floating point matchers that are problematic in approvals", "[approvals][matchers][floating-point]") {
TEST_CASE( "Floating point matchers that are problematic in approvals",
"[approvals][matchers][floating-point]" ) {
REQUIRE_THAT( NAN, !WithinAbs( NAN, 0 ) );
REQUIRE_THAT( NAN, !( WithinAbs( NAN, 100 ) || WithinULP( NAN, 123 ) ) );
REQUIRE_THAT( NAN, !WithinULP( NAN, 123 ) );
@ -547,15 +571,16 @@ namespace { namespace MatchersTests {
SECTION( "Lambdas + different type" ) {
REQUIRE_THAT( "Hello olleH",
Predicate<std::string>(
[] (std::string const& str) -> bool { return str.front() == str.back(); },
"First and last character should be equal")
);
[]( std::string const& str ) -> bool {
return str.front() == str.back();
},
"First and last character should be equal" ) );
REQUIRE_THAT("This wouldn't pass",
!Predicate<std::string>(
[] (std::string const& str) -> bool { return str.front() == str.back(); }
)
);
REQUIRE_THAT(
"This wouldn't pass",
!Predicate<std::string>( []( std::string const& str ) -> bool {
return str.front() == str.back();
} ) );
}
}
@ -568,8 +593,11 @@ namespace { namespace MatchersTests {
CHECK_THAT( actual, !UnorderedEquals( expected ) );
}
TEST_CASE("Predicate matcher can accept const char*", "[matchers][compilation]") {
REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; }));
TEST_CASE( "Predicate matcher can accept const char*",
"[matchers][compilation]" ) {
REQUIRE_THAT( "foo", Predicate<const char*>( []( const char* const& ) {
return true;
} ) );
}
TEST_CASE( "Vector Approx matcher", "[matchers][approx][vector]" ) {
@ -599,7 +627,8 @@ namespace { namespace MatchersTests {
}
}
TEST_CASE("Vector Approx matcher -- failing", "[matchers][approx][vector][.failing]") {
TEST_CASE( "Vector Approx matcher -- failing",
"[matchers][approx][vector][.failing]" ) {
using Catch::Matchers::Approx;
SECTION( "Empty and non empty vectors are not approx equal" ) {
std::vector<double> empty, t1( { 1, 2 } );
@ -612,10 +641,18 @@ namespace { namespace MatchersTests {
}
TEST_CASE( "Exceptions matchers", "[matchers][exceptions][!throws]" ) {
REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, Message("DerivedException::what"));
REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, !Message("derivedexception::what"));
REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, !Message("DerivedException::what"));
REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, Message("SpecialException::what"));
REQUIRE_THROWS_MATCHES( throwsDerivedException(),
DerivedException,
Message( "DerivedException::what" ) );
REQUIRE_THROWS_MATCHES( throwsDerivedException(),
DerivedException,
!Message( "derivedexception::what" ) );
REQUIRE_THROWS_MATCHES( throwsSpecialException( 2 ),
SpecialException,
!Message( "DerivedException::what" ) );
REQUIRE_THROWS_MATCHES( throwsSpecialException( 2 ),
SpecialException,
Message( "SpecialException::what" ) );
}
struct CheckedTestingMatcher : Catch::Matchers::MatcherBase<int> {
@ -627,7 +664,9 @@ namespace { namespace MatchersTests {
return matchSucceeds;
}
std::string describe() const override {
return "CheckedTestingMatcher set to " + (matchSucceeds ? std::string("succeed") : std::string("fail"));
return "CheckedTestingMatcher set to " +
( matchSucceeds ? std::string( "succeed" )
: std::string( "fail" ) );
}
};
@ -668,11 +707,14 @@ namespace { namespace MatchersTests {
return matchSucceeds;
}
std::string describe() const override {
return "CheckedTestingGenericMatcher set to " + (matchSucceeds ? std::string("succeed") : std::string("fail"));
return "CheckedTestingGenericMatcher set to " +
( matchSucceeds ? std::string( "succeed" )
: std::string( "fail" ) );
}
};
TEST_CASE("Composed generic matchers shortcircuit", "[matchers][composed][generic]") {
TEST_CASE( "Composed generic matchers shortcircuit",
"[matchers][composed][generic]" ) {
// Check that if first returns false, second is not touched
CheckedTestingGenericMatcher first, second;
SECTION( "MatchAllOf" ) {
@ -703,18 +745,17 @@ namespace { namespace MatchersTests {
}
}
template <typename Range>
struct EqualsRangeMatcher : Catch::Matchers::MatcherGenericBase {
EqualsRangeMatcher( Range const& range ): m_range{ range } {}
template<typename OtherRange>
bool match(OtherRange const& other) const {
template <typename OtherRange> bool match( OtherRange const& other ) const {
using std::begin;
using std::end;
return std::equal(begin(m_range), end(m_range), begin(other), end(other));
return std::equal(
begin( m_range ), end( m_range ), begin( other ), end( other ) );
}
std::string describe() const override {
@ -737,51 +778,70 @@ namespace { namespace MatchersTests {
std::vector<int> b{ 0, 1, 2 };
std::list<int> c{ 4, 5, 6 };
REQUIRE_THAT(container, EqualsRange(a) || EqualsRange(b) || EqualsRange(c));
REQUIRE_THAT( container,
EqualsRange( a ) || EqualsRange( b ) || EqualsRange( c ) );
}
TEST_CASE("Combining templated and concrete matchers", "[matchers][templated]") {
TEST_CASE( "Combining templated and concrete matchers",
"[matchers][templated]" ) {
std::vector<int> vec{ 1, 3, 5 };
std::array<int, 3> a{ { 5, 3, 1 } };
REQUIRE_THAT( vec,
Predicate<std::vector<int>>([](auto const& v) {
return std::all_of(v.begin(), v.end(), [](int elem) {
Predicate<std::vector<int>>(
[]( auto const& v ) {
return std::all_of(
v.begin(), v.end(), []( int elem ) {
return elem % 2 == 1;
} );
}, "All elements are odd") &&
},
"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;
using Catch::Matchers::StartsWith;
REQUIRE_THAT(str, StartsWith("foo") && EqualsRange(arr) && EndsWith("bar"));
REQUIRE_THAT(str, StartsWith("foo") && !EqualsRange(bad_arr) && EndsWith("bar"));
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( 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));
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;
TEST_CASE( "Combining concrete matchers does not use templated matchers",
"[matchers][templated]" ) {
using Catch::Matchers::EndsWith;
using Catch::Matchers::StartsWith;
STATIC_REQUIRE(std::is_same<
decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))),
Catch::Matchers::Detail::MatchAnyOf<std::string>
>::value);
STATIC_REQUIRE(
std::is_same<decltype( StartsWith( "foo" ) ||
( StartsWith( "bar" ) && EndsWith( "bar" ) &&
!EndsWith( "foo" ) ) ),
Catch::Matchers::Detail::MatchAnyOf<std::string>>::value );
}
struct MatcherA : Catch::Matchers::MatcherGenericBase {
std::string describe() const override { return "equals: (int) 1 or (float) 1.0f"; }
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; }
};
@ -793,8 +853,7 @@ namespace { namespace MatchersTests {
struct MatcherC : Catch::Matchers::MatcherGenericBase {
std::string describe() const override { return "equals: (T) 1"; }
template<typename T>
bool match(T t) const { return t == T{1}; }
template <typename T> bool match( T t ) const { return t == T{ 1 }; }
};
struct MatcherD : Catch::Matchers::MatcherGenericBase {
@ -803,108 +862,119 @@ namespace { namespace MatchersTests {
};
TEST_CASE( "Combining only templated matchers", "[matchers][templated]" ) {
STATIC_REQUIRE(std::is_same<
decltype(MatcherA() || MatcherB()),
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB>
>::value);
STATIC_REQUIRE(
std::is_same<decltype( MatcherA() || MatcherB() ),
Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, MatcherB>>::value );
REQUIRE_THAT( 1, MatcherA() || MatcherB() );
STATIC_REQUIRE(std::is_same<
decltype(MatcherA() && MatcherB()),
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB>
>::value);
STATIC_REQUIRE(
std::is_same<decltype( MatcherA() && MatcherB() ),
Catch::Matchers::Detail::
MatchAllOfGeneric<MatcherA, MatcherB>>::value );
REQUIRE_THAT( 1, MatcherA() && MatcherB() );
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( MatcherA() || !MatcherB() ),
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::MatchNotOfGeneric<MatcherB>>
>::value);
Catch::Matchers::Detail::MatchAnyOfGeneric<
MatcherA,
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherB>>>::value );
REQUIRE_THAT( 1, MatcherA() || !MatcherB() );
}
TEST_CASE("Combining MatchAnyOfGeneric does not nest", "[matchers][templated]") {
TEST_CASE( "Combining MatchAnyOfGeneric does not nest",
"[matchers][templated]" ) {
// MatchAnyOfGeneric LHS + some matcher RHS
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( ( MatcherA() || MatcherB() ) || MatcherC() ),
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC>
>::value);
Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC>>::value );
REQUIRE_THAT( 1, ( MatcherA() || MatcherB() ) || MatcherC() );
// some matcher LHS + MatchAnyOfGeneric RHS
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( MatcherA() || ( MatcherB() || MatcherC() ) ),
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC>
>::value);
Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC>>::value );
REQUIRE_THAT( 1, MatcherA() || ( MatcherB() || MatcherC() ) );
// MatchAnyOfGeneric LHS + MatchAnyOfGeneric RHS
STATIC_REQUIRE(std::is_same<
decltype((MatcherA() || MatcherB()) || (MatcherC() || MatcherD())),
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
>::value);
STATIC_REQUIRE(
std::is_same<
decltype( ( MatcherA() || MatcherB() ) ||
( MatcherC() || MatcherD() ) ),
Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>>::
value );
REQUIRE_THAT(1, (MatcherA() || MatcherB()) || (MatcherC() || MatcherD()));
REQUIRE_THAT(
1, ( MatcherA() || MatcherB() ) || ( MatcherC() || MatcherD() ) );
}
TEST_CASE("Combining MatchAllOfGeneric does not nest", "[matchers][templated]") {
TEST_CASE( "Combining MatchAllOfGeneric does not nest",
"[matchers][templated]" ) {
// MatchAllOfGeneric lhs + some matcher RHS
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( ( MatcherA() && MatcherB() ) && MatcherC() ),
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>
>::value);
Catch::Matchers::Detail::
MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>>::value );
REQUIRE_THAT( 1, ( MatcherA() && MatcherB() ) && MatcherC() );
// some matcher LHS + MatchAllOfGeneric RSH
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( MatcherA() && ( MatcherB() && MatcherC() ) ),
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>
>::value);
Catch::Matchers::Detail::
MatchAllOfGeneric<MatcherA, MatcherB, MatcherC>>::value );
REQUIRE_THAT( 1, MatcherA() && ( MatcherB() && MatcherC() ) );
// MatchAllOfGeneric LHS + MatchAllOfGeneric RHS
STATIC_REQUIRE(std::is_same<
decltype((MatcherA() && MatcherB()) && (MatcherC() && MatcherD())),
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
>::value);
STATIC_REQUIRE(
std::is_same<
decltype( ( MatcherA() && MatcherB() ) &&
( MatcherC() && MatcherD() ) ),
Catch::Matchers::Detail::
MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>>::
value );
REQUIRE_THAT(1, (MatcherA() && MatcherB()) && (MatcherC() && MatcherD()));
REQUIRE_THAT(
1, ( MatcherA() && MatcherB() ) && ( MatcherC() && MatcherD() ) );
}
TEST_CASE("Combining MatchNotOfGeneric does not nest", "[matchers][templated]") {
STATIC_REQUIRE(std::is_same<
TEST_CASE( "Combining MatchNotOfGeneric does not nest",
"[matchers][templated]" ) {
STATIC_REQUIRE(
std::is_same<
decltype( !MatcherA() ),
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>
>::value);
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>>::value );
REQUIRE_THAT( 0, !MatcherA() );
STATIC_REQUIRE(std::is_same<
decltype(!!MatcherA()),
MatcherA const&
>::value);
STATIC_REQUIRE(
std::is_same<decltype( !!MatcherA() ), MatcherA const&>::value );
REQUIRE_THAT( 1, !!MatcherA() );
STATIC_REQUIRE(std::is_same<
STATIC_REQUIRE(
std::is_same<
decltype( !!!MatcherA() ),
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>
>::value);
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>>::value );
REQUIRE_THAT( 0, !!!MatcherA() );
STATIC_REQUIRE(std::is_same<
decltype(!!!!MatcherA()),
MatcherA const &
>::value);
STATIC_REQUIRE(
std::is_same<decltype( !!!!MatcherA() ), MatcherA const&>::value );
REQUIRE_THAT( 1, !!!!MatcherA() );
}
@ -912,7 +982,8 @@ namespace { namespace MatchersTests {
struct EvilAddressOfOperatorUsed : std::exception {
EvilAddressOfOperatorUsed() {}
const char* what() const noexcept override {
return "overloaded address-of operator of matcher was used instead of std::addressof";
return "overloaded address-of operator of matcher was used instead of "
"std::addressof";
}
};
@ -924,25 +995,19 @@ namespace { namespace MatchersTests {
};
struct EvilMatcher : Catch::Matchers::MatcherGenericBase {
std::string describe() const override {
return "equals: 45";
}
std::string describe() const override { return "equals: 45"; }
bool match(int i) const {
return i == 45;
}
bool match( int i ) const { return i == 45; }
EvilMatcher const* operator& () const {
throw EvilAddressOfOperatorUsed();
}
EvilMatcher const* operator&() const { throw EvilAddressOfOperatorUsed(); }
int operator,(EvilMatcher const&) const {
throw EvilCommaOperatorUsed();
}
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);
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() );
@ -955,14 +1020,9 @@ namespace { namespace MatchersTests {
ImmovableMatcher& operator=( ImmovableMatcher const& ) = delete;
ImmovableMatcher& operator=( ImmovableMatcher&& ) = delete;
std::string describe() const override {
return "always false";
}
std::string describe() const override { return "always false"; }
template<typename T>
bool match(T&&) const {
return false;
}
template <typename T> bool match( T&& ) const { return false; }
};
struct MatcherWasMovedOrCopied : std::exception {
@ -974,12 +1034,12 @@ namespace { namespace MatchersTests {
struct ThrowOnCopyOrMoveMatcher : Catch::Matchers::MatcherGenericBase {
ThrowOnCopyOrMoveMatcher() = default;
[[noreturn]]
ThrowOnCopyOrMoveMatcher(ThrowOnCopyOrMoveMatcher const&): Catch::Matchers::MatcherGenericBase() {
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher const& ):
Catch::Matchers::MatcherGenericBase() {
throw MatcherWasMovedOrCopied();
}
[[noreturn]]
ThrowOnCopyOrMoveMatcher(ThrowOnCopyOrMoveMatcher &&): Catch::Matchers::MatcherGenericBase() {
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher&& ):
Catch::Matchers::MatcherGenericBase() {
throw MatcherWasMovedOrCopied();
}
ThrowOnCopyOrMoveMatcher& operator=( ThrowOnCopyOrMoveMatcher const& ) {
@ -989,39 +1049,35 @@ namespace { namespace MatchersTests {
throw MatcherWasMovedOrCopied();
}
std::string describe() const override {
return "always false";
}
std::string describe() const override { return "always false"; }
template<typename T>
bool match(T&&) const {
return 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( "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());
TEST_CASE( "Immovable matchers can be used",
"[matchers][templated][approvals]" ) {
REQUIRE_THAT( 123,
( ImmovableMatcher() && ImmovableMatcher() ) ||
!ImmovableMatcher() );
}
struct ReferencingMatcher : Catch::Matchers::MatcherGenericBase {
std::string describe() const override {
return "takes reference";
}
bool match(int& i) const {
return i == 22;
}
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]") {
TEST_CASE( "Matchers can take references",
"[matchers][templated][approvals]" ) {
REQUIRE_THAT( 22, ReferencingMatcher{} );
}
} } // namespace MatchersTests
#ifdef __clang__
# pragma clang diagnostic pop
#endif

View File

@ -19,28 +19,25 @@
#include <array>
#include <tuple>
namespace { namespace MiscTests {
namespace {
#ifndef MISC_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define MISC_TEST_HELPERS_INCLUDED
inline const char* makeString( bool makeNull ) {
static const char* makeString(bool makeNull) {
return makeNull ? nullptr : "valid string";
}
inline bool testCheckedIf( bool flag ) {
static bool testCheckedIf(bool flag) {
CHECKED_IF(flag)
return true;
else
return false;
}
inline bool testCheckedElse( bool flag ) {
static bool testCheckedElse(bool flag) {
CHECKED_ELSE(flag)
return false;
return true;
}
inline unsigned int Factorial( unsigned int number ) {
static unsigned int Factorial(unsigned int number) {
return number > 1 ? Factorial(number - 1) * number : 1;
}
@ -48,7 +45,7 @@ static int f() {
return 1;
}
inline void manuallyRegisteredTestFunction() {
static void manuallyRegisteredTestFunction() {
SUCCEED("was called");
}
@ -72,7 +69,8 @@ template<typename T, size_t S>
struct Bar {
size_t size() { return S; }
};
#endif
}
TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
int a = 1;
@ -521,5 +519,3 @@ TEMPLATE_TEST_CASE_SIG("#1954 - 7 arg template test case sig compiles", "[regres
(1, 1, 1, 1, 1, 0, 0), (5, 1, 1, 1, 1, 0, 0), (5, 3, 1, 1, 1, 0, 0)) {
SUCCEED();
}
}} // namespace MiscTests