mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-22 11:23:29 +01:00
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.
This commit is contained in:
parent
a1be19aa1b
commit
cf6575576f
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
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)
|
||||
|
@ -17,7 +17,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 +37,7 @@ namespace Catch {
|
||||
}
|
||||
};
|
||||
|
||||
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
|
||||
using StringMatcher = Matchers::MatcherBase<std::string>;
|
||||
|
||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
std::string MatcherUntypedBase::toString() const {
|
||||
if( m_cachedToString.empty() )
|
||||
@ -19,10 +18,5 @@ namespace Matchers {
|
||||
|
||||
MatcherUntypedBase::~MatcherUntypedBase() = default;
|
||||
|
||||
} // namespace Impl
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
@ -15,11 +15,11 @@
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
template<typename ArgT> struct MatchAllOf;
|
||||
template<typename ArgT> struct MatchAnyOf;
|
||||
template<typename ArgT> struct MatchNotOf;
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
class MatcherUntypedBase {
|
||||
public:
|
||||
@ -29,16 +29,11 @@ namespace Matchers {
|
||||
std::string toString() const;
|
||||
|
||||
protected:
|
||||
virtual ~MatcherUntypedBase();
|
||||
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;
|
||||
@ -58,16 +53,19 @@ namespace Matchers {
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {};
|
||||
|
||||
|
||||
MatchAllOf<T> operator && ( MatcherBase const& other ) const;
|
||||
MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
|
||||
MatchNotOf<T> operator ! () const;
|
||||
};
|
||||
namespace Detail {
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchAllOf : 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))
|
||||
@ -91,16 +89,35 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
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 : 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 ) {
|
||||
@ -125,19 +142,34 @@ namespace Matchers {
|
||||
return description;
|
||||
}
|
||||
|
||||
MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
|
||||
auto copy(*this);
|
||||
copy.m_matchers.push_back( &other );
|
||||
return copy;
|
||||
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 : MatcherBase<ArgT> {
|
||||
|
||||
MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
|
||||
explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
|
||||
m_underlyingMatcher( underlyingMatcher )
|
||||
{}
|
||||
|
||||
bool match( ArgT const& arg ) const override {
|
||||
return !m_underlyingMatcher.match( arg );
|
||||
@ -146,29 +178,29 @@ namespace Matchers {
|
||||
std::string describe() const override {
|
||||
return "not " + m_underlyingMatcher.toString();
|
||||
}
|
||||
|
||||
private:
|
||||
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 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 Impl
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
>;
|
||||
|
||||
@ -161,102 +157,101 @@ namespace Matchers {
|
||||
|
||||
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
|
||||
|
||||
// FIXME: enable_if_t
|
||||
|
||||
// compose only generic matchers
|
||||
template<typename MatcherLHS, typename MatcherRHS>
|
||||
typename std::enable_if<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type
|
||||
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
|
||||
template<typename MatcherT>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
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>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatchersLHS..., MatcherRHS>>::type
|
||||
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 MatcherLHS, typename... MatchersRHS>
|
||||
typename std::enable_if<Detail::is_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatchersRHS...>>::type
|
||||
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))};
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
MatcherT const& operator ! (MatchNotOfGeneric<MatcherT> const& matcher) {
|
||||
return matcher.m_matcher;
|
||||
}
|
||||
template<typename MatcherT>
|
||||
MatcherT const& operator ! (Detail::MatchNotOfGeneric<MatcherT> const& matcher) {
|
||||
return matcher.m_matcher;
|
||||
}
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherGenericBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif //TWOBLUECUBES_CATCH_MATCHERS_TEMPLATES_HPP_INCLUDED
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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("not there", Catch::CaseSensitive::No)" type="CHECK_THAT">
|
||||
FAILED:
|
||||
|
@ -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("not there", Catch::CaseSensitive::No))">
|
||||
FAILED:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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']
|
||||
|
@ -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) && Catch::VectorContains("."_catch_sr)
|
||||
tags, VectorContains("magic-tag"_catch_sr) && 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>
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user