Implements custom description string for MATCHER*.
This commit is contained in:
		@@ -40,18 +40,11 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <gmock/gmock-matchers.h>
 | 
			
		||||
#include <gmock/gmock-printers.h>
 | 
			
		||||
 | 
			
		||||
namespace testing {
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// Generates a non-fatal failure iff 'description' is not a valid
 | 
			
		||||
// matcher description.
 | 
			
		||||
inline void ValidateMatcherDescription(const char* description) {
 | 
			
		||||
  EXPECT_STREQ("", description)
 | 
			
		||||
      << "The description string in a MATCHER*() macro must be \"\" "
 | 
			
		||||
         "at this moment.  We will implement custom description string soon.";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implements ElementsAre() and ElementsAreArray().
 | 
			
		||||
template <typename Container>
 | 
			
		||||
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
 | 
			
		||||
@@ -674,10 +667,18 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
//
 | 
			
		||||
// will define a matcher with the given name that executes the
 | 
			
		||||
// statements, which must return a bool to indicate if the match
 | 
			
		||||
// succeeds.  For now, the description_string must be "", but we'll
 | 
			
		||||
// allow other values soon.  Inside the statements, you can refer to
 | 
			
		||||
// the value being matched by 'arg', and refer to its type by
 | 
			
		||||
// 'arg_type'.  For example:
 | 
			
		||||
// succeeds.  Inside the statements, you can refer to the value being
 | 
			
		||||
// matched by 'arg', and refer to its type by 'arg_type'.
 | 
			
		||||
//
 | 
			
		||||
// The description string documents what the matcher does, and is used
 | 
			
		||||
// to generate the failure message when the match fails.  Since a
 | 
			
		||||
// MATCHER() is usually defined in a header file shared by multiple
 | 
			
		||||
// C++ source files, we require the description to be a C-string
 | 
			
		||||
// literal to avoid possible side effects.  It can be empty, in which
 | 
			
		||||
// case we'll use the sequence of words in the matcher name as the
 | 
			
		||||
// description.
 | 
			
		||||
//
 | 
			
		||||
// For example:
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER(IsEven, "") { return (arg % 2) == 0; }
 | 
			
		||||
//
 | 
			
		||||
@@ -740,6 +741,38 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to
 | 
			
		||||
// support multi-parameter matchers.
 | 
			
		||||
//
 | 
			
		||||
// When defining a parameterized matcher, you can use Python-style
 | 
			
		||||
// interpolations in the description string to refer to the parameter
 | 
			
		||||
// values.  We support the following syntax currently:
 | 
			
		||||
//
 | 
			
		||||
//   %%       a single '%' character
 | 
			
		||||
//   %(*)s    all parameters of the matcher printed as a tuple
 | 
			
		||||
//   %(foo)s  value of the matcher parameter named 'foo'
 | 
			
		||||
//
 | 
			
		||||
// For example,
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
 | 
			
		||||
//     return low <= arg && arg <= hi;
 | 
			
		||||
//   }
 | 
			
		||||
//   ...
 | 
			
		||||
//   EXPECT_THAT(3, InClosedRange(4, 6));
 | 
			
		||||
//
 | 
			
		||||
// would generate a failure that contains the message:
 | 
			
		||||
//
 | 
			
		||||
//   Expected: is in range [4, 6]
 | 
			
		||||
//
 | 
			
		||||
// If you specify "" as the description, the failure message will
 | 
			
		||||
// contain the sequence of words in the matcher name followed by the
 | 
			
		||||
// parameter values printed as a tuple.  For example,
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_P2(InClosedRange, low, hi, "") { ... }
 | 
			
		||||
//   ...
 | 
			
		||||
//   EXPECT_THAT(3, InClosedRange(4, 6));
 | 
			
		||||
//
 | 
			
		||||
// would generate a failure that contains the text:
 | 
			
		||||
//
 | 
			
		||||
//   Expected: in closed range (4, 6)
 | 
			
		||||
//
 | 
			
		||||
// For the purpose of typing, you can view
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
 | 
			
		||||
@@ -796,25 +829,77 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
// To learn more about using these macros, please search for 'MATCHER'
 | 
			
		||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
 | 
			
		||||
 | 
			
		||||
namespace testing {
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 | 
			
		||||
#define MATCHER(name, description)\
 | 
			
		||||
  class name##Matcher {\
 | 
			
		||||
   public:\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl() {}\
 | 
			
		||||
      gmock_Impl(const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<>());\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>());\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##Matcher() {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  inline name##Matcher name() {\
 | 
			
		||||
    return name##Matcher();\
 | 
			
		||||
@@ -830,23 +915,32 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\
 | 
			
		||||
      explicit gmock_Impl(p0##_type gmock_p0, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type>(p0));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type>\
 | 
			
		||||
  inline name##MatcherP<p0##_type> name(p0##_type p0) {\
 | 
			
		||||
@@ -864,30 +958,35 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
 | 
			
		||||
          p1(gmock_p1) {}\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type>(p0, p1));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
 | 
			
		||||
        p1(gmock_p1) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type>\
 | 
			
		||||
  inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \
 | 
			
		||||
@@ -906,35 +1005,39 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
          p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
               gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
 | 
			
		||||
                    p2));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
      p2##_type p2;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
    p2##_type p2;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type>\
 | 
			
		||||
  inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
 | 
			
		||||
@@ -955,40 +1058,42 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
          p3(gmock_p3) {}\
 | 
			
		||||
          p3##_type gmock_p3, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, \
 | 
			
		||||
                    p3##_type>(p0, p1, p2, p3));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
      p2##_type p2;\
 | 
			
		||||
      p3##_type p3;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
 | 
			
		||||
        p2(gmock_p2), p3(gmock_p3) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
    p2##_type p2;\
 | 
			
		||||
    p3##_type p3;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type>\
 | 
			
		||||
@@ -1013,45 +1118,45 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \
 | 
			
		||||
          p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type>(p0, p1, p2, p3, p4));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
      p2##_type p2;\
 | 
			
		||||
      p3##_type p3;\
 | 
			
		||||
      p4##_type p4;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, \
 | 
			
		||||
        p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
        p3(gmock_p3), p4(gmock_p4) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
    p2##_type p2;\
 | 
			
		||||
    p3##_type p3;\
 | 
			
		||||
    p4##_type p4;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type>\
 | 
			
		||||
@@ -1076,25 +1181,18 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
          p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), p5(gmock_p5), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p5, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
@@ -1102,17 +1200,20 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      p3##_type p3;\
 | 
			
		||||
      p4##_type p4;\
 | 
			
		||||
      p5##_type p5;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4, p5));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
        p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
@@ -1120,6 +1221,7 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    p3##_type p3;\
 | 
			
		||||
    p4##_type p4;\
 | 
			
		||||
    p5##_type p5;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type, typename p5##_type>\
 | 
			
		||||
@@ -1147,26 +1249,20 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
 | 
			
		||||
          p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
 | 
			
		||||
          p6##_type gmock_p6, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
 | 
			
		||||
               gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p5, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p6, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
 | 
			
		||||
                    p6));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
@@ -1175,18 +1271,22 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      p4##_type p4;\
 | 
			
		||||
      p5##_type p5;\
 | 
			
		||||
      p6##_type p6;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4, p5, p6));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
        p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
 | 
			
		||||
        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
 | 
			
		||||
        p6(gmock_p6) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
 | 
			
		||||
          NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
@@ -1195,6 +1295,7 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    p4##_type p4;\
 | 
			
		||||
    p5##_type p5;\
 | 
			
		||||
    p6##_type p6;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type, typename p5##_type, \
 | 
			
		||||
@@ -1225,29 +1326,20 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
 | 
			
		||||
          p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \
 | 
			
		||||
          p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \
 | 
			
		||||
          p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
 | 
			
		||||
          p6##_type gmock_p6, p7##_type gmock_p7, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
 | 
			
		||||
               gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p5, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p6, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p7, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
 | 
			
		||||
                    p3, p4, p5, p6, p7));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
@@ -1257,11 +1349,13 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      p5##_type p5;\
 | 
			
		||||
      p6##_type p6;\
 | 
			
		||||
      p7##_type p7;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4, p5, p6, p7));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, \
 | 
			
		||||
              gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
@@ -1269,7 +1363,10 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
        p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
 | 
			
		||||
        p7(gmock_p7) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
 | 
			
		||||
          #p7, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
@@ -1279,6 +1376,7 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    p5##_type p5;\
 | 
			
		||||
    p6##_type p6;\
 | 
			
		||||
    p7##_type p7;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type, typename p5##_type, \
 | 
			
		||||
@@ -1310,32 +1408,20 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
     public:\
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
 | 
			
		||||
          p6##_type gmock_p6, p7##_type gmock_p7, \
 | 
			
		||||
          p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
 | 
			
		||||
          p7(gmock_p7), p8(gmock_p8) {}\
 | 
			
		||||
          p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
 | 
			
		||||
               p8(gmock_p8), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p5, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p6, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p7, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p8, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type, p5##_type, p6##_type, p7##_type, \
 | 
			
		||||
                    p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
@@ -1346,11 +1432,13 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      p6##_type p6;\
 | 
			
		||||
      p7##_type p7;\
 | 
			
		||||
      p8##_type p8;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4, p5, p6, p7, p8));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, \
 | 
			
		||||
              gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
@@ -1358,7 +1446,10 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
        p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
 | 
			
		||||
        p8(gmock_p8) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
 | 
			
		||||
          #p7, #p8, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
@@ -1369,6 +1460,7 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    p6##_type p6;\
 | 
			
		||||
    p7##_type p7;\
 | 
			
		||||
    p8##_type p8;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type, typename p5##_type, \
 | 
			
		||||
@@ -1403,33 +1495,20 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
 | 
			
		||||
          p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
 | 
			
		||||
          p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
 | 
			
		||||
          p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
 | 
			
		||||
          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
 | 
			
		||||
          p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
 | 
			
		||||
          p9##_type gmock_p9, \
 | 
			
		||||
          const ::testing::internal::Interpolations& gmock_interp)\
 | 
			
		||||
           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
 | 
			
		||||
               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
 | 
			
		||||
               p8(gmock_p8), p9(gmock_p9), gmock_interp_(gmock_interp) {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p1, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p2, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p3, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p4, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p5, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p6, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p7, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p8, os);\
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p9, os);\
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
 | 
			
		||||
                    p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
 | 
			
		||||
                    p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\
 | 
			
		||||
      p0##_type p0;\
 | 
			
		||||
      p1##_type p1;\
 | 
			
		||||
@@ -1441,11 +1520,13 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
      p7##_type p7;\
 | 
			
		||||
      p8##_type p8;\
 | 
			
		||||
      p9##_type p9;\
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>(p0, p1, \
 | 
			
		||||
          p2, p3, p4, p5, p6, p7, p8, p9));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, \
 | 
			
		||||
              gmock_interp_));\
 | 
			
		||||
    }\
 | 
			
		||||
    name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \
 | 
			
		||||
        p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
 | 
			
		||||
@@ -1453,7 +1534,10 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
        p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
 | 
			
		||||
        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
 | 
			
		||||
        p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { #p0, #p1, #p2, #p3, #p4, #p5, #p6, \
 | 
			
		||||
          #p7, #p8, #p9, NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\
 | 
			
		||||
    p0##_type p0;\
 | 
			
		||||
    p1##_type p1;\
 | 
			
		||||
@@ -1465,6 +1549,7 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
    p7##_type p7;\
 | 
			
		||||
    p8##_type p8;\
 | 
			
		||||
    p9##_type p9;\
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\
 | 
			
		||||
  template <typename p0##_type, typename p1##_type, typename p2##_type, \
 | 
			
		||||
      typename p3##_type, typename p4##_type, typename p5##_type, \
 | 
			
		||||
 
 | 
			
		||||
@@ -43,18 +43,11 @@ $var n = 10  $$ The maximum arity we support.
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <gmock/gmock-matchers.h>
 | 
			
		||||
#include <gmock/gmock-printers.h>
 | 
			
		||||
 | 
			
		||||
namespace testing {
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// Generates a non-fatal failure iff 'description' is not a valid
 | 
			
		||||
// matcher description.
 | 
			
		||||
inline void ValidateMatcherDescription(const char* description) {
 | 
			
		||||
  EXPECT_STREQ("", description)
 | 
			
		||||
      << "The description string in a MATCHER*() macro must be \"\" "
 | 
			
		||||
         "at this moment.  We will implement custom description string soon.";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implements ElementsAre() and ElementsAreArray().
 | 
			
		||||
template <typename Container>
 | 
			
		||||
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
 | 
			
		||||
@@ -310,6 +303,9 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
 | 
			
		||||
$$   // show up in the generated code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// The MATCHER* family of macros can be used in a namespace scope to
 | 
			
		||||
// define custom matchers easily.  The syntax:
 | 
			
		||||
@@ -318,10 +314,18 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
//
 | 
			
		||||
// will define a matcher with the given name that executes the
 | 
			
		||||
// statements, which must return a bool to indicate if the match
 | 
			
		||||
// succeeds.  For now, the description_string must be "", but we'll
 | 
			
		||||
// allow other values soon.  Inside the statements, you can refer to
 | 
			
		||||
// the value being matched by 'arg', and refer to its type by
 | 
			
		||||
// 'arg_type'.  For example:
 | 
			
		||||
// succeeds.  Inside the statements, you can refer to the value being
 | 
			
		||||
// matched by 'arg', and refer to its type by 'arg_type'.
 | 
			
		||||
//
 | 
			
		||||
// The description string documents what the matcher does, and is used
 | 
			
		||||
// to generate the failure message when the match fails.  Since a
 | 
			
		||||
// MATCHER() is usually defined in a header file shared by multiple
 | 
			
		||||
// C++ source files, we require the description to be a C-string
 | 
			
		||||
// literal to avoid possible side effects.  It can be empty, in which
 | 
			
		||||
// case we'll use the sequence of words in the matcher name as the
 | 
			
		||||
// description.
 | 
			
		||||
//
 | 
			
		||||
// For example:
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER(IsEven, "") { return (arg % 2) == 0; }
 | 
			
		||||
//
 | 
			
		||||
@@ -384,6 +388,38 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
 | 
			
		||||
// support multi-parameter matchers.
 | 
			
		||||
//
 | 
			
		||||
// When defining a parameterized matcher, you can use Python-style
 | 
			
		||||
// interpolations in the description string to refer to the parameter
 | 
			
		||||
// values.  We support the following syntax currently:
 | 
			
		||||
//
 | 
			
		||||
//   %%       a single '%' character
 | 
			
		||||
//   %(*)s    all parameters of the matcher printed as a tuple
 | 
			
		||||
//   %(foo)s  value of the matcher parameter named 'foo'
 | 
			
		||||
//
 | 
			
		||||
// For example,
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") {
 | 
			
		||||
//     return low <= arg && arg <= hi;
 | 
			
		||||
//   }
 | 
			
		||||
//   ...
 | 
			
		||||
//   EXPECT_THAT(3, InClosedRange(4, 6));
 | 
			
		||||
//
 | 
			
		||||
// would generate a failure that contains the message:
 | 
			
		||||
//
 | 
			
		||||
//   Expected: is in range [4, 6]
 | 
			
		||||
//
 | 
			
		||||
// If you specify "" as the description, the failure message will
 | 
			
		||||
// contain the sequence of words in the matcher name followed by the
 | 
			
		||||
// parameter values printed as a tuple.  For example,
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_P2(InClosedRange, low, hi, "") { ... }
 | 
			
		||||
//   ...
 | 
			
		||||
//   EXPECT_THAT(3, InClosedRange(4, 6));
 | 
			
		||||
//
 | 
			
		||||
// would generate a failure that contains the text:
 | 
			
		||||
//
 | 
			
		||||
//   Expected: in closed range (4, 6)
 | 
			
		||||
//
 | 
			
		||||
// For the purpose of typing, you can view
 | 
			
		||||
//
 | 
			
		||||
//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
 | 
			
		||||
@@ -440,6 +476,48 @@ ElementsAreArray(const T (&array)[N]) {
 | 
			
		||||
// To learn more about using these macros, please search for 'MATCHER'
 | 
			
		||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
 | 
			
		||||
 | 
			
		||||
namespace testing {
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 | 
			
		||||
$range i 0..n
 | 
			
		||||
$for i
 | 
			
		||||
 | 
			
		||||
@@ -454,7 +532,11 @@ $var template = [[$if i==0 [[]] $else [[
 | 
			
		||||
  template <$for j, [[typename p$j##_type]]>\
 | 
			
		||||
]]]]
 | 
			
		||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
 | 
			
		||||
$var impl_ctor_param_list = [[$for j [[p$j##_type gmock_p$j, ]]
 | 
			
		||||
const ::testing::internal::Interpolations& gmock_interp]]
 | 
			
		||||
$var impl_inits = [[ : $for j [[p$j(gmock_p$j), ]]gmock_interp_(gmock_interp)]]
 | 
			
		||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
 | 
			
		||||
$var params_and_interp = [[$for j [[p$j, ]]gmock_interp_]]
 | 
			
		||||
$var params = [[$for j, [[p$j]]]]
 | 
			
		||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
 | 
			
		||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
 | 
			
		||||
@@ -475,34 +557,29 @@ $var param_field_decls2 = [[$for j
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
 | 
			
		||||
     public:\
 | 
			
		||||
      [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
 | 
			
		||||
      [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
 | 
			
		||||
          $impl_inits {}\
 | 
			
		||||
      virtual bool Matches(arg_type arg) const;\
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* os) const {\
 | 
			
		||||
        *os << ::testing::internal::ConvertIdentifierNameToWords(#name);\
 | 
			
		||||
[[$if i==1 [[        *os << " ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
 | 
			
		||||
]] $elif i>=2 [[        *os << " (";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p0, os);\
 | 
			
		||||
$range k 1..i-1
 | 
			
		||||
$for k [[
 | 
			
		||||
 | 
			
		||||
        *os << ", ";\
 | 
			
		||||
        ::testing::internal::UniversalPrint(p$k, os);\
 | 
			
		||||
]]
 | 
			
		||||
 | 
			
		||||
        *os << ")";\
 | 
			
		||||
 | 
			
		||||
]]]]
 | 
			
		||||
      virtual void DescribeTo(::std::ostream* gmock_os) const {\
 | 
			
		||||
        const ::testing::internal::Strings& gmock_printed_params = \
 | 
			
		||||
            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
 | 
			
		||||
                ::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]]));\
 | 
			
		||||
        *gmock_os << ::testing::internal::FormatMatcherDescription(\
 | 
			
		||||
                     #name, description, gmock_interp_, gmock_printed_params);\
 | 
			
		||||
      }\$param_field_decls
 | 
			
		||||
      const ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
    };\
 | 
			
		||||
    template <typename arg_type>\
 | 
			
		||||
    operator ::testing::Matcher<arg_type>() const {\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(new gmock_Impl<arg_type>($params));\
 | 
			
		||||
      return ::testing::Matcher<arg_type>(\
 | 
			
		||||
          new gmock_Impl<arg_type>($params_and_interp));\
 | 
			
		||||
    }\
 | 
			
		||||
    $class_name($ctor_param_list)$inits {\
 | 
			
		||||
      ::testing::internal::ValidateMatcherDescription(description);\
 | 
			
		||||
      const char* gmock_param_names[] = { $for j [[#p$j, ]]NULL };\
 | 
			
		||||
      gmock_interp_ = ::testing::internal::ValidateMatcherDescription(\
 | 
			
		||||
          gmock_param_names, ("" description ""));\
 | 
			
		||||
    }\$param_field_decls2
 | 
			
		||||
    ::testing::internal::Interpolations gmock_interp_;\
 | 
			
		||||
  };\$template
 | 
			
		||||
  inline $class_name$param_types name($param_types_and_names) {\
 | 
			
		||||
    return $class_name$param_types($params);\
 | 
			
		||||
 
 | 
			
		||||
@@ -41,22 +41,36 @@
 | 
			
		||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
 | 
			
		||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
 | 
			
		||||
// defines Foo.  If both are defined, PrintTo() takes precedence.
 | 
			
		||||
// When T is a reference type, the address of the value is also
 | 
			
		||||
//
 | 
			
		||||
// To aid debugging: when T is a reference type, the address of the
 | 
			
		||||
// value is also printed; when T is a (const) char pointer, both the
 | 
			
		||||
// pointer value and the NUL-terminated string it points to are
 | 
			
		||||
// printed.
 | 
			
		||||
//
 | 
			
		||||
// We also provide some convenient wrappers:
 | 
			
		||||
//
 | 
			
		||||
//   // Prints to a string.
 | 
			
		||||
//   string ::testing::internal::UniversalPrinter<T>::PrintAsString(value);
 | 
			
		||||
//   // Prints a value using its inferred type.
 | 
			
		||||
//   void ::testing::internal::UniversalPrint(const T& value, ostream*);
 | 
			
		||||
//   // Prints a value as the given type to a string.
 | 
			
		||||
//   string ::testing::internal::UniversalPrinter<T>::PrintToString(value);
 | 
			
		||||
//
 | 
			
		||||
//   // Prints a value tersely: for a reference type, the referenced
 | 
			
		||||
//   // value (but not the address) is printed; for a (const) char
 | 
			
		||||
//   // pointer, the NUL-terminated string (but not the pointer) is
 | 
			
		||||
//   // printed.
 | 
			
		||||
//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
 | 
			
		||||
//
 | 
			
		||||
//   // Prints the fields of a tuple tersely to a string vector, one
 | 
			
		||||
//   // element for each field.
 | 
			
		||||
//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(
 | 
			
		||||
//       const Tuple& value);
 | 
			
		||||
 | 
			
		||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
 | 
			
		||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
 | 
			
		||||
 | 
			
		||||
#include <ostream>  // NOLINT
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <gmock/internal/gmock-internal-utils.h>
 | 
			
		||||
#include <gmock/internal/gmock-port.h>
 | 
			
		||||
@@ -350,13 +364,19 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
 | 
			
		||||
// Overload for ::std::tr1::tuple.  Needed for printing function
 | 
			
		||||
// arguments, which are packed as tuples.
 | 
			
		||||
 | 
			
		||||
// This helper template allows PrintTo() for tuples to be defined by
 | 
			
		||||
typedef ::std::vector<string> Strings;
 | 
			
		||||
 | 
			
		||||
// This helper template allows PrintTo() for tuples and
 | 
			
		||||
// UniversalTersePrintTupleFieldsToStrings() to be defined by
 | 
			
		||||
// induction on the number of tuple fields.  The idea is that
 | 
			
		||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
 | 
			
		||||
// fields in tuple t, and can be defined in terms of
 | 
			
		||||
// TuplePrefixPrinter<N - 1>.
 | 
			
		||||
 | 
			
		||||
// The inductive case.
 | 
			
		||||
template <size_t N>
 | 
			
		||||
struct TuplePrefixPrinter {
 | 
			
		||||
  // Prints the first N fields of a tuple.
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
 | 
			
		||||
    TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
 | 
			
		||||
@@ -364,20 +384,33 @@ struct TuplePrefixPrinter {
 | 
			
		||||
    UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
 | 
			
		||||
        ::Print(::std::tr1::get<N - 1>(t), os);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Tersely prints the first N fields of a tuple to a string vector,
 | 
			
		||||
  // one element for each field.
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
 | 
			
		||||
    TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
 | 
			
		||||
    ::std::stringstream ss;
 | 
			
		||||
    UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
 | 
			
		||||
    strings->push_back(ss.str());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Base cases.
 | 
			
		||||
template <>
 | 
			
		||||
struct TuplePrefixPrinter<0> {
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
 | 
			
		||||
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
 | 
			
		||||
};
 | 
			
		||||
template <>
 | 
			
		||||
struct TuplePrefixPrinter<1> {
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
 | 
			
		||||
    UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
 | 
			
		||||
        Print(::std::tr1::get<0>(t), os);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
template <typename Tuple>
 | 
			
		||||
void TuplePrefixPrinter<1>::PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
 | 
			
		||||
  UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
 | 
			
		||||
      Print(::std::tr1::get<0>(t), os);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function for printing a tuple.  T must be instantiated with
 | 
			
		||||
// a tuple type.
 | 
			
		||||
@@ -499,7 +532,7 @@ class UniversalPrinter {
 | 
			
		||||
 | 
			
		||||
  // A convenient wrapper for Print() that returns the print-out as a
 | 
			
		||||
  // string.
 | 
			
		||||
  static string PrintAsString(const T& value) {
 | 
			
		||||
  static string PrintToString(const T& value) {
 | 
			
		||||
    ::std::stringstream ss;
 | 
			
		||||
    Print(value, &ss);
 | 
			
		||||
    return ss.str();
 | 
			
		||||
@@ -548,7 +581,7 @@ class UniversalPrinter<T[N]> {
 | 
			
		||||
 | 
			
		||||
  // A convenient wrapper for Print() that returns the print-out as a
 | 
			
		||||
  // string.
 | 
			
		||||
  static string PrintAsString(const T (&a)[N]) {
 | 
			
		||||
  static string PrintToString(const T (&a)[N]) {
 | 
			
		||||
    ::std::stringstream ss;
 | 
			
		||||
    Print(a, &ss);
 | 
			
		||||
    return ss.str();
 | 
			
		||||
@@ -577,7 +610,7 @@ class UniversalPrinter<T&> {
 | 
			
		||||
 | 
			
		||||
  // A convenient wrapper for Print() that returns the print-out as a
 | 
			
		||||
  // string.
 | 
			
		||||
  static string PrintAsString(const T& value) {
 | 
			
		||||
  static string PrintToString(const T& value) {
 | 
			
		||||
    ::std::stringstream ss;
 | 
			
		||||
    Print(value, &ss);
 | 
			
		||||
    return ss.str();
 | 
			
		||||
@@ -588,15 +621,34 @@ class UniversalPrinter<T&> {
 | 
			
		||||
#endif  // _MSC_VER
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Prints a value using its inferred type.  In particular, if the
 | 
			
		||||
// original type of the value is a reference, the *referenced* type
 | 
			
		||||
// (as opposed to the reference type) will be used, as C++ doesn't
 | 
			
		||||
// infer reference types.  This is useful when you just want to know
 | 
			
		||||
// what the value is and don't care if it's a reference or not.
 | 
			
		||||
// Prints a value tersely: for a reference type, the referenced value
 | 
			
		||||
// (but not the address) is printed; for a (const) char pointer, the
 | 
			
		||||
// NUL-terminated string (but not the pointer) is printed.
 | 
			
		||||
template <typename T>
 | 
			
		||||
void UniversalPrint(const T& value, ::std::ostream* os) {
 | 
			
		||||
void UniversalTersePrint(const T& value, ::std::ostream* os) {
 | 
			
		||||
  UniversalPrinter<T>::Print(value, os);
 | 
			
		||||
}
 | 
			
		||||
inline void UniversalTersePrint(const char* str, ::std::ostream* os) {
 | 
			
		||||
  if (str == NULL) {
 | 
			
		||||
    *os << "NULL";
 | 
			
		||||
  } else {
 | 
			
		||||
    UniversalPrinter<string>::Print(string(str), os);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
inline void UniversalTersePrint(char* str, ::std::ostream* os) {
 | 
			
		||||
  UniversalTersePrint(static_cast<const char*>(str), os);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Prints the fields of a tuple tersely to a string vector, one
 | 
			
		||||
// element for each field.  See the comment before
 | 
			
		||||
// UniversalTersePrint() for how we define "tersely".
 | 
			
		||||
template <typename Tuple>
 | 
			
		||||
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
 | 
			
		||||
  Strings result;
 | 
			
		||||
  TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
 | 
			
		||||
      TersePrintPrefixToStrings(value, &result);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,15 @@
 | 
			
		||||
 | 
			
		||||
// Google Mock - a framework for writing C++ mock classes.
 | 
			
		||||
//
 | 
			
		||||
// This file implements the Matcher<const string&> and
 | 
			
		||||
// Matcher<string>.
 | 
			
		||||
// This file implements Matcher<const string&>, Matcher<string>, and
 | 
			
		||||
// utilities for defining matchers.
 | 
			
		||||
 | 
			
		||||
#include <gmock/gmock-matchers.h>
 | 
			
		||||
#include <gmock/gmock-generated-matchers.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace testing {
 | 
			
		||||
 | 
			
		||||
@@ -58,4 +63,140 @@ Matcher<internal::string>::Matcher(const char* s) {
 | 
			
		||||
  *this = Eq(internal::string(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// Utilities for validating and formatting description strings in the
 | 
			
		||||
// MATCHER*() macros.
 | 
			
		||||
 | 
			
		||||
// Returns the 0-based index of the given parameter in the
 | 
			
		||||
// NULL-terminated parameter array; if the parameter is "*", returns
 | 
			
		||||
// kTupleInterpolation; if it's not found in the list, returns
 | 
			
		||||
// kInvalidInterpolation.
 | 
			
		||||
int GetParamIndex(const char* param_names[], const string& param_name) {
 | 
			
		||||
  if (param_name == "*")
 | 
			
		||||
    return kTupleInterpolation;
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; param_names[i] != NULL; i++) {
 | 
			
		||||
    if (param_name == param_names[i])
 | 
			
		||||
      return i;
 | 
			
		||||
  }
 | 
			
		||||
  return kInvalidInterpolation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If *pstr starts with the given prefix, modifies *pstr to be right
 | 
			
		||||
// past the prefix and returns true; otherwise leaves *pstr unchanged
 | 
			
		||||
// and returns false.  None of pstr, *pstr, and prefix can be NULL.
 | 
			
		||||
bool SkipPrefix(const char* prefix, const char** pstr) {
 | 
			
		||||
  const size_t prefix_len = strlen(prefix);
 | 
			
		||||
  if (strncmp(*pstr, prefix, prefix_len) == 0) {
 | 
			
		||||
    *pstr += prefix_len;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function used by ValidateMatcherDescription() to format
 | 
			
		||||
// error messages.
 | 
			
		||||
string FormatMatcherDescriptionSyntaxError(const char* description,
 | 
			
		||||
                                           const char* error_pos) {
 | 
			
		||||
  ::std::stringstream ss;
 | 
			
		||||
  ss << "Syntax error at index " << (error_pos - description)
 | 
			
		||||
     << " in matcher description \"" << description << "\": ";
 | 
			
		||||
  return ss.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
  Interpolations interps;
 | 
			
		||||
  for (const char* p = description; *p != '\0';) {
 | 
			
		||||
    if (SkipPrefix("%%", &p)) {
 | 
			
		||||
      interps.push_back(Interpolation(p - 2, p, kPercentInterpolation));
 | 
			
		||||
    } else if (SkipPrefix("%(", &p)) {
 | 
			
		||||
      const char* const q = strstr(p, ")s");
 | 
			
		||||
      if (q == NULL) {
 | 
			
		||||
        // TODO(wan@google.com): change the source file location in
 | 
			
		||||
        // the failure to point to where the MATCHER*() macro is used.
 | 
			
		||||
        ADD_FAILURE() << FormatMatcherDescriptionSyntaxError(description, p - 2)
 | 
			
		||||
                      << "an interpolation must end with \")s\", "
 | 
			
		||||
                      << "but \"" << (p - 2) << "\" does not.";
 | 
			
		||||
      } else {
 | 
			
		||||
        const string param_name(p, q);
 | 
			
		||||
        const int param_index = GetParamIndex(param_names, param_name);
 | 
			
		||||
        if (param_index == kInvalidInterpolation) {
 | 
			
		||||
          ADD_FAILURE() << FormatMatcherDescriptionSyntaxError(description, p)
 | 
			
		||||
                        << "\"" << param_name
 | 
			
		||||
                        << "\" is an invalid parameter name.";
 | 
			
		||||
        } else {
 | 
			
		||||
          interps.push_back(Interpolation(p - 2, q + 2, param_index));
 | 
			
		||||
          p = q + 2;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      EXPECT_NE(*p, '%') << FormatMatcherDescriptionSyntaxError(description, p)
 | 
			
		||||
                         << "use \"%%\" instead of \"%\" to print \"%\".";
 | 
			
		||||
      ++p;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return interps;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Joins a vector of strings as if they are fields of a tuple; returns
 | 
			
		||||
// the joined string.
 | 
			
		||||
string JoinAsTuple(const Strings& fields) {
 | 
			
		||||
  switch (fields.size()) {
 | 
			
		||||
    case 0:
 | 
			
		||||
      return "";
 | 
			
		||||
    case 1:
 | 
			
		||||
      return fields[0];
 | 
			
		||||
    default:
 | 
			
		||||
      string result = "(" + fields[0];
 | 
			
		||||
      for (size_t i = 1; i < fields.size(); i++) {
 | 
			
		||||
        result += ", ";
 | 
			
		||||
        result += fields[i];
 | 
			
		||||
      }
 | 
			
		||||
      result += ")";
 | 
			
		||||
      return result;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
  string result;
 | 
			
		||||
  if (*description == '\0') {
 | 
			
		||||
    // When the user supplies an empty description, we calculate one
 | 
			
		||||
    // from the matcher name.
 | 
			
		||||
    result = ConvertIdentifierNameToWords(matcher_name);
 | 
			
		||||
    if (param_values.size() >= 1)
 | 
			
		||||
      result += " " + JoinAsTuple(param_values);
 | 
			
		||||
  } else {
 | 
			
		||||
    // The end position of the last interpolation.
 | 
			
		||||
    const char* last_interp_end = description;
 | 
			
		||||
    for (size_t i = 0; i < interp.size(); i++) {
 | 
			
		||||
      result.append(last_interp_end, interp[i].start_pos);
 | 
			
		||||
      const int param_index = interp[i].param_index;
 | 
			
		||||
      if (param_index == kTupleInterpolation) {
 | 
			
		||||
        result += JoinAsTuple(param_values);
 | 
			
		||||
      } else if (param_index == kPercentInterpolation) {
 | 
			
		||||
        result += '%';
 | 
			
		||||
      } else if (param_index != kInvalidInterpolation) {
 | 
			
		||||
        result += param_values[param_index];
 | 
			
		||||
      }
 | 
			
		||||
      last_interp_end = interp[i].end_pos;
 | 
			
		||||
    }
 | 
			
		||||
    result += last_interp_end;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 
 | 
			
		||||
@@ -390,17 +390,23 @@ TEST(MatcherMacroTest, Works) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests that the description string supplied to MATCHER() must be
 | 
			
		||||
// empty.
 | 
			
		||||
// valid.
 | 
			
		||||
 | 
			
		||||
MATCHER(HasBadDescription, "not empty?") {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
MATCHER(HasBadDescription, "Invalid%") { return true; }
 | 
			
		||||
 | 
			
		||||
TEST(MatcherMacroTest,
 | 
			
		||||
     CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
 | 
			
		||||
  EXPECT_NONFATAL_FAILURE(HasBadDescription(),
 | 
			
		||||
                          "The description string in a MATCHER*() macro "
 | 
			
		||||
                          "must be \"\" at this moment");
 | 
			
		||||
  EXPECT_NONFATAL_FAILURE(
 | 
			
		||||
      HasBadDescription(),
 | 
			
		||||
      "Syntax error at index 7 in matcher description \"Invalid%\": "
 | 
			
		||||
      "use \"%%\" instead of \"%\" to print \"%\".");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MATCHER(HasGoodDescription, "good") { return true; }
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -452,17 +458,26 @@ TEST(MatcherPMacroTest, Works) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests that the description string supplied to MATCHER_P() must be
 | 
			
		||||
// empty.
 | 
			
		||||
// valid.
 | 
			
		||||
 | 
			
		||||
MATCHER_P(HasBadDescription1, n, "not empty?") {
 | 
			
		||||
MATCHER_P(HasBadDescription1, n, "not %(m)s good") {
 | 
			
		||||
  return arg > n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MatcherPMacroTest,
 | 
			
		||||
     CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
 | 
			
		||||
  EXPECT_NONFATAL_FAILURE(HasBadDescription1(2),
 | 
			
		||||
                          "The description string in a MATCHER*() macro "
 | 
			
		||||
                          "must be \"\" at this moment");
 | 
			
		||||
  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 true; }
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
@@ -509,17 +524,29 @@ TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Tests that the description string supplied to MATCHER_Pn() must be
 | 
			
		||||
// empty.
 | 
			
		||||
// valid.
 | 
			
		||||
 | 
			
		||||
MATCHER_P2(HasBadDescription2, m, n, "not empty?") {
 | 
			
		||||
MATCHER_P2(HasBadDescription2, m, n, "not %(good") {
 | 
			
		||||
  return arg > m + n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MatcherPnMacroTest,
 | 
			
		||||
     CreatingMatcherWithBadDescriptionGeneratesNonfatalFailure) {
 | 
			
		||||
  EXPECT_NONFATAL_FAILURE(HasBadDescription2(3, 4),
 | 
			
		||||
                          "The description string in a MATCHER*() macro "
 | 
			
		||||
                          "must be \"\" at this moment");
 | 
			
		||||
  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 true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,15 @@
 | 
			
		||||
#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::stringstream;
 | 
			
		||||
@@ -91,7 +100,18 @@ using testing::Truly;
 | 
			
		||||
using testing::TypedEq;
 | 
			
		||||
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::string;
 | 
			
		||||
 | 
			
		||||
#ifdef GMOCK_HAS_REGEX
 | 
			
		||||
@@ -2769,5 +2789,299 @@ TEST(ContainerEqExtraTest, WorksForMaps) {
 | 
			
		||||
            Explain(m, test_map));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace gmock_matchers_test
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <gmock/gmock-generated-matchers.h>
 | 
			
		||||
#include <gmock/gmock-matchers.h>
 | 
			
		||||
#include <gmock/internal/gmock-port.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
@@ -151,8 +152,11 @@ using ::std::set;
 | 
			
		||||
using ::std::tr1::make_tuple;
 | 
			
		||||
using ::std::tr1::tuple;
 | 
			
		||||
using ::std::vector;
 | 
			
		||||
using ::testing::ElementsAre;
 | 
			
		||||
using ::testing::StartsWith;
 | 
			
		||||
using ::testing::internal::UniversalPrint;
 | 
			
		||||
using ::testing::internal::Strings;
 | 
			
		||||
using ::testing::internal::UniversalTersePrint;
 | 
			
		||||
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
 | 
			
		||||
using ::testing::internal::UniversalPrinter;
 | 
			
		||||
using ::testing::internal::string;
 | 
			
		||||
 | 
			
		||||
@@ -981,28 +985,67 @@ TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
 | 
			
		||||
                         + " " + Print(sizeof(p)) + "-byte object "));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(PrintAsStringTest, WorksForNonReference) {
 | 
			
		||||
  EXPECT_EQ("123", UniversalPrinter<int>::PrintAsString(123));
 | 
			
		||||
TEST(PrintToStringTest, WorksForNonReference) {
 | 
			
		||||
  EXPECT_EQ("123", UniversalPrinter<int>::PrintToString(123));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(PrintAsStringTest, WorksForReference) {
 | 
			
		||||
TEST(PrintToStringTest, WorksForReference) {
 | 
			
		||||
  int n = 123;
 | 
			
		||||
  EXPECT_EQ("@" + PrintPointer(&n) + " 123",
 | 
			
		||||
            UniversalPrinter<const int&>::PrintAsString(n));
 | 
			
		||||
            UniversalPrinter<const int&>::PrintToString(n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalPrintTest, WorksForNonReference) {
 | 
			
		||||
TEST(UniversalTersePrintTest, WorksForNonReference) {
 | 
			
		||||
  ::std::stringstream ss;
 | 
			
		||||
  UniversalPrint(123, &ss);
 | 
			
		||||
  UniversalTersePrint(123, &ss);
 | 
			
		||||
  EXPECT_EQ("123", ss.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalPrintTest, WorksForReference) {
 | 
			
		||||
TEST(UniversalTersePrintTest, WorksForReference) {
 | 
			
		||||
  const int& n = 123;
 | 
			
		||||
  ::std::stringstream ss;
 | 
			
		||||
  UniversalPrint(n, &ss);
 | 
			
		||||
  UniversalTersePrint(n, &ss);
 | 
			
		||||
  EXPECT_EQ("123", ss.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalTersePrintTest, WorksForCString) {
 | 
			
		||||
  const char* s1 = "abc";
 | 
			
		||||
  ::std::stringstream ss1;
 | 
			
		||||
  UniversalTersePrint(s1, &ss1);
 | 
			
		||||
  EXPECT_EQ("\"abc\"", ss1.str());
 | 
			
		||||
 | 
			
		||||
  char* s2 = const_cast<char*>(s1);
 | 
			
		||||
  ::std::stringstream ss2;
 | 
			
		||||
  UniversalTersePrint(s2, &ss2);
 | 
			
		||||
  EXPECT_EQ("\"abc\"", ss2.str());
 | 
			
		||||
 | 
			
		||||
  const char* s3 = NULL;
 | 
			
		||||
  ::std::stringstream ss3;
 | 
			
		||||
  UniversalTersePrint(s3, &ss3);
 | 
			
		||||
  EXPECT_EQ("NULL", ss3.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) {
 | 
			
		||||
  EXPECT_THAT(UniversalTersePrintTupleFieldsToStrings(make_tuple()),
 | 
			
		||||
              ElementsAre());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) {
 | 
			
		||||
  EXPECT_THAT(UniversalTersePrintTupleFieldsToStrings(make_tuple(1)),
 | 
			
		||||
              ElementsAre("1"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) {
 | 
			
		||||
  EXPECT_THAT(UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')),
 | 
			
		||||
              ElementsAre("1", "'a' (97)"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) {
 | 
			
		||||
  const int n = 1;
 | 
			
		||||
  EXPECT_THAT(UniversalTersePrintTupleFieldsToStrings(
 | 
			
		||||
                  tuple<const int&, const char*>(n, "a")),
 | 
			
		||||
              ElementsAre("1", "\"a\""));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace gmock_printers_test
 | 
			
		||||
}  // namespace testing
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user