| Index: testing/gmock/include/gmock/gmock-matchers.h
|
| diff --git a/testing/gmock/include/gmock/gmock-matchers.h b/testing/gmock/include/gmock/gmock-matchers.h
|
| index 66efecd4eb43a87ef9275f624badaa5544756150..2a42bf949f41635e3df8862a173d1997d5b5f54e 100644
|
| --- a/testing/gmock/include/gmock/gmock-matchers.h
|
| +++ b/testing/gmock/include/gmock/gmock-matchers.h
|
| @@ -43,9 +43,9 @@
|
| #include <ostream> // NOLINT
|
| #include <sstream>
|
| #include <string>
|
| +#include <utility>
|
| #include <vector>
|
|
|
| -#include <gmock/gmock-printers.h>
|
| #include <gmock/internal/gmock-internal-utils.h>
|
| #include <gmock/internal/gmock-port.h>
|
| #include <gtest/gtest.h>
|
| @@ -419,20 +419,20 @@ class SafeMatcherCastImpl {
|
| 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),
|
| + GTEST_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_(
|
| + GTEST_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;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
|
| const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
|
| const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
|
| - GMOCK_COMPILE_ASSERT_(
|
| + GTEST_COMPILE_ASSERT_(
|
| kTIsOther || kUIsOther ||
|
| (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
|
| conversion_of_arithmetic_types_must_be_lossless);
|
| @@ -566,7 +566,7 @@ bool TupleMatches(const MatcherTuple& matcher_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 ==
|
| + GTEST_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value ==
|
| tuple_size<ValueTuple>::value,
|
| matcher_and_value_have_different_numbers_of_fields);
|
| return TuplePrefix<tuple_size<ValueTuple>::value>::
|
| @@ -703,11 +703,11 @@ class AnythingMatcher {
|
| } \
|
| virtual void DescribeTo(::std::ostream* os) const { \
|
| *os << relation " "; \
|
| - UniversalPrinter<Rhs>::Print(rhs_, os); \
|
| + UniversalPrint(rhs_, os); \
|
| } \
|
| virtual void DescribeNegationTo(::std::ostream* os) const { \
|
| *os << negated_relation " "; \
|
| - UniversalPrinter<Rhs>::Print(rhs_, os); \
|
| + UniversalPrint(rhs_, os); \
|
| } \
|
| private: \
|
| Rhs rhs_; \
|
| @@ -911,7 +911,7 @@ class StrEqualityMatcher {
|
| if (!case_sensitive_) {
|
| *os << "(ignoring case) ";
|
| }
|
| - UniversalPrinter<StringType>::Print(string_, os);
|
| + UniversalPrint(string_, os);
|
| }
|
|
|
| const StringType string_;
|
| @@ -948,12 +948,12 @@ class HasSubstrMatcher {
|
| // Describes what this matcher matches.
|
| void DescribeTo(::std::ostream* os) const {
|
| *os << "has substring ";
|
| - UniversalPrinter<StringType>::Print(substring_, os);
|
| + UniversalPrint(substring_, os);
|
| }
|
|
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| *os << "has no substring ";
|
| - UniversalPrinter<StringType>::Print(substring_, os);
|
| + UniversalPrint(substring_, os);
|
| }
|
|
|
| private:
|
| @@ -989,12 +989,12 @@ class StartsWithMatcher {
|
|
|
| void DescribeTo(::std::ostream* os) const {
|
| *os << "starts with ";
|
| - UniversalPrinter<StringType>::Print(prefix_, os);
|
| + UniversalPrint(prefix_, os);
|
| }
|
|
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| *os << "doesn't start with ";
|
| - UniversalPrinter<StringType>::Print(prefix_, os);
|
| + UniversalPrint(prefix_, os);
|
| }
|
|
|
| private:
|
| @@ -1029,12 +1029,12 @@ class EndsWithMatcher {
|
|
|
| void DescribeTo(::std::ostream* os) const {
|
| *os << "ends with ";
|
| - UniversalPrinter<StringType>::Print(suffix_, os);
|
| + UniversalPrint(suffix_, os);
|
| }
|
|
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| *os << "doesn't end with ";
|
| - UniversalPrinter<StringType>::Print(suffix_, os);
|
| + UniversalPrint(suffix_, os);
|
| }
|
|
|
| private:
|
| @@ -1096,38 +1096,46 @@ class MatchesRegexMatcher {
|
| //
|
| // We define this as a macro in order to eliminate duplicated source
|
| // code.
|
| -#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op) \
|
| +#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op, relation) \
|
| class name##2Matcher { \
|
| public: \
|
| template <typename T1, typename T2> \
|
| + operator Matcher< ::std::tr1::tuple<T1, T2> >() const { \
|
| + return MakeMatcher(new Impl< ::std::tr1::tuple<T1, T2> >); \
|
| + } \
|
| + template <typename T1, typename T2> \
|
| operator Matcher<const ::std::tr1::tuple<T1, T2>&>() const { \
|
| - return MakeMatcher(new Impl<T1, T2>); \
|
| + return MakeMatcher(new Impl<const ::std::tr1::tuple<T1, T2>&>); \
|
| } \
|
| private: \
|
| - template <typename T1, typename T2> \
|
| - class Impl : public MatcherInterface<const ::std::tr1::tuple<T1, T2>&> { \
|
| + template <typename Tuple> \
|
| + class Impl : public MatcherInterface<Tuple> { \
|
| public: \
|
| virtual bool MatchAndExplain( \
|
| - const ::std::tr1::tuple<T1, T2>& args, \
|
| + Tuple 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"; \
|
| + *os << "are " relation; \
|
| } \
|
| virtual void DescribeNegationTo(::std::ostream* os) const { \
|
| - *os << "are a pair (x, y) where x " #op " y is false"; \
|
| + *os << "aren't " relation; \
|
| } \
|
| }; \
|
| }
|
|
|
| // 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, !=);
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Eq, ==, "an equal pair");
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(
|
| + Ge, >=, "a pair where the first >= the second");
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(
|
| + Gt, >, "a pair where the first > the second");
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(
|
| + Le, <=, "a pair where the first <= the second");
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(
|
| + Lt, <, "a pair where the first < the second");
|
| +GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "an unequal pair");
|
|
|
| #undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_
|
|
|
| @@ -1604,8 +1612,8 @@ class PointeeMatcher {
|
| template <typename Pointer>
|
| class Impl : public MatcherInterface<Pointer> {
|
| public:
|
| - typedef typename PointeeOf<GMOCK_REMOVE_CONST_( // NOLINT
|
| - GMOCK_REMOVE_REFERENCE_(Pointer))>::type Pointee;
|
| + typedef typename PointeeOf<GTEST_REMOVE_CONST_( // NOLINT
|
| + GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee;
|
|
|
| explicit Impl(const InnerMatcher& matcher)
|
| : matcher_(MatcherCast<const Pointee&>(matcher)) {}
|
| @@ -1663,7 +1671,7 @@ class FieldMatcher {
|
| bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
|
| return MatchAndExplainImpl(
|
| typename ::testing::internal::
|
| - is_pointer<GMOCK_REMOVE_CONST_(T)>::type(),
|
| + is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
|
| value, listener);
|
| }
|
|
|
| @@ -1702,9 +1710,9 @@ 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
|
| + // need GTEST_REFERENCE_TO_CONST, which works regardless of
|
| // PropertyType being a reference or not.
|
| - typedef GMOCK_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
|
| + typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
|
|
|
| PropertyMatcher(PropertyType (Class::*property)() const,
|
| const Matcher<RefToConstProperty>& matcher)
|
| @@ -1724,7 +1732,7 @@ class PropertyMatcher {
|
| bool MatchAndExplain(const T&value, MatchResultListener* listener) const {
|
| return MatchAndExplainImpl(
|
| typename ::testing::internal::
|
| - is_pointer<GMOCK_REMOVE_CONST_(T)>::type(),
|
| + is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
|
| value, listener);
|
| }
|
|
|
| @@ -1874,25 +1882,25 @@ class ContainerEqMatcher {
|
| 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)testing::StaticAssertTypeEq<Container,
|
| + GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>();
|
| }
|
|
|
| void DescribeTo(::std::ostream* os) const {
|
| *os << "equals ";
|
| - UniversalPrinter<StlContainer>::Print(rhs_, os);
|
| + UniversalPrint(rhs_, os);
|
| }
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| *os << "does not equal ";
|
| - UniversalPrinter<StlContainer>::Print(rhs_, os);
|
| + UniversalPrint(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
|
| + // GTEST_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)>
|
| + typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)>
|
| LhsView;
|
| typedef typename LhsView::type LhsStlContainer;
|
| StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
|
| @@ -1914,8 +1922,7 @@ class ContainerEqMatcher {
|
| *os << "which has these unexpected elements: ";
|
| printed_header = true;
|
| }
|
| - UniversalPrinter<typename LhsStlContainer::value_type>::
|
| - Print(*it, os);
|
| + UniversalPrint(*it, os);
|
| }
|
| }
|
|
|
| @@ -1933,7 +1940,7 @@ class ContainerEqMatcher {
|
| << " doesn't have these expected elements: ";
|
| printed_header2 = true;
|
| }
|
| - UniversalPrinter<typename StlContainer::value_type>::Print(*it, os);
|
| + UniversalPrint(*it, os);
|
| }
|
| }
|
| }
|
| @@ -1947,55 +1954,218 @@ class ContainerEqMatcher {
|
| GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
|
| };
|
|
|
| -// Implements Contains(element_matcher) for the given argument type Container.
|
| +// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher
|
| +// must be able to be safely cast to Matcher<tuple<const T1&, const
|
| +// T2&> >, where T1 and T2 are the types of elements in the LHS
|
| +// container and the RHS container respectively.
|
| +template <typename TupleMatcher, typename RhsContainer>
|
| +class PointwiseMatcher {
|
| + public:
|
| + typedef internal::StlContainerView<RhsContainer> RhsView;
|
| + typedef typename RhsView::type RhsStlContainer;
|
| + typedef typename RhsStlContainer::value_type RhsValue;
|
| +
|
| + // Like ContainerEq, we make a copy of rhs in case the elements in
|
| + // it are modified after this matcher is created.
|
| + PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)
|
| + : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {
|
| + // Makes sure the user doesn't instantiate this class template
|
| + // with a const or reference type.
|
| + (void)testing::StaticAssertTypeEq<RhsContainer,
|
| + GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>();
|
| + }
|
| +
|
| + template <typename LhsContainer>
|
| + operator Matcher<LhsContainer>() const {
|
| + return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
|
| + }
|
| +
|
| + template <typename LhsContainer>
|
| + class Impl : public MatcherInterface<LhsContainer> {
|
| + public:
|
| + typedef internal::StlContainerView<
|
| + GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView;
|
| + typedef typename LhsView::type LhsStlContainer;
|
| + typedef typename LhsView::const_reference LhsStlContainerReference;
|
| + typedef typename LhsStlContainer::value_type LhsValue;
|
| + // We pass the LHS value and the RHS value to the inner matcher by
|
| + // reference, as they may be expensive to copy. We must use tuple
|
| + // instead of pair here, as a pair cannot hold references (C++ 98,
|
| + // 20.2.2 [lib.pairs]).
|
| + typedef std::tr1::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
|
| +
|
| + Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)
|
| + // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.
|
| + : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),
|
| + rhs_(rhs) {}
|
| +
|
| + virtual void DescribeTo(::std::ostream* os) const {
|
| + *os << "contains " << rhs_.size()
|
| + << " values, where each value and its corresponding value in ";
|
| + UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
|
| + *os << " ";
|
| + mono_tuple_matcher_.DescribeTo(os);
|
| + }
|
| + virtual void DescribeNegationTo(::std::ostream* os) const {
|
| + *os << "doesn't contain exactly " << rhs_.size()
|
| + << " values, or contains a value x at some index i"
|
| + << " where x and the i-th value of ";
|
| + UniversalPrint(rhs_, os);
|
| + *os << " ";
|
| + mono_tuple_matcher_.DescribeNegationTo(os);
|
| + }
|
| +
|
| + virtual bool MatchAndExplain(LhsContainer lhs,
|
| + MatchResultListener* listener) const {
|
| + LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
|
| + const size_t actual_size = lhs_stl_container.size();
|
| + if (actual_size != rhs_.size()) {
|
| + *listener << "which contains " << actual_size << " values";
|
| + return false;
|
| + }
|
| +
|
| + typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
|
| + typename RhsStlContainer::const_iterator right = rhs_.begin();
|
| + for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
|
| + const InnerMatcherArg value_pair(*left, *right);
|
| +
|
| + if (listener->IsInterested()) {
|
| + StringMatchResultListener inner_listener;
|
| + if (!mono_tuple_matcher_.MatchAndExplain(
|
| + value_pair, &inner_listener)) {
|
| + *listener << "where the value pair (";
|
| + UniversalPrint(*left, listener->stream());
|
| + *listener << ", ";
|
| + UniversalPrint(*right, listener->stream());
|
| + *listener << ") at index #" << i << " don't match";
|
| + PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
| + return false;
|
| + }
|
| + } else {
|
| + if (!mono_tuple_matcher_.Matches(value_pair))
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| + }
|
| +
|
| + private:
|
| + const Matcher<InnerMatcherArg> mono_tuple_matcher_;
|
| + const RhsStlContainer rhs_;
|
| +
|
| + GTEST_DISALLOW_ASSIGN_(Impl);
|
| + };
|
| +
|
| + private:
|
| + const TupleMatcher tuple_matcher_;
|
| + const RhsStlContainer rhs_;
|
| +
|
| + GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
|
| +};
|
| +
|
| +// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
|
| template <typename Container>
|
| -class ContainsMatcherImpl : public MatcherInterface<Container> {
|
| +class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
| public:
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(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)
|
| + explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
|
| : inner_matcher_(
|
| - testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
|
| + testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
|
| +
|
| + // Checks whether:
|
| + // * All elements in the container match, if all_elements_should_match.
|
| + // * Any element in the container matches, if !all_elements_should_match.
|
| + bool MatchAndExplainImpl(bool all_elements_should_match,
|
| + 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) {
|
| + StringMatchResultListener inner_listener;
|
| + const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
| +
|
| + if (matches != all_elements_should_match) {
|
| + *listener << "whose element #" << i
|
| + << (matches ? " matches" : " doesn't match");
|
| + PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
| + return !all_elements_should_match;
|
| + }
|
| + }
|
| + return all_elements_should_match;
|
| + }
|
| +
|
| + protected:
|
| + const Matcher<const Element&> inner_matcher_;
|
| +
|
| + GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
|
| +};
|
| +
|
| +// Implements Contains(element_matcher) for the given argument type Container.
|
| +// Symmetric to EachMatcherImpl.
|
| +template <typename Container>
|
| +class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
|
| + public:
|
| + template <typename InnerMatcher>
|
| + explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
|
| + : QuantifierMatcherImpl<Container>(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);
|
| + this->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);
|
| + this->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) {
|
| - StringMatchResultListener inner_listener;
|
| - if (inner_matcher_.MatchAndExplain(*it, &inner_listener)) {
|
| - *listener << "whose element #" << i << " matches";
|
| - PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| + return this->MatchAndExplainImpl(false, container, listener);
|
| }
|
|
|
| private:
|
| - const Matcher<const Element&> inner_matcher_;
|
| -
|
| GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
|
| };
|
|
|
| +// Implements Each(element_matcher) for the given argument type Container.
|
| +// Symmetric to ContainsMatcherImpl.
|
| +template <typename Container>
|
| +class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
|
| + public:
|
| + template <typename InnerMatcher>
|
| + explicit EachMatcherImpl(InnerMatcher inner_matcher)
|
| + : QuantifierMatcherImpl<Container>(inner_matcher) {}
|
| +
|
| + // Describes what this matcher does.
|
| + virtual void DescribeTo(::std::ostream* os) const {
|
| + *os << "only contains elements that ";
|
| + this->inner_matcher_.DescribeTo(os);
|
| + }
|
| +
|
| + virtual void DescribeNegationTo(::std::ostream* os) const {
|
| + *os << "contains some element that ";
|
| + this->inner_matcher_.DescribeNegationTo(os);
|
| + }
|
| +
|
| + virtual bool MatchAndExplain(Container container,
|
| + MatchResultListener* listener) const {
|
| + return this->MatchAndExplainImpl(true, container, listener);
|
| + }
|
| +
|
| + private:
|
| + GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
|
| +};
|
| +
|
| // Implements polymorphic Contains(element_matcher).
|
| template <typename M>
|
| class ContainsMatcher {
|
| @@ -2013,6 +2183,23 @@ class ContainsMatcher {
|
| GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
|
| };
|
|
|
| +// Implements polymorphic Each(element_matcher).
|
| +template <typename M>
|
| +class EachMatcher {
|
| + public:
|
| + explicit EachMatcher(M m) : inner_matcher_(m) {}
|
| +
|
| + template <typename Container>
|
| + operator Matcher<Container>() const {
|
| + return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
|
| + }
|
| +
|
| + private:
|
| + const M inner_matcher_;
|
| +
|
| + GTEST_DISALLOW_ASSIGN_(EachMatcher);
|
| +};
|
| +
|
| // 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
|
| @@ -2020,7 +2207,7 @@ class ContainsMatcher {
|
| template <typename PairType>
|
| class KeyMatcherImpl : public MatcherInterface<PairType> {
|
| public:
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
|
| typedef typename RawPairType::first_type KeyType;
|
|
|
| template <typename InnerMatcher>
|
| @@ -2082,7 +2269,7 @@ class KeyMatcher {
|
| template <typename PairType>
|
| class PairMatcherImpl : public MatcherInterface<PairType> {
|
| public:
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
|
| typedef typename RawPairType::first_type FirstType;
|
| typedef typename RawPairType::second_type SecondType;
|
|
|
| @@ -2189,7 +2376,7 @@ class PairMatcher {
|
| template <typename Container>
|
| class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
| public:
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
| typedef internal::StlContainerView<RawContainer> View;
|
| typedef typename View::type StlContainer;
|
| typedef typename View::const_reference StlContainerReference;
|
| @@ -2308,8 +2495,7 @@ class ElementsAreMatcher0 {
|
|
|
| template <typename Container>
|
| operator Matcher<Container>() const {
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
|
| - RawContainer;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
| typedef typename internal::StlContainerView<RawContainer>::type::value_type
|
| Element;
|
|
|
| @@ -2327,8 +2513,7 @@ class ElementsAreArrayMatcher {
|
|
|
| template <typename Container>
|
| operator Matcher<Container>() const {
|
| - typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
|
| - RawContainer;
|
| + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
| typedef typename internal::StlContainerView<RawContainer>::type::value_type
|
| Element;
|
|
|
| @@ -2539,7 +2724,7 @@ inline PolymorphicMatcher<
|
| return MakePolymorphicMatcher(
|
| internal::PropertyMatcher<Class, PropertyType>(
|
| property,
|
| - MatcherCast<GMOCK_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
|
| + MatcherCast<GTEST_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)
|
| @@ -2823,15 +3008,32 @@ Truly(Predicate pred) {
|
| // values and order differences are not explained.)
|
| template <typename Container>
|
| inline PolymorphicMatcher<internal::ContainerEqMatcher< // NOLINT
|
| - GMOCK_REMOVE_CONST_(Container)> >
|
| + GTEST_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;
|
| + typedef GTEST_REMOVE_CONST_(Container) RawContainer;
|
| return MakePolymorphicMatcher(
|
| internal::ContainerEqMatcher<RawContainer>(rhs));
|
| }
|
|
|
| +// Matches an STL-style container or a native array that contains the
|
| +// same number of elements as in rhs, where its i-th element and rhs's
|
| +// i-th element (as a pair) satisfy the given pair matcher, for all i.
|
| +// TupleMatcher must be able to be safely cast to Matcher<tuple<const
|
| +// T1&, const T2&> >, where T1 and T2 are the types of elements in the
|
| +// LHS container and the RHS container respectively.
|
| +template <typename TupleMatcher, typename Container>
|
| +inline internal::PointwiseMatcher<TupleMatcher,
|
| + GTEST_REMOVE_CONST_(Container)>
|
| +Pointwise(const TupleMatcher& tuple_matcher, 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 GTEST_REMOVE_CONST_(Container) RawContainer;
|
| + return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
|
| + tuple_matcher, rhs);
|
| +}
|
| +
|
| // Matches an STL-style container or a native array that contains at
|
| // least one element matching the given value or matcher.
|
| //
|
| @@ -2855,6 +3057,38 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
|
| return internal::ContainsMatcher<M>(matcher);
|
| }
|
|
|
| +// Matches an STL-style container or a native array that contains only
|
| +// elements matching the given value or matcher.
|
| +//
|
| +// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only
|
| +// the messages are different.
|
| +//
|
| +// Examples:
|
| +// ::std::set<int> page_ids;
|
| +// // Each(m) matches an empty container, regardless of what m is.
|
| +// EXPECT_THAT(page_ids, Each(Eq(1)));
|
| +// EXPECT_THAT(page_ids, Each(Eq(77)));
|
| +//
|
| +// page_ids.insert(3);
|
| +// EXPECT_THAT(page_ids, Each(Gt(0)));
|
| +// EXPECT_THAT(page_ids, Not(Each(Gt(4))));
|
| +// page_ids.insert(1);
|
| +// EXPECT_THAT(page_ids, Not(Each(Lt(2))));
|
| +//
|
| +// ::std::map<int, size_t> page_lengths;
|
| +// page_lengths[1] = 100;
|
| +// page_lengths[2] = 200;
|
| +// page_lengths[3] = 300;
|
| +// EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));
|
| +// EXPECT_THAT(page_lengths, Each(Key(Le(3))));
|
| +//
|
| +// const char* user_ids[] = { "joe", "mike", "tom" };
|
| +// EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom")))));
|
| +template <typename M>
|
| +inline internal::EachMatcher<M> Each(M matcher) {
|
| + return internal::EachMatcher<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.
|
|
|