| 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 9a1bab242a03b60f8d2c7d5ecd67fd0926d02e01..66efecd4eb43a87ef9275f624badaa5544756150 100644
|
| --- a/testing/gmock/include/gmock/gmock-matchers.h
|
| +++ b/testing/gmock/include/gmock/gmock-matchers.h
|
| @@ -453,12 +453,11 @@ Matcher<T> A();
|
| // and MUST NOT BE USED IN USER CODE!!!
|
| namespace internal {
|
|
|
| -// If the explanation is not empty, prints it to the listener.
|
| -// 'listener' must not be NULL.
|
| -inline void PrintIfNotEmpty(
|
| - const internal::string& explanation, MatchResultListener* listener) {
|
| - if (explanation != "") {
|
| - *listener << ", " << explanation;
|
| +// If the explanation is not empty, prints it to the ostream.
|
| +inline void PrintIfNotEmpty(const internal::string& explanation,
|
| + std::ostream* os) {
|
| + if (explanation != "" && os != NULL) {
|
| + *os << ", " << explanation;
|
| }
|
| }
|
|
|
| @@ -480,20 +479,11 @@ bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,
|
| const bool match = matcher.MatchAndExplain(value, &inner_listener);
|
|
|
| UniversalPrint(value, listener->stream());
|
| - PrintIfNotEmpty(inner_listener.str(), listener);
|
| + PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
|
|
| return match;
|
| }
|
|
|
| -// 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>
|
| @@ -510,19 +500,19 @@ class TuplePrefix {
|
| && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple));
|
| }
|
|
|
| - // TuplePrefix<N>::DescribeMatchFailuresTo(matchers, values, os)
|
| + // TuplePrefix<N>::ExplainMatchFailuresTo(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) {
|
| + static void ExplainMatchFailuresTo(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);
|
| + TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);
|
|
|
| // Then describes the failure (if any) in the (N - 1)-th (0-based)
|
| // field.
|
| @@ -542,10 +532,8 @@ class TuplePrefix {
|
| // isn't interesting to the user most of the time. The
|
| // 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);
|
| + internal::UniversalPrint(value, os);
|
| + PrintIfNotEmpty(listener.str(), os);
|
| *os << "\n";
|
| }
|
| }
|
| @@ -562,9 +550,9 @@ class TuplePrefix<0> {
|
| }
|
|
|
| template <typename MatcherTuple, typename ValueTuple>
|
| - static void DescribeMatchFailuresTo(const MatcherTuple& /* matchers */,
|
| - const ValueTuple& /* values */,
|
| - ::std::ostream* /* os */) {}
|
| + static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */,
|
| + const ValueTuple& /* values */,
|
| + ::std::ostream* /* os */) {}
|
| };
|
|
|
| // TupleMatches(matcher_tuple, value_tuple) returns true iff all
|
| @@ -588,11 +576,11 @@ bool TupleMatches(const MatcherTuple& matcher_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) {
|
| +void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
|
| + const ValueTuple& values,
|
| + ::std::ostream* os) {
|
| using ::std::tr1::tuple_size;
|
| - TuplePrefix<tuple_size<MatcherTuple>::value>::DescribeMatchFailuresTo(
|
| + TuplePrefix<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
|
| matchers, values, os);
|
| }
|
|
|
| @@ -695,7 +683,8 @@ class AnythingMatcher {
|
| //
|
| // 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) \
|
| +#define GMOCK_IMPLEMENT_COMPARISON_MATCHER_( \
|
| + name, op, relation, negated_relation) \
|
| template <typename Rhs> class name##Matcher { \
|
| public: \
|
| explicit name##Matcher(const Rhs& rhs) : rhs_(rhs) {} \
|
| @@ -713,11 +702,11 @@ class AnythingMatcher {
|
| return lhs op rhs_; \
|
| } \
|
| virtual void DescribeTo(::std::ostream* os) const { \
|
| - *os << "is " relation " "; \
|
| + *os << relation " "; \
|
| UniversalPrinter<Rhs>::Print(rhs_, os); \
|
| } \
|
| virtual void DescribeNegationTo(::std::ostream* os) const { \
|
| - *os << "is not " relation " "; \
|
| + *os << negated_relation " "; \
|
| UniversalPrinter<Rhs>::Print(rhs_, os); \
|
| } \
|
| private: \
|
| @@ -730,12 +719,12 @@ class AnythingMatcher {
|
|
|
| // 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");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Eq, ==, "is equal to", "isn't equal to");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ge, >=, "is >=", "isn't >=");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Gt, >, "is >", "isn't >");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Le, <=, "is <=", "isn't <=");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Lt, <, "is <", "isn't <");
|
| +GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ne, !=, "isn't equal to", "is equal to");
|
|
|
| #undef GMOCK_IMPLEMENT_COMPARISON_MATCHER_
|
|
|
| @@ -751,7 +740,7 @@ class IsNullMatcher {
|
|
|
| void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| - *os << "is not NULL";
|
| + *os << "isn't NULL";
|
| }
|
| };
|
|
|
| @@ -765,7 +754,7 @@ class NotNullMatcher {
|
| return GetRawPointer(p) != NULL;
|
| }
|
|
|
| - void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; }
|
| + void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
|
| void DescribeNegationTo(::std::ostream* os) const {
|
| *os << "is NULL";
|
| }
|
| @@ -820,7 +809,7 @@ class RefMatcher<T&> {
|
| // in order to match the interface MatcherInterface<Super&>.
|
| virtual bool MatchAndExplain(
|
| Super& x, MatchResultListener* listener) const {
|
| - *listener << "is located @" << static_cast<const void*>(&x);
|
| + *listener << "which is located @" << static_cast<const void*>(&x);
|
| return &x == &object_;
|
| }
|
|
|
| @@ -917,10 +906,7 @@ class StrEqualityMatcher {
|
|
|
| private:
|
| void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
|
| - *os << "is ";
|
| - if (!expect_eq) {
|
| - *os << "not ";
|
| - }
|
| + *os << (expect_eq ? "is " : "isn't ");
|
| *os << "equal to ";
|
| if (!case_sensitive_) {
|
| *os << "(ignoring case) ";
|
| @@ -1212,8 +1198,11 @@ class BothOfMatcherImpl : public MatcherInterface<T> {
|
| }
|
|
|
| virtual void DescribeNegationTo(::std::ostream* os) const {
|
| - *os << "not ";
|
| - DescribeTo(os);
|
| + *os << "(";
|
| + matcher1_.DescribeNegationTo(os);
|
| + *os << ") or (";
|
| + matcher2_.DescribeNegationTo(os);
|
| + *os << ")";
|
| }
|
|
|
| virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
|
| @@ -1240,7 +1229,7 @@ class BothOfMatcherImpl : public MatcherInterface<T> {
|
| } else {
|
| *listener << s1;
|
| if (s2 != "") {
|
| - *listener << "; " << s2;
|
| + *listener << ", and " << s2;
|
| }
|
| }
|
| return true;
|
| @@ -1296,8 +1285,11 @@ class EitherOfMatcherImpl : public MatcherInterface<T> {
|
| }
|
|
|
| virtual void DescribeNegationTo(::std::ostream* os) const {
|
| - *os << "not ";
|
| - DescribeTo(os);
|
| + *os << "(";
|
| + matcher1_.DescribeNegationTo(os);
|
| + *os << ") and (";
|
| + matcher2_.DescribeNegationTo(os);
|
| + *os << ")";
|
| }
|
|
|
| virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
|
| @@ -1324,7 +1316,7 @@ class EitherOfMatcherImpl : public MatcherInterface<T> {
|
| } else {
|
| *listener << s1;
|
| if (s2 != "") {
|
| - *listener << "; " << s2;
|
| + *listener << ", and " << s2;
|
| }
|
| }
|
| return false;
|
| @@ -1462,18 +1454,15 @@ class PredicateFormatterFromMatcher {
|
| // 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)) {
|
| + if (MatchPrintAndExplain(x, matcher, &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());
|
| - }
|
| +
|
| + ::std::stringstream ss;
|
| + ss << "Value of: " << value_text << "\n"
|
| + << "Expected: ";
|
| + matcher.DescribeTo(&ss);
|
| + ss << "\n Actual: " << listener.str();
|
| + return AssertionFailure() << ss.str();
|
| }
|
|
|
| private:
|
| @@ -1548,12 +1537,12 @@ class FloatingEqMatcher {
|
| ::std::numeric_limits<FloatType>::digits10 + 2);
|
| if (FloatingPoint<FloatType>(rhs_).is_nan()) {
|
| if (nan_eq_nan_) {
|
| - *os << "is not NaN";
|
| + *os << "isn't NaN";
|
| } else {
|
| *os << "is anything";
|
| }
|
| } else {
|
| - *os << "is not approximately " << rhs_;
|
| + *os << "isn't approximately " << rhs_;
|
| }
|
| // Restore original precision.
|
| os->precision(old_precision);
|
| @@ -1912,7 +1901,7 @@ class ContainerEqMatcher {
|
|
|
| ::std::ostream* const os = listener->stream();
|
| if (os != NULL) {
|
| - // Something is different. Check for missing values first.
|
| + // Something is different. Check for extra values first.
|
| bool printed_header = false;
|
| for (typename LhsStlContainer::const_iterator it =
|
| lhs_stl_container.begin();
|
| @@ -1922,7 +1911,7 @@ class ContainerEqMatcher {
|
| if (printed_header) {
|
| *os << ", ";
|
| } else {
|
| - *os << "Only in actual: ";
|
| + *os << "which has these unexpected elements: ";
|
| printed_header = true;
|
| }
|
| UniversalPrinter<typename LhsStlContainer::value_type>::
|
| @@ -1930,7 +1919,7 @@ class ContainerEqMatcher {
|
| }
|
| }
|
|
|
| - // Now check for extra values.
|
| + // Now check for missing values.
|
| bool printed_header2 = false;
|
| for (typename StlContainer::const_iterator it = rhs_.begin();
|
| it != rhs_.end(); ++it) {
|
| @@ -1940,7 +1929,8 @@ class ContainerEqMatcher {
|
| if (printed_header2) {
|
| *os << ", ";
|
| } else {
|
| - *os << (printed_header ? "; not" : "Not") << " in actual: ";
|
| + *os << (printed_header ? ",\nand" : "which")
|
| + << " doesn't have these expected elements: ";
|
| printed_header2 = true;
|
| }
|
| UniversalPrinter<typename StlContainer::value_type>::Print(*it, os);
|
| @@ -1990,8 +1980,10 @@ class ContainsMatcherImpl : public MatcherInterface<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";
|
| + StringMatchResultListener inner_listener;
|
| + if (inner_matcher_.MatchAndExplain(*it, &inner_listener)) {
|
| + *listener << "whose element #" << i << " matches";
|
| + PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
| return true;
|
| }
|
| }
|
| @@ -2040,7 +2032,14 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
|
| // 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);
|
| + StringMatchResultListener inner_listener;
|
| + const bool match = inner_matcher_.MatchAndExplain(key_value.first,
|
| + &inner_listener);
|
| + const internal::string explanation = inner_listener.str();
|
| + if (explanation != "") {
|
| + *listener << "whose first field is a value " << explanation;
|
| + }
|
| + return match;
|
| }
|
|
|
| // Describes what this matcher does.
|
| @@ -2125,14 +2124,14 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
|
| if (!first_matcher_.MatchAndExplain(a_pair.first,
|
| &first_inner_listener)) {
|
| *listener << "whose first field does not match";
|
| - PrintIfNotEmpty(first_inner_listener.str(), listener);
|
| + PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
|
| return false;
|
| }
|
| StringMatchResultListener second_inner_listener;
|
| if (!second_matcher_.MatchAndExplain(a_pair.second,
|
| &second_inner_listener)) {
|
| *listener << "whose second field does not match";
|
| - PrintIfNotEmpty(second_inner_listener.str(), listener);
|
| + PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
|
| return false;
|
| }
|
| ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),
|
| @@ -2217,7 +2216,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
| } else {
|
| *os << "has " << Elements(count()) << " where\n";
|
| for (size_t i = 0; i != count(); ++i) {
|
| - *os << "element " << i << " ";
|
| + *os << "element #" << i << " ";
|
| matchers_[i].DescribeTo(os);
|
| if (i + 1 < count()) {
|
| *os << ",\n";
|
| @@ -2229,13 +2228,13 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
| // Describes what the negation of this matcher does.
|
| virtual void DescribeNegationTo(::std::ostream* os) const {
|
| if (count() == 0) {
|
| - *os << "is not empty";
|
| + *os << "isn't empty";
|
| return;
|
| }
|
|
|
| - *os << "does not have " << Elements(count()) << ", or\n";
|
| + *os << "doesn't have " << Elements(count()) << ", or\n";
|
| for (size_t i = 0; i != count(); ++i) {
|
| - *os << "element " << i << " ";
|
| + *os << "element #" << i << " ";
|
| matchers_[i].DescribeNegationTo(os);
|
| if (i + 1 < count()) {
|
| *os << ", or\n";
|
| @@ -2253,7 +2252,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
| // 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);
|
| + *listener << "which has " << Elements(actual_count);
|
| }
|
| return false;
|
| }
|
| @@ -2268,24 +2267,22 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
| } 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());
|
| + *listener << "whose element #" << i << " doesn't match";
|
| + PrintIfNotEmpty(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 << ",\nand ";
|
| }
|
| - *listener << "element " << i << " " << s;
|
| + *listener << "whose element #" << i << " matches, " << s;
|
| reason_printed = true;
|
| }
|
| }
|
|
|