|
|
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic>
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>
#include "gtest/gtest-printers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
#define GTEST_MAYBE_5046_ 5046
#else
#define GTEST_MAYBE_5046_
#endif
GTEST_DISABLE_MSC_WARNINGS_PUSH_( 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
clients of class B */ /* Symbol involving type with internal linkage not defined */)
namespace testing {
// To implement a matcher Foo for type T, define:
// 1. a class FooMatcherMatcher that implements the matcher interface:
// using is_gtest_matcher = void;
// bool MatchAndExplain(const T&, std::ostream*);
// (MatchResultListener* can also be used instead of std::ostream*)
// void DescribeTo(std::ostream*);
// void DescribeNegationTo(std::ostream*);
//
// 2. a factory function that creates a Matcher<T> object from a
// FooMatcherMatcher.
class MatchResultListener { public: // Creates a listener object with the given underlying ostream. The
// listener does not own the ostream, and does not dereference it
// in the constructor or destructor.
explicit MatchResultListener(::std::ostream* os) : stream_(os) {} virtual ~MatchResultListener() = 0; // Makes this class abstract.
// Streams x to the underlying ostream; does nothing if the ostream
// is NULL.
template <typename T> MatchResultListener& operator<<(const T& x) { if (stream_ != nullptr) *stream_ << x; return *this; }
// Returns the underlying ostream.
::std::ostream* stream() { return stream_; }
// Returns true if and only if the listener is interested in an explanation
// of the match result. A matcher's MatchAndExplain() method can use
// this information to avoid generating the explanation when no one
// intends to hear it.
bool IsInterested() const { return stream_ != nullptr; }
private: ::std::ostream* const stream_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); };
inline MatchResultListener::~MatchResultListener() { }
// An instance of a subclass of this knows how to describe itself as a
// matcher.
class GTEST_API_ MatcherDescriberInterface { public: virtual ~MatcherDescriberInterface() {}
// Describes this matcher to an ostream. The function should print
// a verb phrase that describes the property a value matching this
// matcher should have. The subject of the verb phrase is the value
// being matched. For example, the DescribeTo() method of the Gt(7)
// matcher prints "is greater than 7".
virtual void DescribeTo(::std::ostream* os) const = 0;
// Describes the negation of this matcher to an ostream. For
// example, if the description of this matcher is "is greater than
// 7", the negated description could be "is not greater than 7".
// You are not required to override this when implementing
// MatcherInterface, but it is highly advised so that your matcher
// can produce good error messages.
virtual void DescribeNegationTo(::std::ostream* os) const { *os << "not ("; DescribeTo(os); *os << ")"; } };
// The implementation of a matcher.
template <typename T> class MatcherInterface : public MatcherDescriberInterface { public: // Returns true if and only if the matcher matches x; also explains the
// match result to 'listener' if necessary (see the next paragraph), in
// the form of a non-restrictive relative clause ("which ...",
// "whose ...", etc) that describes x. For example, the
// MatchAndExplain() method of the Pointee(...) matcher should
// generate an explanation like "which points to ...".
//
// Implementations of MatchAndExplain() should add an explanation of
// the match result *if and only if* they can provide additional
// information that's not already present (or not obvious) in the
// print-out of x and the matcher's description. Whether the match
// succeeds is not a factor in deciding whether an explanation is
// needed, as sometimes the caller needs to print a failure message
// when the match succeeds (e.g. when the matcher is used inside
// Not()).
//
// For example, a "has at least 10 elements" matcher should explain
// what the actual element count is, regardless of the match result,
// as it is useful information to the reader; on the other hand, an
// "is empty" matcher probably only needs to explain what the actual
// size is when the match fails, as it's redundant to say that the
// size is 0 when the value is already known to be empty.
//
// You should override this method when defining a new matcher.
//
// It's the responsibility of the caller (Google Test) to guarantee
// that 'listener' is not NULL. This helps to simplify a matcher's
// implementation when it doesn't care about the performance, as it
// can talk to 'listener' without checking its validity first.
// However, in order to implement dummy listeners efficiently,
// listener->stream() may be NULL.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
// Inherits these methods from MatcherDescriberInterface:
// virtual void DescribeTo(::std::ostream* os) const = 0;
// virtual void DescribeNegationTo(::std::ostream* os) const;
};
namespace internal {
struct AnyEq { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a == b; } }; struct AnyNe { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a != b; } }; struct AnyLt { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a < b; } }; struct AnyGt { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a > b; } }; struct AnyLe { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a <= b; } }; struct AnyGe { template <typename A, typename B> bool operator()(const A& a, const B& b) const { return a >= b; } };
// A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener { public: DummyMatchResultListener() : MatchResultListener(nullptr) {}
private: GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); };
// A match result listener that forwards the explanation to a given
// ostream. The difference between this and MatchResultListener is
// that the former is concrete.
class StreamMatchResultListener : public MatchResultListener { public: explicit StreamMatchResultListener(::std::ostream* os) : MatchResultListener(os) {}
private: GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); };
struct SharedPayloadBase { std::atomic<int> ref{1}; void Ref() { ref.fetch_add(1, std::memory_order_relaxed); } bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; } };
template <typename T> struct SharedPayload : SharedPayloadBase { explicit SharedPayload(const T& v) : value(v) {} explicit SharedPayload(T&& v) : value(std::move(v)) {}
static void Destroy(SharedPayloadBase* shared) { delete static_cast<SharedPayload*>(shared); }
T value; };
// An internal class for implementing Matcher<T>, which will derive
// from it. We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication.
template <typename T> class MatcherBase : private MatcherDescriberInterface { public: // Returns true if and only if the matcher matches x; also explains the
// match result to 'listener'.
bool MatchAndExplain(const T& x, MatchResultListener* listener) const { GTEST_CHECK_(vtable_ != nullptr); return vtable_->match_and_explain(*this, x, listener); }
// Returns true if and only if this matcher matches x.
bool Matches(const T& x) const { DummyMatchResultListener dummy; return MatchAndExplain(x, &dummy); }
// Describes this matcher to an ostream.
void DescribeTo(::std::ostream* os) const final { GTEST_CHECK_(vtable_ != nullptr); vtable_->describe(*this, os, false); }
// Describes the negation of this matcher to an ostream.
void DescribeNegationTo(::std::ostream* os) const final { GTEST_CHECK_(vtable_ != nullptr); vtable_->describe(*this, os, true); }
// Explains why x matches, or doesn't match, the matcher.
void ExplainMatchResultTo(const T& x, ::std::ostream* os) const { StreamMatchResultListener listener(os); MatchAndExplain(x, &listener); }
// Returns the describer for this matcher object; retains ownership
// of the describer, which is only guaranteed to be alive when
// this matcher object is alive.
const MatcherDescriberInterface* GetDescriber() const { if (vtable_ == nullptr) return nullptr; return vtable_->get_describer(*this); }
protected: MatcherBase() : vtable_(nullptr) {}
// Constructs a matcher from its implementation.
template <typename U> explicit MatcherBase(const MatcherInterface<U>* impl) { Init(impl); }
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> MatcherBase(M&& m) { // NOLINT
Init(std::forward<M>(m)); }
MatcherBase(const MatcherBase& other) : vtable_(other.vtable_), buffer_(other.buffer_) { if (IsShared()) buffer_.shared->Ref(); }
MatcherBase& operator=(const MatcherBase& other) { if (this == &other) return *this; Destroy(); vtable_ = other.vtable_; buffer_ = other.buffer_; if (IsShared()) buffer_.shared->Ref(); return *this; }
MatcherBase(MatcherBase&& other) : vtable_(other.vtable_), buffer_(other.buffer_) { other.vtable_ = nullptr; }
MatcherBase& operator=(MatcherBase&& other) { if (this == &other) return *this; Destroy(); vtable_ = other.vtable_; buffer_ = other.buffer_; other.vtable_ = nullptr; return *this; }
~MatcherBase() override { Destroy(); }
private: struct VTable { bool (*match_and_explain)(const MatcherBase&, const T&, MatchResultListener*); void (*describe)(const MatcherBase&, std::ostream*, bool negation); // Returns the captured object if it implements the interface, otherwise
// returns the MatcherBase itself.
const MatcherDescriberInterface* (*get_describer)(const MatcherBase&); // Called on shared instances when the reference count reaches 0.
void (*shared_destroy)(SharedPayloadBase*); };
bool IsShared() const { return vtable_ != nullptr && vtable_->shared_destroy != nullptr; }
// If the implementation uses a listener, call that.
template <typename P> static auto MatchAndExplainImpl(const MatcherBase& m, const T& value, MatchResultListener* listener) -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) { return P::Get(m).MatchAndExplain(value, listener->stream()); }
template <typename P> static auto MatchAndExplainImpl(const MatcherBase& m, const T& value, MatchResultListener* listener) -> decltype(P::Get(m).MatchAndExplain(value, listener)) { return P::Get(m).MatchAndExplain(value, listener); }
template <typename P> static void DescribeImpl(const MatcherBase& m, std::ostream* os, bool negation) { if (negation) { P::Get(m).DescribeNegationTo(os); } else { P::Get(m).DescribeTo(os); } }
template <typename P> static const MatcherDescriberInterface* GetDescriberImpl( const MatcherBase& m) { // If the impl is a MatcherDescriberInterface, then return it.
// Otherwise use MatcherBase itself.
// This allows us to implement the GetDescriber() function without support
// from the impl, but some users really want to get their impl back when
// they call GetDescriber().
// We use std::get on a tuple as a workaround of not having `if constexpr`.
return std::get<( std::is_convertible<decltype(&P::Get(m)), const MatcherDescriberInterface*>::value ? 1 : 0)>(std::make_tuple(&m, &P::Get(m))); }
template <typename P> const VTable* GetVTable() { static constexpr VTable kVTable = {&MatchAndExplainImpl<P>, &DescribeImpl<P>, &GetDescriberImpl<P>, P::shared_destroy}; return &kVTable; }
union Buffer { // Add some types to give Buffer some common alignment/size use cases.
void* ptr; double d; int64_t i; // And add one for the out-of-line cases.
SharedPayloadBase* shared; };
void Destroy() { if (IsShared() && buffer_.shared->Unref()) { vtable_->shared_destroy(buffer_.shared); } }
template <typename M> static constexpr bool IsInlined() { return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) && std::is_trivially_copy_constructible<M>::value && std::is_trivially_destructible<M>::value; }
template <typename M, bool = MatcherBase::IsInlined<M>()> struct ValuePolicy { static const M& Get(const MatcherBase& m) { // When inlined along with Init, need to be explicit to avoid violating
// strict aliasing rules.
const M *ptr = static_cast<const M*>( static_cast<const void*>(&m.buffer_)); return *ptr; } static void Init(MatcherBase& m, M impl) { ::new (static_cast<void*>(&m.buffer_)) M(impl); } static constexpr auto shared_destroy = nullptr; };
template <typename M> struct ValuePolicy<M, false> { using Shared = SharedPayload<M>; static const M& Get(const MatcherBase& m) { return static_cast<Shared*>(m.buffer_.shared)->value; } template <typename Arg> static void Init(MatcherBase& m, Arg&& arg) { m.buffer_.shared = new Shared(std::forward<Arg>(arg)); } static constexpr auto shared_destroy = &Shared::Destroy; };
template <typename U, bool B> struct ValuePolicy<const MatcherInterface<U>*, B> { using M = const MatcherInterface<U>; using Shared = SharedPayload<std::unique_ptr<M>>; static const M& Get(const MatcherBase& m) { return *static_cast<Shared*>(m.buffer_.shared)->value; } static void Init(MatcherBase& m, M* impl) { m.buffer_.shared = new Shared(std::unique_ptr<M>(impl)); }
static constexpr auto shared_destroy = &Shared::Destroy; };
template <typename M> void Init(M&& m) { using MM = typename std::decay<M>::type; using Policy = ValuePolicy<MM>; vtable_ = GetVTable<Policy>(); Policy::Init(*this, std::forward<M>(m)); }
const VTable* vtable_; Buffer buffer_; };
} // namespace internal
// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
// object that can check whether a value of type T matches. The
// implementation of Matcher<T> is just a std::shared_ptr to const
// MatcherInterface<T>. Don't inherit from Matcher!
template <typename T> class Matcher : public internal::MatcherBase<T> { public: // Constructs a null matcher. Needed for storing Matcher objects in STL
// containers. A default-constructed matcher is not yet initialized. You
// cannot use it until a valid value has been assigned to it.
explicit Matcher() {} // NOLINT
// Constructs a matcher from its implementation.
explicit Matcher(const MatcherInterface<const T&>* impl) : internal::MatcherBase<T>(impl) {}
template <typename U> explicit Matcher( const MatcherInterface<U>* impl, typename std::enable_if<!std::is_same<U, const U&>::value>::type* = nullptr) : internal::MatcherBase<T>(impl) {}
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
// Implicit constructor here allows people to write
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT
};
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected.
template <> class GTEST_API_ Matcher<const std::string&> : public internal::MatcherBase<const std::string&> { public: Matcher() {}
explicit Matcher(const MatcherInterface<const std::string&>* impl) : internal::MatcherBase<const std::string&>(impl) {}
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> Matcher(M&& m) // NOLINT
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
};
template <> class GTEST_API_ Matcher<std::string> : public internal::MatcherBase<std::string> { public: Matcher() {}
explicit Matcher(const MatcherInterface<const std::string&>* impl) : internal::MatcherBase<std::string>(impl) {} explicit Matcher(const MatcherInterface<std::string>* impl) : internal::MatcherBase<std::string>(impl) {}
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> Matcher(M&& m) // NOLINT
: internal::MatcherBase<std::string>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
};
#if GTEST_INTERNAL_HAS_STRING_VIEW
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
// matcher is expected.
template <> class GTEST_API_ Matcher<const internal::StringView&> : public internal::MatcherBase<const internal::StringView&> { public: Matcher() {}
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) : internal::MatcherBase<const internal::StringView&>(impl) {}
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> Matcher(M&& m) // NOLINT
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) { }
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
template <> class GTEST_API_ Matcher<internal::StringView> : public internal::MatcherBase<internal::StringView> { public: Matcher() {}
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) : internal::MatcherBase<internal::StringView>(impl) {} explicit Matcher(const MatcherInterface<internal::StringView>* impl) : internal::MatcherBase<internal::StringView>(impl) {}
template <typename M, typename = typename std::remove_reference< M>::type::is_gtest_matcher> Matcher(M&& m) // NOLINT
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
Matcher(internal::StringView s); // NOLINT
}; #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Prints a matcher in a human-readable format.
template <typename T> std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) { matcher.DescribeTo(&os); return os; }
// The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more
// than one type, e.g. Eq(n) and NotNull()).
//
// To define a polymorphic matcher, a user should provide an Impl
// class that has a DescribeTo() method and a DescribeNegationTo()
// method, and define a member function (or member function template)
//
// bool MatchAndExplain(const Value& value,
// MatchResultListener* listener) const;
//
// See the definition of NotNull() for a complete example.
template <class Impl> class PolymorphicMatcher { public: explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
// Returns a mutable reference to the underlying matcher
// implementation object.
Impl& mutable_impl() { return impl_; }
// Returns an immutable reference to the underlying matcher
// implementation object.
const Impl& impl() const { return impl_; }
template <typename T> operator Matcher<T>() const { return Matcher<T>(new MonomorphicImpl<const T&>(impl_)); }
private: template <typename T> class MonomorphicImpl : public MatcherInterface<T> { public: explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
void DescribeNegationTo(::std::ostream* os) const override { impl_.DescribeNegationTo(os); }
bool MatchAndExplain(T x, MatchResultListener* listener) const override { return impl_.MatchAndExplain(x, listener); }
private: const Impl impl_; };
Impl impl_; };
// Creates a matcher from its implementation.
// DEPRECATED: Especially in the generic code, prefer:
// Matcher<T>(new MyMatcherImpl<const T&>(...));
//
// MakeMatcher may create a Matcher that accepts its argument by value, which
// leads to unnecessary copies & lack of support for non-copyable types.
template <typename T> inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) { return Matcher<T>(impl); }
// Creates a polymorphic matcher from its implementation. This is
// easier to use than the PolymorphicMatcher<Impl> constructor as it
// doesn't require you to explicitly write the template argument, e.g.
//
// MakePolymorphicMatcher(foo);
// vs
// PolymorphicMatcher<TypeOfFoo>(foo);
template <class Impl> inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) { return PolymorphicMatcher<Impl>(impl); }
namespace internal { // Implements a matcher that compares a given value with a
// pre-supplied value using one of the ==, <=, <, etc, operators. The
// two values being compared don't have to have the same type.
//
// The matcher defined here is polymorphic (for example, Eq(5) can be
// used to match an int, a short, a double, etc). Therefore we use
// a template type conversion operator in the implementation.
//
// The following template definition assumes that the Rhs parameter is
// a "bare" type (i.e. neither 'const T' nor 'T&').
template <typename D, typename Rhs, typename Op> class ComparisonBase { public: explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
using is_gtest_matcher = void;
template <typename Lhs> bool MatchAndExplain(const Lhs& lhs, std::ostream*) const { return Op()(lhs, Unwrap(rhs_)); } void DescribeTo(std::ostream* os) const { *os << D::Desc() << " "; UniversalPrint(Unwrap(rhs_), os); } void DescribeNegationTo(std::ostream* os) const { *os << D::NegatedDesc() << " "; UniversalPrint(Unwrap(rhs_), os); }
private: template <typename T> static const T& Unwrap(const T& v) { return v; } template <typename T> static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
Rhs rhs_; };
template <typename Rhs> class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> { public: explicit EqMatcher(const Rhs& rhs) : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { } static const char* Desc() { return "is equal to"; } static const char* NegatedDesc() { return "isn't equal to"; } }; template <typename Rhs> class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> { public: explicit NeMatcher(const Rhs& rhs) : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { } static const char* Desc() { return "isn't equal to"; } static const char* NegatedDesc() { return "is equal to"; } }; template <typename Rhs> class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> { public: explicit LtMatcher(const Rhs& rhs) : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { } static const char* Desc() { return "is <"; } static const char* NegatedDesc() { return "isn't <"; } }; template <typename Rhs> class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> { public: explicit GtMatcher(const Rhs& rhs) : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { } static const char* Desc() { return "is >"; } static const char* NegatedDesc() { return "isn't >"; } }; template <typename Rhs> class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> { public: explicit LeMatcher(const Rhs& rhs) : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { } static const char* Desc() { return "is <="; } static const char* NegatedDesc() { return "isn't <="; } }; template <typename Rhs> class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { public: explicit GeMatcher(const Rhs& rhs) : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { } static const char* Desc() { return "is >="; } static const char* NegatedDesc() { return "isn't >="; } };
template <typename T, typename = typename std::enable_if< std::is_constructible<std::string, T>::value>::type> using StringLike = T;
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class MatchesRegexMatcher { public: MatchesRegexMatcher(const RE* regex, bool full_match) : regex_(regex), full_match_(full_match) {}
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { return MatchAndExplain(std::string(s), listener); } #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
// char*
// const wchar_t*
// wchar_t*
template <typename CharType> bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { return s != nullptr && MatchAndExplain(std::string(s), listener); }
// Matches anything that can convert to std::string.
//
// This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { const std::string& s2(s); return full_match_ ? RE::FullMatch(s2, *regex_) : RE::PartialMatch(s2, *regex_); }
void DescribeTo(::std::ostream* os) const { *os << (full_match_ ? "matches" : "contains") << " regular expression "; UniversalPrinter<std::string>::Print(regex_->pattern(), os); }
void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't " << (full_match_ ? "match" : "contain") << " regular expression "; UniversalPrinter<std::string>::Print(regex_->pattern(), os); }
private: const std::shared_ptr<const RE> regex_; const bool full_match_; }; } // namespace internal
// Matches a string that fully matches regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( const internal::RE* regex) { return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); } template <typename T = std::string> PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( const internal::StringLike<T>& regex) { return MatchesRegex(new internal::RE(std::string(regex))); }
// Matches a string that contains regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( const internal::RE* regex) { return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); } template <typename T = std::string> PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( const internal::StringLike<T>& regex) { return ContainsRegex(new internal::RE(std::string(regex))); }
// Creates a polymorphic matcher that matches anything equal to x.
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile.
template <typename T> inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'.
template <typename T> Matcher<T>::Matcher(T value) { *this = Eq(value); }
// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity.
//
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
// or Matcher<T>(x), but more readable than the latter.
//
// We could define similar monomorphic matchers for other comparison
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
// it yet as those are used much less than Eq() in practice. A user
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
// for example.
template <typename Lhs, typename Rhs> inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
// Creates a polymorphic matcher that matches anything >= x.
template <typename Rhs> inline internal::GeMatcher<Rhs> Ge(Rhs x) { return internal::GeMatcher<Rhs>(x); }
// Creates a polymorphic matcher that matches anything > x.
template <typename Rhs> inline internal::GtMatcher<Rhs> Gt(Rhs x) { return internal::GtMatcher<Rhs>(x); }
// Creates a polymorphic matcher that matches anything <= x.
template <typename Rhs> inline internal::LeMatcher<Rhs> Le(Rhs x) { return internal::LeMatcher<Rhs>(x); }
// Creates a polymorphic matcher that matches anything < x.
template <typename Rhs> inline internal::LtMatcher<Rhs> Lt(Rhs x) { return internal::LtMatcher<Rhs>(x); }
// Creates a polymorphic matcher that matches anything != x.
template <typename Rhs> inline internal::NeMatcher<Rhs> Ne(Rhs x) { return internal::NeMatcher<Rhs>(x); } } // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|