mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 04:07:10 +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:
		| @@ -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; | ||||
|         }; | ||||
|  | ||||
|     } // namespace Detail | ||||
|  | ||||
|     template <typename T> | ||||
|         MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const { | ||||
|             return MatchAllOf<T>() && *this && other; | ||||
|     Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) { | ||||
|         return Detail::MatchAllOf<T>{} && lhs && rhs; | ||||
|     } | ||||
|     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 ); | ||||
|     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 { | ||||
|  | ||||
|         template<typename... MatcherTs> struct MatchAllOfGeneric; | ||||
|         template<typename... MatcherTs> struct MatchAnyOfGeneric; | ||||
|         template<typename MatcherT> struct MatchNotOfGeneric; | ||||
|  | ||||
|     struct MatcherGenericBase : MatcherUntypedBase { | ||||
|             virtual ~MatcherGenericBase(); | ||||
|         virtual ~MatcherGenericBase(); // = default; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     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,48 +157,52 @@ namespace Matchers { | ||||
|  | ||||
|             MatcherT const& m_matcher; | ||||
|         }; | ||||
|     } // namespace Detail | ||||
|  | ||||
|  | ||||
|     // FIXME: enable_if_t | ||||
|  | ||||
|     // compose only generic matchers | ||||
|     template<typename MatcherLHS, typename MatcherRHS> | ||||
|         typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAllOfGeneric<MatcherLHS, MatcherRHS>>::type | ||||
|     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 }; | ||||
|     } | ||||
|  | ||||
|     template<typename MatcherLHS, typename MatcherRHS> | ||||
|         typename std::enable_if<are_generic_matchers<MatcherLHS, MatcherRHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>::type | ||||
|     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 }; | ||||
|     } | ||||
|  | ||||
|     template<typename MatcherT> | ||||
|         typename std::enable_if<is_generic_matcher<MatcherT>::value, MatchNotOfGeneric<MatcherT>>::type | ||||
|     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 | ||||
|     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 }; | ||||
|     } | ||||
|  | ||||
|     template<typename ArgLHS, typename MatcherRHS> | ||||
|         typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type | ||||
|     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 }; | ||||
|     } | ||||
|  | ||||
|     template<typename MatcherLHS, typename ArgRHS> | ||||
|         typename std::enable_if<is_generic_matcher<MatcherLHS>::value, MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>::type | ||||
|     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 }; | ||||
|     } | ||||
|  | ||||
|     template<typename ArgLHS, typename MatcherRHS> | ||||
|         typename std::enable_if<is_generic_matcher<MatcherRHS>::value, MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>::type | ||||
|     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 }; | ||||
|     } | ||||
| @@ -210,53 +210,48 @@ namespace Matchers { | ||||
|  | ||||
|     // 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))}; | ||||
|     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))}; | ||||
|     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))}; | ||||
|     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))}; | ||||
|     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)))}; | ||||
|     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))}; | ||||
|     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) { | ||||
|     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"; | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský