diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 9c457730..ae7e131d 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -1,3002 +1,2874 @@ // 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. // // Author: wan@google.com (Zhanyong Wan) // Google Mock - a framework for writing C++ mock classes. // // This file implements some commonly used argument matchers. More // matchers can be defined by the user implementing the // MatcherInterface<T> interface if necessary. #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #include <algorithm> #include <limits> #include <ostream> // NOLINT #include <sstream> #include <string> #include <vector> #include <gmock/gmock-printers.h> #include <gmock/internal/gmock-internal-utils.h> #include <gmock/internal/gmock-port.h> #include <gtest/gtest.h> namespace testing { // To implement a matcher Foo for type T, define: // 1. a class FooMatcherImpl that implements the // MatcherInterface<T> interface, and // 2. a factory function that creates a Matcher<T> object from a // FooMatcherImpl*. // // The two-level delegation design makes it possible to allow a user // to write "v" instead of "Eq(v)" where a Matcher is expected, which // is impossible if we pass matchers by pointers. It also eases // ownership management as Matcher objects can now be copied like // plain values. // MatchResultListener is an abstract class. Its << operator can be // used by a matcher to explain why a value matches or doesn't match. // // TODO(wan@google.com): add method // bool InterestedInWhy(bool result) const; // to indicate whether the listener is interested in why the match // result is 'result'. class MatchResultListener { public: // Creates a listener object with the given underlying ostream. The // listener does not own the ostream. 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_ != NULL) *stream_ << x; return *this; } // Returns the underlying ostream. ::std::ostream* stream() { return stream_; } private: ::std::ostream* const stream_; GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); }; inline MatchResultListener::~MatchResultListener() { } // The implementation of a matcher. template <typename T> class MatcherInterface { public: virtual ~MatcherInterface() {} // Returns true iff the matcher matches x; also explains the match // result to 'listener'. // - // You should override this method when defining a new matcher. For - // backward compatibility, we provide a default implementation that - // just forwards to the old, deprecated matcher API (Matches() and - // ExplainMatchResultTo()). + // You should override this method when defining a new matcher. // // It's the responsibility of the caller (Google Mock) 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 { - const bool match = Matches(x); - if (listener->stream() != NULL) { - ExplainMatchResultTo(x, listener->stream()); - } - return match; - } - - // DEPRECATED. This method will be removed. Override - // MatchAndExplain() instead. - // - // Returns true iff the matcher matches x. - virtual bool Matches(T /* x */) const { return false; } + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; // Describes this matcher to an ostream. 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 << ")"; } - - // DEPRECATED. This method will be removed. Override - // MatchAndExplain() instead. - // - // Explains why x matches, or doesn't match, the matcher. Override - // this to provide any additional information that helps a user - // understand the match result. - virtual void ExplainMatchResultTo(T /* x */, ::std::ostream* /* os */) const { - // By default, nothing more needs to be explained, as Google Mock - // has already printed the value of x when this function is - // called. - } }; namespace internal { // A match result listener that ignores the explanation. class DummyMatchResultListener : public MatchResultListener { public: DummyMatchResultListener() : MatchResultListener(NULL) {} 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); }; // A match result listener that stores the explanation in a string. class StringMatchResultListener : public MatchResultListener { public: StringMatchResultListener() : MatchResultListener(&ss_) {} // Returns the explanation heard so far. internal::string str() const { return ss_.str(); } private: ::std::stringstream ss_; GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); }; // 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 { public: // Returns true iff the matcher matches x; also explains the match // result to 'listener'. bool MatchAndExplain(T x, MatchResultListener* listener) const { return impl_->MatchAndExplain(x, listener); } // Returns true iff this matcher matches x. bool Matches(T x) const { DummyMatchResultListener dummy; return MatchAndExplain(x, &dummy); } // Describes this matcher to an ostream. void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } // Describes the negation of this matcher to an ostream. void DescribeNegationTo(::std::ostream* os) const { impl_->DescribeNegationTo(os); } // Explains why x matches, or doesn't match, the matcher. void ExplainMatchResultTo(T x, ::std::ostream* os) const { StreamMatchResultListener listener(os); MatchAndExplain(x, &listener); } protected: MatcherBase() {} // Constructs a matcher from its implementation. explicit MatcherBase(const MatcherInterface<T>* impl) : impl_(impl) {} virtual ~MatcherBase() {} private: // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar // interfaces. The former dynamically allocates a chunk of memory // to hold the reference count, while the latter tracks all // references using a circular linked list without allocating // memory. It has been observed that linked_ptr performs better in // typical scenarios. However, shared_ptr can out-perform // linked_ptr when there are many more uses of the copy constructor // than the default constructor. // // If performance becomes a problem, we should see if using // shared_ptr helps. ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_; }; -// The default implementation of ExplainMatchResultTo() for -// polymorphic matchers. -template <typename PolymorphicMatcherImpl, typename T> -inline void ExplainMatchResultTo(const PolymorphicMatcherImpl& /* impl */, - const T& /* x */, - ::std::ostream* /* os */) { - // By default, nothing more needs to be said, as Google Mock already - // prints the value of x elsewhere. -} - -// The default implementation of MatchAndExplain() for polymorphic -// matchers. The type of argument x cannot be const T&, in case -// impl.Matches() takes a non-const reference. -template <typename PolymorphicMatcherImpl, typename T> -inline bool MatchAndExplain(const PolymorphicMatcherImpl& impl, - T& x, - MatchResultListener* listener) { - const bool match = impl.Matches(x); - - ::std::ostream* const os = listener->stream(); - if (os != NULL) { - using ::testing::internal::ExplainMatchResultTo; - // When resolving the following call, both - // ::testing::internal::ExplainMatchResultTo() and - // foo::ExplainMatchResultTo() are considered, where foo is the - // namespace where class PolymorphicMatcherImpl is defined. - ExplainMatchResultTo(impl, x, os); - } - - return match; -} - } // 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 linked_ptr to const // MatcherInterface<T>, so copying is fairly cheap. 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. Matcher() {} // Constructs a matcher from its implementation. explicit Matcher(const MatcherInterface<T>* impl) : internal::MatcherBase<T>(impl) {} // 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 string // matcher is expected. template <> class Matcher<const internal::string&> : public internal::MatcherBase<const internal::string&> { public: Matcher() {} explicit Matcher(const MatcherInterface<const internal::string&>* impl) : internal::MatcherBase<const internal::string&>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where // str is a string object. Matcher(const internal::string& s); // NOLINT // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; template <> class Matcher<internal::string> : public internal::MatcherBase<internal::string> { public: Matcher() {} explicit Matcher(const MatcherInterface<internal::string>* impl) : internal::MatcherBase<internal::string>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where // str is a string object. Matcher(const internal::string& s); // NOLINT // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; // 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 in the old, deprecated way, a user -// first provides an Impl class that has a Matches() method, a -// DescribeTo() method, and a DescribeNegationTo() method. The -// Matches() method is usually a method template (such that it works -// with multiple types). Then the user creates the polymorphic -// matcher using MakePolymorphicMatcher(). To provide additional -// explanation to the match result, define a FREE function (or -// function template) -// -// void ExplainMatchResultTo(const Impl& matcher, const Value& value, -// ::std::ostream* os); -// -// in the SAME NAME SPACE where Impl is defined. -// -// The new, recommended way to define a polymorphic matcher is to -// provide an Impl class that has a DescribeTo() method and a -// DescribeNegationTo() method, and define a FREE function (or -// function template) +// 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 Impl& matcher, const Value& value, -// MatchResultListener* listener); -// -// in the SAME NAME SPACE where Impl is defined. +// 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<T>(impl_)); } private: template <typename T> class MonomorphicImpl : public MatcherInterface<T> { public: explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { impl_.DescribeNegationTo(os); } virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - // C++ uses Argument-Dependent Look-up (aka Koenig Look-up) to - // resolve the call to MatchAndExplain() here. This means that - // if there's a MatchAndExplain() function defined in the name - // space where class Impl is defined, it will be picked by the - // compiler as the better match. Otherwise the default - // implementation of it in ::testing::internal will be picked. - using ::testing::internal::MatchAndExplain; - return MatchAndExplain(impl_, x, listener); + return impl_.MatchAndExplain(x, listener); } private: const Impl impl_; GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); }; Impl impl_; GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); }; // Creates a matcher from its implementation. This is easier to use // than the Matcher<T> constructor as it doesn't require you to // explicitly write the template argument, e.g. // // MakeMatcher(foo); // vs // Matcher<const string&>(foo); 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); } // In order to be safe and clear, casting between different matcher // types is done explicitly via MatcherCast<T>(m), which takes a // matcher m and returns a Matcher<T>. It compiles only when T can be // statically converted to the argument type of m. template <typename T, typename M> Matcher<T> MatcherCast(M m); // Implements SafeMatcherCast(). // // We use an intermediate class to do the actual safe casting as Nokia's // Symbian compiler cannot decide between // template <T, M> ... (M) and // template <T, U> ... (const Matcher<U>&) // for function templates but can for member function templates. template <typename T> class SafeMatcherCastImpl { public: // This overload handles polymorphic matchers only since monomorphic // matchers are handled by the next one. template <typename M> static inline Matcher<T> Cast(M polymorphic_matcher) { return Matcher<T>(polymorphic_matcher); } // This overload handles monomorphic matchers. // // In general, if type T can be implicitly converted to type U, we can // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is // contravariant): just keep a copy of the original Matcher<U>, convert the // argument from type T to U, and then pass it to the underlying Matcher<U>. // The only exception is when U is a reference and T is not, as the // underlying Matcher<U> may be interested in the argument's address, which // is not preserved in the conversion from T to U. template <typename U> static inline Matcher<T> Cast(const Matcher<U>& matcher) { // Enforce that T can be implicitly converted to U. GMOCK_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value), T_must_be_implicitly_convertible_to_U); // Enforce that we are not converting a non-reference type T to a reference // type U. GMOCK_COMPILE_ASSERT_( internal::is_reference<T>::value || !internal::is_reference<U>::value, cannot_convert_non_referentce_arg_to_reference); // In case both T and U are arithmetic types, enforce that the // conversion is not lossy. typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(T)) RawT; typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(U)) RawU; const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; GMOCK_COMPILE_ASSERT_( kTIsOther || kUIsOther || (internal::LosslessArithmeticConvertible<RawT, RawU>::value), conversion_of_arithmetic_types_must_be_lossless); return MatcherCast<T>(matcher); } }; template <typename T, typename M> inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); } // A<T>() returns a matcher that matches any value of type T. template <typename T> Matcher<T> A(); // Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION // and MUST NOT BE USED IN USER CODE!!! namespace internal { // If the given string is not empty and os is not NULL, wraps the // string inside a pair of parentheses and streams the result to os. inline void StreamInParensAsNeeded(const internal::string& str, ::std::ostream* os) { if (!str.empty() && os != NULL) { *os << " (" << str << ")"; } } // An internal helper class for doing compile-time loop on a tuple's // fields. template <size_t N> class TuplePrefix { public: // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true // iff the first N fields of matcher_tuple matches the first N // fields of value_tuple, respectively. template <typename MatcherTuple, typename ValueTuple> static bool Matches(const MatcherTuple& matcher_tuple, const ValueTuple& value_tuple) { using ::std::tr1::get; return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple)); } // TuplePrefix<N>::DescribeMatchFailuresTo(matchers, values, os) // describes failures in matching the first N fields of matchers // against the first N fields of values. If there is no failure, // nothing will be streamed to os. template <typename MatcherTuple, typename ValueTuple> static void DescribeMatchFailuresTo(const MatcherTuple& matchers, const ValueTuple& values, ::std::ostream* os) { using ::std::tr1::tuple_element; using ::std::tr1::get; // First, describes failures in the first N - 1 fields. TuplePrefix<N - 1>::DescribeMatchFailuresTo(matchers, values, os); // Then describes the failure (if any) in the (N - 1)-th (0-based) // field. typename tuple_element<N - 1, MatcherTuple>::type matcher = get<N - 1>(matchers); typedef typename tuple_element<N - 1, ValueTuple>::type Value; Value value = get<N - 1>(values); StringMatchResultListener listener; if (!matcher.MatchAndExplain(value, &listener)) { // TODO(wan): include in the message the name of the parameter // as used in MOCK_METHOD*() when possible. *os << " Expected arg #" << N - 1 << ": "; get<N - 1>(matchers).DescribeTo(os); *os << "\n Actual: "; // We remove the reference in type Value to prevent the // universal printer from printing the address of value, which // isn't interesting to the user most of the time. The - // matcher's ExplainMatchResultTo() method handles the case when + // matcher's MatchAndExplain() method handles the case when // the address is interesting. internal::UniversalPrinter<GMOCK_REMOVE_REFERENCE_(Value)>:: Print(value, os); StreamInParensAsNeeded(listener.str(), os); *os << "\n"; } } }; // The base case. template <> class TuplePrefix<0> { public: template <typename MatcherTuple, typename ValueTuple> static bool Matches(const MatcherTuple& /* matcher_tuple */, const ValueTuple& /* value_tuple */) { return true; } template <typename MatcherTuple, typename ValueTuple> static void DescribeMatchFailuresTo(const MatcherTuple& /* matchers */, const ValueTuple& /* values */, ::std::ostream* /* os */) {} }; // TupleMatches(matcher_tuple, value_tuple) returns true iff all // matchers in matcher_tuple match the corresponding fields in // value_tuple. It is a compiler error if matcher_tuple and // value_tuple have different number of fields or incompatible field // types. template <typename MatcherTuple, typename ValueTuple> bool TupleMatches(const MatcherTuple& matcher_tuple, const ValueTuple& value_tuple) { using ::std::tr1::tuple_size; // Makes sure that matcher_tuple and value_tuple have the same // number of fields. GMOCK_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value == tuple_size<ValueTuple>::value, matcher_and_value_have_different_numbers_of_fields); return TuplePrefix<tuple_size<ValueTuple>::value>:: Matches(matcher_tuple, value_tuple); } // Describes failures in matching matchers against values. If there // is no failure, nothing will be streamed to os. template <typename MatcherTuple, typename ValueTuple> void DescribeMatchFailureTupleTo(const MatcherTuple& matchers, const ValueTuple& values, ::std::ostream* os) { using ::std::tr1::tuple_size; TuplePrefix<tuple_size<MatcherTuple>::value>::DescribeMatchFailuresTo( matchers, values, os); } // The MatcherCastImpl class template is a helper for implementing // MatcherCast(). We need this helper in order to partially // specialize the implementation of MatcherCast() (C++ allows // class/struct templates to be partially specialized, but not // function templates.). // This general version is used when MatcherCast()'s argument is a // polymorphic matcher (i.e. something that can be converted to a // Matcher but is not one yet; for example, Eq(value)). template <typename T, typename M> class MatcherCastImpl { public: static Matcher<T> Cast(M polymorphic_matcher) { return Matcher<T>(polymorphic_matcher); } }; // This more specialized version is used when MatcherCast()'s argument // is already a Matcher. This only compiles when type T can be // statically converted to type U. template <typename T, typename U> class MatcherCastImpl<T, Matcher<U> > { public: static Matcher<T> Cast(const Matcher<U>& source_matcher) { return Matcher<T>(new Impl(source_matcher)); } private: class Impl : public MatcherInterface<T> { public: explicit Impl(const Matcher<U>& source_matcher) : source_matcher_(source_matcher) {} // We delegate the matching logic to the source matcher. virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); } virtual void DescribeTo(::std::ostream* os) const { source_matcher_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { source_matcher_.DescribeNegationTo(os); } private: const Matcher<U> source_matcher_; GTEST_DISALLOW_ASSIGN_(Impl); }; }; // This even more specialized version is used for efficiently casting // a matcher to its own type. template <typename T> class MatcherCastImpl<T, Matcher<T> > { public: static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } }; // Implements A<T>(). template <typename T> class AnyMatcherImpl : public MatcherInterface<T> { public: virtual bool MatchAndExplain( T /* x */, MatchResultListener* /* listener */) const { return true; } virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } virtual void DescribeNegationTo(::std::ostream* os) const { // This is mostly for completeness' safe, as it's not very useful // to write Not(A<bool>()). However we cannot completely rule out // such a possibility, and it doesn't hurt to be prepared. *os << "never matches"; } }; // Implements _, a matcher that matches any value of any // type. This is a polymorphic matcher, so we need a template type // conversion operator to make it appearing as a Matcher<T> for any // type T. class AnythingMatcher { public: template <typename T> operator Matcher<T>() const { return A<T>(); } }; // 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. // // We define this as a macro in order to eliminate duplicated source // code. // // The following template definition assumes that the Rhs parameter is // a "bare" type (i.e. neither 'const T' nor 'T&'). #define GMOCK_IMPLEMENT_COMPARISON_MATCHER_(name, op, relation) \ template <typename Rhs> class name##Matcher { \ public: \ explicit name##Matcher(const Rhs& rhs) : rhs_(rhs) {} \ template <typename Lhs> \ operator Matcher<Lhs>() const { \ return MakeMatcher(new Impl<Lhs>(rhs_)); \ } \ private: \ template <typename Lhs> \ class Impl : public MatcherInterface<Lhs> { \ public: \ explicit Impl(const Rhs& rhs) : rhs_(rhs) {} \ virtual bool MatchAndExplain(\ Lhs lhs, MatchResultListener* /* listener */) const { \ return lhs op rhs_; \ } \ virtual void DescribeTo(::std::ostream* os) const { \ *os << "is " relation " "; \ UniversalPrinter<Rhs>::Print(rhs_, os); \ } \ virtual void DescribeNegationTo(::std::ostream* os) const { \ *os << "is not " relation " "; \ UniversalPrinter<Rhs>::Print(rhs_, os); \ } \ private: \ Rhs rhs_; \ GTEST_DISALLOW_ASSIGN_(Impl); \ }; \ Rhs rhs_; \ GTEST_DISALLOW_ASSIGN_(name##Matcher); \ } // Implements Eq(v), Ge(v), Gt(v), Le(v), Lt(v), and Ne(v) // respectively. GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Eq, ==, "equal to"); GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ge, >=, "greater than or equal to"); GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Gt, >, "greater than"); GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Le, <=, "less than or equal to"); GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Lt, <, "less than"); GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ne, !=, "not equal to"); #undef GMOCK_IMPLEMENT_COMPARISON_MATCHER_ // Implements the polymorphic IsNull() matcher, which matches any raw or smart // pointer that is NULL. class IsNullMatcher { public: template <typename Pointer> - bool Matches(const Pointer& p) const { return GetRawPointer(p) == NULL; } + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return GetRawPointer(p) == NULL; + } void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } void DescribeNegationTo(::std::ostream* os) const { *os << "is not NULL"; } }; -template <typename Pointer> -bool MatchAndExplain(const IsNullMatcher& impl, Pointer& p, - MatchResultListener* /* listener */) { - return impl.Matches(p); -} - // Implements the polymorphic NotNull() matcher, which matches any raw or smart // pointer that is not NULL. class NotNullMatcher { public: template <typename Pointer> - bool Matches(const Pointer& p) const { return GetRawPointer(p) != NULL; } + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return GetRawPointer(p) != NULL; + } void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } }; -template <typename Pointer> -bool MatchAndExplain(const NotNullMatcher& impl, Pointer& p, - MatchResultListener* /* listener */) { - return impl.Matches(p); -} - // Ref(variable) matches any argument that is a reference to // 'variable'. This matcher is polymorphic as it can match any // super type of the type of 'variable'. // // The RefMatcher template class implements Ref(variable). It can // only be instantiated with a reference type. This prevents a user // from mistakenly using Ref(x) to match a non-reference function // argument. For example, the following will righteously cause a // compiler error: // // int n; // Matcher<int> m1 = Ref(n); // This won't compile. // Matcher<int&> m2 = Ref(n); // This will compile. template <typename T> class RefMatcher; template <typename T> class RefMatcher<T&> { // Google Mock is a generic framework and thus needs to support // mocking any function types, including those that take non-const // reference arguments. Therefore the template parameter T (and // Super below) can be instantiated to either a const type or a // non-const type. public: // RefMatcher() takes a T& instead of const T&, as we want the // compiler to catch using Ref(const_value) as a matcher for a // non-const reference. explicit RefMatcher(T& x) : object_(x) {} // NOLINT template <typename Super> operator Matcher<Super&>() const { // By passing object_ (type T&) to Impl(), which expects a Super&, // we make sure that Super is a super type of T. In particular, // this catches using Ref(const_value) as a matcher for a // non-const reference, as you cannot implicitly convert a const // reference to a non-const reference. return MakeMatcher(new Impl<Super>(object_)); } private: template <typename Super> class Impl : public MatcherInterface<Super&> { public: explicit Impl(Super& x) : object_(x) {} // NOLINT - // Matches() takes a Super& (as opposed to const Super&) in - // order to match the interface MatcherInterface<Super&>. + // MatchAndExplain() takes a Super& (as opposed to const Super&) + // in order to match the interface MatcherInterface<Super&>. virtual bool MatchAndExplain( Super& x, MatchResultListener* listener) const { *listener << "is located @" << static_cast<const void*>(&x); return &x == &object_; } virtual void DescribeTo(::std::ostream* os) const { *os << "references the variable "; UniversalPrinter<Super&>::Print(object_, os); } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "does not reference the variable "; UniversalPrinter<Super&>::Print(object_, os); } private: const Super& object_; GTEST_DISALLOW_ASSIGN_(Impl); }; T& object_; GTEST_DISALLOW_ASSIGN_(RefMatcher); }; // Polymorphic helper functions for narrow and wide string matchers. inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { return String::CaseInsensitiveCStringEquals(lhs, rhs); } inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { return String::CaseInsensitiveWideCStringEquals(lhs, rhs); } // String comparison for narrow or wide strings that can have embedded NUL // characters. template <typename StringType> bool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) { // Are the heads equal? if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { return false; } // Skip the equal heads. const typename StringType::value_type nul = 0; const size_t i1 = s1.find(nul), i2 = s2.find(nul); // Are we at the end of either s1 or s2? if (i1 == StringType::npos || i2 == StringType::npos) { return i1 == i2; } // Are the tails equal? return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); } // String matchers. // Implements equality-based string matchers like StrEq, StrCaseNe, and etc. template <typename StringType> class StrEqualityMatcher { public: typedef typename StringType::const_pointer ConstCharPointer; StrEqualityMatcher(const StringType& str, bool expect_eq, bool case_sensitive) : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} // When expect_eq_ is true, returns true iff s is equal to string_; // otherwise returns true iff s is not equal to string_. - bool Matches(ConstCharPointer s) const { + bool MatchAndExplain(ConstCharPointer s, + MatchResultListener* listener) const { if (s == NULL) { return !expect_eq_; } - return Matches(StringType(s)); + return MatchAndExplain(StringType(s), listener); } - bool Matches(const StringType& s) const { + bool MatchAndExplain(const StringType& s, + MatchResultListener* /* listener */) const { const bool eq = case_sensitive_ ? s == string_ : CaseInsensitiveStringEquals(s, string_); return expect_eq_ == eq; } void DescribeTo(::std::ostream* os) const { DescribeToHelper(expect_eq_, os); } void DescribeNegationTo(::std::ostream* os) const { DescribeToHelper(!expect_eq_, os); } private: void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { *os << "is "; if (!expect_eq) { *os << "not "; } *os << "equal to "; if (!case_sensitive_) { *os << "(ignoring case) "; } UniversalPrinter<StringType>::Print(string_, os); } const StringType string_; const bool expect_eq_; const bool case_sensitive_; GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); }; -template <typename StringType, typename T> -bool MatchAndExplain(const StrEqualityMatcher<StringType>& impl, T& s, - MatchResultListener* /* listener */) { - return impl.Matches(s); -} - // Implements the polymorphic HasSubstr(substring) matcher, which // can be used as a Matcher<T> as long as T can be converted to a // string. template <typename StringType> class HasSubstrMatcher { public: typedef typename StringType::const_pointer ConstCharPointer; explicit HasSubstrMatcher(const StringType& substring) : substring_(substring) {} // These overloaded methods allow HasSubstr(substring) to be used as a // Matcher<T> as long as T can be converted to string. Returns true // iff s contains substring_ as a substring. - bool Matches(ConstCharPointer s) const { - return s != NULL && Matches(StringType(s)); + bool MatchAndExplain(ConstCharPointer s, + MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); } - bool Matches(const StringType& s) const { + bool MatchAndExplain(const StringType& s, + MatchResultListener* /* listener */) const { return s.find(substring_) != StringType::npos; } // Describes what this matcher matches. void DescribeTo(::std::ostream* os) const { *os << "has substring "; UniversalPrinter<StringType>::Print(substring_, os); } void DescribeNegationTo(::std::ostream* os) const { *os << "has no substring "; UniversalPrinter<StringType>::Print(substring_, os); } private: const StringType substring_; GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); }; -template <typename StringType, typename T> -bool MatchAndExplain(const HasSubstrMatcher<StringType>& impl, T& s, - MatchResultListener* /* listener */) { - return impl.Matches(s); -} - // Implements the polymorphic StartsWith(substring) matcher, which // can be used as a Matcher<T> as long as T can be converted to a // string. template <typename StringType> class StartsWithMatcher { public: typedef typename StringType::const_pointer ConstCharPointer; explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { } // These overloaded methods allow StartsWith(prefix) to be used as a // Matcher<T> as long as T can be converted to string. Returns true // iff s starts with prefix_. - bool Matches(ConstCharPointer s) const { - return s != NULL && Matches(StringType(s)); + bool MatchAndExplain(ConstCharPointer s, + MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); } - bool Matches(const StringType& s) const { + bool MatchAndExplain(const StringType& s, + MatchResultListener* /* listener */) const { return s.length() >= prefix_.length() && s.substr(0, prefix_.length()) == prefix_; } void DescribeTo(::std::ostream* os) const { *os << "starts with "; UniversalPrinter<StringType>::Print(prefix_, os); } void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't start with "; UniversalPrinter<StringType>::Print(prefix_, os); } private: const StringType prefix_; GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); }; -template <typename StringType, typename T> -bool MatchAndExplain(const StartsWithMatcher<StringType>& impl, T& s, - MatchResultListener* /* listener */) { - return impl.Matches(s); -} - // Implements the polymorphic EndsWith(substring) matcher, which // can be used as a Matcher<T> as long as T can be converted to a // string. template <typename StringType> class EndsWithMatcher { public: typedef typename StringType::const_pointer ConstCharPointer; explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} // These overloaded methods allow EndsWith(suffix) to be used as a // Matcher<T> as long as T can be converted to string. Returns true // iff s ends with suffix_. - bool Matches(ConstCharPointer s) const { - return s != NULL && Matches(StringType(s)); + bool MatchAndExplain(ConstCharPointer s, + MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); } - bool Matches(const StringType& s) const { + bool MatchAndExplain(const StringType& s, + MatchResultListener* /* listener */) const { return s.length() >= suffix_.length() && s.substr(s.length() - suffix_.length()) == suffix_; } void DescribeTo(::std::ostream* os) const { *os << "ends with "; UniversalPrinter<StringType>::Print(suffix_, os); } void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't end with "; UniversalPrinter<StringType>::Print(suffix_, os); } private: const StringType suffix_; GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); }; -template <typename StringType, typename T> -bool MatchAndExplain(const EndsWithMatcher<StringType>& impl, T& s, - MatchResultListener* /* listener */) { - return impl.Matches(s); -} - // 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) {} // These overloaded methods allow MatchesRegex(regex) to be used as // a Matcher<T> as long as T can be converted to string. Returns // true iff s matches regular expression regex. When full_match_ is // true, a full match is done; otherwise a partial match is done. - bool Matches(const char* s) const { - return s != NULL && Matches(internal::string(s)); + bool MatchAndExplain(const char* s, + MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(internal::string(s), listener); } - bool Matches(const internal::string& s) const { + bool MatchAndExplain(const internal::string& s, + MatchResultListener* /* listener */) const { return full_match_ ? RE::FullMatch(s, *regex_) : RE::PartialMatch(s, *regex_); } void DescribeTo(::std::ostream* os) const { *os << (full_match_ ? "matches" : "contains") << " regular expression "; UniversalPrinter<internal::string>::Print(regex_->pattern(), os); } void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't " << (full_match_ ? "match" : "contain") << " regular expression "; UniversalPrinter<internal::string>::Print(regex_->pattern(), os); } private: const internal::linked_ptr<const RE> regex_; const bool full_match_; GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); }; -template <typename T> -bool MatchAndExplain(const MatchesRegexMatcher& impl, T& s, - MatchResultListener* /* listener */) { - return impl.Matches(s); -} - // Implements a matcher that compares the two fields of a 2-tuple // using one of the ==, <=, <, etc, operators. The two fields being // compared don't have to have the same type. // // The matcher defined here is polymorphic (for example, Eq() can be // used to match a tuple<int, short>, a tuple<const long&, double>, // etc). Therefore we use a template type conversion operator in the // implementation. // // We define this as a macro in order to eliminate duplicated source // code. #define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op) \ class name##2Matcher { \ public: \ template <typename T1, typename T2> \ operator Matcher<const ::std::tr1::tuple<T1, T2>&>() const { \ return MakeMatcher(new Impl<T1, T2>); \ } \ private: \ template <typename T1, typename T2> \ class Impl : public MatcherInterface<const ::std::tr1::tuple<T1, T2>&> { \ public: \ virtual bool MatchAndExplain( \ const ::std::tr1::tuple<T1, T2>& args, \ MatchResultListener* /* listener */) const { \ return ::std::tr1::get<0>(args) op ::std::tr1::get<1>(args); \ } \ virtual void DescribeTo(::std::ostream* os) const { \ *os << "are a pair (x, y) where x " #op " y"; \ } \ virtual void DescribeNegationTo(::std::ostream* os) const { \ *os << "are a pair (x, y) where x " #op " y is false"; \ } \ }; \ } // Implements Eq(), Ge(), Gt(), Le(), Lt(), and Ne() respectively. GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Eq, ==); GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ge, >=); GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Gt, >); GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Le, <=); GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Lt, <); GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=); #undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_ // Implements the Not(...) matcher for a particular argument type T. // We do not nest it inside the NotMatcher class template, as that // will prevent different instantiations of NotMatcher from sharing // the same NotMatcherImpl<T> class. template <typename T> class NotMatcherImpl : public MatcherInterface<T> { public: explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {} virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { return !matcher_.MatchAndExplain(x, listener); } virtual void DescribeTo(::std::ostream* os) const { matcher_.DescribeNegationTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { matcher_.DescribeTo(os); } private: const Matcher<T> matcher_; GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); }; // Implements the Not(m) matcher, which matches a value that doesn't // match matcher m. template <typename InnerMatcher> class NotMatcher { public: explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} // This template type conversion operator allows Not(m) to be used // to match any type m can match. template <typename T> operator Matcher<T>() const { return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); } private: InnerMatcher matcher_; GTEST_DISALLOW_ASSIGN_(NotMatcher); }; // Implements the AllOf(m1, m2) matcher for a particular argument type // T. We do not nest it inside the BothOfMatcher class template, as // that will prevent different instantiations of BothOfMatcher from // sharing the same BothOfMatcherImpl<T> class. template <typename T> class BothOfMatcherImpl : public MatcherInterface<T> { public: BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) : matcher1_(matcher1), matcher2_(matcher2) {} virtual void DescribeTo(::std::ostream* os) const { *os << "("; matcher1_.DescribeTo(os); *os << ") and ("; matcher2_.DescribeTo(os); *os << ")"; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "not "; DescribeTo(os); } virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { // If either matcher1_ or matcher2_ doesn't match x, we only need // to explain why one of them fails. StringMatchResultListener listener1; if (!matcher1_.MatchAndExplain(x, &listener1)) { *listener << listener1.str(); return false; } StringMatchResultListener listener2; if (!matcher2_.MatchAndExplain(x, &listener2)) { *listener << listener2.str(); return false; } // Otherwise we need to explain why *both* of them match. const internal::string s1 = listener1.str(); const internal::string s2 = listener2.str(); if (s1 == "") { *listener << s2; } else { *listener << s1; if (s2 != "") { *listener << "; " << s2; } } return true; } private: const Matcher<T> matcher1_; const Matcher<T> matcher2_; GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); }; // Used for implementing the AllOf(m_1, ..., m_n) matcher, which // matches a value that matches all of the matchers m_1, ..., and m_n. template <typename Matcher1, typename Matcher2> class BothOfMatcher { public: BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2) : matcher1_(matcher1), matcher2_(matcher2) {} // This template type conversion operator allows a // BothOfMatcher<Matcher1, Matcher2> object to match any type that // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_))); } private: Matcher1 matcher1_; Matcher2 matcher2_; GTEST_DISALLOW_ASSIGN_(BothOfMatcher); }; // Implements the AnyOf(m1, m2) matcher for a particular argument type // T. We do not nest it inside the AnyOfMatcher class template, as // that will prevent different instantiations of AnyOfMatcher from // sharing the same EitherOfMatcherImpl<T> class. template <typename T> class EitherOfMatcherImpl : public MatcherInterface<T> { public: EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) : matcher1_(matcher1), matcher2_(matcher2) {} virtual void DescribeTo(::std::ostream* os) const { *os << "("; matcher1_.DescribeTo(os); *os << ") or ("; matcher2_.DescribeTo(os); *os << ")"; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "not "; DescribeTo(os); } virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { // If either matcher1_ or matcher2_ matches x, we just need to // explain why *one* of them matches. StringMatchResultListener listener1; if (matcher1_.MatchAndExplain(x, &listener1)) { *listener << listener1.str(); return true; } StringMatchResultListener listener2; if (matcher2_.MatchAndExplain(x, &listener2)) { *listener << listener2.str(); return true; } // Otherwise we need to explain why *both* of them fail. const internal::string s1 = listener1.str(); const internal::string s2 = listener2.str(); if (s1 == "") { *listener << s2; } else { *listener << s1; if (s2 != "") { *listener << "; " << s2; } } return false; } private: const Matcher<T> matcher1_; const Matcher<T> matcher2_; GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl); }; // Used for implementing the AnyOf(m_1, ..., m_n) matcher, which // matches a value that matches at least one of the matchers m_1, ..., // and m_n. template <typename Matcher1, typename Matcher2> class EitherOfMatcher { public: EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2) : matcher1_(matcher1), matcher2_(matcher2) {} // This template type conversion operator allows a // EitherOfMatcher<Matcher1, Matcher2> object to match any type that // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { return Matcher<T>(new EitherOfMatcherImpl<T>( SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_))); } private: Matcher1 matcher1_; Matcher2 matcher2_; GTEST_DISALLOW_ASSIGN_(EitherOfMatcher); }; // Used for implementing Truly(pred), which turns a predicate into a // matcher. template <typename Predicate> class TrulyMatcher { public: explicit TrulyMatcher(Predicate pred) : predicate_(pred) {} // This method template allows Truly(pred) to be used as a matcher // for type T where T is the argument type of predicate 'pred'. The // argument is passed by reference as the predicate may be // interested in the address of the argument. template <typename T> - bool Matches(T& x) const { // NOLINT + bool MatchAndExplain(T& x, // NOLINT + MatchResultListener* /* listener */) const { #if GTEST_OS_WINDOWS // MSVC warns about converting a value into bool (warning 4800). #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4800) // Temporarily disables warning 4800. #endif // GTEST_OS_WINDOWS return predicate_(x); #if GTEST_OS_WINDOWS #pragma warning(pop) // Restores the warning state. #endif // GTEST_OS_WINDOWS } void DescribeTo(::std::ostream* os) const { *os << "satisfies the given predicate"; } void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't satisfy the given predicate"; } private: Predicate predicate_; GTEST_DISALLOW_ASSIGN_(TrulyMatcher); }; -template <typename Predicate, typename T> -bool MatchAndExplain(const TrulyMatcher<Predicate>& impl, T& x, - MatchResultListener* /* listener */) { - return impl.Matches(x); -} - // Used for implementing Matches(matcher), which turns a matcher into // a predicate. template <typename M> class MatcherAsPredicate { public: explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {} // This template operator() allows Matches(m) to be used as a // predicate on type T where m is a matcher on type T. // // The argument x is passed by reference instead of by value, as // some matcher may be interested in its address (e.g. as in // Matches(Ref(n))(x)). template <typename T> bool operator()(const T& x) const { // We let matcher_ commit to a particular type here instead of // when the MatcherAsPredicate object was constructed. This // allows us to write Matches(m) where m is a polymorphic matcher // (e.g. Eq(5)). // // If we write Matcher<T>(matcher_).Matches(x) here, it won't // compile when matcher_ has type Matcher<const T&>; if we write // Matcher<const T&>(matcher_).Matches(x) here, it won't compile // when matcher_ has type Matcher<T>; if we just write // matcher_.Matches(x), it won't compile when matcher_ is // polymorphic, e.g. Eq(5). // // MatcherCast<const T&>() is necessary for making the code work // in all of the above situations. return MatcherCast<const T&>(matcher_).Matches(x); } private: M matcher_; GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate); }; // For implementing ASSERT_THAT() and EXPECT_THAT(). The template // argument M must be a type that can be converted to a matcher. template <typename M> class PredicateFormatterFromMatcher { public: explicit PredicateFormatterFromMatcher(const M& m) : matcher_(m) {} // This template () operator allows a PredicateFormatterFromMatcher // object to act as a predicate-formatter suitable for using with // Google Test's EXPECT_PRED_FORMAT1() macro. template <typename T> AssertionResult operator()(const char* value_text, const T& x) const { // We convert matcher_ to a Matcher<const T&> *now* instead of // when the PredicateFormatterFromMatcher object was constructed, // as matcher_ may be polymorphic (e.g. NotNull()) and we won't // know which type to instantiate it to until we actually see the // type of x here. // // We write MatcherCast<const T&>(matcher_) instead of // Matcher<const T&>(matcher_), as the latter won't compile when // matcher_ has type Matcher<T> (e.g. An<int>()). const Matcher<const T&> matcher = MatcherCast<const T&>(matcher_); StringMatchResultListener listener; if (matcher.MatchAndExplain(x, &listener)) { return AssertionSuccess(); } else { ::std::stringstream ss; ss << "Value of: " << value_text << "\n" << "Expected: "; matcher.DescribeTo(&ss); ss << "\n Actual: "; UniversalPrinter<T>::Print(x, &ss); StreamInParensAsNeeded(listener.str(), &ss); return AssertionFailure(Message() << ss.str()); } } private: const M matcher_; GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher); }; // A helper function for converting a matcher to a predicate-formatter // without the user needing to explicitly write the type. This is // used for implementing ASSERT_THAT() and EXPECT_THAT(). template <typename M> inline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher(const M& matcher) { return PredicateFormatterFromMatcher<M>(matcher); } // Implements the polymorphic floating point equality matcher, which // matches two float values using ULP-based approximation. The // template is meant to be instantiated with FloatType being either // float or double. template <typename FloatType> class FloatingEqMatcher { public: // Constructor for FloatingEqMatcher. // The matcher's input will be compared with rhs. The matcher treats two // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, // equality comparisons between NANs will always return false. FloatingEqMatcher(FloatType rhs, bool nan_eq_nan) : rhs_(rhs), nan_eq_nan_(nan_eq_nan) {} // Implements floating point equality matcher as a Matcher<T>. template <typename T> class Impl : public MatcherInterface<T> { public: Impl(FloatType rhs, bool nan_eq_nan) : rhs_(rhs), nan_eq_nan_(nan_eq_nan) {} virtual bool MatchAndExplain(T value, MatchResultListener* /* listener */) const { const FloatingPoint<FloatType> lhs(value), rhs(rhs_); // Compares NaNs first, if nan_eq_nan_ is true. if (nan_eq_nan_ && lhs.is_nan()) { return rhs.is_nan(); } return lhs.AlmostEquals(rhs); } virtual void DescribeTo(::std::ostream* os) const { // os->precision() returns the previously set precision, which we // store to restore the ostream to its original configuration // after outputting. const ::std::streamsize old_precision = os->precision( ::std::numeric_limits<FloatType>::digits10 + 2); if (FloatingPoint<FloatType>(rhs_).is_nan()) { if (nan_eq_nan_) { *os << "is NaN"; } else { *os << "never matches"; } } else { *os << "is approximately " << rhs_; } os->precision(old_precision); } virtual void DescribeNegationTo(::std::ostream* os) const { // As before, get original precision. const ::std::streamsize old_precision = os->precision( ::std::numeric_limits<FloatType>::digits10 + 2); if (FloatingPoint<FloatType>(rhs_).is_nan()) { if (nan_eq_nan_) { *os << "is not NaN"; } else { *os << "is anything"; } } else { *os << "is not approximately " << rhs_; } // Restore original precision. os->precision(old_precision); } private: const FloatType rhs_; const bool nan_eq_nan_; GTEST_DISALLOW_ASSIGN_(Impl); }; // The following 3 type conversion operators allow FloatEq(rhs) and // NanSensitiveFloatEq(rhs) to be used as a Matcher<float>, a // Matcher<const float&>, or a Matcher<float&>, but nothing else. // (While Google's C++ coding style doesn't allow arguments passed // by non-const reference, we may see them in code not conforming to // the style. Therefore Google Mock needs to support them.) operator Matcher<FloatType>() const { return MakeMatcher(new Impl<FloatType>(rhs_, nan_eq_nan_)); } operator Matcher<const FloatType&>() const { return MakeMatcher(new Impl<const FloatType&>(rhs_, nan_eq_nan_)); } operator Matcher<FloatType&>() const { return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_)); } private: const FloatType rhs_; const bool nan_eq_nan_; GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); }; // Implements the Pointee(m) matcher for matching a pointer whose // pointee matches matcher m. The pointer can be either raw or smart. template <typename InnerMatcher> class PointeeMatcher { public: explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} // This type conversion operator template allows Pointee(m) to be // used as a matcher for any pointer type whose pointee type is // compatible with the inner matcher, where type Pointer can be // either a raw pointer or a smart pointer. // // The reason we do this instead of relying on // MakePolymorphicMatcher() is that the latter is not flexible // enough for implementing the DescribeTo() method of Pointee(). template <typename Pointer> operator Matcher<Pointer>() const { return MakeMatcher(new Impl<Pointer>(matcher_)); } private: // The monomorphic implementation that works for a particular pointer type. template <typename Pointer> class Impl : public MatcherInterface<Pointer> { public: typedef typename PointeeOf<GMOCK_REMOVE_CONST_( // NOLINT GMOCK_REMOVE_REFERENCE_(Pointer))>::type Pointee; explicit Impl(const InnerMatcher& matcher) : matcher_(MatcherCast<const Pointee&>(matcher)) {} virtual void DescribeTo(::std::ostream* os) const { *os << "points to a value that "; matcher_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "does not point to a value that "; matcher_.DescribeTo(os); } virtual bool MatchAndExplain(Pointer pointer, MatchResultListener* listener) const { if (GetRawPointer(pointer) == NULL) return false; StringMatchResultListener inner_listener; const bool match = matcher_.MatchAndExplain(*pointer, &inner_listener); const internal::string s = inner_listener.str(); if (s != "") { *listener << "points to a value that " << s; } return match; } private: const Matcher<const Pointee&> matcher_; GTEST_DISALLOW_ASSIGN_(Impl); }; const InnerMatcher matcher_; GTEST_DISALLOW_ASSIGN_(PointeeMatcher); }; // Implements the Field() matcher for matching a field (i.e. member // variable) of an object. template <typename Class, typename FieldType> class FieldMatcher { public: FieldMatcher(FieldType Class::*field, const Matcher<const FieldType&>& matcher) : field_(field), matcher_(matcher) {} void DescribeTo(::std::ostream* os) const { *os << "the given field "; matcher_.DescribeTo(os); } void DescribeNegationTo(::std::ostream* os) const { *os << "the given field "; matcher_.DescribeNegationTo(os); } - // The first argument of MatchAndExplain() is needed to help + template <typename T> + bool MatchAndExplain(const T& value, MatchResultListener* listener) const { + return MatchAndExplainImpl( + typename ::testing::internal:: + is_pointer<GMOCK_REMOVE_CONST_(T)>::type(), + value, listener); + } + + private: + // The first argument of MatchAndExplainImpl() is needed to help // Symbian's C++ compiler choose which overload to use. Its type is // true_type iff the Field() matcher is used to match a pointer. - bool MatchAndExplain(false_type /* is_not_pointer */, const Class& obj, - MatchResultListener* listener) const { + bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + MatchResultListener* listener) const { StringMatchResultListener inner_listener; const bool match = matcher_.MatchAndExplain(obj.*field_, &inner_listener); const internal::string s = inner_listener.str(); if (s != "") { *listener << "the given field " << s; } return match; } - bool MatchAndExplain(true_type /* is_pointer */, const Class* p, - MatchResultListener* listener) const { + bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, + MatchResultListener* listener) const { if (p == NULL) return false; // Since *p has a field, it must be a class/struct/union type and // thus cannot be a pointer. Therefore we pass false_type() as // the first argument. - return MatchAndExplain(false_type(), *p, listener); + return MatchAndExplainImpl(false_type(), *p, listener); } - private: const FieldType Class::*field_; const Matcher<const FieldType&> matcher_; GTEST_DISALLOW_ASSIGN_(FieldMatcher); }; -template <typename Class, typename FieldType, typename T> -bool MatchAndExplain(const FieldMatcher<Class, FieldType>& matcher, - T& value, MatchResultListener* listener) { - return matcher.MatchAndExplain( - typename ::testing::internal::is_pointer<GMOCK_REMOVE_CONST_(T)>::type(), - value, listener); -} - // Implements the Property() matcher for matching a property // (i.e. return value of a getter method) of an object. template <typename Class, typename PropertyType> class PropertyMatcher { public: // The property may have a reference type, so 'const PropertyType&' // may cause double references and fail to compile. That's why we // need GMOCK_REFERENCE_TO_CONST, which works regardless of // PropertyType being a reference or not. typedef GMOCK_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; PropertyMatcher(PropertyType (Class::*property)() const, const Matcher<RefToConstProperty>& matcher) : property_(property), matcher_(matcher) {} void DescribeTo(::std::ostream* os) const { *os << "the given property "; matcher_.DescribeTo(os); } void DescribeNegationTo(::std::ostream* os) const { *os << "the given property "; matcher_.DescribeNegationTo(os); } - // The first argument of MatchAndExplain() is needed to help + template <typename T> + bool MatchAndExplain(const T&value, MatchResultListener* listener) const { + return MatchAndExplainImpl( + typename ::testing::internal:: + is_pointer<GMOCK_REMOVE_CONST_(T)>::type(), + value, listener); + } + + private: + // The first argument of MatchAndExplainImpl() is needed to help // Symbian's C++ compiler choose which overload to use. Its type is // true_type iff the Property() matcher is used to match a pointer. - bool MatchAndExplain(false_type /* is_not_pointer */, const Class& obj, - MatchResultListener* listener) const { + bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + MatchResultListener* listener) const { StringMatchResultListener inner_listener; const bool match = matcher_.MatchAndExplain((obj.*property_)(), &inner_listener); const internal::string s = inner_listener.str(); if (s != "") { *listener << "the given property " << s; } return match; } - bool MatchAndExplain(true_type /* is_pointer */, const Class* p, - MatchResultListener* listener) const { + bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, + MatchResultListener* listener) const { if (p == NULL) return false; // Since *p has a property method, it must be a class/struct/union // type and thus cannot be a pointer. Therefore we pass // false_type() as the first argument. - return MatchAndExplain(false_type(), *p, listener); + return MatchAndExplainImpl(false_type(), *p, listener); } - private: PropertyType (Class::*property_)() const; const Matcher<RefToConstProperty> matcher_; GTEST_DISALLOW_ASSIGN_(PropertyMatcher); }; -template <typename Class, typename PropertyType, typename T> -bool MatchAndExplain(const PropertyMatcher<Class, PropertyType>& matcher, - T& value, MatchResultListener* listener) { - return matcher.MatchAndExplain( - typename ::testing::internal::is_pointer<GMOCK_REMOVE_CONST_(T)>::type(), - value, listener); -} - // Type traits specifying various features of different functors for ResultOf. // The default template specifies features for functor objects. // Functor classes have to typedef argument_type and result_type // to be compatible with ResultOf. template <typename Functor> struct CallableTraits { typedef typename Functor::result_type ResultType; typedef Functor StorageType; static void CheckIsValid(Functor /* functor */) {} template <typename T> static ResultType Invoke(Functor f, T arg) { return f(arg); } }; // Specialization for function pointers. template <typename ArgType, typename ResType> struct CallableTraits<ResType(*)(ArgType)> { typedef ResType ResultType; typedef ResType(*StorageType)(ArgType); static void CheckIsValid(ResType(*f)(ArgType)) { GTEST_CHECK_(f != NULL) << "NULL function pointer is passed into ResultOf()."; } template <typename T> static ResType Invoke(ResType(*f)(ArgType), T arg) { return (*f)(arg); } }; // Implements the ResultOf() matcher for matching a return value of a // unary function of an object. template <typename Callable> class ResultOfMatcher { public: typedef typename CallableTraits<Callable>::ResultType ResultType; ResultOfMatcher(Callable callable, const Matcher<ResultType>& matcher) : callable_(callable), matcher_(matcher) { CallableTraits<Callable>::CheckIsValid(callable_); } template <typename T> operator Matcher<T>() const { return Matcher<T>(new Impl<T>(callable_, matcher_)); } private: typedef typename CallableTraits<Callable>::StorageType CallableStorageType; template <typename T> class Impl : public MatcherInterface<T> { public: Impl(CallableStorageType callable, const Matcher<ResultType>& matcher) : callable_(callable), matcher_(matcher) {} virtual void DescribeTo(::std::ostream* os) const { *os << "result of the given callable "; matcher_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "result of the given callable "; matcher_.DescribeNegationTo(os); } virtual bool MatchAndExplain(T obj, MatchResultListener* listener) const { StringMatchResultListener inner_listener; const bool match = matcher_.MatchAndExplain( CallableTraits<Callable>::template Invoke<T>(callable_, obj), &inner_listener); const internal::string s = inner_listener.str(); if (s != "") *listener << "result of the given callable " << s; return match; } private: // Functors often define operator() as non-const method even though // they are actualy stateless. But we need to use them even when // 'this' is a const pointer. It's the user's responsibility not to // use stateful callables with ResultOf(), which does't guarantee // how many times the callable will be invoked. mutable CallableStorageType callable_; const Matcher<ResultType> matcher_; GTEST_DISALLOW_ASSIGN_(Impl); }; // class Impl const CallableStorageType callable_; const Matcher<ResultType> matcher_; GTEST_DISALLOW_ASSIGN_(ResultOfMatcher); }; -// Explains the result of matching a value against a functor matcher. -template <typename T, typename Callable> -void ExplainMatchResultTo(const ResultOfMatcher<Callable>& matcher, - T obj, ::std::ostream* os) { - matcher.ExplainMatchResultTo(obj, os); -} - // Implements an equality matcher for any STL-style container whose elements // support ==. This matcher is like Eq(), but its failure explanations provide // more detailed information that is useful when the container is used as a set. // The failure message reports elements that are in one of the operands but not // the other. The failure messages do not report duplicate or out-of-order // elements in the containers (which don't properly matter to sets, but can // occur if the containers are vectors or lists, for example). // // Uses the container's const_iterator, value_type, operator ==, // begin(), and end(). template <typename Container> class ContainerEqMatcher { public: typedef internal::StlContainerView<Container> View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; // We make a copy of rhs in case the elements in it are modified // after this matcher is created. explicit ContainerEqMatcher(const Container& rhs) : rhs_(View::Copy(rhs)) { // Makes sure the user doesn't instantiate this class template // with a const or reference type. testing::StaticAssertTypeEq<Container, GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))>(); } void DescribeTo(::std::ostream* os) const { *os << "equals "; UniversalPrinter<StlContainer>::Print(rhs_, os); } void DescribeNegationTo(::std::ostream* os) const { *os << "does not equal "; UniversalPrinter<StlContainer>::Print(rhs_, os); } template <typename LhsContainer> bool MatchAndExplain(const LhsContainer& lhs, MatchResultListener* listener) const { // GMOCK_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug // that causes LhsContainer to be a const type sometimes. typedef internal::StlContainerView<GMOCK_REMOVE_CONST_(LhsContainer)> LhsView; typedef typename LhsView::type LhsStlContainer; StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); if (lhs_stl_container == rhs_) return true; ::std::ostream* const os = listener->stream(); if (os != NULL) { // Something is different. Check for missing values first. bool printed_header = false; for (typename LhsStlContainer::const_iterator it = lhs_stl_container.begin(); it != lhs_stl_container.end(); ++it) { if (internal::ArrayAwareFind(rhs_.begin(), rhs_.end(), *it) == rhs_.end()) { if (printed_header) { *os << ", "; } else { *os << "Only in actual: "; printed_header = true; } UniversalPrinter<typename LhsStlContainer::value_type>:: Print(*it, os); } } // Now check for extra values. bool printed_header2 = false; for (typename StlContainer::const_iterator it = rhs_.begin(); it != rhs_.end(); ++it) { if (internal::ArrayAwareFind( lhs_stl_container.begin(), lhs_stl_container.end(), *it) == lhs_stl_container.end()) { if (printed_header2) { *os << ", "; } else { *os << (printed_header ? "; not" : "Not") << " in actual: "; printed_header2 = true; } UniversalPrinter<typename StlContainer::value_type>::Print(*it, os); } } } return false; } private: const StlContainer rhs_; GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher); }; -template <typename LhsContainer, typename Container> -bool MatchAndExplain(const ContainerEqMatcher<Container>& matcher, - LhsContainer& lhs, - MatchResultListener* listener) { - return matcher.MatchAndExplain(lhs, listener); -} - // Implements Contains(element_matcher) for the given argument type Container. template <typename Container> class ContainsMatcherImpl : public MatcherInterface<Container> { public: typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer; typedef StlContainerView<RawContainer> View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; typedef typename StlContainer::value_type Element; template <typename InnerMatcher> explicit ContainsMatcherImpl(InnerMatcher inner_matcher) : inner_matcher_( testing::SafeMatcherCast<const Element&>(inner_matcher)) {} // Describes what this matcher does. virtual void DescribeTo(::std::ostream* os) const { *os << "contains at least one element that "; inner_matcher_.DescribeTo(os); } // Describes what the negation of this matcher does. virtual void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't contain any element that "; inner_matcher_.DescribeTo(os); } virtual bool MatchAndExplain(Container container, MatchResultListener* listener) const { StlContainerReference stl_container = View::ConstReference(container); size_t i = 0; for (typename StlContainer::const_iterator it = stl_container.begin(); it != stl_container.end(); ++it, ++i) { if (inner_matcher_.Matches(*it)) { *listener << "element " << i << " matches"; return true; } } return false; } private: const Matcher<const Element&> inner_matcher_; GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl); }; // Implements polymorphic Contains(element_matcher). template <typename M> class ContainsMatcher { public: explicit ContainsMatcher(M m) : inner_matcher_(m) {} template <typename Container> operator Matcher<Container>() const { return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_)); } private: const M inner_matcher_; GTEST_DISALLOW_ASSIGN_(ContainsMatcher); }; // Implements Key(inner_matcher) for the given argument pair type. // Key(inner_matcher) matches an std::pair whose 'first' field matches // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an // std::map that contains at least one element whose key is >= 5. template <typename PairType> class KeyMatcherImpl : public MatcherInterface<PairType> { public: typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType; typedef typename RawPairType::first_type KeyType; template <typename InnerMatcher> explicit KeyMatcherImpl(InnerMatcher inner_matcher) : inner_matcher_( testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { } // Returns true iff 'key_value.first' (the key) matches the inner matcher. virtual bool MatchAndExplain(PairType key_value, MatchResultListener* listener) const { return inner_matcher_.MatchAndExplain(key_value.first, listener); } // Describes what this matcher does. virtual void DescribeTo(::std::ostream* os) const { *os << "has a key that "; inner_matcher_.DescribeTo(os); } // Describes what the negation of this matcher does. virtual void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't have a key that "; inner_matcher_.DescribeTo(os); } private: const Matcher<const KeyType&> inner_matcher_; GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl); }; // Implements polymorphic Key(matcher_for_key). template <typename M> class KeyMatcher { public: explicit KeyMatcher(M m) : matcher_for_key_(m) {} template <typename PairType> operator Matcher<PairType>() const { return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_)); } private: const M matcher_for_key_; GTEST_DISALLOW_ASSIGN_(KeyMatcher); }; // Implements Pair(first_matcher, second_matcher) for the given argument pair // type with its two matchers. See Pair() function below. template <typename PairType> class PairMatcherImpl : public MatcherInterface<PairType> { public: typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType; typedef typename RawPairType::first_type FirstType; typedef typename RawPairType::second_type SecondType; template <typename FirstMatcher, typename SecondMatcher> PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher) : first_matcher_( testing::SafeMatcherCast<const FirstType&>(first_matcher)), second_matcher_( testing::SafeMatcherCast<const SecondType&>(second_matcher)) { } // Describes what this matcher does. virtual void DescribeTo(::std::ostream* os) const { *os << "has a first field that "; first_matcher_.DescribeTo(os); *os << ", and has a second field that "; second_matcher_.DescribeTo(os); } // Describes what the negation of this matcher does. virtual void DescribeNegationTo(::std::ostream* os) const { *os << "has a first field that "; first_matcher_.DescribeNegationTo(os); *os << ", or has a second field that "; second_matcher_.DescribeNegationTo(os); } // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second' // matches second_matcher. virtual bool MatchAndExplain(PairType a_pair, MatchResultListener* listener) const { StringMatchResultListener listener1; const bool match1 = first_matcher_.MatchAndExplain(a_pair.first, &listener1); internal::string s1 = listener1.str(); if (s1 != "") { s1 = "the first field " + s1; } if (!match1) { *listener << s1; return false; } StringMatchResultListener listener2; const bool match2 = second_matcher_.MatchAndExplain(a_pair.second, &listener2); internal::string s2 = listener2.str(); if (s2 != "") { s2 = "the second field " + s2; } if (!match2) { *listener << s2; return false; } *listener << s1; if (s1 != "" && s2 != "") { *listener << ", and "; } *listener << s2; return true; } private: const Matcher<const FirstType&> first_matcher_; const Matcher<const SecondType&> second_matcher_; GTEST_DISALLOW_ASSIGN_(PairMatcherImpl); }; // Implements polymorphic Pair(first_matcher, second_matcher). template <typename FirstMatcher, typename SecondMatcher> class PairMatcher { public: PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher) : first_matcher_(first_matcher), second_matcher_(second_matcher) {} template <typename PairType> operator Matcher<PairType> () const { return MakeMatcher( new PairMatcherImpl<PairType>( first_matcher_, second_matcher_)); } private: const FirstMatcher first_matcher_; const SecondMatcher second_matcher_; GTEST_DISALLOW_ASSIGN_(PairMatcher); }; // Implements ElementsAre() and ElementsAreArray(). template <typename Container> class ElementsAreMatcherImpl : public MatcherInterface<Container> { public: typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer; typedef internal::StlContainerView<RawContainer> View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; typedef typename StlContainer::value_type Element; // Constructs the matcher from a sequence of element values or // element matchers. template <typename InputIter> ElementsAreMatcherImpl(InputIter first, size_t a_count) { matchers_.reserve(a_count); InputIter it = first; for (size_t i = 0; i != a_count; ++i, ++it) { matchers_.push_back(MatcherCast<const Element&>(*it)); } } // Describes what this matcher does. virtual void DescribeTo(::std::ostream* os) const { if (count() == 0) { *os << "is empty"; } else if (count() == 1) { *os << "has 1 element that "; matchers_[0].DescribeTo(os); } else { *os << "has " << Elements(count()) << " where\n"; for (size_t i = 0; i != count(); ++i) { *os << "element " << i << " "; matchers_[i].DescribeTo(os); if (i + 1 < count()) { *os << ",\n"; } } } } // Describes what the negation of this matcher does. virtual void DescribeNegationTo(::std::ostream* os) const { if (count() == 0) { *os << "is not empty"; return; } *os << "does not have " << Elements(count()) << ", or\n"; for (size_t i = 0; i != count(); ++i) { *os << "element " << i << " "; matchers_[i].DescribeNegationTo(os); if (i + 1 < count()) { *os << ", or\n"; } } } virtual bool MatchAndExplain(Container container, MatchResultListener* listener) const { StlContainerReference stl_container = View::ConstReference(container); const size_t actual_count = stl_container.size(); if (actual_count != count()) { // The element count doesn't match. If the container is empty, // there's no need to explain anything as Google Mock already // prints the empty container. Otherwise we just need to show // how many elements there actually are. if (actual_count != 0) { *listener << "has " << Elements(actual_count); } return false; } typename StlContainer::const_iterator it = stl_container.begin(); // explanations[i] is the explanation of the element at index i. std::vector<internal::string> explanations(count()); for (size_t i = 0; i != count(); ++it, ++i) { StringMatchResultListener s; if (matchers_[i].MatchAndExplain(*it, &s)) { explanations[i] = s.str(); } else { // The container has the right size but the i-th element // doesn't match its expectation. *listener << "element " << i << " doesn't match"; StreamInParensAsNeeded(s.str(), listener->stream()); return false; } } // Every element matches its expectation. We need to explain why // (the obvious ones can be skipped). bool reason_printed = false; for (size_t i = 0; i != count(); ++i) { const internal::string& s = explanations[i]; if (!s.empty()) { if (reason_printed) { *listener << ",\n"; } *listener << "element " << i << " " << s; reason_printed = true; } } return true; } private: static Message Elements(size_t count) { return Message() << count << (count == 1 ? " element" : " elements"); } size_t count() const { return matchers_.size(); } std::vector<Matcher<const Element&> > matchers_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl); }; // Implements ElementsAre() of 0 arguments. class ElementsAreMatcher0 { public: ElementsAreMatcher0() {} template <typename Container> operator Matcher<Container>() const { typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer; typedef typename internal::StlContainerView<RawContainer>::type::value_type Element; const Matcher<const Element&>* const matchers = NULL; return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0)); } }; // Implements ElementsAreArray(). template <typename T> class ElementsAreArrayMatcher { public: ElementsAreArrayMatcher(const T* first, size_t count) : first_(first), count_(count) {} template <typename Container> operator Matcher<Container>() const { typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer; typedef typename internal::StlContainerView<RawContainer>::type::value_type Element; return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_)); } private: const T* const first_; const size_t count_; GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); }; // Constants denoting interpolations in a matcher description string. const int kTupleInterpolation = -1; // "%(*)s" const int kPercentInterpolation = -2; // "%%" const int kInvalidInterpolation = -3; // "%" followed by invalid text // Records the location and content of an interpolation. struct Interpolation { Interpolation(const char* start, const char* end, int param) : start_pos(start), end_pos(end), param_index(param) {} // Points to the start of the interpolation (the '%' character). const char* start_pos; // Points to the first character after the interpolation. const char* end_pos; // 0-based index of the interpolated matcher parameter; // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%". int param_index; }; typedef ::std::vector<Interpolation> Interpolations; // Parses a matcher description string and returns a vector of // interpolations that appear in the string; generates non-fatal // failures iff 'description' is an invalid matcher description. // 'param_names' is a NULL-terminated array of parameter names in the // order they appear in the MATCHER_P*() parameter list. Interpolations ValidateMatcherDescription( const char* param_names[], const char* description); // Returns the actual matcher description, given the matcher name, // user-supplied description template string, interpolations in the // string, and the printed values of the matcher parameters. string FormatMatcherDescription( const char* matcher_name, const char* description, const Interpolations& interp, const Strings& param_values); } // namespace internal // Implements MatcherCast(). template <typename T, typename M> inline Matcher<T> MatcherCast(M matcher) { return internal::MatcherCastImpl<T, M>::Cast(matcher); } // _ is a matcher that matches anything of any type. // // This definition is fine as: // // 1. The C++ standard permits using the name _ in a namespace that // is not the global namespace or ::std. // 2. The AnythingMatcher class has no data member or constructor, // so it's OK to create global variables of this type. // 3. c-style has approved of using _ in this case. const internal::AnythingMatcher _ = {}; // Creates a matcher that matches any value of the given type T. template <typename T> inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); } // Creates a matcher that matches any value of the given type T. template <typename T> inline Matcher<T> An() { return A<T>(); } // 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); } // Creates a polymorphic matcher that matches any NULL pointer. inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { return MakePolymorphicMatcher(internal::IsNullMatcher()); } // Creates a polymorphic matcher that matches any non-NULL pointer. // This is convenient as Not(NULL) doesn't compile (the compiler // thinks that that expression is comparing a pointer with an integer). inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() { return MakePolymorphicMatcher(internal::NotNullMatcher()); } // Creates a polymorphic matcher that matches any argument that // references variable x. template <typename T> inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT return internal::RefMatcher<T&>(x); } // Creates a matcher that matches any double argument approximately // equal to rhs, where two NANs are considered unequal. inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { return internal::FloatingEqMatcher<double>(rhs, false); } // Creates a matcher that matches any double argument approximately // equal to rhs, including NaN values when rhs is NaN. inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { return internal::FloatingEqMatcher<double>(rhs, true); } // Creates a matcher that matches any float argument approximately // equal to rhs, where two NANs are considered unequal. inline internal::FloatingEqMatcher<float> FloatEq(float rhs) { return internal::FloatingEqMatcher<float>(rhs, false); } // Creates a matcher that matches any double argument approximately // equal to rhs, including NaN values when rhs is NaN. inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { return internal::FloatingEqMatcher<float>(rhs, true); } // Creates a matcher that matches a pointer (raw or smart) that points // to a value that matches inner_matcher. template <typename InnerMatcher> inline internal::PointeeMatcher<InnerMatcher> Pointee( const InnerMatcher& inner_matcher) { return internal::PointeeMatcher<InnerMatcher>(inner_matcher); } // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, // Field(&Foo::number, Ge(5)) // matches a Foo object x iff x.number >= 5. template <typename Class, typename FieldType, typename FieldMatcher> inline PolymorphicMatcher< internal::FieldMatcher<Class, FieldType> > Field( FieldType Class::*field, const FieldMatcher& matcher) { return MakePolymorphicMatcher( internal::FieldMatcher<Class, FieldType>( field, MatcherCast<const FieldType&>(matcher))); // The call to MatcherCast() is required for supporting inner // matchers of compatible types. For example, it allows // Field(&Foo::bar, m) // to compile where bar is an int32 and m is a matcher for int64. } // Creates a matcher that matches an object whose given property // matches 'matcher'. For example, // Property(&Foo::str, StartsWith("hi")) // matches a Foo object x iff x.str() starts with "hi". template <typename Class, typename PropertyType, typename PropertyMatcher> inline PolymorphicMatcher< internal::PropertyMatcher<Class, PropertyType> > Property( PropertyType (Class::*property)() const, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType>( property, MatcherCast<GMOCK_REFERENCE_TO_CONST_(PropertyType)>(matcher))); // The call to MatcherCast() is required for supporting inner // matchers of compatible types. For example, it allows // Property(&Foo::bar, m) // to compile where bar() returns an int32 and m is a matcher for int64. } // Creates a matcher that matches an object iff the result of applying // a callable to x matches 'matcher'. // For example, // ResultOf(f, StartsWith("hi")) // matches a Foo object x iff f(x) starts with "hi". // callable parameter can be a function, function pointer, or a functor. // Callable has to satisfy the following conditions: // * It is required to keep no state affecting the results of // the calls on it and make no assumptions about how many calls // will be made. Any state it keeps must be protected from the // concurrent access. // * If it is a function object, it has to define type result_type. // We recommend deriving your functor classes from std::unary_function. template <typename Callable, typename ResultOfMatcher> internal::ResultOfMatcher<Callable> ResultOf( Callable callable, const ResultOfMatcher& matcher) { return internal::ResultOfMatcher<Callable>( callable, MatcherCast<typename internal::CallableTraits<Callable>::ResultType>( matcher)); // The call to MatcherCast() is required for supporting inner // matchers of compatible types. For example, it allows // ResultOf(Function, m) // to compile where Function() returns an int32 and m is a matcher for int64. } // String matchers. // Matches a string equal to str. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > StrEq(const internal::string& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( str, true, true)); } // Matches a string not equal to str. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > StrNe(const internal::string& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( str, false, true)); } // Matches a string equal to str, ignoring case. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > StrCaseEq(const internal::string& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( str, true, false)); } // Matches a string not equal to str, ignoring case. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> > StrCaseNe(const internal::string& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>( str, false, false)); } // Creates a matcher that matches any string, std::string, or C string // that contains the given substring. inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::string> > HasSubstr(const internal::string& substring) { return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::string>( substring)); } // Matches a string that starts with 'prefix' (case-sensitive). inline PolymorphicMatcher<internal::StartsWithMatcher<internal::string> > StartsWith(const internal::string& prefix) { return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::string>( prefix)); } // Matches a string that ends with 'suffix' (case-sensitive). inline PolymorphicMatcher<internal::EndsWithMatcher<internal::string> > EndsWith(const internal::string& suffix) { return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::string>( suffix)); } // 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)); } inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( const internal::string& regex) { return MatchesRegex(new internal::RE(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)); } inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( const internal::string& regex) { return ContainsRegex(new internal::RE(regex)); } #if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING // Wide string matchers. // Matches a string equal to str. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > StrEq(const internal::wstring& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( str, true, true)); } // Matches a string not equal to str. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > StrNe(const internal::wstring& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( str, false, true)); } // Matches a string equal to str, ignoring case. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > StrCaseEq(const internal::wstring& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( str, true, false)); } // Matches a string not equal to str, ignoring case. inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > StrCaseNe(const internal::wstring& str) { return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( str, false, false)); } // Creates a matcher that matches any wstring, std::wstring, or C wide string // that contains the given substring. inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> > HasSubstr(const internal::wstring& substring) { return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>( substring)); } // Matches a string that starts with 'prefix' (case-sensitive). inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> > StartsWith(const internal::wstring& prefix) { return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>( prefix)); } // Matches a string that ends with 'suffix' (case-sensitive). inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> > EndsWith(const internal::wstring& suffix) { return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>( suffix)); } #endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING // Creates a polymorphic matcher that matches a 2-tuple where the // first field == the second field. inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); } // Creates a polymorphic matcher that matches a 2-tuple where the // first field >= the second field. inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); } // Creates a polymorphic matcher that matches a 2-tuple where the // first field > the second field. inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); } // Creates a polymorphic matcher that matches a 2-tuple where the // first field <= the second field. inline internal::Le2Matcher Le() { return internal::Le2Matcher(); } // Creates a polymorphic matcher that matches a 2-tuple where the // first field < the second field. inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } // Creates a polymorphic matcher that matches a 2-tuple where the // first field != the second field. inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } // Creates a matcher that matches any value of type T that m doesn't // match. template <typename InnerMatcher> inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { return internal::NotMatcher<InnerMatcher>(m); } // Creates a matcher that matches any value that matches all of the // given matchers. // // For now we only support up to 5 matchers. Support for more // matchers can be added as needed, or the user can use nested // AllOf()s. template <typename Matcher1, typename Matcher2> inline internal::BothOfMatcher<Matcher1, Matcher2> AllOf(Matcher1 m1, Matcher2 m2) { return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2); } template <typename Matcher1, typename Matcher2, typename Matcher3> inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, Matcher3> > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { return AllOf(m1, AllOf(m2, m3)); } template <typename Matcher1, typename Matcher2, typename Matcher3, typename Matcher4> inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, internal::BothOfMatcher<Matcher3, Matcher4> > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { return AllOf(m1, AllOf(m2, m3, m4)); } template <typename Matcher1, typename Matcher2, typename Matcher3, typename Matcher4, typename Matcher5> inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, Matcher5> > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { return AllOf(m1, AllOf(m2, m3, m4, m5)); } // Creates a matcher that matches any value that matches at least one // of the given matchers. // // For now we only support up to 5 matchers. Support for more // matchers can be added as needed, or the user can use nested // AnyOf()s. template <typename Matcher1, typename Matcher2> inline internal::EitherOfMatcher<Matcher1, Matcher2> AnyOf(Matcher1 m1, Matcher2 m2) { return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2); } template <typename Matcher1, typename Matcher2, typename Matcher3> inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, Matcher3> > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { return AnyOf(m1, AnyOf(m2, m3)); } template <typename Matcher1, typename Matcher2, typename Matcher3, typename Matcher4> inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, internal::EitherOfMatcher<Matcher3, Matcher4> > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { return AnyOf(m1, AnyOf(m2, m3, m4)); } template <typename Matcher1, typename Matcher2, typename Matcher3, typename Matcher4, typename Matcher5> inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, Matcher5> > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { return AnyOf(m1, AnyOf(m2, m3, m4, m5)); } // Returns a matcher that matches anything that satisfies the given // predicate. The predicate can be any unary function or functor // whose return type can be implicitly converted to bool. template <typename Predicate> inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> > Truly(Predicate pred) { return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); } // Returns a matcher that matches an equal container. // This matcher behaves like Eq(), but in the event of mismatch lists the // values that are included in one container but not the other. (Duplicate // values and order differences are not explained.) template <typename Container> inline PolymorphicMatcher<internal::ContainerEqMatcher< // NOLINT GMOCK_REMOVE_CONST_(Container)> > ContainerEq(const Container& rhs) { // This following line is for working around a bug in MSVC 8.0, // which causes Container to be a const type sometimes. typedef GMOCK_REMOVE_CONST_(Container) RawContainer; return MakePolymorphicMatcher( internal::ContainerEqMatcher<RawContainer>(rhs)); } // Matches an STL-style container or a native array that contains at // least one element matching the given value or matcher. // // Examples: // ::std::set<int> page_ids; // page_ids.insert(3); // page_ids.insert(1); // EXPECT_THAT(page_ids, Contains(1)); // EXPECT_THAT(page_ids, Contains(Gt(2))); // EXPECT_THAT(page_ids, Not(Contains(4))); // // ::std::map<int, size_t> page_lengths; // page_lengths[1] = 100; // EXPECT_THAT(page_lengths, // Contains(::std::pair<const int, size_t>(1, 100))); // // const char* user_ids[] = { "joe", "mike", "tom" }; // EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom")))); template <typename M> inline internal::ContainsMatcher<M> Contains(M matcher) { return internal::ContainsMatcher<M>(matcher); } // Key(inner_matcher) matches an std::pair whose 'first' field matches // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an // std::map that contains at least one element whose key is >= 5. template <typename M> inline internal::KeyMatcher<M> Key(M inner_matcher) { return internal::KeyMatcher<M>(inner_matcher); } // Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field // matches first_matcher and whose 'second' field matches second_matcher. For // example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used // to match a std::map<int, string> that contains exactly one element whose key // is >= 5 and whose value equals "foo". template <typename FirstMatcher, typename SecondMatcher> inline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { return internal::PairMatcher<FirstMatcher, SecondMatcher>( first_matcher, second_matcher); } // Returns a predicate that is satisfied by anything that matches the // given matcher. template <typename M> inline internal::MatcherAsPredicate<M> Matches(M matcher) { return internal::MatcherAsPredicate<M>(matcher); } // Returns true iff the value matches the matcher. template <typename T, typename M> inline bool Value(const T& value, M matcher) { return testing::Matches(matcher)(value); } // AllArgs(m) is a synonym of m. This is useful in // // EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq())); // // which is easier to read than // // EXPECT_CALL(foo, Bar(_, _)).With(Eq()); template <typename InnerMatcher> inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } // These macros allow using matchers to check values in Google Test // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // succeed iff the value matches the matcher. If the assertion fails, // the value and the description of the matcher will be printed. #define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) #define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) } // namespace testing #endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ diff --git a/test/gmock-generated-matchers_test.cc b/test/gmock-generated-matchers_test.cc index 40c2367c..5e14c42a 100644 --- a/test/gmock-generated-matchers_test.cc +++ b/test/gmock-generated-matchers_test.cc @@ -1,1107 +1,1109 @@ // Copyright 2008, 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. // Google Mock - a framework for writing C++ mock classes. // // This file tests the built-in matchers generated by a script. #include <gmock/gmock-generated-matchers.h> #include <list> #include <map> #include <set> #include <sstream> #include <string> #include <utility> #include <vector> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <gtest/gtest-spi.h> namespace { using std::list; using std::map; using std::pair; using std::set; using std::stringstream; using std::vector; using std::tr1::get; using std::tr1::make_tuple; using std::tr1::tuple; using testing::_; using testing::Args; using testing::Contains; using testing::ElementsAre; using testing::ElementsAreArray; using testing::Eq; using testing::Ge; using testing::Gt; using testing::Lt; using testing::MakeMatcher; using testing::Matcher; using testing::MatcherInterface; +using testing::MatchResultListener; using testing::Ne; using testing::Not; using testing::Pointee; using testing::Ref; using testing::StaticAssertTypeEq; using testing::StrEq; using testing::Value; using testing::internal::string; // Returns the description of the given matcher. template <typename T> string Describe(const Matcher<T>& m) { stringstream ss; m.DescribeTo(&ss); return ss.str(); } // Returns the description of the negation of the given matcher. template <typename T> string DescribeNegation(const Matcher<T>& m) { stringstream ss; m.DescribeNegationTo(&ss); return ss.str(); } // Returns the reason why x matches, or doesn't match, m. template <typename MatcherType, typename Value> string Explain(const MatcherType& m, const Value& x) { stringstream ss; m.ExplainMatchResultTo(x, &ss); return ss.str(); } // Tests Args<k0, ..., kn>(m). TEST(ArgsTest, AcceptsZeroTemplateArg) { const tuple<int, bool> t(5, true); EXPECT_THAT(t, Args<>(Eq(tuple<>()))); EXPECT_THAT(t, Not(Args<>(Ne(tuple<>())))); } TEST(ArgsTest, AcceptsOneTemplateArg) { const tuple<int, bool> t(5, true); EXPECT_THAT(t, Args<0>(Eq(make_tuple(5)))); EXPECT_THAT(t, Args<1>(Eq(make_tuple(true)))); EXPECT_THAT(t, Not(Args<1>(Eq(make_tuple(false))))); } TEST(ArgsTest, AcceptsTwoTemplateArgs) { const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 1>(Lt()))); EXPECT_THAT(t, (Args<1, 2>(Lt()))); EXPECT_THAT(t, Not(Args<0, 2>(Gt()))); } TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 0>(Eq()))); EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); } TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<2, 0>(Gt()))); EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); } // The MATCHER*() macros trigger warning C4100 (unreferenced formal // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in // the macro definition, as the warnings are generated when the macro // is expanded and macro expansion cannot contain #pragma. Therefore // we suppress them here. #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4100) #endif MATCHER(SumIsZero, "") { return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0; } TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { EXPECT_THAT(make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero()))); EXPECT_THAT(make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero()))); } TEST(ArgsTest, CanBeNested) { const tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); } TEST(ArgsTest, CanMatchTupleByValue) { typedef tuple<char, int, int> Tuple3; const Matcher<Tuple3> m = Args<1, 2>(Lt()); EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2))); EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2))); } TEST(ArgsTest, CanMatchTupleByReference) { typedef tuple<char, char, int> Tuple3; const Matcher<const Tuple3&> m = Args<0, 1>(Lt()); EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2))); EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2))); } // Validates that arg is printed as str. MATCHER_P(PrintsAs, str, "") { typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(arg_type)) RawTuple; return testing::internal::UniversalPrinter<RawTuple>::PrintToString(arg) == str; } TEST(ArgsTest, AcceptsTenTemplateArgs) { EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), (Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); } TEST(ArgsTest, DescirbesSelfCorrectly) { const Matcher<tuple<int, bool, char> > m = Args<2, 0>(Lt()); EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair (x, y) where x < y", Describe(m)); } TEST(ArgsTest, DescirbesNestedArgsCorrectly) { const Matcher<const tuple<int, bool, char, int>&> m = Args<0, 2, 3>(Args<2, 0>(Lt())); EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple " "whose fields (#2, #0) are a pair (x, y) where x < y", Describe(m)); } TEST(ArgsTest, DescribesNegationCorrectly) { const Matcher<tuple<int, char> > m = Args<1, 0>(Gt()); EXPECT_EQ("are a tuple whose fields (#1, #0) are a pair (x, y) " "where x > y is false", DescribeNegation(m)); } // For testing ExplainMatchResultTo(). class GreaterThanMatcher : public MatcherInterface<int> { public: explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} - virtual bool Matches(int lhs) const { return lhs > rhs_; } - virtual void DescribeTo(::std::ostream* os) const { *os << "is greater than " << rhs_; } - virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { + virtual bool MatchAndExplain(int lhs, + MatchResultListener* listener) const { const int diff = lhs - rhs_; if (diff > 0) { - *os << "is " << diff << " more than " << rhs_; + *listener << "is " << diff << " more than " << rhs_; } else if (diff == 0) { - *os << "is the same as " << rhs_; + *listener << "is the same as " << rhs_; } else { - *os << "is " << -diff << " less than " << rhs_; + *listener << "is " << -diff << " less than " << rhs_; } + + return lhs > rhs_; } private: int rhs_; }; Matcher<int> GreaterThan(int n) { return MakeMatcher(new GreaterThanMatcher(n)); } // Tests for ElementsAre(). // Evaluates to the number of elements in 'array'. #define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0])) TEST(ElementsAreTest, CanDescribeExpectingNoElement) { Matcher<const vector<int>&> m = ElementsAre(); EXPECT_EQ("is empty", Describe(m)); } TEST(ElementsAreTest, CanDescribeExpectingOneElement) { Matcher<vector<int> > m = ElementsAre(Gt(5)); EXPECT_EQ("has 1 element that is greater than 5", Describe(m)); } TEST(ElementsAreTest, CanDescribeExpectingManyElements) { Matcher<list<string> > m = ElementsAre(StrEq("one"), "two"); EXPECT_EQ("has 2 elements where\n" "element 0 is equal to \"one\",\n" "element 1 is equal to \"two\"", Describe(m)); } TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) { Matcher<vector<int> > m = ElementsAre(); EXPECT_EQ("is not empty", DescribeNegation(m)); } TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) { Matcher<const list<int>& > m = ElementsAre(Gt(5)); EXPECT_EQ("does not have 1 element, or\n" "element 0 is not greater than 5", DescribeNegation(m)); } TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) { Matcher<const list<string>& > m = ElementsAre("one", "two"); EXPECT_EQ("does not have 2 elements, or\n" "element 0 is not equal to \"one\", or\n" "element 1 is not equal to \"two\"", DescribeNegation(m)); } TEST(ElementsAreTest, DoesNotExplainTrivialMatch) { Matcher<const list<int>& > m = ElementsAre(1, Ne(2)); list<int> test_list; test_list.push_back(1); test_list.push_back(3); EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything. } TEST(ElementsAreTest, ExplainsNonTrivialMatch) { Matcher<const vector<int>& > m = ElementsAre(GreaterThan(1), 0, GreaterThan(2)); const int a[] = { 10, 0, 100 }; vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_EQ("element 0 is 9 more than 1,\n" "element 2 is 98 more than 2", Explain(m, test_vector)); } TEST(ElementsAreTest, CanExplainMismatchWrongSize) { Matcher<const list<int>& > m = ElementsAre(1, 3); list<int> test_list; // No need to explain when the container is empty. EXPECT_EQ("", Explain(m, test_list)); test_list.push_back(1); EXPECT_EQ("has 1 element", Explain(m, test_list)); } TEST(ElementsAreTest, CanExplainMismatchRightSize) { Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5)); vector<int> v; v.push_back(2); v.push_back(1); EXPECT_EQ("element 0 doesn't match", Explain(m, v)); v[0] = 1; EXPECT_EQ("element 1 doesn't match (is 4 less than 5)", Explain(m, v)); } TEST(ElementsAreTest, MatchesOneElementVector) { vector<string> test_vector; test_vector.push_back("test string"); EXPECT_THAT(test_vector, ElementsAre(StrEq("test string"))); } TEST(ElementsAreTest, MatchesOneElementList) { list<string> test_list; test_list.push_back("test string"); EXPECT_THAT(test_list, ElementsAre("test string")); } TEST(ElementsAreTest, MatchesThreeElementVector) { vector<string> test_vector; test_vector.push_back("one"); test_vector.push_back("two"); test_vector.push_back("three"); EXPECT_THAT(test_vector, ElementsAre("one", StrEq("two"), _)); } TEST(ElementsAreTest, MatchesOneElementEqMatcher) { vector<int> test_vector; test_vector.push_back(4); EXPECT_THAT(test_vector, ElementsAre(Eq(4))); } TEST(ElementsAreTest, MatchesOneElementAnyMatcher) { vector<int> test_vector; test_vector.push_back(4); EXPECT_THAT(test_vector, ElementsAre(_)); } TEST(ElementsAreTest, MatchesOneElementValue) { vector<int> test_vector; test_vector.push_back(4); EXPECT_THAT(test_vector, ElementsAre(4)); } TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) { vector<int> test_vector; test_vector.push_back(1); test_vector.push_back(2); test_vector.push_back(3); EXPECT_THAT(test_vector, ElementsAre(1, Eq(2), _)); } TEST(ElementsAreTest, MatchesTenElementVector) { const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(test_vector, // The element list can contain values and/or matchers // of different types. ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _)); } TEST(ElementsAreTest, DoesNotMatchWrongSize) { vector<string> test_vector; test_vector.push_back("test string"); test_vector.push_back("test string"); Matcher<vector<string> > m = ElementsAre(StrEq("test string")); EXPECT_FALSE(m.Matches(test_vector)); } TEST(ElementsAreTest, DoesNotMatchWrongValue) { vector<string> test_vector; test_vector.push_back("other string"); Matcher<vector<string> > m = ElementsAre(StrEq("test string")); EXPECT_FALSE(m.Matches(test_vector)); } TEST(ElementsAreTest, DoesNotMatchWrongOrder) { vector<string> test_vector; test_vector.push_back("one"); test_vector.push_back("three"); test_vector.push_back("two"); Matcher<vector<string> > m = ElementsAre( StrEq("one"), StrEq("two"), StrEq("three")); EXPECT_FALSE(m.Matches(test_vector)); } TEST(ElementsAreTest, WorksForNestedContainer) { const char* strings[] = { "Hi", "world" }; vector<list<char> > nested; for (size_t i = 0; i < GMOCK_ARRAY_SIZE_(strings); i++) { nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i]))); } EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')), ElementsAre('w', 'o', _, _, 'd'))); EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'), ElementsAre('w', 'o', _, _, 'd')))); } TEST(ElementsAreTest, WorksWithByRefElementMatchers) { int a[] = { 0, 1, 2 }; vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2]))); EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2])))); } TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) { int a[] = { 0, 1, 2 }; vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _))); EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3)))); } TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) { int array[] = { 0, 1, 2 }; EXPECT_THAT(array, ElementsAre(0, 1, _)); EXPECT_THAT(array, Not(ElementsAre(1, _, _))); EXPECT_THAT(array, Not(ElementsAre(0, _))); } class NativeArrayPassedAsPointerAndSize { public: NativeArrayPassedAsPointerAndSize() {} MOCK_METHOD2(Helper, void(int* array, int size)); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(NativeArrayPassedAsPointerAndSize); }; TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) { int array[] = { 0, 1 }; ::std::tr1::tuple<int*, size_t> array_as_tuple(array, 2); EXPECT_THAT(array_as_tuple, ElementsAre(0, 1)); EXPECT_THAT(array_as_tuple, Not(ElementsAre(0))); NativeArrayPassedAsPointerAndSize helper; EXPECT_CALL(helper, Helper(_, _)) .With(ElementsAre(0, 1)); helper.Helper(array, 2); } TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) { const char a2[][3] = { "hi", "lo" }; EXPECT_THAT(a2, ElementsAre(ElementsAre('h', 'i', '\0'), ElementsAre('l', 'o', '\0'))); EXPECT_THAT(a2, ElementsAre(StrEq("hi"), StrEq("lo"))); EXPECT_THAT(a2, ElementsAre(Not(ElementsAre('h', 'o', '\0')), ElementsAre('l', 'o', '\0'))); } // Tests for ElementsAreArray(). Since ElementsAreArray() shares most // of the implementation with ElementsAre(), we don't test it as // thoroughly here. TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) { const int a[] = { 1, 2, 3 }; vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(test_vector, ElementsAreArray(a)); test_vector[2] = 0; EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); } TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) { const char* a[] = { "one", "two", "three" }; vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(test_vector, ElementsAreArray(a, GMOCK_ARRAY_SIZE_(a))); const char** p = a; test_vector[0] = "1"; EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GMOCK_ARRAY_SIZE_(a)))); } TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) { const char* a[] = { "one", "two", "three" }; vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(test_vector, ElementsAreArray(a)); test_vector[0] = "1"; EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); } TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) { const Matcher<string> kMatcherArray[] = { StrEq("one"), StrEq("two"), StrEq("three") }; vector<string> test_vector; test_vector.push_back("one"); test_vector.push_back("two"); test_vector.push_back("three"); EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray)); test_vector.push_back("three"); EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray))); } // Since ElementsAre() and ElementsAreArray() share much of the // implementation, we only do a sanity test for native arrays here. TEST(ElementsAreArrayTest, WorksWithNativeArray) { ::std::string a[] = { "hi", "ho" }; ::std::string b[] = { "hi", "ho" }; EXPECT_THAT(a, ElementsAreArray(b)); EXPECT_THAT(a, ElementsAreArray(b, 2)); EXPECT_THAT(a, Not(ElementsAreArray(b, 1))); } // Tests for the MATCHER*() macro family. // Tests that a simple MATCHER() definition works. MATCHER(IsEven, "") { return (arg % 2) == 0; } TEST(MatcherMacroTest, Works) { const Matcher<int> m = IsEven(); EXPECT_TRUE(m.Matches(6)); EXPECT_FALSE(m.Matches(7)); EXPECT_EQ("is even", Describe(m)); EXPECT_EQ("not (is even)", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 6)); EXPECT_EQ("", Explain(m, 7)); } // Tests explaining match result in a MATCHER* macro. MATCHER(IsEven2, "is even") { if ((arg % 2) == 0) { // Verifies that we can stream to result_listener, a listener // supplied by the MATCHER macro implicitly. *result_listener << "OK"; return true; } else { *result_listener << "% 2 == " << (arg % 2); return false; } } MATCHER_P2(EqSumOf, x, y, "") { if (arg == (x + y)) { *result_listener << "OK"; return true; } else { // Verifies that we can stream to the underlying stream of // result_listener. if (result_listener->stream() != NULL) { *result_listener->stream() << "diff == " << (x + y - arg); } return false; } } TEST(MatcherMacroTest, CanExplainMatchResult) { const Matcher<int> m1 = IsEven2(); EXPECT_EQ("OK", Explain(m1, 4)); EXPECT_EQ("% 2 == 1", Explain(m1, 5)); const Matcher<int> m2 = EqSumOf(1, 2); EXPECT_EQ("OK", Explain(m2, 3)); EXPECT_EQ("diff == -1", Explain(m2, 4)); } // Tests that the description string supplied to MATCHER() must be // valid. MATCHER(HasBadDescription, "Invalid%") { // Uses arg to suppress "unused parameter" warning. return arg==arg; } TEST(MatcherMacroTest, CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) { EXPECT_NONFATAL_FAILURE( HasBadDescription(), "Syntax error at index 7 in matcher description \"Invalid%\": " "use \"%%\" instead of \"%\" to print \"%\"."); } MATCHER(HasGoodDescription, "good") { return arg==arg; } TEST(MatcherMacroTest, AcceptsValidDescription) { const Matcher<int> m = HasGoodDescription(); EXPECT_EQ("good", Describe(m)); } // Tests that the body of MATCHER() can reference the type of the // value being matched. MATCHER(IsEmptyString, "") { StaticAssertTypeEq< ::std::string, arg_type>(); return arg == ""; } MATCHER(IsEmptyStringByRef, "") { StaticAssertTypeEq<const ::std::string&, arg_type>(); return arg == ""; } TEST(MatcherMacroTest, CanReferenceArgType) { const Matcher< ::std::string> m1 = IsEmptyString(); EXPECT_TRUE(m1.Matches("")); const Matcher<const ::std::string&> m2 = IsEmptyStringByRef(); EXPECT_TRUE(m2.Matches("")); } // Tests that MATCHER() can be used in a namespace. namespace matcher_test { MATCHER(IsOdd, "") { return (arg % 2) != 0; } } // namespace matcher_test TEST(MatcherMacroTest, WorksInNamespace) { Matcher<int> m = matcher_test::IsOdd(); EXPECT_FALSE(m.Matches(4)); EXPECT_TRUE(m.Matches(5)); } // Tests that Value() can be used to compose matchers. MATCHER(IsPositiveOdd, "") { return Value(arg, matcher_test::IsOdd()) && arg > 0; } TEST(MatcherMacroTest, CanBeComposedUsingValue) { EXPECT_THAT(3, IsPositiveOdd()); EXPECT_THAT(4, Not(IsPositiveOdd())); EXPECT_THAT(-1, Not(IsPositiveOdd())); } // Tests that a simple MATCHER_P() definition works. MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; } TEST(MatcherPMacroTest, Works) { const Matcher<int> m = IsGreaterThan32And(5); EXPECT_TRUE(m.Matches(36)); EXPECT_FALSE(m.Matches(5)); EXPECT_EQ("is greater than 32 and 5", Describe(m)); EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36)); EXPECT_EQ("", Explain(m, 5)); } // Tests that the description string supplied to MATCHER_P() must be // valid. MATCHER_P(HasBadDescription1, n, "not %(m)s good") { return arg > n; } TEST(MatcherPMacroTest, CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) { EXPECT_NONFATAL_FAILURE( HasBadDescription1(2), "Syntax error at index 6 in matcher description \"not %(m)s good\": " "\"m\" is an invalid parameter name."); } MATCHER_P(HasGoodDescription1, n, "good %(n)s") { return arg==arg; } TEST(MatcherPMacroTest, AcceptsValidDescription) { const Matcher<int> m = HasGoodDescription1(5); EXPECT_EQ("good 5", Describe(m)); } // Tests that the description is calculated correctly from the matcher name. MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; } TEST(MatcherPMacroTest, GeneratesCorrectDescription) { const Matcher<int> m = _is_Greater_Than32and_(5); EXPECT_EQ("is greater than 32 and 5", Describe(m)); EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36)); EXPECT_EQ("", Explain(m, 5)); } // Tests that a MATCHER_P matcher can be explicitly instantiated with // a reference parameter type. class UncopyableFoo { public: explicit UncopyableFoo(char value) : value_(value) {} private: UncopyableFoo(const UncopyableFoo&); void operator=(const UncopyableFoo&); char value_; }; MATCHER_P(ReferencesUncopyable, variable, "") { return &arg == &variable; } TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) { UncopyableFoo foo1('1'), foo2('2'); const Matcher<const UncopyableFoo&> m = ReferencesUncopyable<const UncopyableFoo&>(foo1); EXPECT_TRUE(m.Matches(foo1)); EXPECT_FALSE(m.Matches(foo2)); // We don't want the address of the parameter printed, as most // likely it will just annoy the user. If the address is // interesting, the user should consider passing the parameter by // pointer instead. EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m)); } // Tests that the description string supplied to MATCHER_Pn() must be // valid. MATCHER_P2(HasBadDescription2, m, n, "not %(good") { return arg > m + n; } TEST(MatcherPnMacroTest, CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) { EXPECT_NONFATAL_FAILURE( HasBadDescription2(3, 4), "Syntax error at index 4 in matcher description \"not %(good\": " "an interpolation must end with \")s\", but \"%(good\" does not."); } MATCHER_P2(HasComplexDescription, foo, bar, "is as complex as %(foo)s %(bar)s (i.e. %(*)s or %%%(foo)s!)") { return arg==arg; } TEST(MatcherPnMacroTest, AcceptsValidDescription) { Matcher<int> m = HasComplexDescription(100, "ducks"); EXPECT_EQ("is as complex as 100 \"ducks\" (i.e. (100, \"ducks\") or %100!)", Describe(m)); } // Tests that the body of MATCHER_Pn() can reference the parameter // types. MATCHER_P3(ParamTypesAreIntLongAndChar, foo, bar, baz, "") { StaticAssertTypeEq<int, foo_type>(); StaticAssertTypeEq<long, bar_type>(); // NOLINT StaticAssertTypeEq<char, baz_type>(); return arg == 0; } TEST(MatcherPnMacroTest, CanReferenceParamTypes) { EXPECT_THAT(0, ParamTypesAreIntLongAndChar(10, 20L, 'a')); } // Tests that a MATCHER_Pn matcher can be explicitly instantiated with // reference parameter types. MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") { return &arg == &variable1 || &arg == &variable2; } TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) { UncopyableFoo foo1('1'), foo2('2'), foo3('3'); const Matcher<const UncopyableFoo&> m = ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); EXPECT_TRUE(m.Matches(foo1)); EXPECT_TRUE(m.Matches(foo2)); EXPECT_FALSE(m.Matches(foo3)); } TEST(MatcherPnMacroTest, GeneratesCorretDescriptionWhenExplicitlyInstantiatedWithReferences) { UncopyableFoo foo1('1'), foo2('2'); const Matcher<const UncopyableFoo&> m = ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); // We don't want the addresses of the parameters printed, as most // likely they will just annoy the user. If the addresses are // interesting, the user should consider passing the parameters by // pointers instead. EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)", Describe(m)); } // Tests that a simple MATCHER_P2() definition works. MATCHER_P2(IsNotInClosedRange, low, hi, "") { return arg < low || arg > hi; } TEST(MatcherPnMacroTest, Works) { const Matcher<const long&> m = IsNotInClosedRange(10, 20); // NOLINT EXPECT_TRUE(m.Matches(36L)); EXPECT_FALSE(m.Matches(15L)); EXPECT_EQ("is not in closed range (10, 20)", Describe(m)); EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36L)); EXPECT_EQ("", Explain(m, 15L)); } // Tests that MATCHER*() definitions can be overloaded on the number // of parameters; also tests MATCHER_Pn() where n >= 3. MATCHER(EqualsSumOf, "") { return arg == 0; } MATCHER_P(EqualsSumOf, a, "") { return arg == a; } MATCHER_P2(EqualsSumOf, a, b, "") { return arg == a + b; } MATCHER_P3(EqualsSumOf, a, b, c, "") { return arg == a + b + c; } MATCHER_P4(EqualsSumOf, a, b, c, d, "") { return arg == a + b + c + d; } MATCHER_P5(EqualsSumOf, a, b, c, d, e, "") { return arg == a + b + c + d + e; } MATCHER_P6(EqualsSumOf, a, b, c, d, e, f, "") { return arg == a + b + c + d + e + f; } MATCHER_P7(EqualsSumOf, a, b, c, d, e, f, g, "") { return arg == a + b + c + d + e + f + g; } MATCHER_P8(EqualsSumOf, a, b, c, d, e, f, g, h, "") { return arg == a + b + c + d + e + f + g + h; } MATCHER_P9(EqualsSumOf, a, b, c, d, e, f, g, h, i, "") { return arg == a + b + c + d + e + f + g + h + i; } MATCHER_P10(EqualsSumOf, a, b, c, d, e, f, g, h, i, j, "") { return arg == a + b + c + d + e + f + g + h + i + j; } TEST(MatcherPnMacroTest, CanBeOverloadedOnNumberOfParameters) { EXPECT_THAT(0, EqualsSumOf()); EXPECT_THAT(1, EqualsSumOf(1)); EXPECT_THAT(12, EqualsSumOf(10, 2)); EXPECT_THAT(123, EqualsSumOf(100, 20, 3)); EXPECT_THAT(1234, EqualsSumOf(1000, 200, 30, 4)); EXPECT_THAT(12345, EqualsSumOf(10000, 2000, 300, 40, 5)); EXPECT_THAT("abcdef", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f')); EXPECT_THAT("abcdefg", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g')); EXPECT_THAT("abcdefgh", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h")); EXPECT_THAT("abcdefghi", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h", 'i')); EXPECT_THAT("abcdefghij", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h", 'i', ::std::string("j"))); EXPECT_THAT(1, Not(EqualsSumOf())); EXPECT_THAT(-1, Not(EqualsSumOf(1))); EXPECT_THAT(-12, Not(EqualsSumOf(10, 2))); EXPECT_THAT(-123, Not(EqualsSumOf(100, 20, 3))); EXPECT_THAT(-1234, Not(EqualsSumOf(1000, 200, 30, 4))); EXPECT_THAT(-12345, Not(EqualsSumOf(10000, 2000, 300, 40, 5))); EXPECT_THAT("abcdef ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f'))); EXPECT_THAT("abcdefg ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g'))); EXPECT_THAT("abcdefgh ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h"))); EXPECT_THAT("abcdefghi ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h", 'i'))); EXPECT_THAT("abcdefghij ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h", 'i', ::std::string("j")))); } // Tests that a MATCHER_Pn() definition can be instantiated with any // compatible parameter types. TEST(MatcherPnMacroTest, WorksForDifferentParameterTypes) { EXPECT_THAT(123, EqualsSumOf(100L, 20, static_cast<char>(3))); EXPECT_THAT("abcd", EqualsSumOf(::std::string("a"), "b", 'c', "d")); EXPECT_THAT(124, Not(EqualsSumOf(100L, 20, static_cast<char>(3)))); EXPECT_THAT("abcde", Not(EqualsSumOf(::std::string("a"), "b", 'c', "d"))); } // Tests that the matcher body can promote the parameter types. MATCHER_P2(EqConcat, prefix, suffix, "") { // The following lines promote the two parameters to desired types. std::string prefix_str(prefix); char suffix_char = static_cast<char>(suffix); return arg == prefix_str + suffix_char; } TEST(MatcherPnMacroTest, SimpleTypePromotion) { Matcher<std::string> no_promo = EqConcat(std::string("foo"), 't'); Matcher<const std::string&> promo = EqConcat("foo", static_cast<int>('t')); EXPECT_FALSE(no_promo.Matches("fool")); EXPECT_FALSE(promo.Matches("fool")); EXPECT_TRUE(no_promo.Matches("foot")); EXPECT_TRUE(promo.Matches("foot")); } // Verifies the type of a MATCHER*. TEST(MatcherPnMacroTest, TypesAreCorrect) { // EqualsSumOf() must be assignable to a EqualsSumOfMatcher variable. EqualsSumOfMatcher a0 = EqualsSumOf(); // EqualsSumOf(1) must be assignable to a EqualsSumOfMatcherP variable. EqualsSumOfMatcherP<int> a1 = EqualsSumOf(1); // EqualsSumOf(p1, ..., pk) must be assignable to a EqualsSumOfMatcherPk // variable, and so on. EqualsSumOfMatcherP2<int, char> a2 = EqualsSumOf(1, '2'); EqualsSumOfMatcherP3<int, int, char> a3 = EqualsSumOf(1, 2, '3'); EqualsSumOfMatcherP4<int, int, int, char> a4 = EqualsSumOf(1, 2, 3, '4'); EqualsSumOfMatcherP5<int, int, int, int, char> a5 = EqualsSumOf(1, 2, 3, 4, '5'); EqualsSumOfMatcherP6<int, int, int, int, int, char> a6 = EqualsSumOf(1, 2, 3, 4, 5, '6'); EqualsSumOfMatcherP7<int, int, int, int, int, int, char> a7 = EqualsSumOf(1, 2, 3, 4, 5, 6, '7'); EqualsSumOfMatcherP8<int, int, int, int, int, int, int, char> a8 = EqualsSumOf(1, 2, 3, 4, 5, 6, 7, '8'); EqualsSumOfMatcherP9<int, int, int, int, int, int, int, int, char> a9 = EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, '9'); EqualsSumOfMatcherP10<int, int, int, int, int, int, int, int, int, char> a10 = EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); } // Tests that matcher-typed parameters can be used in Value() inside a // MATCHER_Pn definition. // Succeeds if arg matches exactly 2 of the 3 matchers. MATCHER_P3(TwoOf, m1, m2, m3, "") { const int count = static_cast<int>(Value(arg, m1)) + static_cast<int>(Value(arg, m2)) + static_cast<int>(Value(arg, m3)); return count == 2; } TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) { EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10))); EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0)))); } // Tests Contains(). TEST(ContainsTest, ListMatchesWhenElementIsInContainer) { list<int> some_list; some_list.push_back(3); some_list.push_back(1); some_list.push_back(2); EXPECT_THAT(some_list, Contains(1)); EXPECT_THAT(some_list, Contains(Gt(2.5))); EXPECT_THAT(some_list, Contains(Eq(2.0f))); list<string> another_list; another_list.push_back("fee"); another_list.push_back("fie"); another_list.push_back("foe"); another_list.push_back("fum"); EXPECT_THAT(another_list, Contains(string("fee"))); } TEST(ContainsTest, ListDoesNotMatchWhenElementIsNotInContainer) { list<int> some_list; some_list.push_back(3); some_list.push_back(1); EXPECT_THAT(some_list, Not(Contains(4))); } TEST(ContainsTest, SetMatchesWhenElementIsInContainer) { set<int> some_set; some_set.insert(3); some_set.insert(1); some_set.insert(2); EXPECT_THAT(some_set, Contains(Eq(1.0))); EXPECT_THAT(some_set, Contains(Eq(3.0f))); EXPECT_THAT(some_set, Contains(2)); set<const char*> another_set; another_set.insert("fee"); another_set.insert("fie"); another_set.insert("foe"); another_set.insert("fum"); EXPECT_THAT(another_set, Contains(Eq(string("fum")))); } TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) { set<int> some_set; some_set.insert(3); some_set.insert(1); EXPECT_THAT(some_set, Not(Contains(4))); set<const char*> c_string_set; c_string_set.insert("hello"); EXPECT_THAT(c_string_set, Not(Contains(string("hello").c_str()))); } TEST(ContainsTest, DescribesItselfCorrectly) { const int a[2] = { 1, 2 }; Matcher<const int(&)[2]> m = Contains(2); EXPECT_EQ("element 1 matches", Explain(m, a)); m = Contains(3); EXPECT_EQ("", Explain(m, a)); } TEST(ContainsTest, ExplainsMatchResultCorrectly) { Matcher<vector<int> > m = Contains(1); EXPECT_EQ("contains at least one element that is equal to 1", Describe(m)); Matcher<vector<int> > m2 = Not(m); EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2)); } TEST(ContainsTest, MapMatchesWhenElementIsInContainer) { map<const char*, int> my_map; const char* bar = "a string"; my_map[bar] = 2; EXPECT_THAT(my_map, Contains(pair<const char* const, int>(bar, 2))); map<string, int> another_map; another_map["fee"] = 1; another_map["fie"] = 2; another_map["foe"] = 3; another_map["fum"] = 4; EXPECT_THAT(another_map, Contains(pair<const string, int>(string("fee"), 1))); EXPECT_THAT(another_map, Contains(pair<const string, int>("fie", 2))); } TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) { map<int, int> some_map; some_map[1] = 11; some_map[2] = 22; EXPECT_THAT(some_map, Not(Contains(pair<const int, int>(2, 23)))); } TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) { const char* string_array[] = { "fee", "fie", "foe", "fum" }; EXPECT_THAT(string_array, Contains(Eq(string("fum")))); } TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) { int int_array[] = { 1, 2, 3, 4 }; EXPECT_THAT(int_array, Not(Contains(5))); } TEST(ContainsTest, AcceptsMatcher) { const int a[] = { 1, 2, 3 }; EXPECT_THAT(a, Contains(Gt(2))); EXPECT_THAT(a, Not(Contains(Gt(4)))); } TEST(ContainsTest, WorksForNativeArrayAsTuple) { const int a[] = { 1, 2 }; const int* const pointer = a; EXPECT_THAT(make_tuple(pointer, 2), Contains(1)); EXPECT_THAT(make_tuple(pointer, 2), Not(Contains(Gt(3)))); } TEST(ContainsTest, WorksForTwoDimensionalNativeArray) { int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6))); EXPECT_THAT(a, Contains(Contains(5))); EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5)))); EXPECT_THAT(a, Contains(Not(Contains(5)))); } #ifdef _MSC_VER #pragma warning(pop) #endif } // namespace diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc index 555cc228..b674cd8a 100644 --- a/test/gmock-matchers_test.cc +++ b/test/gmock-matchers_test.cc @@ -1,3709 +1,3708 @@ // 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. // // Author: wan@google.com (Zhanyong Wan) // Google Mock - a framework for writing C++ mock classes. // // This file tests some commonly used argument matchers. #include <gmock/gmock-matchers.h> #include <string.h> #include <functional> #include <list> #include <map> #include <set> #include <sstream> #include <string> #include <utility> #include <vector> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <gtest/gtest-spi.h> namespace testing { namespace internal { string FormatMatcherDescriptionSyntaxError(const char* description, const char* error_pos); int GetParamIndex(const char* param_names[], const string& param_name); string JoinAsTuple(const Strings& fields); bool SkipPrefix(const char* prefix, const char** pstr); } // namespace internal namespace gmock_matchers_test { using std::map; using std::multimap; using std::stringstream; using std::tr1::make_tuple; using testing::A; using testing::AllArgs; using testing::AllOf; using testing::An; using testing::AnyOf; using testing::ByRef; using testing::DoubleEq; using testing::EndsWith; using testing::Eq; using testing::Field; using testing::FloatEq; using testing::Ge; using testing::Gt; using testing::HasSubstr; using testing::IsNull; using testing::Key; using testing::Le; using testing::Lt; using testing::MakeMatcher; using testing::MakePolymorphicMatcher; using testing::Matcher; using testing::MatcherCast; using testing::MatcherInterface; using testing::Matches; using testing::MatchResultListener; using testing::NanSensitiveDoubleEq; using testing::NanSensitiveFloatEq; using testing::Ne; using testing::Not; using testing::NotNull; using testing::Pair; using testing::Pointee; using testing::PolymorphicMatcher; using testing::Property; using testing::Ref; using testing::ResultOf; using testing::StartsWith; using testing::StrCaseEq; using testing::StrCaseNe; using testing::StrEq; using testing::StrNe; using testing::Truly; using testing::TypedEq; using testing::Value; using testing::_; using testing::internal::FloatingEqMatcher; using testing::internal::FormatMatcherDescriptionSyntaxError; using testing::internal::GetParamIndex; using testing::internal::Interpolation; using testing::internal::Interpolations; using testing::internal::JoinAsTuple; using testing::internal::SkipPrefix; using testing::internal::String; using testing::internal::Strings; using testing::internal::ValidateMatcherDescription; using testing::internal::kInvalidInterpolation; using testing::internal::kPercentInterpolation; using testing::internal::kTupleInterpolation; using testing::internal::linked_ptr; using testing::internal::scoped_ptr; using testing::internal::string; using testing::ContainsRegex; using testing::MatchesRegex; using testing::internal::RE; // For testing ExplainMatchResultTo(). class GreaterThanMatcher : public MatcherInterface<int> { public: explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} - virtual bool Matches(int lhs) const { return lhs > rhs_; } - virtual void DescribeTo(::std::ostream* os) const { *os << "is greater than " << rhs_; } - virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { + virtual bool MatchAndExplain(int lhs, + MatchResultListener* listener) const { const int diff = lhs - rhs_; if (diff > 0) { - *os << "is " << diff << " more than " << rhs_; + *listener << "is " << diff << " more than " << rhs_; } else if (diff == 0) { - *os << "is the same as " << rhs_; + *listener << "is the same as " << rhs_; } else { - *os << "is " << -diff << " less than " << rhs_; + *listener << "is " << -diff << " less than " << rhs_; } + + return lhs > rhs_; } private: int rhs_; }; Matcher<int> GreaterThan(int n) { return MakeMatcher(new GreaterThanMatcher(n)); } // Returns the description of the given matcher. template <typename T> string Describe(const Matcher<T>& m) { stringstream ss; m.DescribeTo(&ss); return ss.str(); } // Returns the description of the negation of the given matcher. template <typename T> string DescribeNegation(const Matcher<T>& m) { stringstream ss; m.DescribeNegationTo(&ss); return ss.str(); } // Returns the reason why x matches, or doesn't match, m. template <typename MatcherType, typename Value> string Explain(const MatcherType& m, const Value& x) { stringstream ss; m.ExplainMatchResultTo(x, &ss); return ss.str(); } // Makes sure that the MatcherInterface<T> interface doesn't // change. class EvenMatcherImpl : public MatcherInterface<int> { public: - virtual bool Matches(int x) const { return x % 2 == 0; } + virtual bool MatchAndExplain(int x, + MatchResultListener* /* listener */) const { + return x % 2 == 0; + } virtual void DescribeTo(::std::ostream* os) const { *os << "is an even number"; } // We deliberately don't define DescribeNegationTo() and // ExplainMatchResultTo() here, to make sure the definition of these // two methods is optional. }; TEST(MatcherInterfaceTest, CanBeImplementedUsingDeprecatedAPI) { EvenMatcherImpl m; } // Tests implementing a monomorphic matcher using MatchAndExplain(). class NewEvenMatcherImpl : public MatcherInterface<int> { public: virtual bool MatchAndExplain(int x, MatchResultListener* listener) const { const bool match = x % 2 == 0; // Verifies that we can stream to a listener directly. *listener << "value % " << 2; if (listener->stream() != NULL) { // Verifies that we can stream to a listener's underlying stream // too. *listener->stream() << " == " << (x % 2); } return match; } virtual void DescribeTo(::std::ostream* os) const { *os << "is an even number"; } }; TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) { Matcher<int> m = MakeMatcher(new NewEvenMatcherImpl); EXPECT_TRUE(m.Matches(2)); EXPECT_FALSE(m.Matches(3)); EXPECT_EQ("value % 2 == 0", Explain(m, 2)); EXPECT_EQ("value % 2 == 1", Explain(m, 3)); } // Tests default-constructing a matcher. TEST(MatcherTest, CanBeDefaultConstructed) { Matcher<double> m; } // Tests that Matcher<T> can be constructed from a MatcherInterface<T>*. TEST(MatcherTest, CanBeConstructedFromMatcherInterface) { const MatcherInterface<int>* impl = new EvenMatcherImpl; Matcher<int> m(impl); EXPECT_TRUE(m.Matches(4)); EXPECT_FALSE(m.Matches(5)); } // Tests that value can be used in place of Eq(value). TEST(MatcherTest, CanBeImplicitlyConstructedFromValue) { Matcher<int> m1 = 5; EXPECT_TRUE(m1.Matches(5)); EXPECT_FALSE(m1.Matches(6)); } // Tests that NULL can be used in place of Eq(NULL). TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) { Matcher<int*> m1 = NULL; EXPECT_TRUE(m1.Matches(NULL)); int n = 0; EXPECT_FALSE(m1.Matches(&n)); } // Tests that matchers are copyable. TEST(MatcherTest, IsCopyable) { // Tests the copy constructor. Matcher<bool> m1 = Eq(false); EXPECT_TRUE(m1.Matches(false)); EXPECT_FALSE(m1.Matches(true)); // Tests the assignment operator. m1 = Eq(true); EXPECT_TRUE(m1.Matches(true)); EXPECT_FALSE(m1.Matches(false)); } // Tests that Matcher<T>::DescribeTo() calls // MatcherInterface<T>::DescribeTo(). TEST(MatcherTest, CanDescribeItself) { EXPECT_EQ("is an even number", Describe(Matcher<int>(new EvenMatcherImpl))); } // Tests Matcher<T>::MatchAndExplain(). TEST(MatcherTest, MatchAndExplain) { Matcher<int> m = GreaterThan(0); ::testing::internal::StringMatchResultListener listener1; EXPECT_TRUE(m.MatchAndExplain(42, &listener1)); EXPECT_EQ("is 42 more than 0", listener1.str()); ::testing::internal::StringMatchResultListener listener2; EXPECT_FALSE(m.MatchAndExplain(-9, &listener2)); EXPECT_EQ("is 9 less than 0", listener2.str()); } // Tests that a C-string literal can be implicitly converted to a // Matcher<string> or Matcher<const string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { Matcher<string> m1 = "hi"; EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); Matcher<const string&> m2 = "hi"; EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } // Tests that a string object can be implicitly converted to a // Matcher<string> or Matcher<const string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { Matcher<string> m1 = string("hi"); EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); Matcher<const string&> m2 = string("hi"); EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } // Tests that MakeMatcher() constructs a Matcher<T> from a // MatcherInterface* without requiring the user to explicitly // write the type. TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) { const MatcherInterface<int>* dummy_impl = NULL; Matcher<int> m = MakeMatcher(dummy_impl); } // Tests that MakePolymorphicMatcher() can construct a polymorphic // matcher from its implementation using the old API. const int bar = 1; class ReferencesBarOrIsZeroImpl { public: template <typename T> - bool Matches(const T& x) const { + bool MatchAndExplain(const T& x, + MatchResultListener* /* listener */) const { const void* p = &x; return p == &bar || x == 0; } void DescribeTo(::std::ostream* os) const { *os << "bar or zero"; } void DescribeNegationTo(::std::ostream* os) const { *os << "doesn't reference bar and is not zero"; } }; // This function verifies that MakePolymorphicMatcher() returns a // PolymorphicMatcher<T> where T is the argument's type. PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() { return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl()); } TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) { // Using a polymorphic matcher to match a reference type. Matcher<const int&> m1 = ReferencesBarOrIsZero(); EXPECT_TRUE(m1.Matches(0)); // Verifies that the identity of a by-reference argument is preserved. EXPECT_TRUE(m1.Matches(bar)); EXPECT_FALSE(m1.Matches(1)); EXPECT_EQ("bar or zero", Describe(m1)); // Using a polymorphic matcher to match a value type. Matcher<double> m2 = ReferencesBarOrIsZero(); EXPECT_TRUE(m2.Matches(0.0)); EXPECT_FALSE(m2.Matches(0.1)); EXPECT_EQ("bar or zero", Describe(m2)); } // Tests implementing a polymorphic matcher using MatchAndExplain(). class PolymorphicIsEvenImpl { public: void DescribeTo(::std::ostream* os) const { *os << "is even"; } void DescribeNegationTo(::std::ostream* os) const { *os << "is odd"; } -}; -template <typename T> -bool MatchAndExplain(const PolymorphicIsEvenImpl& /* impl */, - T x, MatchResultListener* listener) { - // Verifies that we can stream to the listener directly. - *listener << "% " << 2; - if (listener->stream() != NULL) { - // Verifies that we can stream to the listener's underlying stream - // too. - *listener->stream() << " == " << (x % 2); + template <typename T> + bool MatchAndExplain(const T& x, MatchResultListener* listener) const { + // Verifies that we can stream to the listener directly. + *listener << "% " << 2; + if (listener->stream() != NULL) { + // Verifies that we can stream to the listener's underlying stream + // too. + *listener->stream() << " == " << (x % 2); + } + return (x % 2) == 0; } - return (x % 2) == 0; -} +}; PolymorphicMatcher<PolymorphicIsEvenImpl> PolymorphicIsEven() { return MakePolymorphicMatcher(PolymorphicIsEvenImpl()); } TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) { // Using PolymorphicIsEven() as a Matcher<int>. const Matcher<int> m1 = PolymorphicIsEven(); EXPECT_TRUE(m1.Matches(42)); EXPECT_FALSE(m1.Matches(43)); EXPECT_EQ("is even", Describe(m1)); const Matcher<int> not_m1 = Not(m1); EXPECT_EQ("is odd", Describe(not_m1)); EXPECT_EQ("% 2 == 0", Explain(m1, 42)); // Using PolymorphicIsEven() as a Matcher<char>. const Matcher<char> m2 = PolymorphicIsEven(); EXPECT_TRUE(m2.Matches('\x42')); EXPECT_FALSE(m2.Matches('\x43')); EXPECT_EQ("is even", Describe(m2)); const Matcher<char> not_m2 = Not(m2); EXPECT_EQ("is odd", Describe(not_m2)); EXPECT_EQ("% 2 == 0", Explain(m2, '\x42')); } // Tests that MatcherCast<T>(m) works when m is a polymorphic matcher. TEST(MatcherCastTest, FromPolymorphicMatcher) { Matcher<int> m = MatcherCast<int>(Eq(5)); EXPECT_TRUE(m.Matches(5)); EXPECT_FALSE(m.Matches(6)); } // For testing casting matchers between compatible types. class IntValue { public: // An int can be statically (although not implicitly) cast to a // IntValue. explicit IntValue(int a_value) : value_(a_value) {} int value() const { return value_; } private: int value_; }; // For testing casting matchers between compatible types. bool IsPositiveIntValue(const IntValue& foo) { return foo.value() > 0; } // Tests that MatcherCast<T>(m) works when m is a Matcher<U> where T // can be statically converted to U. TEST(MatcherCastTest, FromCompatibleType) { Matcher<double> m1 = Eq(2.0); Matcher<int> m2 = MatcherCast<int>(m1); EXPECT_TRUE(m2.Matches(2)); EXPECT_FALSE(m2.Matches(3)); Matcher<IntValue> m3 = Truly(IsPositiveIntValue); Matcher<int> m4 = MatcherCast<int>(m3); // In the following, the arguments 1 and 0 are statically converted // to IntValue objects, and then tested by the IsPositiveIntValue() // predicate. EXPECT_TRUE(m4.Matches(1)); EXPECT_FALSE(m4.Matches(0)); } // Tests that MatcherCast<T>(m) works when m is a Matcher<const T&>. TEST(MatcherCastTest, FromConstReferenceToNonReference) { Matcher<const int&> m1 = Eq(0); Matcher<int> m2 = MatcherCast<int>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } // Tests that MatcherCast<T>(m) works when m is a Matcher<T&>. TEST(MatcherCastTest, FromReferenceToNonReference) { Matcher<int&> m1 = Eq(0); Matcher<int> m2 = MatcherCast<int>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } // Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. TEST(MatcherCastTest, FromNonReferenceToConstReference) { Matcher<int> m1 = Eq(0); Matcher<const int&> m2 = MatcherCast<const int&>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } // Tests that MatcherCast<T&>(m) works when m is a Matcher<T>. TEST(MatcherCastTest, FromNonReferenceToReference) { Matcher<int> m1 = Eq(0); Matcher<int&> m2 = MatcherCast<int&>(m1); int n = 0; EXPECT_TRUE(m2.Matches(n)); n = 1; EXPECT_FALSE(m2.Matches(n)); } // Tests that MatcherCast<T>(m) works when m is a Matcher<T>. TEST(MatcherCastTest, FromSameType) { Matcher<int> m1 = Eq(0); Matcher<int> m2 = MatcherCast<int>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } class Base {}; class Derived : public Base {}; // Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher. TEST(SafeMatcherCastTest, FromPolymorphicMatcher) { Matcher<char> m2 = SafeMatcherCast<char>(Eq(32)); EXPECT_TRUE(m2.Matches(' ')); EXPECT_FALSE(m2.Matches('\n')); } // Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where // T and U are arithmetic types and T can be losslessly converted to // U. TEST(SafeMatcherCastTest, FromLosslesslyConvertibleArithmeticType) { Matcher<double> m1 = DoubleEq(1.0); Matcher<float> m2 = SafeMatcherCast<float>(m1); EXPECT_TRUE(m2.Matches(1.0f)); EXPECT_FALSE(m2.Matches(2.0f)); Matcher<char> m3 = SafeMatcherCast<char>(TypedEq<int>('a')); EXPECT_TRUE(m3.Matches('a')); EXPECT_FALSE(m3.Matches('b')); } // Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where T and U // are pointers or references to a derived and a base class, correspondingly. TEST(SafeMatcherCastTest, FromBaseClass) { Derived d, d2; Matcher<Base*> m1 = Eq(&d); Matcher<Derived*> m2 = SafeMatcherCast<Derived*>(m1); EXPECT_TRUE(m2.Matches(&d)); EXPECT_FALSE(m2.Matches(&d2)); Matcher<Base&> m3 = Ref(d); Matcher<Derived&> m4 = SafeMatcherCast<Derived&>(m3); EXPECT_TRUE(m4.Matches(d)); EXPECT_FALSE(m4.Matches(d2)); } // Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<const T&>. TEST(SafeMatcherCastTest, FromConstReferenceToReference) { int n = 0; Matcher<const int&> m1 = Ref(n); Matcher<int&> m2 = SafeMatcherCast<int&>(m1); int n1 = 0; EXPECT_TRUE(m2.Matches(n)); EXPECT_FALSE(m2.Matches(n1)); } // Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { Matcher<int> m1 = Eq(0); Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } // Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>. TEST(SafeMatcherCastTest, FromNonReferenceToReference) { Matcher<int> m1 = Eq(0); Matcher<int&> m2 = SafeMatcherCast<int&>(m1); int n = 0; EXPECT_TRUE(m2.Matches(n)); n = 1; EXPECT_FALSE(m2.Matches(n)); } // Tests that SafeMatcherCast<T>(m) works when m is a Matcher<T>. TEST(SafeMatcherCastTest, FromSameType) { Matcher<int> m1 = Eq(0); Matcher<int> m2 = SafeMatcherCast<int>(m1); EXPECT_TRUE(m2.Matches(0)); EXPECT_FALSE(m2.Matches(1)); } // Tests that A<T>() matches any value of type T. TEST(ATest, MatchesAnyValue) { // Tests a matcher for a value type. Matcher<double> m1 = A<double>(); EXPECT_TRUE(m1.Matches(91.43)); EXPECT_TRUE(m1.Matches(-15.32)); // Tests a matcher for a reference type. int a = 2; int b = -6; Matcher<int&> m2 = A<int&>(); EXPECT_TRUE(m2.Matches(a)); EXPECT_TRUE(m2.Matches(b)); } // Tests that A<T>() describes itself properly. TEST(ATest, CanDescribeSelf) { EXPECT_EQ("is anything", Describe(A<bool>())); } // Tests that An<T>() matches any value of type T. TEST(AnTest, MatchesAnyValue) { // Tests a matcher for a value type. Matcher<int> m1 = An<int>(); EXPECT_TRUE(m1.Matches(9143)); EXPECT_TRUE(m1.Matches(-1532)); // Tests a matcher for a reference type. int a = 2; int b = -6; Matcher<int&> m2 = An<int&>(); EXPECT_TRUE(m2.Matches(a)); EXPECT_TRUE(m2.Matches(b)); } // Tests that An<T>() describes itself properly. TEST(AnTest, CanDescribeSelf) { EXPECT_EQ("is anything", Describe(An<int>())); } // Tests that _ can be used as a matcher for any type and matches any // value of that type. TEST(UnderscoreTest, MatchesAnyValue) { // Uses _ as a matcher for a value type. Matcher<int> m1 = _; EXPECT_TRUE(m1.Matches(123)); EXPECT_TRUE(m1.Matches(-242)); // Uses _ as a matcher for a reference type. bool a = false; const bool b = true; Matcher<const bool&> m2 = _; EXPECT_TRUE(m2.Matches(a)); EXPECT_TRUE(m2.Matches(b)); } // Tests that _ describes itself properly. TEST(UnderscoreTest, CanDescribeSelf) { Matcher<int> m = _; EXPECT_EQ("is anything", Describe(m)); } // Tests that Eq(x) matches any value equal to x. TEST(EqTest, MatchesEqualValue) { // 2 C-strings with same content but different addresses. const char a1[] = "hi"; const char a2[] = "hi"; Matcher<const char*> m1 = Eq(a1); EXPECT_TRUE(m1.Matches(a1)); EXPECT_FALSE(m1.Matches(a2)); } // Tests that Eq(v) describes itself properly. class Unprintable { public: Unprintable() : c_('a') {} bool operator==(const Unprintable& /* rhs */) { return true; } private: char c_; }; TEST(EqTest, CanDescribeSelf) { Matcher<Unprintable> m = Eq(Unprintable()); EXPECT_EQ("is equal to 1-byte object <61>", Describe(m)); } // Tests that Eq(v) can be used to match any type that supports // comparing with type T, where T is v's type. TEST(EqTest, IsPolymorphic) { Matcher<int> m1 = Eq(1); EXPECT_TRUE(m1.Matches(1)); EXPECT_FALSE(m1.Matches(2)); Matcher<char> m2 = Eq(1); EXPECT_TRUE(m2.Matches('\1')); EXPECT_FALSE(m2.Matches('a')); } // Tests that TypedEq<T>(v) matches values of type T that's equal to v. TEST(TypedEqTest, ChecksEqualityForGivenType) { Matcher<char> m1 = TypedEq<char>('a'); EXPECT_TRUE(m1.Matches('a')); EXPECT_FALSE(m1.Matches('b')); Matcher<int> m2 = TypedEq<int>(6); EXPECT_TRUE(m2.Matches(6)); EXPECT_FALSE(m2.Matches(7)); } // Tests that TypedEq(v) describes itself properly. TEST(TypedEqTest, CanDescribeSelf) { EXPECT_EQ("is equal to 2", Describe(TypedEq<int>(2))); } // Tests that TypedEq<T>(v) has type Matcher<T>. // Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T // is a "bare" type (i.e. not in the form of const U or U&). If v's // type is not T, the compiler will generate a message about // "undefined referece". template <typename T> struct Type { static bool IsTypeOf(const T& /* v */) { return true; } template <typename T2> static void IsTypeOf(T2 v); }; TEST(TypedEqTest, HasSpecifiedType) { // Verfies that the type of TypedEq<T>(v) is Matcher<T>. Type<Matcher<int> >::IsTypeOf(TypedEq<int>(5)); Type<Matcher<double> >::IsTypeOf(TypedEq<double>(5)); } // Tests that Ge(v) matches anything >= v. TEST(GeTest, ImplementsGreaterThanOrEqual) { Matcher<int> m1 = Ge(0); EXPECT_TRUE(m1.Matches(1)); EXPECT_TRUE(m1.Matches(0)); EXPECT_FALSE(m1.Matches(-1)); } // Tests that Ge(v) describes itself properly. TEST(GeTest, CanDescribeSelf) { Matcher<int> m = Ge(5); EXPECT_EQ("is greater than or equal to 5", Describe(m)); } // Tests that Gt(v) matches anything > v. TEST(GtTest, ImplementsGreaterThan) { Matcher<double> m1 = Gt(0); EXPECT_TRUE(m1.Matches(1.0)); EXPECT_FALSE(m1.Matches(0.0)); EXPECT_FALSE(m1.Matches(-1.0)); } // Tests that Gt(v) describes itself properly. TEST(GtTest, CanDescribeSelf) { Matcher<int> m = Gt(5); EXPECT_EQ("is greater than 5", Describe(m)); } // Tests that Le(v) matches anything <= v. TEST(LeTest, ImplementsLessThanOrEqual) { Matcher<char> m1 = Le('b'); EXPECT_TRUE(m1.Matches('a')); EXPECT_TRUE(m1.Matches('b')); EXPECT_FALSE(m1.Matches('c')); } // Tests that Le(v) describes itself properly. TEST(LeTest, CanDescribeSelf) { Matcher<int> m = Le(5); EXPECT_EQ("is less than or equal to 5", Describe(m)); } // Tests that Lt(v) matches anything < v. TEST(LtTest, ImplementsLessThan) { Matcher<const string&> m1 = Lt("Hello"); EXPECT_TRUE(m1.Matches("Abc")); EXPECT_FALSE(m1.Matches("Hello")); EXPECT_FALSE(m1.Matches("Hello, world!")); } // Tests that Lt(v) describes itself properly. TEST(LtTest, CanDescribeSelf) { Matcher<int> m = Lt(5); EXPECT_EQ("is less than 5", Describe(m)); } // Tests that Ne(v) matches anything != v. TEST(NeTest, ImplementsNotEqual) { Matcher<int> m1 = Ne(0); EXPECT_TRUE(m1.Matches(1)); EXPECT_TRUE(m1.Matches(-1)); EXPECT_FALSE(m1.Matches(0)); } // Tests that Ne(v) describes itself properly. TEST(NeTest, CanDescribeSelf) { Matcher<int> m = Ne(5); EXPECT_EQ("is not equal to 5", Describe(m)); } // Tests that IsNull() matches any NULL pointer of any type. TEST(IsNullTest, MatchesNullPointer) { Matcher<int*> m1 = IsNull(); int* p1 = NULL; int n = 0; EXPECT_TRUE(m1.Matches(p1)); EXPECT_FALSE(m1.Matches(&n)); Matcher<const char*> m2 = IsNull(); const char* p2 = NULL; EXPECT_TRUE(m2.Matches(p2)); EXPECT_FALSE(m2.Matches("hi")); #if !GTEST_OS_SYMBIAN // Nokia's Symbian compiler generates: // gmock-matchers.h: ambiguous access to overloaded function // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(void *)' // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(const testing:: // MatcherInterface<void *> *)' // gmock-matchers.h: (point of instantiation: 'testing:: // gmock_matchers_test::IsNullTest_MatchesNullPointer_Test::TestBody()') // gmock-matchers.h: (instantiating: 'testing::PolymorphicMatc Matcher<void*> m3 = IsNull(); void* p3 = NULL; EXPECT_TRUE(m3.Matches(p3)); EXPECT_FALSE(m3.Matches(reinterpret_cast<void*>(0xbeef))); #endif } TEST(IsNullTest, LinkedPtr) { const Matcher<linked_ptr<int> > m = IsNull(); const linked_ptr<int> null_p; const linked_ptr<int> non_null_p(new int); EXPECT_TRUE(m.Matches(null_p)); EXPECT_FALSE(m.Matches(non_null_p)); } TEST(IsNullTest, ReferenceToConstLinkedPtr) { const Matcher<const linked_ptr<double>&> m = IsNull(); const linked_ptr<double> null_p; const linked_ptr<double> non_null_p(new double); EXPECT_TRUE(m.Matches(null_p)); EXPECT_FALSE(m.Matches(non_null_p)); } TEST(IsNullTest, ReferenceToConstScopedPtr) { const Matcher<const scoped_ptr<double>&> m = IsNull(); const scoped_ptr<double> null_p; const scoped_ptr<double> non_null_p(new double); EXPECT_TRUE(m.Matches(null_p)); EXPECT_FALSE(m.Matches(non_null_p)); } // Tests that IsNull() describes itself properly. TEST(IsNullTest, CanDescribeSelf) { Matcher<int*> m = IsNull(); EXPECT_EQ("is NULL", Describe(m)); EXPECT_EQ("is not NULL", DescribeNegation(m)); } // Tests that NotNull() matches any non-NULL pointer of any type. TEST(NotNullTest, MatchesNonNullPointer) { Matcher<int*> m1 = NotNull(); int* p1 = NULL; int n = 0; EXPECT_FALSE(m1.Matches(p1)); EXPECT_TRUE(m1.Matches(&n)); Matcher<const char*> m2 = NotNull(); const char* p2 = NULL; EXPECT_FALSE(m2.Matches(p2)); EXPECT_TRUE(m2.Matches("hi")); } TEST(NotNullTest, LinkedPtr) { const Matcher<linked_ptr<int> > m = NotNull(); const linked_ptr<int> null_p; const linked_ptr<int> non_null_p(new int); EXPECT_FALSE(m.Matches(null_p)); EXPECT_TRUE(m.Matches(non_null_p)); } TEST(NotNullTest, ReferenceToConstLinkedPtr) { const Matcher<const linked_ptr<double>&> m = NotNull(); const linked_ptr<double> null_p; const linked_ptr<double> non_null_p(new double); EXPECT_FALSE(m.Matches(null_p)); EXPECT_TRUE(m.Matches(non_null_p)); } TEST(NotNullTest, ReferenceToConstScopedPtr) { const Matcher<const scoped_ptr<double>&> m = NotNull(); const scoped_ptr<double> null_p; const scoped_ptr<double> non_null_p(new double); EXPECT_FALSE(m.Matches(null_p)); EXPECT_TRUE(m.Matches(non_null_p)); } // Tests that NotNull() describes itself properly. TEST(NotNullTest, CanDescribeSelf) { Matcher<int*> m = NotNull(); EXPECT_EQ("is not NULL", Describe(m)); } // Tests that Ref(variable) matches an argument that references // 'variable'. TEST(RefTest, MatchesSameVariable) { int a = 0; int b = 0; Matcher<int&> m = Ref(a); EXPECT_TRUE(m.Matches(a)); EXPECT_FALSE(m.Matches(b)); } // Tests that Ref(variable) describes itself properly. TEST(RefTest, CanDescribeSelf) { int n = 5; Matcher<int&> m = Ref(n); stringstream ss; ss << "references the variable @" << &n << " 5"; EXPECT_EQ(string(ss.str()), Describe(m)); } // Test that Ref(non_const_varialbe) can be used as a matcher for a // const reference. TEST(RefTest, CanBeUsedAsMatcherForConstReference) { int a = 0; int b = 0; Matcher<const int&> m = Ref(a); EXPECT_TRUE(m.Matches(a)); EXPECT_FALSE(m.Matches(b)); } // Tests that Ref(variable) is covariant, i.e. Ref(derived) can be // used wherever Ref(base) can be used (Ref(derived) is a sub-type // of Ref(base), but not vice versa. TEST(RefTest, IsCovariant) { Base base, base2; Derived derived; Matcher<const Base&> m1 = Ref(base); EXPECT_TRUE(m1.Matches(base)); EXPECT_FALSE(m1.Matches(base2)); EXPECT_FALSE(m1.Matches(derived)); m1 = Ref(derived); EXPECT_TRUE(m1.Matches(derived)); EXPECT_FALSE(m1.Matches(base)); EXPECT_FALSE(m1.Matches(base2)); } // Tests string comparison matchers. TEST(StrEqTest, MatchesEqualString) { Matcher<const char*> m = StrEq(string("Hello")); EXPECT_TRUE(m.Matches("Hello")); EXPECT_FALSE(m.Matches("hello")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const string&> m2 = StrEq("Hello"); EXPECT_TRUE(m2.Matches("Hello")); EXPECT_FALSE(m2.Matches("Hi")); } TEST(StrEqTest, CanDescribeSelf) { Matcher<string> m = StrEq("Hi-\'\"\?\\\a\b\f\n\r\t\v\xD3"); EXPECT_EQ("is equal to \"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\\xD3\"", Describe(m)); string str("01204500800"); str[3] = '\0'; Matcher<string> m2 = StrEq(str); EXPECT_EQ("is equal to \"012\\04500800\"", Describe(m2)); str[0] = str[6] = str[7] = str[9] = str[10] = '\0'; Matcher<string> m3 = StrEq(str); EXPECT_EQ("is equal to \"\\012\\045\\0\\08\\0\\0\"", Describe(m3)); } TEST(StrNeTest, MatchesUnequalString) { Matcher<const char*> m = StrNe("Hello"); EXPECT_TRUE(m.Matches("")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches("Hello")); Matcher<string> m2 = StrNe(string("Hello")); EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hello")); } TEST(StrNeTest, CanDescribeSelf) { Matcher<const char*> m = StrNe("Hi"); EXPECT_EQ("is not equal to \"Hi\"", Describe(m)); } TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { Matcher<const char*> m = StrCaseEq(string("Hello")); EXPECT_TRUE(m.Matches("Hello")); EXPECT_TRUE(m.Matches("hello")); EXPECT_FALSE(m.Matches("Hi")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const string&> m2 = StrCaseEq("Hello"); EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hi")); } TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { string str1("oabocdooeoo"); string str2("OABOCDOOEOO"); Matcher<const string&> m0 = StrCaseEq(str1); EXPECT_FALSE(m0.Matches(str2 + string(1, '\0'))); str1[3] = str2[3] = '\0'; Matcher<const string&> m1 = StrCaseEq(str1); EXPECT_TRUE(m1.Matches(str2)); str1[0] = str1[6] = str1[7] = str1[10] = '\0'; str2[0] = str2[6] = str2[7] = str2[10] = '\0'; Matcher<const string&> m2 = StrCaseEq(str1); str1[9] = str2[9] = '\0'; EXPECT_FALSE(m2.Matches(str2)); Matcher<const string&> m3 = StrCaseEq(str1); EXPECT_TRUE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(str2 + "x")); str2.append(1, '\0'); EXPECT_FALSE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(string(str2, 0, 9))); } TEST(StrCaseEqTest, CanDescribeSelf) { Matcher<string> m = StrCaseEq("Hi"); EXPECT_EQ("is equal to (ignoring case) \"Hi\"", Describe(m)); } TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { Matcher<const char*> m = StrCaseNe("Hello"); EXPECT_TRUE(m.Matches("Hi")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches("Hello")); EXPECT_FALSE(m.Matches("hello")); Matcher<string> m2 = StrCaseNe(string("Hello")); EXPECT_TRUE(m2.Matches("")); EXPECT_FALSE(m2.Matches("Hello")); } TEST(StrCaseNeTest, CanDescribeSelf) { Matcher<const char*> m = StrCaseNe("Hi"); EXPECT_EQ("is not equal to (ignoring case) \"Hi\"", Describe(m)); } // Tests that HasSubstr() works for matching string-typed values. TEST(HasSubstrTest, WorksForStringClasses) { const Matcher<string> m1 = HasSubstr("foo"); EXPECT_TRUE(m1.Matches(string("I love food."))); EXPECT_FALSE(m1.Matches(string("tofo"))); const Matcher<const std::string&> m2 = HasSubstr("foo"); EXPECT_TRUE(m2.Matches(std::string("I love food."))); EXPECT_FALSE(m2.Matches(std::string("tofo"))); } // Tests that HasSubstr() works for matching C-string-typed values. TEST(HasSubstrTest, WorksForCStrings) { const Matcher<char*> m1 = HasSubstr("foo"); EXPECT_TRUE(m1.Matches(const_cast<char*>("I love food."))); EXPECT_FALSE(m1.Matches(const_cast<char*>("tofo"))); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const char*> m2 = HasSubstr("foo"); EXPECT_TRUE(m2.Matches("I love food.")); EXPECT_FALSE(m2.Matches("tofo")); EXPECT_FALSE(m2.Matches(NULL)); } // Tests that HasSubstr(s) describes itself properly. TEST(HasSubstrTest, CanDescribeSelf) { Matcher<string> m = HasSubstr("foo\n\""); EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m)); } TEST(KeyTest, CanDescribeSelf) { Matcher<const std::pair<std::string, int>&> m = Key("foo"); EXPECT_EQ("has a key that is equal to \"foo\"", Describe(m)); } TEST(KeyTest, MatchesCorrectly) { std::pair<int, std::string> p(25, "foo"); EXPECT_THAT(p, Key(25)); EXPECT_THAT(p, Not(Key(42))); EXPECT_THAT(p, Key(Ge(20))); EXPECT_THAT(p, Not(Key(Lt(25)))); } TEST(KeyTest, SafelyCastsInnerMatcher) { Matcher<int> is_positive = Gt(0); Matcher<int> is_negative = Lt(0); std::pair<char, bool> p('a', true); EXPECT_THAT(p, Key(is_positive)); EXPECT_THAT(p, Not(Key(is_negative))); } TEST(KeyTest, InsideContainsUsingMap) { std::map<int, char> container; container.insert(std::make_pair(1, 'a')); container.insert(std::make_pair(2, 'b')); container.insert(std::make_pair(4, 'c')); EXPECT_THAT(container, Contains(Key(1))); EXPECT_THAT(container, Not(Contains(Key(3)))); } TEST(KeyTest, InsideContainsUsingMultimap) { std::multimap<int, char> container; container.insert(std::make_pair(1, 'a')); container.insert(std::make_pair(2, 'b')); container.insert(std::make_pair(4, 'c')); EXPECT_THAT(container, Not(Contains(Key(25)))); container.insert(std::make_pair(25, 'd')); EXPECT_THAT(container, Contains(Key(25))); container.insert(std::make_pair(25, 'e')); EXPECT_THAT(container, Contains(Key(25))); EXPECT_THAT(container, Contains(Key(1))); EXPECT_THAT(container, Not(Contains(Key(3)))); } TEST(PairTest, Typing) { // Test verifies the following type conversions can be compiled. Matcher<const std::pair<const char*, int>&> m1 = Pair("foo", 42); Matcher<const std::pair<const char*, int> > m2 = Pair("foo", 42); Matcher<std::pair<const char*, int> > m3 = Pair("foo", 42); Matcher<std::pair<int, const std::string> > m4 = Pair(25, "42"); Matcher<std::pair<const std::string, int> > m5 = Pair("25", 42); } TEST(PairTest, CanDescribeSelf) { Matcher<const std::pair<std::string, int>&> m1 = Pair("foo", 42); EXPECT_EQ("has a first field that is equal to \"foo\"" ", and has a second field that is equal to 42", Describe(m1)); EXPECT_EQ("has a first field that is not equal to \"foo\"" ", or has a second field that is not equal to 42", DescribeNegation(m1)); // Double and triple negation (1 or 2 times not and description of negation). Matcher<const std::pair<int, int>&> m2 = Not(Pair(Not(13), 42)); EXPECT_EQ("has a first field that is not equal to 13" ", and has a second field that is equal to 42", DescribeNegation(m2)); } TEST(PairTest, CanExplainMatchResultTo) { // If neither field matches, Pair() should explain about the first // field. const Matcher<std::pair<int, int> > m = Pair(GreaterThan(0), GreaterThan(0)); EXPECT_EQ("the first field is 1 less than 0", Explain(m, std::make_pair(-1, -2))); // If the first field matches but the second doesn't, Pair() should // explain about the second field. EXPECT_EQ("the second field is 2 less than 0", Explain(m, std::make_pair(1, -2))); // If the first field doesn't match but the second does, Pair() // should explain about the first field. EXPECT_EQ("the first field is 1 less than 0", Explain(m, std::make_pair(-1, 2))); // If both fields match, Pair() should explain about them both. EXPECT_EQ("the first field is 1 more than 0" ", and the second field is 2 more than 0", Explain(m, std::make_pair(1, 2))); } TEST(PairTest, MatchesCorrectly) { std::pair<int, std::string> p(25, "foo"); // Both fields match. EXPECT_THAT(p, Pair(25, "foo")); EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); // 'first' doesnt' match, but 'second' matches. EXPECT_THAT(p, Not(Pair(42, "foo"))); EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); // 'first' matches, but 'second' doesn't match. EXPECT_THAT(p, Not(Pair(25, "bar"))); EXPECT_THAT(p, Not(Pair(25, Not("foo")))); // Neither field matches. EXPECT_THAT(p, Not(Pair(13, "bar"))); EXPECT_THAT(p, Not(Pair(Lt(13), HasSubstr("a")))); } TEST(PairTest, SafelyCastsInnerMatchers) { Matcher<int> is_positive = Gt(0); Matcher<int> is_negative = Lt(0); std::pair<char, bool> p('a', true); EXPECT_THAT(p, Pair(is_positive, _)); EXPECT_THAT(p, Not(Pair(is_negative, _))); EXPECT_THAT(p, Pair(_, is_positive)); EXPECT_THAT(p, Not(Pair(_, is_negative))); } TEST(PairTest, InsideContainsUsingMap) { std::map<int, char> container; container.insert(std::make_pair(1, 'a')); container.insert(std::make_pair(2, 'b')); container.insert(std::make_pair(4, 'c')); EXPECT_THAT(container, Contains(Pair(1, 'a'))); EXPECT_THAT(container, Contains(Pair(1, _))); EXPECT_THAT(container, Contains(Pair(_, 'a'))); EXPECT_THAT(container, Not(Contains(Pair(3, _)))); } // Tests StartsWith(s). TEST(StartsWithTest, MatchesStringWithGivenPrefix) { const Matcher<const char*> m1 = StartsWith(string("")); EXPECT_TRUE(m1.Matches("Hi")); EXPECT_TRUE(m1.Matches("")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const string&> m2 = StartsWith("Hi"); EXPECT_TRUE(m2.Matches("Hi")); EXPECT_TRUE(m2.Matches("Hi Hi!")); EXPECT_TRUE(m2.Matches("High")); EXPECT_FALSE(m2.Matches("H")); EXPECT_FALSE(m2.Matches(" Hi")); } TEST(StartsWithTest, CanDescribeSelf) { Matcher<const std::string> m = StartsWith("Hi"); EXPECT_EQ("starts with \"Hi\"", Describe(m)); } // Tests EndsWith(s). TEST(EndsWithTest, MatchesStringWithGivenSuffix) { const Matcher<const char*> m1 = EndsWith(""); EXPECT_TRUE(m1.Matches("Hi")); EXPECT_TRUE(m1.Matches("")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const string&> m2 = EndsWith(string("Hi")); EXPECT_TRUE(m2.Matches("Hi")); EXPECT_TRUE(m2.Matches("Wow Hi Hi")); EXPECT_TRUE(m2.Matches("Super Hi")); EXPECT_FALSE(m2.Matches("i")); EXPECT_FALSE(m2.Matches("Hi ")); } TEST(EndsWithTest, CanDescribeSelf) { Matcher<const std::string> m = EndsWith("Hi"); EXPECT_EQ("ends with \"Hi\"", Describe(m)); } // Tests MatchesRegex(). TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { const Matcher<const char*> m1 = MatchesRegex("a.*z"); EXPECT_TRUE(m1.Matches("az")); EXPECT_TRUE(m1.Matches("abcz")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const string&> m2 = MatchesRegex(new RE("a.*z")); EXPECT_TRUE(m2.Matches("azbz")); EXPECT_FALSE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1az")); } TEST(MatchesRegexTest, CanDescribeSelf) { Matcher<const std::string> m1 = MatchesRegex(string("Hi.*")); EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1)); Matcher<const char*> m2 = MatchesRegex(new RE("a.*")); EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); } // Tests ContainsRegex(). TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { const Matcher<const char*> m1 = ContainsRegex(string("a.*z")); EXPECT_TRUE(m1.Matches("az")); EXPECT_TRUE(m1.Matches("0abcz1")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const string&> m2 = ContainsRegex(new RE("a.*z")); EXPECT_TRUE(m2.Matches("azbz")); EXPECT_TRUE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1a")); } TEST(ContainsRegexTest, CanDescribeSelf) { Matcher<const std::string> m1 = ContainsRegex("Hi.*"); EXPECT_EQ("contains regular expression \"Hi.*\"", Describe(m1)); Matcher<const char*> m2 = ContainsRegex(new RE("a.*")); EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); } // Tests for wide strings. #if GTEST_HAS_STD_WSTRING TEST(StdWideStrEqTest, MatchesEqual) { Matcher<const wchar_t*> m = StrEq(::std::wstring(L"Hello")); EXPECT_TRUE(m.Matches(L"Hello")); EXPECT_FALSE(m.Matches(L"hello")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const ::std::wstring&> m2 = StrEq(L"Hello"); EXPECT_TRUE(m2.Matches(L"Hello")); EXPECT_FALSE(m2.Matches(L"Hi")); Matcher<const ::std::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); ::std::wstring str(L"01204500800"); str[3] = L'\0'; Matcher<const ::std::wstring&> m4 = StrEq(str); EXPECT_TRUE(m4.Matches(str)); str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; Matcher<const ::std::wstring&> m5 = StrEq(str); EXPECT_TRUE(m5.Matches(str)); } TEST(StdWideStrEqTest, CanDescribeSelf) { Matcher< ::std::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v"); EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"", Describe(m)); Matcher< ::std::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", Describe(m2)); ::std::wstring str(L"01204500800"); str[3] = L'\0'; Matcher<const ::std::wstring&> m4 = StrEq(str); EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; Matcher<const ::std::wstring&> m5 = StrEq(str); EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); } TEST(StdWideStrNeTest, MatchesUnequalString) { Matcher<const wchar_t*> m = StrNe(L"Hello"); EXPECT_TRUE(m.Matches(L"")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches(L"Hello")); Matcher< ::std::wstring> m2 = StrNe(::std::wstring(L"Hello")); EXPECT_TRUE(m2.Matches(L"hello")); EXPECT_FALSE(m2.Matches(L"Hello")); } TEST(StdWideStrNeTest, CanDescribeSelf) { Matcher<const wchar_t*> m = StrNe(L"Hi"); EXPECT_EQ("is not equal to L\"Hi\"", Describe(m)); } TEST(StdWideStrCaseEqTest, MatchesEqualStringIgnoringCase) { Matcher<const wchar_t*> m = StrCaseEq(::std::wstring(L"Hello")); EXPECT_TRUE(m.Matches(L"Hello")); EXPECT_TRUE(m.Matches(L"hello")); EXPECT_FALSE(m.Matches(L"Hi")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const ::std::wstring&> m2 = StrCaseEq(L"Hello"); EXPECT_TRUE(m2.Matches(L"hello")); EXPECT_FALSE(m2.Matches(L"Hi")); } TEST(StdWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { ::std::wstring str1(L"oabocdooeoo"); ::std::wstring str2(L"OABOCDOOEOO"); Matcher<const ::std::wstring&> m0 = StrCaseEq(str1); EXPECT_FALSE(m0.Matches(str2 + ::std::wstring(1, L'\0'))); str1[3] = str2[3] = L'\0'; Matcher<const ::std::wstring&> m1 = StrCaseEq(str1); EXPECT_TRUE(m1.Matches(str2)); str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; Matcher<const ::std::wstring&> m2 = StrCaseEq(str1); str1[9] = str2[9] = L'\0'; EXPECT_FALSE(m2.Matches(str2)); Matcher<const ::std::wstring&> m3 = StrCaseEq(str1); EXPECT_TRUE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(str2 + L"x")); str2.append(1, L'\0'); EXPECT_FALSE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(::std::wstring(str2, 0, 9))); } TEST(StdWideStrCaseEqTest, CanDescribeSelf) { Matcher< ::std::wstring> m = StrCaseEq(L"Hi"); EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); } TEST(StdWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); EXPECT_TRUE(m.Matches(L"Hi")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches(L"Hello")); EXPECT_FALSE(m.Matches(L"hello")); Matcher< ::std::wstring> m2 = StrCaseNe(::std::wstring(L"Hello")); EXPECT_TRUE(m2.Matches(L"")); EXPECT_FALSE(m2.Matches(L"Hello")); } TEST(StdWideStrCaseNeTest, CanDescribeSelf) { Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m)); } // Tests that HasSubstr() works for matching wstring-typed values. TEST(StdWideHasSubstrTest, WorksForStringClasses) { const Matcher< ::std::wstring> m1 = HasSubstr(L"foo"); EXPECT_TRUE(m1.Matches(::std::wstring(L"I love food."))); EXPECT_FALSE(m1.Matches(::std::wstring(L"tofo"))); const Matcher<const ::std::wstring&> m2 = HasSubstr(L"foo"); EXPECT_TRUE(m2.Matches(::std::wstring(L"I love food."))); EXPECT_FALSE(m2.Matches(::std::wstring(L"tofo"))); } // Tests that HasSubstr() works for matching C-wide-string-typed values. TEST(StdWideHasSubstrTest, WorksForCStrings) { const Matcher<wchar_t*> m1 = HasSubstr(L"foo"); EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food."))); EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo"))); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); EXPECT_TRUE(m2.Matches(L"I love food.")); EXPECT_FALSE(m2.Matches(L"tofo")); EXPECT_FALSE(m2.Matches(NULL)); } // Tests that HasSubstr(s) describes itself properly. TEST(StdWideHasSubstrTest, CanDescribeSelf) { Matcher< ::std::wstring> m = HasSubstr(L"foo\n\""); EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); } // Tests StartsWith(s). TEST(StdWideStartsWithTest, MatchesStringWithGivenPrefix) { const Matcher<const wchar_t*> m1 = StartsWith(::std::wstring(L"")); EXPECT_TRUE(m1.Matches(L"Hi")); EXPECT_TRUE(m1.Matches(L"")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const ::std::wstring&> m2 = StartsWith(L"Hi"); EXPECT_TRUE(m2.Matches(L"Hi")); EXPECT_TRUE(m2.Matches(L"Hi Hi!")); EXPECT_TRUE(m2.Matches(L"High")); EXPECT_FALSE(m2.Matches(L"H")); EXPECT_FALSE(m2.Matches(L" Hi")); } TEST(StdWideStartsWithTest, CanDescribeSelf) { Matcher<const ::std::wstring> m = StartsWith(L"Hi"); EXPECT_EQ("starts with L\"Hi\"", Describe(m)); } // Tests EndsWith(s). TEST(StdWideEndsWithTest, MatchesStringWithGivenSuffix) { const Matcher<const wchar_t*> m1 = EndsWith(L""); EXPECT_TRUE(m1.Matches(L"Hi")); EXPECT_TRUE(m1.Matches(L"")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const ::std::wstring&> m2 = EndsWith(::std::wstring(L"Hi")); EXPECT_TRUE(m2.Matches(L"Hi")); EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); EXPECT_TRUE(m2.Matches(L"Super Hi")); EXPECT_FALSE(m2.Matches(L"i")); EXPECT_FALSE(m2.Matches(L"Hi ")); } TEST(StdWideEndsWithTest, CanDescribeSelf) { Matcher<const ::std::wstring> m = EndsWith(L"Hi"); EXPECT_EQ("ends with L\"Hi\"", Describe(m)); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING TEST(GlobalWideStrEqTest, MatchesEqual) { Matcher<const wchar_t*> m = StrEq(::wstring(L"Hello")); EXPECT_TRUE(m.Matches(L"Hello")); EXPECT_FALSE(m.Matches(L"hello")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const ::wstring&> m2 = StrEq(L"Hello"); EXPECT_TRUE(m2.Matches(L"Hello")); EXPECT_FALSE(m2.Matches(L"Hi")); Matcher<const ::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); ::wstring str(L"01204500800"); str[3] = L'\0'; Matcher<const ::wstring&> m4 = StrEq(str); EXPECT_TRUE(m4.Matches(str)); str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; Matcher<const ::wstring&> m5 = StrEq(str); EXPECT_TRUE(m5.Matches(str)); } TEST(GlobalWideStrEqTest, CanDescribeSelf) { Matcher< ::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v"); EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"", Describe(m)); Matcher< ::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", Describe(m2)); ::wstring str(L"01204500800"); str[3] = L'\0'; Matcher<const ::wstring&> m4 = StrEq(str); EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; Matcher<const ::wstring&> m5 = StrEq(str); EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); } TEST(GlobalWideStrNeTest, MatchesUnequalString) { Matcher<const wchar_t*> m = StrNe(L"Hello"); EXPECT_TRUE(m.Matches(L"")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches(L"Hello")); Matcher< ::wstring> m2 = StrNe(::wstring(L"Hello")); EXPECT_TRUE(m2.Matches(L"hello")); EXPECT_FALSE(m2.Matches(L"Hello")); } TEST(GlobalWideStrNeTest, CanDescribeSelf) { Matcher<const wchar_t*> m = StrNe(L"Hi"); EXPECT_EQ("is not equal to L\"Hi\"", Describe(m)); } TEST(GlobalWideStrCaseEqTest, MatchesEqualStringIgnoringCase) { Matcher<const wchar_t*> m = StrCaseEq(::wstring(L"Hello")); EXPECT_TRUE(m.Matches(L"Hello")); EXPECT_TRUE(m.Matches(L"hello")); EXPECT_FALSE(m.Matches(L"Hi")); EXPECT_FALSE(m.Matches(NULL)); Matcher<const ::wstring&> m2 = StrCaseEq(L"Hello"); EXPECT_TRUE(m2.Matches(L"hello")); EXPECT_FALSE(m2.Matches(L"Hi")); } TEST(GlobalWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { ::wstring str1(L"oabocdooeoo"); ::wstring str2(L"OABOCDOOEOO"); Matcher<const ::wstring&> m0 = StrCaseEq(str1); EXPECT_FALSE(m0.Matches(str2 + ::wstring(1, L'\0'))); str1[3] = str2[3] = L'\0'; Matcher<const ::wstring&> m1 = StrCaseEq(str1); EXPECT_TRUE(m1.Matches(str2)); str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; Matcher<const ::wstring&> m2 = StrCaseEq(str1); str1[9] = str2[9] = L'\0'; EXPECT_FALSE(m2.Matches(str2)); Matcher<const ::wstring&> m3 = StrCaseEq(str1); EXPECT_TRUE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(str2 + L"x")); str2.append(1, L'\0'); EXPECT_FALSE(m3.Matches(str2)); EXPECT_FALSE(m3.Matches(::wstring(str2, 0, 9))); } TEST(GlobalWideStrCaseEqTest, CanDescribeSelf) { Matcher< ::wstring> m = StrCaseEq(L"Hi"); EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); } TEST(GlobalWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); EXPECT_TRUE(m.Matches(L"Hi")); EXPECT_TRUE(m.Matches(NULL)); EXPECT_FALSE(m.Matches(L"Hello")); EXPECT_FALSE(m.Matches(L"hello")); Matcher< ::wstring> m2 = StrCaseNe(::wstring(L"Hello")); EXPECT_TRUE(m2.Matches(L"")); EXPECT_FALSE(m2.Matches(L"Hello")); } TEST(GlobalWideStrCaseNeTest, CanDescribeSelf) { Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m)); } // Tests that HasSubstr() works for matching wstring-typed values. TEST(GlobalWideHasSubstrTest, WorksForStringClasses) { const Matcher< ::wstring> m1 = HasSubstr(L"foo"); EXPECT_TRUE(m1.Matches(::wstring(L"I love food."))); EXPECT_FALSE(m1.Matches(::wstring(L"tofo"))); const Matcher<const ::wstring&> m2 = HasSubstr(L"foo"); EXPECT_TRUE(m2.Matches(::wstring(L"I love food."))); EXPECT_FALSE(m2.Matches(::wstring(L"tofo"))); } // Tests that HasSubstr() works for matching C-wide-string-typed values. TEST(GlobalWideHasSubstrTest, WorksForCStrings) { const Matcher<wchar_t*> m1 = HasSubstr(L"foo"); EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food."))); EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo"))); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); EXPECT_TRUE(m2.Matches(L"I love food.")); EXPECT_FALSE(m2.Matches(L"tofo")); EXPECT_FALSE(m2.Matches(NULL)); } // Tests that HasSubstr(s) describes itself properly. TEST(GlobalWideHasSubstrTest, CanDescribeSelf) { Matcher< ::wstring> m = HasSubstr(L"foo\n\""); EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); } // Tests StartsWith(s). TEST(GlobalWideStartsWithTest, MatchesStringWithGivenPrefix) { const Matcher<const wchar_t*> m1 = StartsWith(::wstring(L"")); EXPECT_TRUE(m1.Matches(L"Hi")); EXPECT_TRUE(m1.Matches(L"")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const ::wstring&> m2 = StartsWith(L"Hi"); EXPECT_TRUE(m2.Matches(L"Hi")); EXPECT_TRUE(m2.Matches(L"Hi Hi!")); EXPECT_TRUE(m2.Matches(L"High")); EXPECT_FALSE(m2.Matches(L"H")); EXPECT_FALSE(m2.Matches(L" Hi")); } TEST(GlobalWideStartsWithTest, CanDescribeSelf) { Matcher<const ::wstring> m = StartsWith(L"Hi"); EXPECT_EQ("starts with L\"Hi\"", Describe(m)); } // Tests EndsWith(s). TEST(GlobalWideEndsWithTest, MatchesStringWithGivenSuffix) { const Matcher<const wchar_t*> m1 = EndsWith(L""); EXPECT_TRUE(m1.Matches(L"Hi")); EXPECT_TRUE(m1.Matches(L"")); EXPECT_FALSE(m1.Matches(NULL)); const Matcher<const ::wstring&> m2 = EndsWith(::wstring(L"Hi")); EXPECT_TRUE(m2.Matches(L"Hi")); EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); EXPECT_TRUE(m2.Matches(L"Super Hi")); EXPECT_FALSE(m2.Matches(L"i")); EXPECT_FALSE(m2.Matches(L"Hi ")); } TEST(GlobalWideEndsWithTest, CanDescribeSelf) { Matcher<const ::wstring> m = EndsWith(L"Hi"); EXPECT_EQ("ends with L\"Hi\"", Describe(m)); } #endif // GTEST_HAS_GLOBAL_WSTRING typedef ::std::tr1::tuple<long, int> Tuple2; // NOLINT // Tests that Eq() matches a 2-tuple where the first field == the // second field. TEST(Eq2Test, MatchesEqualArguments) { Matcher<const Tuple2&> m = Eq(); EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); } // Tests that Eq() describes itself properly. TEST(Eq2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Eq(); EXPECT_EQ("are a pair (x, y) where x == y", Describe(m)); } // Tests that Ge() matches a 2-tuple where the first field >= the // second field. TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) { Matcher<const Tuple2&> m = Ge(); EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); } // Tests that Ge() describes itself properly. TEST(Ge2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Ge(); EXPECT_EQ("are a pair (x, y) where x >= y", Describe(m)); } // Tests that Gt() matches a 2-tuple where the first field > the // second field. TEST(Gt2Test, MatchesGreaterThanArguments) { Matcher<const Tuple2&> m = Gt(); EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); } // Tests that Gt() describes itself properly. TEST(Gt2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Gt(); EXPECT_EQ("are a pair (x, y) where x > y", Describe(m)); } // Tests that Le() matches a 2-tuple where the first field <= the // second field. TEST(Le2Test, MatchesLessThanOrEqualArguments) { Matcher<const Tuple2&> m = Le(); EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); EXPECT_FALSE(m.Matches(Tuple2(5L, 4))); } // Tests that Le() describes itself properly. TEST(Le2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Le(); EXPECT_EQ("are a pair (x, y) where x <= y", Describe(m)); } // Tests that Lt() matches a 2-tuple where the first field < the // second field. TEST(Lt2Test, MatchesLessThanArguments) { Matcher<const Tuple2&> m = Lt(); EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); EXPECT_FALSE(m.Matches(Tuple2(5L, 4))); } // Tests that Lt() describes itself properly. TEST(Lt2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Lt(); EXPECT_EQ("are a pair (x, y) where x < y", Describe(m)); } // Tests that Ne() matches a 2-tuple where the first field != the // second field. TEST(Ne2Test, MatchesUnequalArguments) { Matcher<const Tuple2&> m = Ne(); EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); } // Tests that Ne() describes itself properly. TEST(Ne2Test, CanDescribeSelf) { Matcher<const Tuple2&> m = Ne(); EXPECT_EQ("are a pair (x, y) where x != y", Describe(m)); } // Tests that Not(m) matches any value that doesn't match m. TEST(NotTest, NegatesMatcher) { Matcher<int> m; m = Not(Eq(2)); EXPECT_TRUE(m.Matches(3)); EXPECT_FALSE(m.Matches(2)); } // Tests that Not(m) describes itself properly. TEST(NotTest, CanDescribeSelf) { Matcher<int> m = Not(Eq(5)); EXPECT_EQ("is not equal to 5", Describe(m)); } // Tests that monomorphic matchers are safely cast by the Not matcher. TEST(NotTest, NotMatcherSafelyCastsMonomorphicMatchers) { // greater_than_5 is a monomorphic matcher. Matcher<int> greater_than_5 = Gt(5); Matcher<const int&> m = Not(greater_than_5); Matcher<int&> m2 = Not(greater_than_5); Matcher<int&> m3 = Not(m); } // Tests that AllOf(m1, ..., mn) matches any value that matches all of // the given matchers. TEST(AllOfTest, MatchesWhenAllMatch) { Matcher<int> m; m = AllOf(Le(2), Ge(1)); EXPECT_TRUE(m.Matches(1)); EXPECT_TRUE(m.Matches(2)); EXPECT_FALSE(m.Matches(0)); EXPECT_FALSE(m.Matches(3)); m = AllOf(Gt(0), Ne(1), Ne(2)); EXPECT_TRUE(m.Matches(3)); EXPECT_FALSE(m.Matches(2)); EXPECT_FALSE(m.Matches(1)); EXPECT_FALSE(m.Matches(0)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); EXPECT_TRUE(m.Matches(4)); EXPECT_FALSE(m.Matches(3)); EXPECT_FALSE(m.Matches(2)); EXPECT_FALSE(m.Matches(1)); EXPECT_FALSE(m.Matches(0)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); EXPECT_TRUE(m.Matches(0)); EXPECT_TRUE(m.Matches(1)); EXPECT_FALSE(m.Matches(3)); } // Tests that AllOf(m1, ..., mn) describes itself properly. TEST(AllOfTest, CanDescribeSelf) { Matcher<int> m; m = AllOf(Le(2), Ge(1)); EXPECT_EQ("(is less than or equal to 2) and " "(is greater than or equal to 1)", Describe(m)); m = AllOf(Gt(0), Ne(1), Ne(2)); EXPECT_EQ("(is greater than 0) and " "((is not equal to 1) and " "(is not equal to 2))", Describe(m)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); EXPECT_EQ("(is greater than 0) and " "((is not equal to 1) and " "((is not equal to 2) and " "(is not equal to 3)))", Describe(m)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); EXPECT_EQ("(is greater than or equal to 0) and " "((is less than 10) and " "((is not equal to 3) and " "((is not equal to 5) and " "(is not equal to 7))))", Describe(m)); } // Tests that monomorphic matchers are safely cast by the AllOf matcher. TEST(AllOfTest, AllOfMatcherSafelyCastsMonomorphicMatchers) { // greater_than_5 and less_than_10 are monomorphic matchers. Matcher<int> greater_than_5 = Gt(5); Matcher<int> less_than_10 = Lt(10); Matcher<const int&> m = AllOf(greater_than_5, less_than_10); Matcher<int&> m2 = AllOf(greater_than_5, less_than_10); Matcher<int&> m3 = AllOf(greater_than_5, m2); // Tests that BothOf works when composing itself. Matcher<const int&> m4 = AllOf(greater_than_5, less_than_10, less_than_10); Matcher<int&> m5 = AllOf(greater_than_5, less_than_10, less_than_10); } // Tests that AnyOf(m1, ..., mn) matches any value that matches at // least one of the given matchers. TEST(AnyOfTest, MatchesWhenAnyMatches) { Matcher<int> m; m = AnyOf(Le(1), Ge(3)); EXPECT_TRUE(m.Matches(1)); EXPECT_TRUE(m.Matches(4)); EXPECT_FALSE(m.Matches(2)); m = AnyOf(Lt(0), Eq(1), Eq(2)); EXPECT_TRUE(m.Matches(-1)); EXPECT_TRUE(m.Matches(1)); EXPECT_TRUE(m.Matches(2)); EXPECT_FALSE(m.Matches(0)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); EXPECT_TRUE(m.Matches(-1)); EXPECT_TRUE(m.Matches(1)); EXPECT_TRUE(m.Matches(2)); EXPECT_TRUE(m.Matches(3)); EXPECT_FALSE(m.Matches(0)); m = AnyOf(Le(0), Gt(10), 3, 5, 7); EXPECT_TRUE(m.Matches(0)); EXPECT_TRUE(m.Matches(11)); EXPECT_TRUE(m.Matches(3)); EXPECT_FALSE(m.Matches(2)); } // Tests that AnyOf(m1, ..., mn) describes itself properly. TEST(AnyOfTest, CanDescribeSelf) { Matcher<int> m; m = AnyOf(Le(1), Ge(3)); EXPECT_EQ("(is less than or equal to 1) or " "(is greater than or equal to 3)", Describe(m)); m = AnyOf(Lt(0), Eq(1), Eq(2)); EXPECT_EQ("(is less than 0) or " "((is equal to 1) or (is equal to 2))", Describe(m)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); EXPECT_EQ("(is less than 0) or " "((is equal to 1) or " "((is equal to 2) or " "(is equal to 3)))", Describe(m)); m = AnyOf(Le(0), Gt(10), 3, 5, 7); EXPECT_EQ("(is less than or equal to 0) or " "((is greater than 10) or " "((is equal to 3) or " "((is equal to 5) or " "(is equal to 7))))", Describe(m)); } // Tests that monomorphic matchers are safely cast by the AnyOf matcher. TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) { // greater_than_5 and less_than_10 are monomorphic matchers. Matcher<int> greater_than_5 = Gt(5); Matcher<int> less_than_10 = Lt(10); Matcher<const int&> m = AnyOf(greater_than_5, less_than_10); Matcher<int&> m2 = AnyOf(greater_than_5, less_than_10); Matcher<int&> m3 = AnyOf(greater_than_5, m2); // Tests that EitherOf works when composing itself. Matcher<const int&> m4 = AnyOf(greater_than_5, less_than_10, less_than_10); Matcher<int&> m5 = AnyOf(greater_than_5, less_than_10, less_than_10); } // The following predicate function and predicate functor are for // testing the Truly(predicate) matcher. // Returns non-zero if the input is positive. Note that the return // type of this function is not bool. It's OK as Truly() accepts any // unary function or functor whose return type can be implicitly // converted to bool. int IsPositive(double x) { return x > 0 ? 1 : 0; } // This functor returns true if the input is greater than the given // number. class IsGreaterThan { public: explicit IsGreaterThan(int threshold) : threshold_(threshold) {} bool operator()(int n) const { return n > threshold_; } private: int threshold_; }; // For testing Truly(). const int foo = 0; // This predicate returns true iff the argument references foo and has // a zero value. bool ReferencesFooAndIsZero(const int& n) { return (&n == &foo) && (n == 0); } // Tests that Truly(predicate) matches what satisfies the given // predicate. TEST(TrulyTest, MatchesWhatSatisfiesThePredicate) { Matcher<double> m = Truly(IsPositive); EXPECT_TRUE(m.Matches(2.0)); EXPECT_FALSE(m.Matches(-1.5)); } // Tests that Truly(predicate_functor) works too. TEST(TrulyTest, CanBeUsedWithFunctor) { Matcher<int> m = Truly(IsGreaterThan(5)); EXPECT_TRUE(m.Matches(6)); EXPECT_FALSE(m.Matches(4)); } // Tests that Truly(predicate) can describe itself properly. TEST(TrulyTest, CanDescribeSelf) { Matcher<double> m = Truly(IsPositive); EXPECT_EQ("satisfies the given predicate", Describe(m)); } // Tests that Truly(predicate) works when the matcher takes its // argument by reference. TEST(TrulyTest, WorksForByRefArguments) { Matcher<const int&> m = Truly(ReferencesFooAndIsZero); EXPECT_TRUE(m.Matches(foo)); int n = 0; EXPECT_FALSE(m.Matches(n)); } // Tests that Matches(m) is a predicate satisfied by whatever that // matches matcher m. TEST(MatchesTest, IsSatisfiedByWhatMatchesTheMatcher) { EXPECT_TRUE(Matches(Ge(0))(1)); EXPECT_FALSE(Matches(Eq('a'))('b')); } // Tests that Matches(m) works when the matcher takes its argument by // reference. TEST(MatchesTest, WorksOnByRefArguments) { int m = 0, n = 0; EXPECT_TRUE(Matches(AllOf(Ref(n), Eq(0)))(n)); EXPECT_FALSE(Matches(Ref(m))(n)); } // Tests that a Matcher on non-reference type can be used in // Matches(). TEST(MatchesTest, WorksWithMatcherOnNonRefType) { Matcher<int> eq5 = Eq(5); EXPECT_TRUE(Matches(eq5)(5)); EXPECT_FALSE(Matches(eq5)(2)); } // Tests Value(value, matcher). Since Value() is a simple wrapper for // Matches(), which has been tested already, we don't spend a lot of // effort on testing Value(). TEST(ValueTest, WorksWithPolymorphicMatcher) { EXPECT_TRUE(Value("hi", StartsWith("h"))); EXPECT_FALSE(Value(5, Gt(10))); } TEST(ValueTest, WorksWithMonomorphicMatcher) { const Matcher<int> is_zero = Eq(0); EXPECT_TRUE(Value(0, is_zero)); EXPECT_FALSE(Value('a', is_zero)); int n = 0; const Matcher<const int&> ref_n = Ref(n); EXPECT_TRUE(Value(n, ref_n)); EXPECT_FALSE(Value(1, ref_n)); } TEST(AllArgsTest, WorksForTuple) { EXPECT_THAT(make_tuple(1, 2L), AllArgs(Lt())); EXPECT_THAT(make_tuple(2L, 1), Not(AllArgs(Lt()))); } TEST(AllArgsTest, WorksForNonTuple) { EXPECT_THAT(42, AllArgs(Gt(0))); EXPECT_THAT('a', Not(AllArgs(Eq('b')))); } class AllArgsHelper { public: AllArgsHelper() {} MOCK_METHOD2(Helper, int(char x, int y)); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(AllArgsHelper); }; TEST(AllArgsTest, WorksInWithClause) { AllArgsHelper helper; ON_CALL(helper, Helper(_, _)) .With(AllArgs(Lt())) .WillByDefault(Return(1)); EXPECT_CALL(helper, Helper(_, _)); EXPECT_CALL(helper, Helper(_, _)) .With(AllArgs(Gt())) .WillOnce(Return(2)); EXPECT_EQ(1, helper.Helper('\1', 2)); EXPECT_EQ(2, helper.Helper('a', 1)); } // Tests that ASSERT_THAT() and EXPECT_THAT() work when the value // matches the matcher. TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) { ASSERT_THAT(5, Ge(2)) << "This should succeed."; ASSERT_THAT("Foo", EndsWith("oo")); EXPECT_THAT(2, AllOf(Le(7), Ge(0))) << "This should succeed too."; EXPECT_THAT("Hello", StartsWith("Hell")); } // Tests that ASSERT_THAT() and EXPECT_THAT() work when the value // doesn't match the matcher. TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) { // 'n' must be static as it is used in an EXPECT_FATAL_FAILURE(), // which cannot reference auto variables. static int n; n = 5; // VC++ prior to version 8.0 SP1 has a bug where it will not see any // functions declared in the namespace scope from within nested classes. // EXPECT/ASSERT_(NON)FATAL_FAILURE macros use nested classes so that all // namespace-level functions invoked inside them need to be explicitly // resolved. EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Gt(10)), "Value of: n\n" "Expected: is greater than 10\n" " Actual: 5"); n = 0; EXPECT_NONFATAL_FAILURE( EXPECT_THAT(n, ::testing::AllOf(::testing::Le(7), ::testing::Ge(5))), "Value of: n\n" "Expected: (is less than or equal to 7) and " "(is greater than or equal to 5)\n" " Actual: 0"); } // Tests that ASSERT_THAT() and EXPECT_THAT() work when the argument // has a reference type. TEST(MatcherAssertionTest, WorksForByRefArguments) { // We use a static variable here as EXPECT_FATAL_FAILURE() cannot // reference auto variables. static int n; n = 0; EXPECT_THAT(n, AllOf(Le(7), Ref(n))); EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), "Value of: n\n" "Expected: does not reference the variable @"); // Tests the "Actual" part. EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), "Actual: 0 (is located @"); } #if !GTEST_OS_SYMBIAN // Tests that ASSERT_THAT() and EXPECT_THAT() work when the matcher is // monomorphic. // ASSERT_THAT("hello", starts_with_he) fails to compile with Nokia's // Symbian compiler: it tries to compile // template<T, U> class MatcherCastImpl { ... -// virtual bool Matches(T x) const { -// return source_matcher_.Matches(static_cast<U>(x)); +// virtual bool MatchAndExplain(T x, ...) const { +// return source_matcher_.MatchAndExplain(static_cast<U>(x), ...); // with U == string and T == const char* // With ASSERT_THAT("hello"...) changed to ASSERT_THAT(string("hello") ... ) // the compiler silently crashes with no output. // If MatcherCastImpl is changed to use U(x) instead of static_cast<U>(x) // the code compiles but the converted string is bogus. TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) { Matcher<const char*> starts_with_he = StartsWith("he"); ASSERT_THAT("hello", starts_with_he); Matcher<const string&> ends_with_ok = EndsWith("ok"); ASSERT_THAT("book", ends_with_ok); Matcher<int> is_greater_than_5 = Gt(5); EXPECT_NONFATAL_FAILURE(EXPECT_THAT(5, is_greater_than_5), "Value of: 5\n" "Expected: is greater than 5\n" " Actual: 5"); } #endif // !GTEST_OS_SYMBIAN // Tests floating-point matchers. template <typename RawType> class FloatingPointTest : public testing::Test { protected: typedef typename testing::internal::FloatingPoint<RawType> Floating; typedef typename Floating::Bits Bits; virtual void SetUp() { const size_t max_ulps = Floating::kMaxUlps; // The bits that represent 0.0. const Bits zero_bits = Floating(0).bits(); // Makes some numbers close to 0.0. close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2); close_to_negative_zero_ = -Floating::ReinterpretBits( zero_bits + max_ulps - max_ulps/2); further_from_negative_zero_ = -Floating::ReinterpretBits( zero_bits + max_ulps + 1 - max_ulps/2); // The bits that represent 1.0. const Bits one_bits = Floating(1).bits(); // Makes some numbers close to 1.0. close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps); further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1); // +infinity. infinity_ = Floating::Infinity(); // The bits that represent +infinity. const Bits infinity_bits = Floating(infinity_).bits(); // Makes some numbers close to infinity. close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps); further_from_infinity_ = Floating::ReinterpretBits( infinity_bits - max_ulps - 1); // Makes some NAN's. nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1); nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200); } void TestSize() { EXPECT_EQ(sizeof(RawType), sizeof(Bits)); } // A battery of tests for FloatingEqMatcher::Matches. // matcher_maker is a pointer to a function which creates a FloatingEqMatcher. void TestMatches( testing::internal::FloatingEqMatcher<RawType> (*matcher_maker)(RawType)) { Matcher<RawType> m1 = matcher_maker(0.0); EXPECT_TRUE(m1.Matches(-0.0)); EXPECT_TRUE(m1.Matches(close_to_positive_zero_)); EXPECT_TRUE(m1.Matches(close_to_negative_zero_)); EXPECT_FALSE(m1.Matches(1.0)); Matcher<RawType> m2 = matcher_maker(close_to_positive_zero_); EXPECT_FALSE(m2.Matches(further_from_negative_zero_)); Matcher<RawType> m3 = matcher_maker(1.0); EXPECT_TRUE(m3.Matches(close_to_one_)); EXPECT_FALSE(m3.Matches(further_from_one_)); // Test commutativity: matcher_maker(0.0).Matches(1.0) was tested above. EXPECT_FALSE(m3.Matches(0.0)); Matcher<RawType> m4 = matcher_maker(-infinity_); EXPECT_TRUE(m4.Matches(-close_to_infinity_)); Matcher<RawType> m5 = matcher_maker(infinity_); EXPECT_TRUE(m5.Matches(close_to_infinity_)); // This is interesting as the representations of infinity_ and nan1_ // are only 1 DLP apart. EXPECT_FALSE(m5.Matches(nan1_)); // matcher_maker can produce a Matcher<const RawType&>, which is needed in // some cases. Matcher<const RawType&> m6 = matcher_maker(0.0); EXPECT_TRUE(m6.Matches(-0.0)); EXPECT_TRUE(m6.Matches(close_to_positive_zero_)); EXPECT_FALSE(m6.Matches(1.0)); // matcher_maker can produce a Matcher<RawType&>, which is needed in some // cases. Matcher<RawType&> m7 = matcher_maker(0.0); RawType x = 0.0; EXPECT_TRUE(m7.Matches(x)); x = 0.01f; EXPECT_FALSE(m7.Matches(x)); } // Pre-calculated numbers to be used by the tests. static RawType close_to_positive_zero_; static RawType close_to_negative_zero_; static RawType further_from_negative_zero_; static RawType close_to_one_; static RawType further_from_one_; static RawType infinity_; static RawType close_to_infinity_; static RawType further_from_infinity_; static RawType nan1_; static RawType nan2_; }; template <typename RawType> RawType FloatingPointTest<RawType>::close_to_positive_zero_; template <typename RawType> RawType FloatingPointTest<RawType>::close_to_negative_zero_; template <typename RawType> RawType FloatingPointTest<RawType>::further_from_negative_zero_; template <typename RawType> RawType FloatingPointTest<RawType>::close_to_one_; template <typename RawType> RawType FloatingPointTest<RawType>::further_from_one_; template <typename RawType> RawType FloatingPointTest<RawType>::infinity_; template <typename RawType> RawType FloatingPointTest<RawType>::close_to_infinity_; template <typename RawType> RawType FloatingPointTest<RawType>::further_from_infinity_; template <typename RawType> RawType FloatingPointTest<RawType>::nan1_; template <typename RawType> RawType FloatingPointTest<RawType>::nan2_; // Instantiate FloatingPointTest for testing floats. typedef FloatingPointTest<float> FloatTest; TEST_F(FloatTest, FloatEqApproximatelyMatchesFloats) { TestMatches(&FloatEq); } TEST_F(FloatTest, NanSensitiveFloatEqApproximatelyMatchesFloats) { TestMatches(&NanSensitiveFloatEq); } TEST_F(FloatTest, FloatEqCannotMatchNaN) { // FloatEq never matches NaN. Matcher<float> m = FloatEq(nan1_); EXPECT_FALSE(m.Matches(nan1_)); EXPECT_FALSE(m.Matches(nan2_)); EXPECT_FALSE(m.Matches(1.0)); } TEST_F(FloatTest, NanSensitiveFloatEqCanMatchNaN) { // NanSensitiveFloatEq will match NaN. Matcher<float> m = NanSensitiveFloatEq(nan1_); EXPECT_TRUE(m.Matches(nan1_)); EXPECT_TRUE(m.Matches(nan2_)); EXPECT_FALSE(m.Matches(1.0)); } TEST_F(FloatTest, FloatEqCanDescribeSelf) { Matcher<float> m1 = FloatEq(2.0f); EXPECT_EQ("is approximately 2", Describe(m1)); EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); Matcher<float> m2 = FloatEq(0.5f); EXPECT_EQ("is approximately 0.5", Describe(m2)); EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); Matcher<float> m3 = FloatEq(nan1_); EXPECT_EQ("never matches", Describe(m3)); EXPECT_EQ("is anything", DescribeNegation(m3)); } TEST_F(FloatTest, NanSensitiveFloatEqCanDescribeSelf) { Matcher<float> m1 = NanSensitiveFloatEq(2.0f); EXPECT_EQ("is approximately 2", Describe(m1)); EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); Matcher<float> m2 = NanSensitiveFloatEq(0.5f); EXPECT_EQ("is approximately 0.5", Describe(m2)); EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); Matcher<float> m3 = NanSensitiveFloatEq(nan1_); EXPECT_EQ("is NaN", Describe(m3)); EXPECT_EQ("is not NaN", DescribeNegation(m3)); } // Instantiate FloatingPointTest for testing doubles. typedef FloatingPointTest<double> DoubleTest; TEST_F(DoubleTest, DoubleEqApproximatelyMatchesDoubles) { TestMatches(&DoubleEq); } TEST_F(DoubleTest, NanSensitiveDoubleEqApproximatelyMatchesDoubles) { TestMatches(&NanSensitiveDoubleEq); } TEST_F(DoubleTest, DoubleEqCannotMatchNaN) { // DoubleEq never matches NaN. Matcher<double> m = DoubleEq(nan1_); EXPECT_FALSE(m.Matches(nan1_)); EXPECT_FALSE(m.Matches(nan2_)); EXPECT_FALSE(m.Matches(1.0)); } TEST_F(DoubleTest, NanSensitiveDoubleEqCanMatchNaN) { // NanSensitiveDoubleEq will match NaN. Matcher<double> m = NanSensitiveDoubleEq(nan1_); EXPECT_TRUE(m.Matches(nan1_)); EXPECT_TRUE(m.Matches(nan2_)); EXPECT_FALSE(m.Matches(1.0)); } TEST_F(DoubleTest, DoubleEqCanDescribeSelf) { Matcher<double> m1 = DoubleEq(2.0); EXPECT_EQ("is approximately 2", Describe(m1)); EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); Matcher<double> m2 = DoubleEq(0.5); EXPECT_EQ("is approximately 0.5", Describe(m2)); EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); Matcher<double> m3 = DoubleEq(nan1_); EXPECT_EQ("never matches", Describe(m3)); EXPECT_EQ("is anything", DescribeNegation(m3)); } TEST_F(DoubleTest, NanSensitiveDoubleEqCanDescribeSelf) { Matcher<double> m1 = NanSensitiveDoubleEq(2.0); EXPECT_EQ("is approximately 2", Describe(m1)); EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); Matcher<double> m2 = NanSensitiveDoubleEq(0.5); EXPECT_EQ("is approximately 0.5", Describe(m2)); EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); Matcher<double> m3 = NanSensitiveDoubleEq(nan1_); EXPECT_EQ("is NaN", Describe(m3)); EXPECT_EQ("is not NaN", DescribeNegation(m3)); } TEST(PointeeTest, RawPointer) { const Matcher<int*> m = Pointee(Ge(0)); int n = 1; EXPECT_TRUE(m.Matches(&n)); n = -1; EXPECT_FALSE(m.Matches(&n)); EXPECT_FALSE(m.Matches(NULL)); } TEST(PointeeTest, RawPointerToConst) { const Matcher<const double*> m = Pointee(Ge(0)); double x = 1; EXPECT_TRUE(m.Matches(&x)); x = -1; EXPECT_FALSE(m.Matches(&x)); EXPECT_FALSE(m.Matches(NULL)); } TEST(PointeeTest, ReferenceToConstRawPointer) { const Matcher<int* const &> m = Pointee(Ge(0)); int n = 1; EXPECT_TRUE(m.Matches(&n)); n = -1; EXPECT_FALSE(m.Matches(&n)); EXPECT_FALSE(m.Matches(NULL)); } TEST(PointeeTest, ReferenceToNonConstRawPointer) { const Matcher<double* &> m = Pointee(Ge(0)); double x = 1.0; double* p = &x; EXPECT_TRUE(m.Matches(p)); x = -1; EXPECT_FALSE(m.Matches(p)); p = NULL; EXPECT_FALSE(m.Matches(p)); } TEST(PointeeTest, NeverMatchesNull) { const Matcher<const char*> m = Pointee(_); EXPECT_FALSE(m.Matches(NULL)); } // Tests that we can write Pointee(value) instead of Pointee(Eq(value)). TEST(PointeeTest, MatchesAgainstAValue) { const Matcher<int*> m = Pointee(5); int n = 5; EXPECT_TRUE(m.Matches(&n)); n = -1; EXPECT_FALSE(m.Matches(&n)); EXPECT_FALSE(m.Matches(NULL)); } TEST(PointeeTest, CanDescribeSelf) { const Matcher<int*> m = Pointee(Gt(3)); EXPECT_EQ("points to a value that is greater than 3", Describe(m)); EXPECT_EQ("does not point to a value that is greater than 3", DescribeNegation(m)); } TEST(PointeeTest, CanExplainMatchResult) { const Matcher<const string*> m = Pointee(StartsWith("Hi")); EXPECT_EQ("", Explain(m, static_cast<const string*>(NULL))); const Matcher<int*> m2 = Pointee(GreaterThan(1)); int n = 3; EXPECT_EQ("points to a value that is 2 more than 1", Explain(m2, &n)); } // An uncopyable class. class Uncopyable { public: explicit Uncopyable(int a_value) : value_(a_value) {} int value() const { return value_; } private: const int value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Uncopyable); }; // Returns true iff x.value() is positive. bool ValueIsPositive(const Uncopyable& x) { return x.value() > 0; } // A user-defined struct for testing Field(). struct AStruct { AStruct() : x(0), y(1.0), z(5), p(NULL) {} AStruct(const AStruct& rhs) : x(rhs.x), y(rhs.y), z(rhs.z.value()), p(rhs.p) {} int x; // A non-const field. const double y; // A const field. Uncopyable z; // An uncopyable field. const char* p; // A pointer field. private: GTEST_DISALLOW_ASSIGN_(AStruct); }; // A derived struct for testing Field(). struct DerivedStruct : public AStruct { char ch; private: GTEST_DISALLOW_ASSIGN_(DerivedStruct); }; // Tests that Field(&Foo::field, ...) works when field is non-const. TEST(FieldTest, WorksForNonConstField) { Matcher<AStruct> m = Field(&AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(a)); a.x = -1; EXPECT_FALSE(m.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is const. TEST(FieldTest, WorksForConstField) { AStruct a; Matcher<AStruct> m = Field(&AStruct::y, Ge(0.0)); EXPECT_TRUE(m.Matches(a)); m = Field(&AStruct::y, Le(0.0)); EXPECT_FALSE(m.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is not copyable. TEST(FieldTest, WorksForUncopyableField) { AStruct a; Matcher<AStruct> m = Field(&AStruct::z, Truly(ValueIsPositive)); EXPECT_TRUE(m.Matches(a)); m = Field(&AStruct::z, Not(Truly(ValueIsPositive))); EXPECT_FALSE(m.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is a pointer. TEST(FieldTest, WorksForPointerField) { // Matching against NULL. Matcher<AStruct> m = Field(&AStruct::p, static_cast<const char*>(NULL)); AStruct a; EXPECT_TRUE(m.Matches(a)); a.p = "hi"; EXPECT_FALSE(m.Matches(a)); // Matching a pointer that is not NULL. m = Field(&AStruct::p, StartsWith("hi")); a.p = "hill"; EXPECT_TRUE(m.Matches(a)); a.p = "hole"; EXPECT_FALSE(m.Matches(a)); } // Tests that Field() works when the object is passed by reference. TEST(FieldTest, WorksForByRefArgument) { Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(a)); a.x = -1; EXPECT_FALSE(m.Matches(a)); } // Tests that Field(&Foo::field, ...) works when the argument's type // is a sub-type of Foo. TEST(FieldTest, WorksForArgumentOfSubType) { // Note that the matcher expects DerivedStruct but we say AStruct // inside Field(). Matcher<const DerivedStruct&> m = Field(&AStruct::x, Ge(0)); DerivedStruct d; EXPECT_TRUE(m.Matches(d)); d.x = -1; EXPECT_FALSE(m.Matches(d)); } // Tests that Field(&Foo::field, m) works when field's type and m's // argument type are compatible but not the same. TEST(FieldTest, WorksForCompatibleMatcherType) { // The field is an int, but the inner matcher expects a signed char. Matcher<const AStruct&> m = Field(&AStruct::x, Matcher<signed char>(Ge(0))); AStruct a; EXPECT_TRUE(m.Matches(a)); a.x = -1; EXPECT_FALSE(m.Matches(a)); } // Tests that Field() can describe itself. TEST(FieldTest, CanDescribeSelf) { Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); EXPECT_EQ("the given field is not greater than or equal to 0", DescribeNegation(m)); } // Tests that Field() can explain the match result. TEST(FieldTest, CanExplainMatchResult) { Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); AStruct a; a.x = 1; EXPECT_EQ("", Explain(m, a)); m = Field(&AStruct::x, GreaterThan(0)); EXPECT_EQ("the given field is 1 more than 0", Explain(m, a)); } // Tests that Field() works when the argument is a pointer to const. TEST(FieldForPointerTest, WorksForPointerToConst) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(&a)); a.x = -1; EXPECT_FALSE(m.Matches(&a)); } // Tests that Field() works when the argument is a pointer to non-const. TEST(FieldForPointerTest, WorksForPointerToNonConst) { Matcher<AStruct*> m = Field(&AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(&a)); a.x = -1; EXPECT_FALSE(m.Matches(&a)); } // Tests that Field() works when the argument is a reference to a const pointer. TEST(FieldForPointerTest, WorksForReferenceToConstPointer) { Matcher<AStruct* const&> m = Field(&AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(&a)); a.x = -1; EXPECT_FALSE(m.Matches(&a)); } // Tests that Field() does not match the NULL pointer. TEST(FieldForPointerTest, DoesNotMatchNull) { Matcher<const AStruct*> m = Field(&AStruct::x, _); EXPECT_FALSE(m.Matches(NULL)); } // Tests that Field(&Foo::field, ...) works when the argument's type // is a sub-type of const Foo*. TEST(FieldForPointerTest, WorksForArgumentOfSubType) { // Note that the matcher expects DerivedStruct but we say AStruct // inside Field(). Matcher<DerivedStruct*> m = Field(&AStruct::x, Ge(0)); DerivedStruct d; EXPECT_TRUE(m.Matches(&d)); d.x = -1; EXPECT_FALSE(m.Matches(&d)); } // Tests that Field() can describe itself when used to match a pointer. TEST(FieldForPointerTest, CanDescribeSelf) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); EXPECT_EQ("the given field is not greater than or equal to 0", DescribeNegation(m)); } // Tests that Field() can explain the result of matching a pointer. TEST(FieldForPointerTest, CanExplainMatchResult) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); AStruct a; a.x = 1; EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL))); EXPECT_EQ("", Explain(m, &a)); m = Field(&AStruct::x, GreaterThan(0)); EXPECT_EQ("the given field is 1 more than 0", Explain(m, &a)); } // A user-defined class for testing Property(). class AClass { public: AClass() : n_(0) {} // A getter that returns a non-reference. int n() const { return n_; } void set_n(int new_n) { n_ = new_n; } // A getter that returns a reference to const. const string& s() const { return s_; } void set_s(const string& new_s) { s_ = new_s; } // A getter that returns a reference to non-const. double& x() const { return x_; } private: int n_; string s_; static double x_; }; double AClass::x_ = 0.0; // A derived class for testing Property(). class DerivedClass : public AClass { private: int k_; }; // Tests that Property(&Foo::property, ...) works when property() // returns a non-reference. TEST(PropertyTest, WorksForNonReferenceProperty) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_TRUE(m.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); } // Tests that Property(&Foo::property, ...) works when property() // returns a reference to const. TEST(PropertyTest, WorksForReferenceToConstProperty) { Matcher<const AClass&> m = Property(&AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(a)); } // Tests that Property(&Foo::property, ...) works when property() // returns a reference to non-const. TEST(PropertyTest, WorksForReferenceToNonConstProperty) { double x = 0.0; AClass a; Matcher<const AClass&> m = Property(&AClass::x, Ref(x)); EXPECT_FALSE(m.Matches(a)); m = Property(&AClass::x, Not(Ref(x))); EXPECT_TRUE(m.Matches(a)); } // Tests that Property(&Foo::property, ...) works when the argument is // passed by value. TEST(PropertyTest, WorksForByValueArgument) { Matcher<AClass> m = Property(&AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(a)); } // Tests that Property(&Foo::property, ...) works when the argument's // type is a sub-type of Foo. TEST(PropertyTest, WorksForArgumentOfSubType) { // The matcher expects a DerivedClass, but inside the Property() we // say AClass. Matcher<const DerivedClass&> m = Property(&AClass::n, Ge(0)); DerivedClass d; d.set_n(1); EXPECT_TRUE(m.Matches(d)); d.set_n(-1); EXPECT_FALSE(m.Matches(d)); } // Tests that Property(&Foo::property, m) works when property()'s type // and m's argument type are compatible but different. TEST(PropertyTest, WorksForCompatibleMatcherType) { // n() returns an int but the inner matcher expects a signed char. Matcher<const AClass&> m = Property(&AClass::n, Matcher<signed char>(Ge(0))); AClass a; EXPECT_TRUE(m.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); } // Tests that Property() can describe itself. TEST(PropertyTest, CanDescribeSelf) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); EXPECT_EQ("the given property is not greater than or equal to 0", DescribeNegation(m)); } // Tests that Property() can explain the match result. TEST(PropertyTest, CanExplainMatchResult) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_EQ("", Explain(m, a)); m = Property(&AClass::n, GreaterThan(0)); EXPECT_EQ("the given property is 1 more than 0", Explain(m, a)); } // Tests that Property() works when the argument is a pointer to const. TEST(PropertyForPointerTest, WorksForPointerToConst) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_TRUE(m.Matches(&a)); a.set_n(-1); EXPECT_FALSE(m.Matches(&a)); } // Tests that Property() works when the argument is a pointer to non-const. TEST(PropertyForPointerTest, WorksForPointerToNonConst) { Matcher<AClass*> m = Property(&AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(&a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(&a)); } // Tests that Property() works when the argument is a reference to a // const pointer. TEST(PropertyForPointerTest, WorksForReferenceToConstPointer) { Matcher<AClass* const&> m = Property(&AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(&a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(&a)); } // Tests that Property() does not match the NULL pointer. TEST(PropertyForPointerTest, WorksForReferenceToNonConstProperty) { Matcher<const AClass*> m = Property(&AClass::x, _); EXPECT_FALSE(m.Matches(NULL)); } // Tests that Property(&Foo::property, ...) works when the argument's // type is a sub-type of const Foo*. TEST(PropertyForPointerTest, WorksForArgumentOfSubType) { // The matcher expects a DerivedClass, but inside the Property() we // say AClass. Matcher<const DerivedClass*> m = Property(&AClass::n, Ge(0)); DerivedClass d; d.set_n(1); EXPECT_TRUE(m.Matches(&d)); d.set_n(-1); EXPECT_FALSE(m.Matches(&d)); } // Tests that Property() can describe itself when used to match a pointer. TEST(PropertyForPointerTest, CanDescribeSelf) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); EXPECT_EQ("the given property is not greater than or equal to 0", DescribeNegation(m)); } // Tests that Property() can explain the result of matching a pointer. TEST(PropertyForPointerTest, CanExplainMatchResult) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL))); EXPECT_EQ("", Explain(m, &a)); m = Property(&AClass::n, GreaterThan(0)); EXPECT_EQ("the given property is 1 more than 0", Explain(m, &a)); } // Tests ResultOf. // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function pointer. string IntToStringFunction(int input) { return input == 1 ? "foo" : "bar"; } TEST(ResultOfTest, WorksForFunctionPointers) { Matcher<int> matcher = ResultOf(&IntToStringFunction, Eq(string("foo"))); EXPECT_TRUE(matcher.Matches(1)); EXPECT_FALSE(matcher.Matches(2)); } // Tests that ResultOf() can describe itself. TEST(ResultOfTest, CanDescribeItself) { Matcher<int> matcher = ResultOf(&IntToStringFunction, StrEq("foo")); EXPECT_EQ("result of the given callable is equal to \"foo\"", Describe(matcher)); EXPECT_EQ("result of the given callable is not equal to \"foo\"", DescribeNegation(matcher)); } // Tests that ResultOf() can explain the match result. int IntFunction(int input) { return input == 42 ? 80 : 90; } TEST(ResultOfTest, CanExplainMatchResult) { Matcher<int> matcher = ResultOf(&IntFunction, Ge(85)); EXPECT_EQ("", Explain(matcher, 36)); matcher = ResultOf(&IntFunction, GreaterThan(85)); EXPECT_EQ("result of the given callable is 5 more than 85", Explain(matcher, 36)); } // Tests that ResultOf(f, ...) compiles and works as expected when f(x) // returns a non-reference. TEST(ResultOfTest, WorksForNonReferenceResults) { Matcher<int> matcher = ResultOf(&IntFunction, Eq(80)); EXPECT_TRUE(matcher.Matches(42)); EXPECT_FALSE(matcher.Matches(36)); } // Tests that ResultOf(f, ...) compiles and works as expected when f(x) // returns a reference to non-const. double& DoubleFunction(double& input) { return input; } Uncopyable& RefUncopyableFunction(Uncopyable& obj) { return obj; } TEST(ResultOfTest, WorksForReferenceToNonConstResults) { double x = 3.14; double x2 = x; Matcher<double&> matcher = ResultOf(&DoubleFunction, Ref(x)); EXPECT_TRUE(matcher.Matches(x)); EXPECT_FALSE(matcher.Matches(x2)); // Test that ResultOf works with uncopyable objects Uncopyable obj(0); Uncopyable obj2(0); Matcher<Uncopyable&> matcher2 = ResultOf(&RefUncopyableFunction, Ref(obj)); EXPECT_TRUE(matcher2.Matches(obj)); EXPECT_FALSE(matcher2.Matches(obj2)); } // Tests that ResultOf(f, ...) compiles and works as expected when f(x) // returns a reference to const. const string& StringFunction(const string& input) { return input; } TEST(ResultOfTest, WorksForReferenceToConstResults) { string s = "foo"; string s2 = s; Matcher<const string&> matcher = ResultOf(&StringFunction, Ref(s)); EXPECT_TRUE(matcher.Matches(s)); EXPECT_FALSE(matcher.Matches(s2)); } // Tests that ResultOf(f, m) works when f(x) and m's // argument types are compatible but different. TEST(ResultOfTest, WorksForCompatibleMatcherTypes) { // IntFunction() returns int but the inner matcher expects a signed char. Matcher<int> matcher = ResultOf(IntFunction, Matcher<signed char>(Ge(85))); EXPECT_TRUE(matcher.Matches(36)); EXPECT_FALSE(matcher.Matches(42)); } // Tests that the program aborts when ResultOf is passed // a NULL function pointer. TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) { EXPECT_DEATH_IF_SUPPORTED( ResultOf(static_cast<string(*)(int)>(NULL), Eq(string("foo"))), "NULL function pointer is passed into ResultOf\\(\\)\\."); } // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function reference. TEST(ResultOfTest, WorksForFunctionReferences) { Matcher<int> matcher = ResultOf(IntToStringFunction, StrEq("foo")); EXPECT_TRUE(matcher.Matches(1)); EXPECT_FALSE(matcher.Matches(2)); } // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function object. struct Functor : public ::std::unary_function<int, string> { result_type operator()(argument_type input) const { return IntToStringFunction(input); } }; TEST(ResultOfTest, WorksForFunctors) { Matcher<int> matcher = ResultOf(Functor(), Eq(string("foo"))); EXPECT_TRUE(matcher.Matches(1)); EXPECT_FALSE(matcher.Matches(2)); } // Tests that ResultOf(f, ...) compiles and works as expected when f is a // functor with more then one operator() defined. ResultOf() must work // for each defined operator(). struct PolymorphicFunctor { typedef int result_type; int operator()(int n) { return n; } int operator()(const char* s) { return static_cast<int>(strlen(s)); } }; TEST(ResultOfTest, WorksForPolymorphicFunctors) { Matcher<int> matcher_int = ResultOf(PolymorphicFunctor(), Ge(5)); EXPECT_TRUE(matcher_int.Matches(10)); EXPECT_FALSE(matcher_int.Matches(2)); Matcher<const char*> matcher_string = ResultOf(PolymorphicFunctor(), Ge(5)); EXPECT_TRUE(matcher_string.Matches("long string")); EXPECT_FALSE(matcher_string.Matches("shrt")); } const int* ReferencingFunction(const int& n) { return &n; } struct ReferencingFunctor { typedef const int* result_type; result_type operator()(const int& n) { return &n; } }; TEST(ResultOfTest, WorksForReferencingCallables) { const int n = 1; const int n2 = 1; Matcher<const int&> matcher2 = ResultOf(ReferencingFunction, Eq(&n)); EXPECT_TRUE(matcher2.Matches(n)); EXPECT_FALSE(matcher2.Matches(n2)); Matcher<const int&> matcher3 = ResultOf(ReferencingFunctor(), Eq(&n)); EXPECT_TRUE(matcher3.Matches(n)); EXPECT_FALSE(matcher3.Matches(n2)); } class DivisibleByImpl { public: explicit DivisibleByImpl(int a_divider) : divider_(a_divider) {} + // For testing using ExplainMatchResultTo() with polymorphic matchers. template <typename T> - bool Matches(const T& n) const { + bool MatchAndExplain(const T& n, MatchResultListener* listener) const { + *listener << "is " << (n % divider_) << " modulo " + << divider_; return (n % divider_) == 0; } void DescribeTo(::std::ostream* os) const { *os << "is divisible by " << divider_; } void DescribeNegationTo(::std::ostream* os) const { *os << "is not divisible by " << divider_; } void set_divider(int a_divider) { divider_ = a_divider; } int divider() const { return divider_; } private: int divider_; }; -// For testing using ExplainMatchResultTo() with polymorphic matchers. -template <typename T> -void ExplainMatchResultTo(const DivisibleByImpl& impl, const T& n, - ::std::ostream* os) { - *os << "is " << (n % impl.divider()) << " modulo " - << impl.divider(); -} - PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) { return MakePolymorphicMatcher(DivisibleByImpl(n)); } // Tests that when AllOf() fails, only the first failing matcher is // asked to explain why. TEST(ExplainMatchResultTest, AllOf_False_False) { const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3)); EXPECT_EQ("is 1 modulo 4", Explain(m, 5)); } // Tests that when AllOf() fails, only the first failing matcher is // asked to explain why. TEST(ExplainMatchResultTest, AllOf_False_True) { const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3)); EXPECT_EQ("is 2 modulo 4", Explain(m, 6)); } // Tests that when AllOf() fails, only the first failing matcher is // asked to explain why. TEST(ExplainMatchResultTest, AllOf_True_False) { const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3)); EXPECT_EQ("is 2 modulo 3", Explain(m, 5)); } // Tests that when AllOf() succeeds, all matchers are asked to explain // why. TEST(ExplainMatchResultTest, AllOf_True_True) { const Matcher<int> m = AllOf(DivisibleBy(2), DivisibleBy(3)); EXPECT_EQ("is 0 modulo 2; is 0 modulo 3", Explain(m, 6)); } TEST(ExplainMatchResultTest, AllOf_True_True_2) { const Matcher<int> m = AllOf(Ge(2), Le(3)); EXPECT_EQ("", Explain(m, 2)); } TEST(ExplainmatcherResultTest, MonomorphicMatcher) { const Matcher<int> m = GreaterThan(5); EXPECT_EQ("is 1 more than 5", Explain(m, 6)); } // The following two tests verify that values without a public copy // ctor can be used as arguments to matchers like Eq(), Ge(), and etc // with the help of ByRef(). class NotCopyable { public: explicit NotCopyable(int a_value) : value_(a_value) {} int value() const { return value_; } bool operator==(const NotCopyable& rhs) const { return value() == rhs.value(); } bool operator>=(const NotCopyable& rhs) const { return value() >= rhs.value(); } private: int value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(NotCopyable); }; TEST(ByRefTest, AllowsNotCopyableConstValueInMatchers) { const NotCopyable const_value1(1); const Matcher<const NotCopyable&> m = Eq(ByRef(const_value1)); const NotCopyable n1(1), n2(2); EXPECT_TRUE(m.Matches(n1)); EXPECT_FALSE(m.Matches(n2)); } TEST(ByRefTest, AllowsNotCopyableValueInMatchers) { NotCopyable value2(2); const Matcher<NotCopyable&> m = Ge(ByRef(value2)); NotCopyable n1(1), n2(2); EXPECT_FALSE(m.Matches(n1)); EXPECT_TRUE(m.Matches(n2)); } #if GTEST_HAS_TYPED_TEST // Tests ContainerEq with different container types, and // different element types. template <typename T> class ContainerEqTest : public testing::Test {}; typedef testing::Types< std::set<int>, std::vector<size_t>, std::multiset<size_t>, std::list<int> > ContainerEqTestTypes; TYPED_TEST_CASE(ContainerEqTest, ContainerEqTestTypes); // Tests that the filled container is equal to itself. TYPED_TEST(ContainerEqTest, EqualsSelf) { static const int vals[] = {1, 1, 2, 3, 5, 8}; TypeParam my_set(vals, vals + 6); const Matcher<TypeParam> m = ContainerEq(my_set); EXPECT_TRUE(m.Matches(my_set)); EXPECT_EQ("", Explain(m, my_set)); } // Tests that missing values are reported. TYPED_TEST(ContainerEqTest, ValueMissing) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {2, 1, 8, 5}; TypeParam my_set(vals, vals + 6); TypeParam test_set(test_vals, test_vals + 4); const Matcher<TypeParam> m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Not in actual: 3", Explain(m, test_set)); } // Tests that added values are reported. TYPED_TEST(ContainerEqTest, ValueAdded) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 3, 5, 8, 46}; TypeParam my_set(vals, vals + 6); TypeParam test_set(test_vals, test_vals + 6); const Matcher<const TypeParam&> m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Only in actual: 46", Explain(m, test_set)); } // Tests that added and missing values are reported together. TYPED_TEST(ContainerEqTest, ValueAddedAndRemoved) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 3, 8, 46}; TypeParam my_set(vals, vals + 6); TypeParam test_set(test_vals, test_vals + 5); const Matcher<TypeParam> m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Only in actual: 46; not in actual: 5", Explain(m, test_set)); } // Tests duplicated value -- expect no explanation. TYPED_TEST(ContainerEqTest, DuplicateDifference) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 3, 5, 8}; TypeParam my_set(vals, vals + 6); TypeParam test_set(test_vals, test_vals + 5); const Matcher<const TypeParam&> m = ContainerEq(my_set); // Depending on the container, match may be true or false // But in any case there should be no explanation. EXPECT_EQ("", Explain(m, test_set)); } #endif // GTEST_HAS_TYPED_TEST // Tests that mutliple missing values are reported. // Using just vector here, so order is predicatble. TEST(ContainerEqExtraTest, MultipleValuesMissing) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {2, 1, 5}; std::vector<int> my_set(vals, vals + 6); std::vector<int> test_set(test_vals, test_vals + 3); const Matcher<std::vector<int> > m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Not in actual: 3, 8", Explain(m, test_set)); } // Tests that added values are reported. // Using just vector here, so order is predicatble. TEST(ContainerEqExtraTest, MultipleValuesAdded) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46}; std::list<size_t> my_set(vals, vals + 6); std::list<size_t> test_set(test_vals, test_vals + 7); const Matcher<const std::list<size_t>&> m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Only in actual: 92, 46", Explain(m, test_set)); } // Tests that added and missing values are reported together. TEST(ContainerEqExtraTest, MultipleValuesAddedAndRemoved) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 3, 92, 46}; std::list<size_t> my_set(vals, vals + 6); std::list<size_t> test_set(test_vals, test_vals + 5); const Matcher<const std::list<size_t> > m = ContainerEq(my_set); EXPECT_FALSE(m.Matches(test_set)); EXPECT_EQ("Only in actual: 92, 46; not in actual: 5, 8", Explain(m, test_set)); } // Tests to see that duplicate elements are detected, // but (as above) not reported in the explanation. TEST(ContainerEqExtraTest, MultiSetOfIntDuplicateDifference) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 3, 5, 8}; std::vector<int> my_set(vals, vals + 6); std::vector<int> test_set(test_vals, test_vals + 5); const Matcher<std::vector<int> > m = ContainerEq(my_set); EXPECT_TRUE(m.Matches(my_set)); EXPECT_FALSE(m.Matches(test_set)); // There is nothing to report when both sets contain all the same values. EXPECT_EQ("", Explain(m, test_set)); } // Tests that ContainerEq works for non-trivial associative containers, // like maps. TEST(ContainerEqExtraTest, WorksForMaps) { std::map<int, std::string> my_map; my_map[0] = "a"; my_map[1] = "b"; std::map<int, std::string> test_map; test_map[0] = "aa"; test_map[1] = "b"; const Matcher<const std::map<int, std::string>&> m = ContainerEq(my_map); EXPECT_TRUE(m.Matches(my_map)); EXPECT_FALSE(m.Matches(test_map)); EXPECT_EQ("Only in actual: (0, \"aa\"); not in actual: (0, \"a\")", Explain(m, test_map)); } TEST(ContainerEqExtraTest, WorksForNativeArray) { int a1[] = { 1, 2, 3 }; int a2[] = { 1, 2, 3 }; int b[] = { 1, 2, 4 }; EXPECT_THAT(a1, ContainerEq(a2)); EXPECT_THAT(a1, Not(ContainerEq(b))); } TEST(ContainerEqExtraTest, WorksForTwoDimensionalNativeArray) { const char a1[][3] = { "hi", "lo" }; const char a2[][3] = { "hi", "lo" }; const char b[][3] = { "lo", "hi" }; // Tests using ContainerEq() in the first dimension. EXPECT_THAT(a1, ContainerEq(a2)); EXPECT_THAT(a1, Not(ContainerEq(b))); // Tests using ContainerEq() in the second dimension. EXPECT_THAT(a1, ElementsAre(ContainerEq(a2[0]), ContainerEq(a2[1]))); EXPECT_THAT(a1, ElementsAre(Not(ContainerEq(b[0])), ContainerEq(a2[1]))); } TEST(ContainerEqExtraTest, WorksForNativeArrayAsTuple) { const int a1[] = { 1, 2, 3 }; const int a2[] = { 1, 2, 3 }; const int b[] = { 1, 2, 3, 4 }; const int* const p1 = a1; EXPECT_THAT(make_tuple(p1, 3), ContainerEq(a2)); EXPECT_THAT(make_tuple(p1, 3), Not(ContainerEq(b))); const int c[] = { 1, 3, 2 }; EXPECT_THAT(make_tuple(p1, 3), Not(ContainerEq(c))); } TEST(ContainerEqExtraTest, CopiesNativeArrayParameter) { std::string a1[][3] = { { "hi", "hello", "ciao" }, { "bye", "see you", "ciao" } }; std::string a2[][3] = { { "hi", "hello", "ciao" }, { "bye", "see you", "ciao" } }; const Matcher<const std::string(&)[2][3]> m = ContainerEq(a2); EXPECT_THAT(a1, m); a2[0][0] = "ha"; EXPECT_THAT(a1, m); } // Tests GetParamIndex(). TEST(GetParamIndexTest, WorksForEmptyParamList) { const char* params[] = { NULL }; EXPECT_EQ(kTupleInterpolation, GetParamIndex(params, "*")); EXPECT_EQ(kInvalidInterpolation, GetParamIndex(params, "a")); } TEST(GetParamIndexTest, RecognizesStar) { const char* params[] = { "a", "b", NULL }; EXPECT_EQ(kTupleInterpolation, GetParamIndex(params, "*")); } TEST(GetParamIndexTest, RecognizesKnownParam) { const char* params[] = { "foo", "bar", NULL }; EXPECT_EQ(0, GetParamIndex(params, "foo")); EXPECT_EQ(1, GetParamIndex(params, "bar")); } TEST(GetParamIndexTest, RejectsUnknownParam) { const char* params[] = { "foo", "bar", NULL }; EXPECT_EQ(kInvalidInterpolation, GetParamIndex(params, "foobar")); } // Tests SkipPrefix(). TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { const char* const str = "hello"; const char* p = str; EXPECT_TRUE(SkipPrefix("", &p)); EXPECT_EQ(str, p); p = str; EXPECT_TRUE(SkipPrefix("hell", &p)); EXPECT_EQ(str + 4, p); } TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { const char* const str = "world"; const char* p = str; EXPECT_FALSE(SkipPrefix("W", &p)); EXPECT_EQ(str, p); p = str; EXPECT_FALSE(SkipPrefix("world!", &p)); EXPECT_EQ(str, p); } // Tests FormatMatcherDescriptionSyntaxError(). TEST(FormatMatcherDescriptionSyntaxErrorTest, FormatsCorrectly) { const char* const description = "hello%world"; EXPECT_EQ("Syntax error at index 5 in matcher description \"hello%world\": ", FormatMatcherDescriptionSyntaxError(description, description + 5)); } // Tests ValidateMatcherDescription(). TEST(ValidateMatcherDescriptionTest, AcceptsEmptyDescription) { const char* params[] = { "foo", "bar", NULL }; EXPECT_THAT(ValidateMatcherDescription(params, ""), ElementsAre()); } TEST(ValidateMatcherDescriptionTest, AcceptsNonEmptyDescriptionWithNoInterpolation) { const char* params[] = { "foo", "bar", NULL }; EXPECT_THAT(ValidateMatcherDescription(params, "a simple description"), ElementsAre()); } // The MATCHER*() macros trigger warning C4100 (unreferenced formal // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in // the macro definition, as the warnings are generated when the macro // is expanded and macro expansion cannot contain #pragma. Therefore // we suppress them here. #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4100) #endif // We use MATCHER_P3() to define a matcher for testing // ValidateMatcherDescription(); otherwise we'll end up with much // plumbing code. This is not circular as // ValidateMatcherDescription() doesn't affect whether the matcher // matches a value or not. MATCHER_P3(EqInterpolation, start, end, index, "equals Interpolation%(*)s") { return arg.start_pos == start && arg.end_pos == end && arg.param_index == index; } #ifdef _MSC_VER #pragma warning(pop) #endif TEST(ValidateMatcherDescriptionTest, AcceptsPercentInterpolation) { const char* params[] = { "foo", NULL }; const char* const desc = "one %%"; EXPECT_THAT(ValidateMatcherDescription(params, desc), ElementsAre(EqInterpolation(desc + 4, desc + 6, kPercentInterpolation))); } TEST(ValidateMatcherDescriptionTest, AcceptsTupleInterpolation) { const char* params[] = { "foo", "bar", "baz", NULL }; const char* const desc = "%(*)s after"; EXPECT_THAT(ValidateMatcherDescription(params, desc), ElementsAre(EqInterpolation(desc, desc + 5, kTupleInterpolation))); } TEST(ValidateMatcherDescriptionTest, AcceptsParamInterpolation) { const char* params[] = { "foo", "bar", "baz", NULL }; const char* const desc = "a %(bar)s."; EXPECT_THAT(ValidateMatcherDescription(params, desc), ElementsAre(EqInterpolation(desc + 2, desc + 9, 1))); } TEST(ValidateMatcherDescriptionTest, AcceptsMultiplenterpolations) { const char* params[] = { "foo", "bar", "baz", NULL }; const char* const desc = "%(baz)s %(foo)s %(bar)s"; EXPECT_THAT(ValidateMatcherDescription(params, desc), ElementsAre(EqInterpolation(desc, desc + 7, 2), EqInterpolation(desc + 8, desc + 15, 0), EqInterpolation(desc + 16, desc + 23, 1))); } TEST(ValidateMatcherDescriptionTest, AcceptsRepeatedParams) { const char* params[] = { "foo", "bar", NULL }; const char* const desc = "%(foo)s and %(foo)s"; EXPECT_THAT(ValidateMatcherDescription(params, desc), ElementsAre(EqInterpolation(desc, desc + 7, 0), EqInterpolation(desc + 12, desc + 19, 0))); } TEST(ValidateMatcherDescriptionTest, RejectsUnknownParam) { const char* params[] = { "a", "bar", NULL }; EXPECT_NONFATAL_FAILURE({ EXPECT_THAT(ValidateMatcherDescription(params, "%(foo)s"), ElementsAre()); }, "Syntax error at index 2 in matcher description \"%(foo)s\": " "\"foo\" is an invalid parameter name."); } TEST(ValidateMatcherDescriptionTest, RejectsUnfinishedParam) { const char* params[] = { "a", "bar", NULL }; EXPECT_NONFATAL_FAILURE({ EXPECT_THAT(ValidateMatcherDescription(params, "%(foo)"), ElementsAre()); }, "Syntax error at index 0 in matcher description \"%(foo)\": " "an interpolation must end with \")s\", but \"%(foo)\" does not."); EXPECT_NONFATAL_FAILURE({ EXPECT_THAT(ValidateMatcherDescription(params, "x%(a"), ElementsAre()); }, "Syntax error at index 1 in matcher description \"x%(a\": " "an interpolation must end with \")s\", but \"%(a\" does not."); } TEST(ValidateMatcherDescriptionTest, RejectsSinglePercent) { const char* params[] = { "a", NULL }; EXPECT_NONFATAL_FAILURE({ EXPECT_THAT(ValidateMatcherDescription(params, "a %."), ElementsAre()); }, "Syntax error at index 2 in matcher description \"a %.\": " "use \"%%\" instead of \"%\" to print \"%\"."); } // Tests JoinAsTuple(). TEST(JoinAsTupleTest, JoinsEmptyTuple) { EXPECT_EQ("", JoinAsTuple(Strings())); } TEST(JoinAsTupleTest, JoinsOneTuple) { const char* fields[] = { "1" }; EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); } TEST(JoinAsTupleTest, JoinsTwoTuple) { const char* fields[] = { "1", "a" }; EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); } TEST(JoinAsTupleTest, JoinsTenTuple) { const char* fields[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }; EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", JoinAsTuple(Strings(fields, fields + 10))); } // Tests FormatMatcherDescription(). TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { EXPECT_EQ("is even", FormatMatcherDescription("IsEven", "", Interpolations(), Strings())); const char* params[] = { "5" }; EXPECT_EQ("equals 5", FormatMatcherDescription("Equals", "", Interpolations(), Strings(params, params + 1))); const char* params2[] = { "5", "8" }; EXPECT_EQ("is in range (5, 8)", FormatMatcherDescription("IsInRange", "", Interpolations(), Strings(params2, params2 + 2))); } TEST(FormatMatcherDescriptionTest, WorksForDescriptionWithNoInterpolation) { EXPECT_EQ("is positive", FormatMatcherDescription("Gt0", "is positive", Interpolations(), Strings())); const char* params[] = { "5", "6" }; EXPECT_EQ("is negative", FormatMatcherDescription("Lt0", "is negative", Interpolations(), Strings(params, params + 2))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionStartsWithInterpolation) { const char* params[] = { "5" }; const char* const desc = "%(num)s times bigger"; const Interpolation interp[] = { Interpolation(desc, desc + 7, 0) }; EXPECT_EQ("5 times bigger", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 1), Strings(params, params + 1))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionEndsWithInterpolation) { const char* params[] = { "5", "6" }; const char* const desc = "is bigger than %(y)s"; const Interpolation interp[] = { Interpolation(desc + 15, desc + 20, 1) }; EXPECT_EQ("is bigger than 6", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 1), Strings(params, params + 2))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionStartsAndEndsWithInterpolation) { const char* params[] = { "5", "6" }; const char* const desc = "%(x)s <= arg <= %(y)s"; const Interpolation interp[] = { Interpolation(desc, desc + 5, 0), Interpolation(desc + 16, desc + 21, 1) }; EXPECT_EQ("5 <= arg <= 6", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 2), Strings(params, params + 2))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionDoesNotStartOrEndWithInterpolation) { const char* params[] = { "5.2" }; const char* const desc = "has %(x)s cents"; const Interpolation interp[] = { Interpolation(desc + 4, desc + 9, 0) }; EXPECT_EQ("has 5.2 cents", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 1), Strings(params, params + 1))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionContainsMultipleInterpolations) { const char* params[] = { "5", "6" }; const char* const desc = "in %(*)s or [%(x)s, %(y)s]"; const Interpolation interp[] = { Interpolation(desc + 3, desc + 8, kTupleInterpolation), Interpolation(desc + 13, desc + 18, 0), Interpolation(desc + 20, desc + 25, 1) }; EXPECT_EQ("in (5, 6) or [5, 6]", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 3), Strings(params, params + 2))); } TEST(FormatMatcherDescriptionTest, WorksWhenDescriptionContainsRepeatedParams) { const char* params[] = { "9" }; const char* const desc = "in [-%(x)s, %(x)s]"; const Interpolation interp[] = { Interpolation(desc + 5, desc + 10, 0), Interpolation(desc + 12, desc + 17, 0) }; EXPECT_EQ("in [-9, 9]", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 2), Strings(params, params + 1))); } TEST(FormatMatcherDescriptionTest, WorksForDescriptionWithInvalidInterpolation) { const char* params[] = { "9" }; const char* const desc = "> %(x)s %(x)"; const Interpolation interp[] = { Interpolation(desc + 2, desc + 7, 0) }; EXPECT_EQ("> 9 %(x)", FormatMatcherDescription("Foo", desc, Interpolations(interp, interp + 1), Strings(params, params + 1))); } // Tests PolymorphicMatcher::mutable_impl(). TEST(PolymorphicMatcherTest, CanAccessMutableImpl) { PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); DivisibleByImpl& impl = m.mutable_impl(); EXPECT_EQ(42, impl.divider()); impl.set_divider(0); EXPECT_EQ(0, m.mutable_impl().divider()); } // Tests PolymorphicMatcher::impl(). TEST(PolymorphicMatcherTest, CanAccessImpl) { const PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); const DivisibleByImpl& impl = m.impl(); EXPECT_EQ(42, impl.divider()); } } // namespace gmock_matchers_test } // namespace testing