1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-01-15 22:58:02 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Martin Hořeňovský
c3013a6251
Move matcher implementation to their own subfolder
In the future we can expect many more matchers, so let's give them
a place to live.

Also moved matcher-related internal files to `internal` subfolder.
Ideally we should sort out all of our source code, but that will
have to come later.
2020-02-20 17:42:11 +01:00
Martin Hořeňovský
40e35d4318
Reorganize base headers for matchers 2020-02-20 13:39:04 +01:00
Martin Hořeňovský
b83a12b12c
Replace enable_if with enable_if_t 2020-02-20 13:03:38 +01:00
Martin Hořeňovský
d33af93e17
Cleanup visibility in generic not matcher 2020-02-20 13:03:36 +01:00
Martin Hořeňovský
25c5ae240c
Disable copies on generic matcher combinators 2020-02-20 13:03:34 +01:00
Martin Hořeňovský
260263b9bf
Combined matchers are now final 2020-02-20 13:03:32 +01:00
Martin Hořeňovský
cf6575576f
Start fixing up Matchers: namespaces, composition ops
This commit also forbids composing lvalues of composed matchers, as
per previous deprecation notice. I do not expect this to be contentious
in practice, because there was a bug in that usage for years, and
nobody complained.
2020-02-20 13:03:30 +01:00
40 changed files with 480 additions and 525 deletions

View File

@ -9,34 +9,6 @@ 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

View File

@ -53,6 +53,7 @@
* The description type now must be a `const char*` or implicitly convertible to it
* The `[!hide]` tag has been removed.
* Use `[.]` or `[.foo]` instead.
* Lvalues of composed matchers cannot be composed further
### Fixes
* The `INFO` macro no longer contains superfluous semicolon (#1456)

View File

@ -39,7 +39,7 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/catch_assertioninfo.h
${SOURCES_DIR}/catch_assertionresult.h
${SOURCES_DIR}/catch_capture.hpp
${SOURCES_DIR}/catch_capture_matchers.h
${SOURCES_DIR}/internal/catch_capture_matchers.h
${SOURCES_DIR}/catch_clara.h
${SOURCES_DIR}/catch_commandline.h
${SOURCES_DIR}/catch_common.h
@ -72,13 +72,13 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/catch_interfaces_testcase.h
${SOURCES_DIR}/catch_leak_detector.h
${SOURCES_DIR}/catch_list.h
${SOURCES_DIR}/catch_matchers.h
${SOURCES_DIR}/catch_matchers_exception.hpp
${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}/matchers/catch_matchers.h
${SOURCES_DIR}/matchers/catch_matchers_exception.hpp
${SOURCES_DIR}/matchers/catch_matchers_floating.h
${SOURCES_DIR}/matchers/catch_matchers_generic.hpp
${SOURCES_DIR}/matchers/catch_matchers_string.h
${SOURCES_DIR}/matchers/catch_matchers_templates.hpp
${SOURCES_DIR}/matchers/catch_matchers_vector.h
${SOURCES_DIR}/catch_message.h
${SOURCES_DIR}/catch_meta.hpp
${SOURCES_DIR}/catch_objc.hpp
@ -130,7 +130,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_approx.cpp
${SOURCES_DIR}/catch_assertionhandler.cpp
${SOURCES_DIR}/catch_assertionresult.cpp
${SOURCES_DIR}/catch_capture_matchers.cpp
${SOURCES_DIR}/internal/catch_capture_matchers.cpp
${SOURCES_DIR}/catch_commandline.cpp
${SOURCES_DIR}/catch_common.cpp
${SOURCES_DIR}/catch_config.cpp
@ -155,12 +155,12 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_interfaces_testcase.cpp
${SOURCES_DIR}/catch_list.cpp
${SOURCES_DIR}/catch_leak_detector.cpp
${SOURCES_DIR}/catch_matchers.cpp
${SOURCES_DIR}/catch_matchers_exception.cpp
${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}/matchers/catch_matchers.cpp
${SOURCES_DIR}/matchers/catch_matchers_exception.cpp
${SOURCES_DIR}/matchers/catch_matchers_floating.cpp
${SOURCES_DIR}/matchers/catch_matchers_generic.cpp
${SOURCES_DIR}/matchers/catch_matchers_string.cpp
${SOURCES_DIR}/matchers/catch_matchers_templates.cpp
${SOURCES_DIR}/catch_message.cpp
${SOURCES_DIR}/catch_output_redirect.cpp
${SOURCES_DIR}/catch_registry_hub.cpp

View File

@ -26,7 +26,6 @@
#include <catch2/catch_compiler_capabilities.h>
#include <catch2/catch_string_manip.h>
#include <catch2/catch_capture_matchers.h>
#include <catch2/catch_generators.hpp>
#include <catch2/catch_generators_generic.hpp>
#include <catch2/catch_generators_specific.hpp>

View File

@ -14,9 +14,9 @@
#include <catch2/catch_enforce.h>
#include <catch2/catch_debugger.h>
#include <catch2/catch_interfaces_registry_hub.h>
#include <catch2/catch_capture_matchers.h>
#include <catch2/internal/catch_capture_matchers.h>
#include <catch2/catch_run_context.h>
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_string.h>
namespace Catch {

View File

@ -1,174 +0,0 @@
/*
* Created by Phil Nash on 04/03/2012.
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
#include <catch2/catch_common.h>
#include <string>
#include <vector>
namespace Catch {
namespace Matchers {
namespace Impl {
template<typename ArgT> struct MatchAllOf;
template<typename ArgT> struct MatchAnyOf;
template<typename ArgT> struct MatchNotOf;
class MatcherUntypedBase {
public:
MatcherUntypedBase() = default;
MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
std::string toString() const;
protected:
virtual ~MatcherUntypedBase();
virtual std::string describe() const = 0;
mutable std::string m_cachedToString;
};
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#endif
template<typename ObjectT>
struct MatcherMethod {
virtual bool match( ObjectT const& arg ) const = 0;
};
#if defined(__OBJC__)
// Hack to fix Catch GH issue #1661. Could use id for generic Object support.
// use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
template<>
struct MatcherMethod<NSString*> {
virtual bool match( NSString* arg ) const = 0;
};
#endif
#ifdef __clang__
# pragma clang diagnostic pop
#endif
template<typename T>
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
MatchAllOf<T> operator && ( MatcherBase const& other ) const;
MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
MatchNotOf<T> operator ! () const;
};
template<typename ArgT>
struct MatchAllOf : MatcherBase<ArgT> {
bool match( ArgT const& arg ) const override {
for( auto matcher : m_matchers ) {
if (!matcher->match(arg))
return false;
}
return true;
}
std::string describe() const override {
std::string description;
description.reserve( 4 + m_matchers.size()*32 );
description += "( ";
bool first = true;
for( auto matcher : m_matchers ) {
if( first )
first = false;
else
description += " and ";
description += matcher->toString();
}
description += " )";
return description;
}
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;
};
template<typename ArgT>
struct MatchAnyOf : MatcherBase<ArgT> {
bool match( ArgT const& arg ) const override {
for( auto matcher : m_matchers ) {
if (matcher->match(arg))
return true;
}
return false;
}
std::string describe() const override {
std::string description;
description.reserve( 4 + m_matchers.size()*32 );
description += "( ";
bool first = true;
for( auto matcher : m_matchers ) {
if( first )
first = false;
else
description += " or ";
description += matcher->toString();
}
description += " )";
return description;
}
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;
};
template<typename ArgT>
struct MatchNotOf : MatcherBase<ArgT> {
MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
bool match( ArgT const& arg ) const override {
return !m_underlyingMatcher.match( arg );
}
std::string describe() const override {
return "not " + m_underlyingMatcher.toString();
}
MatcherBase<ArgT> const& m_underlyingMatcher;
};
template<typename T>
MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
return MatchAllOf<T>() && *this && other;
}
template<typename T>
MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
return MatchAnyOf<T>() || *this || other;
}
template<typename T>
MatchNotOf<T> MatcherBase<T>::operator ! () const {
return MatchNotOf<T>( *this );
}
} // namespace Impl
} // namespace Matchers
using namespace Matchers;
using Matchers::Impl::MatcherBase;
} // namespace Catch
#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED

View File

@ -7,7 +7,6 @@
#define TWOBLUECUBES_CATCH_TEST_MACROS_HPP_INCLUDED
#include <catch2/catch_capture.hpp>
#include <catch2/catch_capture_matchers.h>
#include <catch2/catch_interfaces_exception.h>
#include <catch2/catch_preprocessor.hpp>
#include <catch2/catch_section.h>
@ -23,8 +22,6 @@
#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@ -35,14 +32,8 @@
#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
@ -111,8 +102,6 @@
#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
@ -123,15 +112,9 @@
#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
@ -211,8 +194,6 @@
#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
#define CATCH_CHECK( ... ) (void)(0)
@ -223,14 +204,8 @@
#define CATCH_CHECK_THROWS( ... ) (void)(0)
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CATCH_CHECK_NOTHROW( ... ) (void)(0)
#define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
#define CATCH_INFO( msg ) (void)(0)
#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
#define CATCH_WARN( msg ) (void)(0)
@ -287,8 +262,6 @@
#define REQUIRE_THROWS( ... ) (void)(0)
#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define REQUIRE_NOTHROW( ... ) (void)(0)
#define CHECK( ... ) (void)(0)
@ -299,14 +272,8 @@
#define CHECK_THROWS( ... ) (void)(0)
#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CHECK_NOTHROW( ... ) (void)(0)
#define CHECK_THAT( arg, matcher ) (void)(0)
#define REQUIRE_THAT( arg, matcher ) (void)(0)
#define INFO( msg ) (void)(0)
#define UNSCOPED_INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)

View File

@ -1,17 +1,13 @@
/*
* Created by Phil on 9/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_capture_matchers.h>
#include <catch2/internal/catch_capture_matchers.h>
#include <catch2/matchers/catch_matchers.h>
#include <catch2/catch_interfaces_registry_hub.h>
namespace Catch {
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
// This is the general overload that takes a any string matcher
// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
// the Equals matcher (so the header does not mention matchers)

View File

@ -1,7 +1,4 @@
/*
* Created by Phil on 9/8/2017
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
@ -9,7 +6,6 @@
#define TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED
#include <catch2/catch_capture.hpp>
#include <catch2/catch_matchers.h>
#include <catch2/catch_stringref.h>
namespace Catch {
@ -17,7 +13,7 @@ namespace Catch {
template<typename ArgT, typename MatcherT>
class MatchExpr : public ITransientExpression {
ArgT && m_arg;
MatcherT m_matcher;
MatcherT const& m_matcher;
StringRef m_matcherString;
public:
MatchExpr( ArgT && arg, MatcherT const& matcher, StringRef const& matcherString )
@ -37,7 +33,12 @@ namespace Catch {
}
};
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
namespace Matchers {
template <typename ArgT>
struct MatcherBase;
}
using StringMatcher = Matchers::MatcherBase<std::string>;
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
@ -80,4 +81,5 @@ namespace Catch {
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
#endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED

View File

@ -1,28 +1,22 @@
/*
* Created by Phil Nash on 19/07/2017.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
namespace Catch {
namespace Matchers {
namespace Impl {
namespace Matchers {
std::string MatcherUntypedBase::toString() const {
if( m_cachedToString.empty() )
if (m_cachedToString.empty())
m_cachedToString = describe();
return m_cachedToString;
}
MatcherUntypedBase::~MatcherUntypedBase() = default;
} // namespace Impl
} // namespace Matchers
using namespace Matchers;
using Matchers::Impl::MatcherBase;
} // namespace Matchers
} // namespace Catch

View File

@ -0,0 +1,250 @@
/*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
#include <catch2/catch_common.h>
#include <catch2/internal/catch_capture_matchers.h>
#include <string>
#include <vector>
namespace Catch {
namespace Matchers {
class MatcherUntypedBase {
public:
MatcherUntypedBase() = default;
MatcherUntypedBase(MatcherUntypedBase const&) = default;
MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
std::string toString() const;
protected:
virtual ~MatcherUntypedBase(); // = default;
virtual std::string describe() const = 0;
mutable std::string m_cachedToString;
};
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#endif
template<typename ObjectT>
struct MatcherMethod {
virtual bool match(ObjectT const& arg) const = 0;
};
#if defined(__OBJC__)
// Hack to fix Catch GH issue #1661. Could use id for generic Object support.
// use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
template<>
struct MatcherMethod<NSString*> {
virtual bool match(NSString* arg) const = 0;
};
#endif
#ifdef __clang__
# pragma clang diagnostic pop
#endif
template<typename T>
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {};
namespace Detail {
template<typename ArgT>
struct MatchAllOf final : MatcherBase<ArgT> {
MatchAllOf() = default;
MatchAllOf(MatchAllOf const&) = delete;
MatchAllOf& operator=(MatchAllOf const&) = delete;
MatchAllOf(MatchAllOf&&) = default;
MatchAllOf& operator=(MatchAllOf&&) = default;
bool match( ArgT const& arg ) const override {
for( auto matcher : m_matchers ) {
if (!matcher->match(arg))
return false;
}
return true;
}
std::string describe() const override {
std::string description;
description.reserve( 4 + m_matchers.size()*32 );
description += "( ";
bool first = true;
for( auto matcher : m_matchers ) {
if( first )
first = false;
else
description += " and ";
description += matcher->toString();
}
description += " )";
return description;
}
friend MatchAllOf operator&& (MatchAllOf&& lhs, MatcherBase<ArgT> const& rhs) {
lhs.m_matchers.push_back(&rhs);
return std::move(lhs);
}
friend MatchAllOf operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf&& rhs) {
rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
return std::move(rhs);
}
private:
std::vector<MatcherBase<ArgT> const*> m_matchers;
};
//! lvalue overload is intentionally deleted, users should
//! not be trying to compose stored composition matchers
template<typename ArgT>
MatchAllOf<ArgT> operator&& (MatchAllOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
//! lvalue overload is intentionally deleted, users should
//! not be trying to compose stored composition matchers
template<typename ArgT>
MatchAllOf<ArgT> operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf<ArgT> const& rhs) = delete;
template<typename ArgT>
struct MatchAnyOf final : MatcherBase<ArgT> {
MatchAnyOf() = default;
MatchAnyOf(MatchAnyOf const&) = delete;
MatchAnyOf& operator=(MatchAnyOf const&) = delete;
MatchAnyOf(MatchAnyOf&&) = default;
MatchAnyOf& operator=(MatchAnyOf&&) = default;
bool match( ArgT const& arg ) const override {
for( auto matcher : m_matchers ) {
if (matcher->match(arg))
return true;
}
return false;
}
std::string describe() const override {
std::string description;
description.reserve( 4 + m_matchers.size()*32 );
description += "( ";
bool first = true;
for( auto matcher : m_matchers ) {
if( first )
first = false;
else
description += " or ";
description += matcher->toString();
}
description += " )";
return description;
}
friend MatchAnyOf operator|| (MatchAnyOf&& lhs, MatcherBase<ArgT> const& rhs) {
lhs.m_matchers.push_back(&rhs);
return std::move(lhs);
}
friend MatchAnyOf operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf&& rhs) {
rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
return std::move(rhs);
}
private:
std::vector<MatcherBase<ArgT> const*> m_matchers;
};
//! lvalue overload is intentionally deleted, users should
//! not be trying to compose stored composition matchers
template<typename ArgT>
MatchAnyOf<ArgT> operator|| (MatchAnyOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
//! lvalue overload is intentionally deleted, users should
//! not be trying to compose stored composition matchers
template<typename ArgT>
MatchAnyOf<ArgT> operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf<ArgT> const& rhs) = delete;
template<typename ArgT>
struct MatchNotOf final : MatcherBase<ArgT> {
explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
m_underlyingMatcher( underlyingMatcher )
{}
bool match( ArgT const& arg ) const override {
return !m_underlyingMatcher.match( arg );
}
std::string describe() const override {
return "not " + m_underlyingMatcher.toString();
}
private:
MatcherBase<ArgT> const& m_underlyingMatcher;
};
} // namespace Detail
template <typename T>
Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
return Detail::MatchAllOf<T>{} && lhs && rhs;
}
template <typename T>
Detail::MatchAnyOf<T> operator|| (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
return Detail::MatchAnyOf<T>{} || lhs || rhs;
}
template <typename T>
Detail::MatchNotOf<T> operator! (MatcherBase<T> const& matcher) {
return Detail::MatchNotOf<T>{ matcher };
}
} // namespace Matchers
} // namespace Catch
#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#define CHECK_THAT( arg, matcher ) (void)(0)
#define REQUIRE_THAT( arg, matcher ) (void)(0)
#endif // end of user facing macro declarations
#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED

View File

@ -5,7 +5,7 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_matchers_exception.hpp>
#include <catch2/matchers/catch_matchers_exception.hpp>
namespace Catch {

View File

@ -7,7 +7,7 @@
#ifndef TWOBLUECUBES_CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
namespace Catch {
namespace Matchers {

View File

@ -5,7 +5,7 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_matchers_floating.h>
#include <catch2/matchers/catch_matchers_floating.h>
#include <catch2/catch_enforce.h>
#include <catch2/catch_polyfills.hpp>
#include <catch2/catch_to_string.hpp>

View File

@ -7,7 +7,7 @@
#ifndef TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
namespace Catch {
namespace Matchers {

View File

@ -1,4 +1,4 @@
#include <catch2/catch_matchers_generic.hpp>
#include <catch2/matchers/catch_matchers_generic.hpp>
std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
if (desc.empty()) {

View File

@ -8,7 +8,7 @@
#define TWOBLUECUBES_CATCH_MATCHERS_GENERIC_HPP_INCLUDED
#include <catch2/catch_common.h>
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
#include <catch2/catch_meta.hpp>
#include <string>

View File

@ -1,12 +1,9 @@
/*
* Created by Phil Nash on 08/02/2017.
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_string.h>
#include <catch2/catch_string_manip.h>
#include <catch2/catch_tostring.h>

View File

@ -8,7 +8,7 @@
#ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
#include <string>

View File

@ -1,9 +1,10 @@
#include <catch2/catch_matchers_templates.hpp>
#include <catch2/matchers/catch_matchers_templates.hpp>
namespace Catch {
namespace Matchers {
namespace Impl {
MatcherGenericBase::~MatcherGenericBase() {}
MatcherGenericBase::~MatcherGenericBase() = default;
namespace Detail {
std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end) {
std::string description;
@ -27,6 +28,7 @@ namespace Matchers {
description += " )";
return description;
}
}
} // namespace Detail
} // namespace Matchers
} // namespace Catch

View File

@ -2,7 +2,7 @@
#define TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
#include <catch2/catch_common.h>
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
#include <catch2/catch_stringref.h>
#include <array>
@ -14,16 +14,12 @@
namespace Catch {
namespace Matchers {
namespace Impl {
struct MatcherGenericBase : MatcherUntypedBase {
virtual ~MatcherGenericBase(); // = default;
};
template<typename... MatcherTs> struct MatchAllOfGeneric;
template<typename... MatcherTs> struct MatchAnyOfGeneric;
template<typename MatcherT> struct MatchNotOfGeneric;
struct MatcherGenericBase : MatcherUntypedBase {
virtual ~MatcherGenericBase();
};
namespace Detail {
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{};
@ -63,7 +59,7 @@ namespace Matchers {
template<typename T>
using is_generic_matcher = std::is_base_of<
Catch::Matchers::Impl::MatcherGenericBase,
Catch::Matchers::MatcherGenericBase,
typename std::remove_cv<typename std::remove_reference<T>::type>::type
>;
@ -72,7 +68,7 @@ namespace Matchers {
template<typename T>
using is_matcher = std::is_base_of<
Catch::Matchers::Impl::MatcherUntypedBase,
Catch::Matchers::MatcherUntypedBase,
typename std::remove_cv<typename std::remove_reference<T>::type>::type
>;
@ -111,7 +107,12 @@ namespace Matchers {
template<typename... MatcherTs>
struct MatchAllOfGeneric : MatcherGenericBase {
struct MatchAllOfGeneric final : MatcherGenericBase {
MatchAllOfGeneric(MatchAllOfGeneric const&) = delete;
MatchAllOfGeneric& operator=(MatchAllOfGeneric const&) = delete;
MatchAllOfGeneric(MatchAllOfGeneric&&) = default;
MatchAllOfGeneric& operator=(MatchAllOfGeneric&&) = default;
MatchAllOfGeneric(MatcherTs const&... matchers) : m_matchers{std::addressof(matchers)...} {}
explicit MatchAllOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
@ -129,7 +130,12 @@ namespace Matchers {
template<typename... MatcherTs>
struct MatchAnyOfGeneric : MatcherGenericBase {
struct MatchAnyOfGeneric final : MatcherGenericBase {
MatchAnyOfGeneric(MatchAnyOfGeneric const&) = delete;
MatchAnyOfGeneric& operator=(MatchAnyOfGeneric const&) = delete;
MatchAnyOfGeneric(MatchAnyOfGeneric&&) = default;
MatchAnyOfGeneric& operator=(MatchAnyOfGeneric&&) = default;
MatchAnyOfGeneric(MatcherTs const&... matchers) : m_matchers{std::addressof(matchers)...} {}
explicit MatchAnyOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
@ -147,7 +153,12 @@ namespace Matchers {
template<typename MatcherT>
struct MatchNotOfGeneric : MatcherGenericBase {
struct MatchNotOfGeneric final : MatcherGenericBase {
MatchNotOfGeneric(MatchNotOfGeneric const&) = delete;
MatchNotOfGeneric& operator=(MatchNotOfGeneric const&) = delete;
MatchNotOfGeneric(MatchNotOfGeneric&&) = default;
MatchNotOfGeneric& operator=(MatchNotOfGeneric&&) = default;
explicit MatchNotOfGeneric(MatcherT const& matcher) : m_matcher{matcher} {}
template<typename Arg>
@ -159,104 +170,101 @@ namespace Matchers {
return "not " + m_matcher.toString();
}
//! Negating negation can just unwrap and return underlying matcher
friend MatcherT const& operator ! (Detail::MatchNotOfGeneric<MatcherT> const& matcher) {
return matcher.m_matcher;
}
private:
MatcherT const& m_matcher;
};
} // namespace Detail
// compose only generic matchers
template<typename MatcherLHS, typename MatcherRHS>
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type
// compose only generic matchers
template<typename MatcherLHS, typename MatcherRHS>
std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
return {lhs, rhs};
}
return { lhs, rhs };
}
template<typename MatcherLHS, typename MatcherRHS>
typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type
template<typename MatcherLHS, typename MatcherRHS>
std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
return {lhs, rhs};
}
return { lhs, rhs };
}
template<typename MatcherT>
typename std::enable_if<is_generic_matcher<MatcherT>::value, MatchNotOfGeneric<MatcherT>>::type
//! Wrap provided generic matcher in generic negator
template<typename MatcherT>
std::enable_if_t<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>
operator ! (MatcherT const& matcher) {
return MatchNotOfGeneric<MatcherT>{matcher};
}
return Detail::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
// compose mixed generic and non-generic matchers
template<typename MatcherLHS, typename ArgRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
return {lhs, rhs};
}
return { lhs, rhs };
}
template<typename ArgLHS, typename MatcherRHS>
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
template<typename ArgLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
return {lhs, rhs};
}
return { lhs, rhs };
}
template<typename MatcherLHS, typename ArgRHS>
typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
template<typename MatcherLHS, typename ArgRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
return {lhs, rhs};
}
return { lhs, rhs };
}
template<typename ArgLHS, typename MatcherRHS>
typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
template<typename ArgLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
return {lhs, 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))};
}
// avoid deep nesting of matcher templates
template<typename... MatchersLHS, typename... MatchersRHS>
Detail::MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>
operator && (Detail::MatchAllOfGeneric<MatchersLHS...>&& lhs, Detail::MatchAllOfGeneric<MatchersRHS...>&& rhs) {
return Detail::MatchAllOfGeneric<MatchersLHS..., MatchersRHS...>{Detail::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... MatchersLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatchersLHS..., MatcherRHS>>
operator && (Detail::MatchAllOfGeneric<MatchersLHS...>&& lhs, MatcherRHS const& rhs) {
return Detail::MatchAllOfGeneric<MatchersLHS..., MatcherRHS>{Detail::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 MatcherLHS, typename... MatchersRHS>
std::enable_if_t<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatchersRHS...>>
operator && (MatcherLHS const& lhs, Detail::MatchAllOfGeneric<MatchersRHS...>&& rhs) {
return Detail::MatchAllOfGeneric<MatcherLHS, MatchersRHS...>{Detail::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... MatchersRHS>
Detail::MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>
operator || (Detail::MatchAnyOfGeneric<MatchersLHS...>&& lhs, Detail::MatchAnyOfGeneric<MatchersRHS...>&& rhs) {
return Detail::MatchAnyOfGeneric<MatchersLHS..., MatchersRHS...>{Detail::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... MatchersLHS, typename MatcherRHS>
std::enable_if_t<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>>
operator || (Detail::MatchAnyOfGeneric<MatchersLHS...>&& lhs, MatcherRHS const& rhs) {
return Detail::MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>{Detail::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
template<typename MatcherLHS, typename... MatchersRHS>
std::enable_if_t<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>>
operator || (MatcherLHS const& lhs, Detail::MatchAnyOfGeneric<MatchersRHS...>&& rhs) {
return Detail::MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>{Detail::array_cat(static_cast<void const*>(std::addressof(lhs)), std::move(rhs.m_matchers))};
}
} // namespace Matchers
using namespace Matchers;
using Matchers::Impl::MatcherGenericBase;
} // namespace Catch
#endif //TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED

View File

@ -8,7 +8,7 @@
#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
#include <catch2/catch_matchers.h>
#include <catch2/matchers/catch_matchers.h>
#include <catch2/catch_approx.h>
#include <algorithm>

View File

@ -5,8 +5,8 @@
// This won't provide full coverage, but it might be worth checking
// the other branch as well
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_generic.hpp>
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_generic.hpp>
#include <catch2/matchers/catch_matchers_string.h>
#include <type_traits>
#include <stdexcept>

View File

@ -99,7 +99,6 @@ 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

View File

@ -33,7 +33,7 @@ Compilation.tests.cpp:<line number>: passed: a == t for: 3 == 3
Compilation.tests.cpp:<line number>: passed: throws_int(true)
Compilation.tests.cpp:<line number>: passed: throws_int(true), int
Compilation.tests.cpp:<line number>: passed: throws_int(false)
Compilation.tests.cpp:<line number>: passed: "aaa", Catch::EndsWith("aaa") for: "aaa" ends with: "aaa"
Compilation.tests.cpp:<line number>: passed: "aaa", Catch::Matchers::EndsWith("aaa") for: "aaa" ends with: "aaa"
Compilation.tests.cpp:<line number>: passed: templated_tests<int>(3) for: true
Misc.tests.cpp:<line number>: failed: f() == 0 for: 1 == 0
Misc.tests.cpp:<line number>: passed: errno == 1 for: 1 == 1
@ -263,28 +263,28 @@ 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: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(!MatcherA()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))), Catch::Matchers::Detail::MatchAnyOf<std::string> >::value'
Matchers.tests.cpp:<line number>: passed: with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Detail::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: with 1 message: 'std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::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" )
@ -344,8 +344,6 @@ 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
@ -1841,7 +1839,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: Timing.result == Timing.itera
InternalBenchmark.tests.cpp:<line number>: passed: Timing.iterations >= time.count() for: 128 >= 100
Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
Tag.tests.cpp:<line number>: passed: tags, Catch::VectorContains("magic-tag"_catch_sr) && Catch::VectorContains("."_catch_sr) for: { ., magic-tag } ( Contains: magic-tag and Contains: . )
Tag.tests.cpp:<line number>: passed: tags, VectorContains("magic-tag"_catch_sr) && VectorContains("."_catch_sr) for: { ., magic-tag } ( Contains: magic-tag and Contains: . )
StringManip.tests.cpp:<line number>: passed: splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc", ','), Equals(std::vector<StringRef>{"abc"}) for: { abc } Equals: { abc }
StringManip.tests.cpp:<line number>: passed: splitStringRef("abc,def", ','), Equals(std::vector<StringRef>{"abc", "def"}) for: { abc, def } Equals: { abc, def }

View File

@ -1380,6 +1380,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 329 | 255 passed | 70 failed | 4 failed as expected
assertions: 1841 | 1689 passed | 131 failed | 21 failed as expected
test cases: 328 | 254 passed | 70 failed | 4 failed as expected
assertions: 1839 | 1687 passed | 131 failed | 21 failed as expected

View File

@ -271,7 +271,7 @@ Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( throws_int(false) )
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
REQUIRE_THAT( "aaa", Catch::Matchers::EndsWith("aaa") )
with expansion:
"aaa" ends with: "aaa"
@ -2125,7 +2125,7 @@ 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::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC> >::value
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1, MatcherA() && MatcherB() && MatcherC() )
@ -2136,7 +2136,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()),
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC,
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC,
MatcherD> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2154,7 +2154,7 @@ 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::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC> >::value
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 1, MatcherA() || MatcherB() || MatcherC() )
@ -2165,7 +2165,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()),
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC,
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC,
MatcherD> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2182,8 +2182,8 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(!MatcherA()), Catch::Matchers::Impl::MatchNotOfGeneric
<MatcherA> >::value
std::is_same< decltype(!MatcherA()), Catch::Matchers::Detail::
MatchNotOfGeneric<MatcherA> >::value
Matchers.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( 0, !MatcherA() )
@ -2201,7 +2201,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Impl::
std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Detail::
MatchNotOfGeneric<MatcherA> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2227,8 +2227,8 @@ 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
("bar") && !EndsWith("foo"))), Catch::Matchers::Detail::MatchAnyOf<std::
string> >::value
-------------------------------------------------------------------------------
Combining only templated matchers
@ -2238,7 +2238,7 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Impl::
std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, MatcherB> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2248,7 +2248,7 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Impl::
std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Detail::
MatchAllOfGeneric<MatcherA, MatcherB> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2258,8 +2258,8 @@ with expansion:
Matchers.tests.cpp:<line number>: PASSED:
with message:
std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Impl::
MatchAnyOfGeneric<MatcherA, Catch::Matchers::Impl::MatchNotOfGeneric
std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Detail::
MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::MatchNotOfGeneric
<MatcherB>> >::value
Matchers.tests.cpp:<line number>: PASSED:
@ -2610,24 +2610,6 @@ 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
-------------------------------------------------------------------------------
@ -13485,7 +13467,7 @@ Tag.tests.cpp:<line number>
...............................................................................
Tag.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( tags, Catch::VectorContains("magic-tag"_catch_sr) && Catch::VectorContains("."_catch_sr) )
REQUIRE_THAT( tags, VectorContains("magic-tag"_catch_sr) && VectorContains("."_catch_sr) )
with expansion:
{ ., magic-tag } ( Contains: magic-tag and Contains: . )
@ -14414,6 +14396,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 329 | 239 passed | 86 failed | 4 failed as expected
assertions: 1858 | 1689 passed | 148 failed | 21 failed as expected
test cases: 328 | 238 passed | 86 failed | 4 failed as expected
assertions: 1856 | 1687 passed | 148 failed | 21 failed as expected

View File

@ -271,7 +271,7 @@ Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( throws_int(false) )
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
REQUIRE_THAT( "aaa", Catch::Matchers::EndsWith("aaa") )
with expansion:
"aaa" ends with: "aaa"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="132" tests="1859" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="132" tests="1857" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/>
@ -364,7 +364,6 @@ 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(&quot;not there&quot;, Catch::CaseSensitive::No)" type="CHECK_THAT">
FAILED:

View File

@ -925,7 +925,6 @@ Exception.tests.cpp:<line number>
<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(&quot;not there&quot;, Catch::CaseSensitive::No))">
FAILED:

View File

@ -65,7 +65,7 @@ ok {test-number} - throws_int(true), int
# #833
ok {test-number} - throws_int(false)
# #833
ok {test-number} - "aaa", Catch::EndsWith("aaa") for: "aaa" ends with: "aaa"
ok {test-number} - "aaa", Catch::Matchers::EndsWith("aaa") for: "aaa" ends with: "aaa"
# #833
ok {test-number} - templated_tests<int>(3) for: true
# #835 -- errno should not be touched by Catch
@ -525,23 +525,23 @@ 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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB() && MatcherC() && MatcherD()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB() || MatcherC() || MatcherD()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(!MatcherA()), Catch::Matchers::Detail::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
@ -549,7 +549,7 @@ ok {test-number} - with 1 message: 'std::is_same< decltype(!!MatcherA()), Matche
# 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'
ok {test-number} - with 1 message: 'std::is_same< decltype(!!!MatcherA()), Catch::Matchers::Detail::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
@ -557,17 +557,17 @@ ok {test-number} - with 1 message: 'std::is_same< decltype(!!!!MatcherA()), Matc
# 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'
ok {test-number} - with 1 message: 'std::is_same< decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || MatcherB()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() && MatcherB()), Catch::Matchers::Detail::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'
ok {test-number} - with 1 message: 'std::is_same< decltype(MatcherA() || !MatcherB()), Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::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
@ -686,10 +686,6 @@ 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
@ -3509,7 +3505,7 @@ not ok {test-number} - false with 1 message: '3'
# sends information to INFO
not ok {test-number} - false with 2 messages: 'hi' and 'i := 7'
# shortened hide tags are split apart
ok {test-number} - tags, Catch::VectorContains("magic-tag"_catch_sr) && Catch::VectorContains("."_catch_sr) for: { ., magic-tag } ( Contains: magic-tag and Contains: . )
ok {test-number} - tags, VectorContains("magic-tag"_catch_sr) && VectorContains("."_catch_sr) for: { ., magic-tag } ( Contains: magic-tag and Contains: . )
# splitString
ok {test-number} - splitStringRef("", ','), Equals(std::vector<StringRef>()) for: { } Equals: { }
# splitString
@ -3708,5 +3704,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..1850
1..1848

View File

@ -231,8 +231,6 @@ 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']

View File

@ -299,7 +299,7 @@ Nor would this
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/UsageTests/Compilation.tests.cpp" >
<Original>
"aaa", Catch::EndsWith("aaa")
"aaa", Catch::Matchers::EndsWith("aaa")
</Original>
<Expanded>
"aaa" ends with: "aaa"
@ -3011,25 +3011,6 @@ 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>
@ -16273,7 +16254,7 @@ loose text artifact
<TestCase name="shortened hide tags are split apart" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="tests/<exe-name>/IntrospectiveTests/Tag.tests.cpp" >
<Original>
tags, Catch::VectorContains("magic-tag"_catch_sr) &amp;&amp; Catch::VectorContains("."_catch_sr)
tags, VectorContains("magic-tag"_catch_sr) &amp;&amp; VectorContains("."_catch_sr)
</Original>
<Expanded>
{ ., magic-tag } ( Contains: magic-tag and Contains: . )
@ -17283,7 +17264,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1689" failures="149" expectedFailures="21"/>
<OverallResults successes="1687" failures="149" expectedFailures="21"/>
</Group>
<OverallResults successes="1689" failures="148" expectedFailures="21"/>
<OverallResults successes="1687" failures="148" expectedFailures="21"/>
</Catch>

View File

@ -5,7 +5,7 @@
#include <catch2/catch_approx.h>
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_string.h>
#include <catch2/catch_test_spec_parser.h>
#include <catch2/catch_test_case_info.h>
#include <catch2/catch_config.hpp>

View File

@ -1,5 +1,5 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_vector.h>
#include <catch2/matchers/catch_matchers_vector.h>
#include <catch2/catch_string_manip.h>
static const char * const no_whitespace = "There is no extra whitespace here";

View File

@ -3,8 +3,8 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/catch_matchers_string.h>
#include <catch2/catch_matchers_vector.h>
#include <catch2/matchers/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_vector.h>
#include <catch2/catch_tag_alias_registry.h>
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_test_case_info.h>
@ -41,11 +41,12 @@ TEST_CASE( "Tag alias can be registered against tag patterns" ) {
TEST_CASE("shortened hide tags are split apart") {
using Catch::StringRef;
using Catch::Matchers::VectorContains;
auto testcase = Catch::makeTestCaseInfo("", {"fake test name", "[.magic-tag]"}, CATCH_INTERNAL_LINEINFO);
// Transform ...
std::vector<StringRef> tags;
for (auto const& tag : testcase->tags) {
tags.push_back(tag.original);
}
REQUIRE_THAT(tags, Catch::VectorContains("magic-tag"_catch_sr) && Catch::VectorContains("."_catch_sr));
REQUIRE_THAT(tags, VectorContains("magic-tag"_catch_sr) && VectorContains("."_catch_sr));
}

View File

@ -1,5 +1,5 @@
#include <catch2/catch_enum_values_registry.h>
#include <catch2/catch_matchers_vector.h>
#include <catch2/matchers/catch_matchers_vector.h>
#include <catch2/catch_test_macros.hpp>
enum class EnumClass3 { Value1, Value2, Value3, Value4 };

View File

@ -29,7 +29,7 @@ std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
///////////////////////////////
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_string.h>
#include <cstring>
@ -79,7 +79,7 @@ namespace { namespace CompilationTests {
REQUIRE_THROWS(throws_int(true));
CHECK_THROWS_AS(throws_int(true), int);
REQUIRE_NOTHROW(throws_int(false));
REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
REQUIRE_THAT("aaa", Catch::Matchers::EndsWith("aaa"));
return true;
}

View File

@ -4,7 +4,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_string.h>
#include <string>
#include <stdexcept>

View File

@ -4,12 +4,12 @@
*/
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_matchers_exception.hpp>
#include <catch2/catch_matchers_floating.h>
#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 <catch2/matchers/catch_matchers_exception.hpp>
#include <catch2/matchers/catch_matchers_floating.h>
#include <catch2/matchers/catch_matchers_generic.hpp>
#include <catch2/matchers/catch_matchers_string.h>
#include <catch2/matchers/catch_matchers_vector.h>
#include <catch2/matchers/catch_matchers_templates.hpp>
#include <algorithm>
#include <cmath>
@ -78,7 +78,7 @@ namespace { namespace MatchersTests {
throw DerivedException{};
}
class ExceptionMatcher : public Catch::MatcherBase<SpecialException> {
class ExceptionMatcher : public Catch::Matchers::MatcherBase<SpecialException> {
int m_expected;
public:
ExceptionMatcher(int i) : m_expected(i) {}
@ -556,19 +556,8 @@ 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 {
struct EqualsRangeMatcher : Catch::Matchers::MatcherGenericBase {
EqualsRangeMatcher(Range const& range) : range{ range } {}
@ -604,7 +593,6 @@ namespace { namespace MatchersTests {
}
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 }};
@ -640,28 +628,28 @@ namespace { namespace MatchersTests {
STATIC_REQUIRE(std::is_same<
decltype(StartsWith("foo") || (StartsWith("bar") && EndsWith("bar") && !EndsWith("foo"))),
Catch::Matchers::Impl::MatchAnyOf<std::string>
Catch::Matchers::Detail::MatchAnyOf<std::string>
>::value);
}
struct MatcherA : Catch::MatcherGenericBase {
struct MatcherA : Catch::Matchers::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 {
struct MatcherB : Catch::Matchers::MatcherGenericBase {
std::string describe() const override { return "equals: (long long) 1"; }
bool match(long long l) const { return l == 1ll; }
};
struct MatcherC : Catch::MatcherGenericBase {
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}; }
};
struct MatcherD : Catch::MatcherGenericBase {
struct MatcherD : Catch::Matchers::MatcherGenericBase {
std::string describe() const override { return "equals: true"; }
bool match(bool b) const { return b == true; }
};
@ -669,21 +657,21 @@ namespace { namespace MatchersTests {
TEST_CASE("Combining only templated matchers", "[matchers][templated]") {
STATIC_REQUIRE(std::is_same<
decltype(MatcherA() || MatcherB()),
Catch::Matchers::Impl::MatchAnyOfGeneric<MatcherA, MatcherB>
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB>
>::value);
REQUIRE_THAT(1, MatcherA() || MatcherB());
STATIC_REQUIRE(std::is_same<
decltype(MatcherA() && MatcherB()),
Catch::Matchers::Impl::MatchAllOfGeneric<MatcherA, MatcherB>
Catch::Matchers::Detail::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>>
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, Catch::Matchers::Detail::MatchNotOfGeneric<MatcherB>>
>::value);
REQUIRE_THAT(1, MatcherA() || !MatcherB());
@ -692,14 +680,14 @@ namespace { namespace MatchersTests {
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>
Catch::Matchers::Detail::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>
Catch::Matchers::Detail::MatchAnyOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
>::value);
REQUIRE_THAT(1, MatcherA() || MatcherB() || MatcherC() || MatcherD());
@ -708,14 +696,14 @@ namespace { namespace MatchersTests {
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>
Catch::Matchers::Detail::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>
Catch::Matchers::Detail::MatchAllOfGeneric<MatcherA, MatcherB, MatcherC, MatcherD>
>::value);
REQUIRE_THAT(1, MatcherA() && MatcherB() && MatcherC() && MatcherD());
@ -724,7 +712,7 @@ namespace { namespace MatchersTests {
TEST_CASE("Combining MatchNotOfGeneric does not nest", "[matchers][templated]") {
STATIC_REQUIRE(std::is_same<
decltype(!MatcherA()),
Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA>
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>
>::value);
REQUIRE_THAT(0, !MatcherA());
@ -738,7 +726,7 @@ namespace { namespace MatchersTests {
STATIC_REQUIRE(std::is_same<
decltype(!!!MatcherA()),
Catch::Matchers::Impl::MatchNotOfGeneric<MatcherA>
Catch::Matchers::Detail::MatchNotOfGeneric<MatcherA>
>::value);
REQUIRE_THAT(0, !!!MatcherA());
@ -765,7 +753,7 @@ namespace { namespace MatchersTests {
}
};
struct EvilMatcher : Catch::MatcherGenericBase {
struct EvilMatcher : Catch::Matchers::MatcherGenericBase {
std::string describe() const override {
return "equals: 45";
}
@ -790,7 +778,7 @@ namespace { namespace MatchersTests {
REQUIRE_NOTHROW((EvilMatcher() && EvilMatcher()) || !EvilMatcher());
}
struct ImmovableMatcher : Catch::MatcherGenericBase {
struct ImmovableMatcher : Catch::Matchers::MatcherGenericBase {
ImmovableMatcher() = default;
ImmovableMatcher(ImmovableMatcher const&) = delete;
ImmovableMatcher(ImmovableMatcher &&) = delete;
@ -814,7 +802,7 @@ namespace { namespace MatchersTests {
}
};
struct ThrowOnCopyOrMoveMatcher : Catch::MatcherGenericBase {
struct ThrowOnCopyOrMoveMatcher : Catch::Matchers::MatcherGenericBase {
ThrowOnCopyOrMoveMatcher() = default;
[[noreturn]]
ThrowOnCopyOrMoveMatcher(ThrowOnCopyOrMoveMatcher const&) {
@ -849,7 +837,7 @@ namespace { namespace MatchersTests {
REQUIRE_THAT(123, (ImmovableMatcher() && ImmovableMatcher()) || !ImmovableMatcher());
}
struct ReferencingMatcher : Catch::MatcherGenericBase {
struct ReferencingMatcher : Catch::Matchers::MatcherGenericBase {
std::string describe() const override {
return "takes reference";
}