diff options
author | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2010-03-24 17:35:11 +0000 |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2010-03-24 17:35:11 +0000 |
commit | b1c7f93c52d7fbf484f34d01a65cfaec03786564 (patch) | |
tree | 1e506bb6f4bf1e426abac589824a93e06b0146eb /include | |
parent | 676e8cc6092853c9dbf1eeab2402be0069d8fb7e (diff) | |
download | googletest-b1c7f93c52d7fbf484f34d01a65cfaec03786564.tar.gz googletest-b1c7f93c52d7fbf484f34d01a65cfaec03786564.tar.bz2 googletest-b1c7f93c52d7fbf484f34d01a65cfaec03786564.zip |
Improves matcher messages across the board.
Diffstat (limited to 'include')
-rw-r--r-- | include/gmock/gmock-generated-matchers.h | 21 | ||||
-rw-r--r-- | include/gmock/gmock-generated-matchers.h.pump | 17 | ||||
-rw-r--r-- | include/gmock/gmock-matchers.h | 171 | ||||
-rw-r--r-- | include/gmock/gmock-spec-builders.h | 12 |
4 files changed, 123 insertions, 98 deletions
diff --git a/include/gmock/gmock-generated-matchers.h b/include/gmock/gmock-generated-matchers.h index 731ad7df..9e5bedea 100644 --- a/include/gmock/gmock-generated-matchers.h +++ b/include/gmock/gmock-generated-matchers.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gmock-generated-matchers.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. @@ -231,15 +233,28 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { virtual bool MatchAndExplain(ArgsTuple args, MatchResultListener* listener) const { - return inner_matcher_.MatchAndExplain(GetSelectedArgs(args), listener); + const SelectedArgs& selected_args = GetSelectedArgs(args); + if (!listener->IsInterested()) + return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = inner_matcher_.MatchAndExplain(selected_args, + &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; } virtual void DescribeTo(::std::ostream* os) const { + *os << "are a tuple "; PrintIndices(os); inner_matcher_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "are a tuple "; PrintIndices(os); inner_matcher_.DescribeNegationTo(os); } @@ -252,7 +267,7 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { // Prints the indices of the selected fields. static void PrintIndices(::std::ostream* os) { - *os << "are a tuple whose fields ("; + *os << "whose fields ("; const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 }; for (int i = 0; i < 10; i++) { if (indices[i] < 0) diff --git a/include/gmock/gmock-generated-matchers.h.pump b/include/gmock/gmock-generated-matchers.h.pump index fb2bc358..07a51a36 100644 --- a/include/gmock/gmock-generated-matchers.h.pump +++ b/include/gmock/gmock-generated-matchers.h.pump @@ -118,15 +118,28 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { virtual bool MatchAndExplain(ArgsTuple args, MatchResultListener* listener) const { - return inner_matcher_.MatchAndExplain(GetSelectedArgs(args), listener); + const SelectedArgs& selected_args = GetSelectedArgs(args); + if (!listener->IsInterested()) + return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = inner_matcher_.MatchAndExplain(selected_args, + &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; } virtual void DescribeTo(::std::ostream* os) const { + *os << "are a tuple "; PrintIndices(os); inner_matcher_.DescribeTo(os); } virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "are a tuple "; PrintIndices(os); inner_matcher_.DescribeNegationTo(os); } @@ -138,7 +151,7 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { // Prints the indices of the selected fields. static void PrintIndices(::std::ostream* os) { - *os << "are a tuple whose fields ("; + *os << "whose fields ("; const int indices[$n] = { $ks }; for (int i = 0; i < $n; i++) { if (indices[i] < 0) diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 9a1bab24..66efecd4 100644 --- a/include/gmock/gmock-matchers.h +++ b/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; } } diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h index 9b60f692..74a095da 100644 --- a/include/gmock/gmock-spec-builders.h +++ b/include/gmock/gmock-spec-builders.h @@ -993,8 +993,8 @@ class TypedExpectation : public ExpectationBase { // Describes the result of matching the arguments against this // expectation to the given ostream. // L >= g_gmock_mutex - void DescribeMatchResultTo(const ArgumentTuple& args, - ::std::ostream* os) const { + void ExplainMatchResultTo(const ArgumentTuple& args, + ::std::ostream* os) const { g_gmock_mutex.AssertHeld(); if (is_retired()) { @@ -1002,7 +1002,7 @@ class TypedExpectation : public ExpectationBase { << " Actual: it is retired\n"; } else if (!Matches(args)) { if (!TupleMatches(matchers_, args)) { - DescribeMatchFailureTupleTo(matchers_, args, os); + ExplainMatchFailureTupleTo(matchers_, args, os); } StringMatchResultListener listener; if (!extra_matcher_.MatchAndExplain(args, &listener)) { @@ -1010,7 +1010,7 @@ class TypedExpectation : public ExpectationBase { extra_matcher_.DescribeTo(os); *os << "\n Actual: don't match"; - internal::StreamInParensAsNeeded(listener.str(), os); + internal::PrintIfNotEmpty(listener.str(), os); *os << "\n"; } } else if (!AllPrerequisitesAreSatisfied()) { @@ -1028,7 +1028,7 @@ class TypedExpectation : public ExpectationBase { *os << " (end of pre-requisites)\n"; } else { // This line is here just for completeness' sake. It will never - // be executed as currently the DescribeMatchResultTo() function + // be executed as currently the ExplainMatchResultTo() function // is called only when the mock function call does NOT match the // expectation. *os << "The call matches the expectation.\n"; @@ -1618,7 +1618,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { *why << "tried expectation #" << i << ": "; } *why << expectations_[i]->source_text() << "...\n"; - expectations_[i]->DescribeMatchResultTo(args, why); + expectations_[i]->ExplainMatchResultTo(args, why); expectations_[i]->DescribeCallCountTo(why); } } |