diff options
Diffstat (limited to 'googlemock')
| -rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 198 | ||||
| -rw-r--r-- | googlemock/src/gmock-matchers.cc | 58 | ||||
| -rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 299 | 
3 files changed, 483 insertions, 72 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 000908a1..0ac3b299 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -287,7 +287,7 @@ class MatcherBase {    }    // Returns true iff this matcher matches x. -  bool Matches(T x) const { +  bool Matches(GTEST_REFERENCE_TO_CONST_(T) x) const {      DummyMatchResultListener dummy;      return MatchAndExplain(x, &dummy);    } @@ -301,7 +301,8 @@ class MatcherBase {    }    // Explains why x matches, or doesn't match, the matcher. -  void ExplainMatchResultTo(T x, ::std::ostream* os) const { +  void ExplainMatchResultTo(GTEST_REFERENCE_TO_CONST_(T) x, +                            ::std::ostream* os) const {      StreamMatchResultListener listener(os);      MatchAndExplain(x, &listener);    } @@ -317,7 +318,8 @@ class MatcherBase {    MatcherBase() {}    // Constructs a matcher from its implementation. -  explicit MatcherBase(const MatcherInterface<T>* impl) +  explicit MatcherBase( +      const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl)        : impl_(impl) {}    template <typename U> @@ -342,7 +344,9 @@ class MatcherBase {    //    // If performance becomes a problem, we should see if using    // shared_ptr helps. -  ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_; +  ::testing::internal::linked_ptr< +      const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> > +      impl_;  };  }  // namespace internal @@ -407,6 +411,8 @@ class GTEST_API_ Matcher<std::string>   public:    Matcher() {} +  explicit Matcher(const MatcherInterface<const std::string&>* impl) +      : internal::MatcherBase<std::string>(impl) {}    explicit Matcher(const MatcherInterface<std::string>* impl)        : internal::MatcherBase<std::string>(impl) {} @@ -449,28 +455,95 @@ class GTEST_API_ Matcher<const ::string&>    Matcher(const char* s);  // NOLINT  }; +template <> +class GTEST_API_ Matcher< ::string> +    : public internal::MatcherBase< ::string> { + public: +  Matcher() {} + +  explicit Matcher(const MatcherInterface<const ::string&>* impl) +      : internal::MatcherBase< ::string>(impl) {} +  explicit Matcher(const MatcherInterface< ::string>* impl) +      : internal::MatcherBase< ::string>(impl) {} + +  // Allows the user to write str instead of Eq(str) sometimes, where +  // str is a std::string object. +  Matcher(const std::string& s);  // NOLINT + +  // Allows the user to write str instead of Eq(str) sometimes, where +  // str is a ::string object. +  Matcher(const ::string& s);  // NOLINT + +  // Allows the user to write "foo" instead of Eq("foo") sometimes. +  Matcher(const char* s);  // NOLINT  }; +#endif  // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_ABSL +// The following two specializations allow the user to write str +// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view +// matcher is expected.  template <> -class GTEST_API_ Matcher<StringPiece> -    : public internal::MatcherBase<StringPiece> { +class GTEST_API_ Matcher<const absl::string_view&> +    : public internal::MatcherBase<const absl::string_view&> {   public:    Matcher() {} -  explicit Matcher(const MatcherInterface<StringPiece>* impl) -      : internal::MatcherBase<StringPiece>(impl) {} +  explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) +      : internal::MatcherBase<const absl::string_view&>(impl) {}    // Allows the user to write str instead of Eq(str) sometimes, where -  // str is a string object. -  Matcher(const internal::string& s);  // NOLINT +  // str is a std::string object. +  Matcher(const std::string& s);  // NOLINT + +#if GTEST_HAS_GLOBAL_STRING +  // Allows the user to write str instead of Eq(str) sometimes, where +  // str is a ::string object. +  Matcher(const ::string& s);  // NOLINT +#endif                         // GTEST_HAS_GLOBAL_STRING    // Allows the user to write "foo" instead of Eq("foo") sometimes.    Matcher(const char* s);  // NOLINT -  // Allows the user to pass StringPieces directly. -  Matcher(StringPiece s);  // NOLINT +  // Allows the user to pass absl::string_views directly. +  Matcher(absl::string_view s);  // NOLINT  }; -#endif  // GTEST_HAS_STRING_PIECE_ + +template <> +class GTEST_API_ Matcher<absl::string_view> +    : public internal::MatcherBase<absl::string_view> { + public: +  Matcher() {} + +  explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) +      : internal::MatcherBase<absl::string_view>(impl) {} +  explicit Matcher(const MatcherInterface<absl::string_view>* impl) +      : internal::MatcherBase<absl::string_view>(impl) {} + +  // Allows the user to write str instead of Eq(str) sometimes, where +  // str is a std::string object. +  Matcher(const std::string& s);  // NOLINT + +#if GTEST_HAS_GLOBAL_STRING +  // Allows the user to write str instead of Eq(str) sometimes, where +  // str is a ::string object. +  Matcher(const ::string& s);  // NOLINT +#endif                         // GTEST_HAS_GLOBAL_STRING + +  // Allows the user to write "foo" instead of Eq("foo") sometimes. +  Matcher(const char* s);  // NOLINT + +  // Allows the user to pass absl::string_views directly. +  Matcher(absl::string_view s);  // NOLINT +}; +#endif  // GTEST_HAS_ABSL + +// Prints a matcher in a human-readable format. +template <typename T> +std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) { +  matcher.DescribeTo(&os); +  return os; +}  // The PolymorphicMatcher class template makes it easy to implement a  // polymorphic matcher (i.e. a matcher that can match values of more @@ -499,7 +572,7 @@ class PolymorphicMatcher {    template <typename T>    operator Matcher<T>() const { -    return Matcher<T>(new MonomorphicImpl<T>(impl_)); +    return Matcher<T>(new MonomorphicImpl<GTEST_REFERENCE_TO_CONST_(T)>(impl_));    }   private: @@ -845,7 +918,7 @@ class TuplePrefix {      typename tuple_element<N - 1, MatcherTuple>::type matcher =          get<N - 1>(matchers);      typedef typename tuple_element<N - 1, ValueTuple>::type Value; -    Value value = get<N - 1>(values); +    GTEST_REFERENCE_TO_CONST_(Value) value = get<N - 1>(values);      StringMatchResultListener listener;      if (!matcher.MatchAndExplain(value, &listener)) {        // TODO(wan): include in the message the name of the parameter @@ -950,10 +1023,12 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {  // Implements A<T>().  template <typename T> -class AnyMatcherImpl : public MatcherInterface<T> { +class AnyMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {   public: -  virtual bool MatchAndExplain( -      T /* x */, MatchResultListener* /* listener */) const { return true; } +  virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) /* x */, +                               MatchResultListener* /* listener */) const { +    return true; +  }    virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; }    virtual void DescribeNegationTo(::std::ostream* os) const {      // This is mostly for completeness' safe, as it's not very useful @@ -1223,6 +1298,19 @@ class StrEqualityMatcher {                       bool case_sensitive)        : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} +#if GTEST_HAS_ABSL +  bool MatchAndExplain(const absl::string_view& s, +                       MatchResultListener* listener) const { +    if (s.data() == NULL) { +      return !expect_eq_; +    } +    // This should fail to compile if absl::string_view is used with wide +    // strings. +    const StringType& str = string(s); +    return MatchAndExplain(str, listener); +  } +#endif  // GTEST_HAS_ABSL +    // Accepts pointer types, particularly:    //   const char*    //   char* @@ -1239,7 +1327,7 @@ class StrEqualityMatcher {    // Matches anything that can convert to StringType.    //    // This is a template, not just a plain function with const StringType&, -  // because StringPiece has some interfering non-explicit constructors. +  // because absl::string_view has some interfering non-explicit constructors.    template <typename MatcheeStringType>    bool MatchAndExplain(const MatcheeStringType& s,                         MatchResultListener* /* listener */) const { @@ -1283,6 +1371,19 @@ class HasSubstrMatcher {    explicit HasSubstrMatcher(const StringType& substring)        : substring_(substring) {} +#if GTEST_HAS_ABSL +  bool MatchAndExplain(const absl::string_view& s, +                       MatchResultListener* listener) const { +    if (s.data() == NULL) { +      return false; +    } +    // This should fail to compile if absl::string_view is used with wide +    // strings. +    const StringType& str = string(s); +    return MatchAndExplain(str, listener); +  } +#endif  // GTEST_HAS_ABSL +    // Accepts pointer types, particularly:    //   const char*    //   char* @@ -1296,7 +1397,7 @@ class HasSubstrMatcher {    // Matches anything that can convert to StringType.    //    // This is a template, not just a plain function with const StringType&, -  // because StringPiece has some interfering non-explicit constructors. +  // because absl::string_view has some interfering non-explicit constructors.    template <typename MatcheeStringType>    bool MatchAndExplain(const MatcheeStringType& s,                         MatchResultListener* /* listener */) const { @@ -1330,6 +1431,19 @@ class StartsWithMatcher {    explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {    } +#if GTEST_HAS_ABSL +  bool MatchAndExplain(const absl::string_view& s, +                       MatchResultListener* listener) const { +    if (s.data() == NULL) { +      return false; +    } +    // This should fail to compile if absl::string_view is used with wide +    // strings. +    const StringType& str = string(s); +    return MatchAndExplain(str, listener); +  } +#endif  // GTEST_HAS_ABSL +    // Accepts pointer types, particularly:    //   const char*    //   char* @@ -1343,7 +1457,7 @@ class StartsWithMatcher {    // Matches anything that can convert to StringType.    //    // This is a template, not just a plain function with const StringType&, -  // because StringPiece has some interfering non-explicit constructors. +  // because absl::string_view has some interfering non-explicit constructors.    template <typename MatcheeStringType>    bool MatchAndExplain(const MatcheeStringType& s,                         MatchResultListener* /* listener */) const { @@ -1376,6 +1490,19 @@ class EndsWithMatcher {   public:    explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} +#if GTEST_HAS_ABSL +  bool MatchAndExplain(const absl::string_view& s, +                       MatchResultListener* listener) const { +    if (s.data() == NULL) { +      return false; +    } +    // This should fail to compile if absl::string_view is used with wide +    // strings. +    const StringType& str = string(s); +    return MatchAndExplain(str, listener); +  } +#endif  // GTEST_HAS_ABSL +    // Accepts pointer types, particularly:    //   const char*    //   char* @@ -1389,7 +1516,7 @@ class EndsWithMatcher {    // Matches anything that can convert to StringType.    //    // This is a template, not just a plain function with const StringType&, -  // because StringPiece has some interfering non-explicit constructors. +  // because absl::string_view has some interfering non-explicit constructors.    template <typename MatcheeStringType>    bool MatchAndExplain(const MatcheeStringType& s,                         MatchResultListener* /* listener */) const { @@ -1422,6 +1549,13 @@ class MatchesRegexMatcher {    MatchesRegexMatcher(const RE* regex, bool full_match)        : regex_(regex), full_match_(full_match) {} +#if GTEST_HAS_ABSL +  bool MatchAndExplain(const absl::string_view& s, +                       MatchResultListener* listener) const { +    return s.data() && MatchAndExplain(string(s), listener); +  } +#endif  // GTEST_HAS_ABSL +    // Accepts pointer types, particularly:    //   const char*    //   char* @@ -1535,12 +1669,13 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> {  // will prevent different instantiations of NotMatcher from sharing  // the same NotMatcherImpl<T> class.  template <typename T> -class NotMatcherImpl : public MatcherInterface<T> { +class NotMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {   public:    explicit NotMatcherImpl(const Matcher<T>& matcher)        : matcher_(matcher) {} -  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { +  virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, +                               MatchResultListener* listener) const {      return !matcher_.MatchAndExplain(x, listener);    } @@ -1583,7 +1718,8 @@ class NotMatcher {  // that will prevent different instantiations of BothOfMatcher from  // sharing the same BothOfMatcherImpl<T> class.  template <typename T> -class BothOfMatcherImpl : public MatcherInterface<T> { +class BothOfMatcherImpl +    : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {   public:    BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)        : matcher1_(matcher1), matcher2_(matcher2) {} @@ -1604,7 +1740,8 @@ class BothOfMatcherImpl : public MatcherInterface<T> {      *os << ")";    } -  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { +  virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, +                               MatchResultListener* listener) const {      // If either matcher1_ or matcher2_ doesn't match x, we only need      // to explain why one of them fails.      StringMatchResultListener listener1; @@ -1755,7 +1892,8 @@ class BothOfMatcher {  // that will prevent different instantiations of AnyOfMatcher from  // sharing the same EitherOfMatcherImpl<T> class.  template <typename T> -class EitherOfMatcherImpl : public MatcherInterface<T> { +class EitherOfMatcherImpl +    : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {   public:    EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)        : matcher1_(matcher1), matcher2_(matcher2) {} @@ -1776,7 +1914,8 @@ class EitherOfMatcherImpl : public MatcherInterface<T> {      *os << ")";    } -  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { +  virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, +                               MatchResultListener* listener) const {      // If either matcher1_ or matcher2_ matches x, we just need to      // explain why *one* of them matches.      StringMatchResultListener listener1; @@ -2224,7 +2363,8 @@ class PointeeMatcher {    // enough for implementing the DescribeTo() method of Pointee().    template <typename Pointer>    operator Matcher<Pointer>() const { -    return MakeMatcher(new Impl<Pointer>(matcher_)); +    return Matcher<Pointer>( +        new Impl<GTEST_REFERENCE_TO_CONST_(Pointer)>(matcher_));    }   private: diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index a5ed686e..194d992d 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -105,6 +105,53 @@ Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); }  Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); }  #endif  // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_ABSL +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const std::string& s) { +  *this = Eq(s); +} + +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const ::string& s) { *this = Eq(s); } +#endif  // GTEST_HAS_GLOBAL_STRING + +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const char* s) { +  *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(absl::string_view s) { +  *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); } + +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const ::string& s) { *this = Eq(s); } +#endif  // GTEST_HAS_GLOBAL_STRING + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const char* s) { +  *this = Eq(std::string(s)); +} + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(absl::string_view s) { +  *this = Eq(std::string(s)); +} +#endif  // GTEST_HAS_ABSL  namespace internal { @@ -113,12 +160,11 @@ namespace internal {  // 'negation' is false; otherwise returns the description of the  // negation of the matcher.  'param_values' contains a list of strings  // that are the print-out of the matcher's parameters. -GTEST_API_ string FormatMatcherDescription(bool negation, -                                           const char* matcher_name, -                                           const Strings& param_values) { -  string result = ConvertIdentifierNameToWords(matcher_name); -  if (param_values.size() >= 1) -    result += " " + JoinAsTuple(param_values); +GTEST_API_ std::string FormatMatcherDescription(bool negation, +                                                const char* matcher_name, +                                                const Strings& param_values) { +  std::string result = ConvertIdentifierNameToWords(matcher_name); +  if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values);    return negation ? "not (" + result + ")" : result;  } diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 829935ef..cc161346 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -45,6 +45,7 @@  #include <limits>  #include <list>  #include <map> +#include <memory>  #include <set>  #include <sstream>  #include <string> @@ -58,13 +59,11 @@  # include <forward_list>  // NOLINT  #endif -// Disable MSVC2015 warning for std::pair: "decorated name length exceeded, name was truncated". -#if defined(_MSC_VER) && (_MSC_VER == 1900) -# pragma warning(disable:4503) +#if GTEST_LANG_CXX11 +# include <type_traits>  #endif  namespace testing { -  namespace gmock_matchers_test {  using std::greater; @@ -200,17 +199,13 @@ std::string OfType(const std::string& type_name) {  // Returns the description of the given matcher.  template <typename T>  std::string Describe(const Matcher<T>& m) { -  stringstream ss; -  m.DescribeTo(&ss); -  return ss.str(); +  return DescribeMatcher<T>(m);  }  // Returns the description of the negation of the given matcher.  template <typename T>  std::string DescribeNegation(const Matcher<T>& m) { -  stringstream ss; -  m.DescribeNegationTo(&ss); -  return ss.str(); +  return DescribeMatcher<T>(m, true);  }  // Returns the reason why x matches, or doesn't match, m. @@ -221,6 +216,12 @@ std::string Explain(const MatcherType& m, const Value& x) {    return listener.str();  } +TEST(MonotonicMatcherTest, IsPrintable) { +  stringstream ss; +  ss << GreaterThan(5); +  EXPECT_EQ("is > 5", ss.str()); +} +  TEST(MatchResultListenerTest, StreamingWorks) {    StringMatchResultListener listener;    listener << "hi" << 5; @@ -332,6 +333,22 @@ TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) {    EXPECT_FALSE(m1.Matches(&n));  } +// Tests that matchers can be constructed from a variable that is not properly +// defined. This should be illegal, but many users rely on this accidentally. +struct Undefined { +  virtual ~Undefined() = 0; +  static const int kInt = 1; +}; + +TEST(MatcherTest, CanBeConstructedFromUndefinedVariable) { +  Matcher<int> m1 = Undefined::kInt; +  EXPECT_TRUE(m1.Matches(1)); +  EXPECT_FALSE(m1.Matches(2)); +} + +// Test that a matcher parameterized with an abstract class compiles. +TEST(MatcherTest, CanAcceptAbstractClass) { Matcher<const Undefined&> m = _; } +  // Tests that matchers are copyable.  TEST(MatcherTest, IsCopyable) {    // Tests the copy constructor. @@ -365,66 +382,132 @@ TEST(MatcherTest, MatchAndExplain) {  }  // Tests that a C-string literal can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>.  TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { -  Matcher<string> m1 = "hi"; +  Matcher<std::string> m1 = "hi";    EXPECT_TRUE(m1.Matches("hi"));    EXPECT_FALSE(m1.Matches("hello")); -  Matcher<const string&> m2 = "hi"; +  Matcher<const std::string&> m2 = "hi";    EXPECT_TRUE(m2.Matches("hi"));    EXPECT_FALSE(m2.Matches("hello"));  }  // Tests that a string object can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>.  TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { -  Matcher<string> m1 = string("hi"); +  Matcher<std::string> m1 = std::string("hi"); +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const std::string&> m2 = std::string("hi"); +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} + +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<std::string> or Matcher<const std::string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { +  Matcher<std::string> m1 = ::string("hi"); +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const std::string&> m2 = ::string("hi"); +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} +#endif  // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_STRING +// Tests that a C-string literal can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { +  Matcher< ::string> m1 = "hi"; +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const ::string&> m2 = "hi"; +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a std::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromString) { +  Matcher< ::string> m1 = std::string("hi"); +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const ::string&> m2 = std::string("hi"); +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a ::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { +  Matcher< ::string> m1 = ::string("hi");    EXPECT_TRUE(m1.Matches("hi"));    EXPECT_FALSE(m1.Matches("hello")); -  Matcher<const string&> m2 = string("hi"); +  Matcher<const ::string&> m2 = ::string("hi");    EXPECT_TRUE(m2.Matches("hi"));    EXPECT_FALSE(m2.Matches("hello"));  } +#endif  // GTEST_HAS_GLOBAL_STRING -#if GTEST_HAS_STRING_PIECE_ +#if GTEST_HAS_ABSL  // Tests that a C-string literal can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { -  Matcher<StringPiece> m1 = "cats"; +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { +  Matcher<absl::string_view> m1 = "cats";    EXPECT_TRUE(m1.Matches("cats"));    EXPECT_FALSE(m1.Matches("dogs")); -  Matcher<const StringPiece&> m2 = "cats"; +  Matcher<const absl::string_view&> m2 = "cats";    EXPECT_TRUE(m2.Matches("cats"));    EXPECT_FALSE(m2.Matches("dogs"));  } -// Tests that a string object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromString) { -  Matcher<StringPiece> m1 = string("cats"); +// Tests that a std::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { +  Matcher<absl::string_view> m1 = std::string("cats"); +  EXPECT_TRUE(m1.Matches("cats")); +  EXPECT_FALSE(m1.Matches("dogs")); + +  Matcher<const absl::string_view&> m2 = std::string("cats"); +  EXPECT_TRUE(m2.Matches("cats")); +  EXPECT_FALSE(m2.Matches("dogs")); +} + +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { +  Matcher<absl::string_view> m1 = ::string("cats");    EXPECT_TRUE(m1.Matches("cats"));    EXPECT_FALSE(m1.Matches("dogs")); -  Matcher<const StringPiece&> m2 = string("cats"); +  Matcher<const absl::string_view&> m2 = ::string("cats");    EXPECT_TRUE(m2.Matches("cats"));    EXPECT_FALSE(m2.Matches("dogs"));  } +#endif  // GTEST_HAS_GLOBAL_STRING -// Tests that a StringPiece object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromStringPiece) { -  Matcher<StringPiece> m1 = StringPiece("cats"); +// Tests that a absl::string_view object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { +  Matcher<absl::string_view> m1 = absl::string_view("cats");    EXPECT_TRUE(m1.Matches("cats"));    EXPECT_FALSE(m1.Matches("dogs")); -  Matcher<const StringPiece&> m2 = StringPiece("cats"); +  Matcher<const absl::string_view&> m2 = absl::string_view("cats");    EXPECT_TRUE(m2.Matches("cats"));    EXPECT_FALSE(m2.Matches("dogs"));  } -#endif  // GTEST_HAS_STRING_PIECE_ +#endif  // GTEST_HAS_ABSL  // Tests that MakeMatcher() constructs a Matcher<T> from a  // MatcherInterface* without requiring the user to explicitly @@ -613,7 +696,7 @@ TEST(MatcherCastTest, FromSameType) {  struct ConvertibleFromAny {    ConvertibleFromAny(int a_value) : value(a_value) {}    template <typename T> -  explicit ConvertibleFromAny(const T& /*a_value*/) : value(-1) { +  ConvertibleFromAny(const T& /*a_value*/) : value(-1) {      ADD_FAILURE() << "Conversion constructor called";    }    int value; @@ -1177,6 +1260,13 @@ TEST(StrEqTest, MatchesEqualString) {    Matcher<const std::string&> m2 = StrEq("Hello");    EXPECT_TRUE(m2.Matches("Hello"));    EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view&> m3 = StrEq("Hello"); +  EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); +  EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); +  EXPECT_FALSE(m3.Matches(absl::string_view())); +#endif  // GTEST_HAS_ABSL  }  TEST(StrEqTest, CanDescribeSelf) { @@ -1202,6 +1292,13 @@ TEST(StrNeTest, MatchesUnequalString) {    Matcher<std::string> m2 = StrNe(std::string("Hello"));    EXPECT_TRUE(m2.Matches("hello"));    EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view> m3 = StrNe("Hello"); +  EXPECT_TRUE(m3.Matches(absl::string_view(""))); +  EXPECT_TRUE(m3.Matches(absl::string_view())); +  EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); +#endif  // GTEST_HAS_ABSL  }  TEST(StrNeTest, CanDescribeSelf) { @@ -1210,15 +1307,23 @@ TEST(StrNeTest, CanDescribeSelf) {  }  TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { -  Matcher<const char*> m = StrCaseEq(string("Hello")); +  Matcher<const char*> m = StrCaseEq(std::string("Hello"));    EXPECT_TRUE(m.Matches("Hello"));    EXPECT_TRUE(m.Matches("hello"));    EXPECT_FALSE(m.Matches("Hi"));    EXPECT_FALSE(m.Matches(NULL)); -  Matcher<const string&> m2 = StrCaseEq("Hello"); +  Matcher<const std::string&> m2 = StrCaseEq("Hello");    EXPECT_TRUE(m2.Matches("hello"));    EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view&> m3 = StrCaseEq(std::string("Hello")); +  EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); +  EXPECT_TRUE(m3.Matches(absl::string_view("hello"))); +  EXPECT_FALSE(m3.Matches(absl::string_view("Hi"))); +  EXPECT_FALSE(m3.Matches(absl::string_view())); +#endif  // GTEST_HAS_ABSL  }  TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { @@ -1261,6 +1366,14 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) {    Matcher<std::string> m2 = StrCaseNe(std::string("Hello"));    EXPECT_TRUE(m2.Matches(""));    EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view> m3 = StrCaseNe("Hello"); +  EXPECT_TRUE(m3.Matches(absl::string_view("Hi"))); +  EXPECT_TRUE(m3.Matches(absl::string_view())); +  EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); +  EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); +#endif  // GTEST_HAS_ABSL  }  TEST(StrCaseNeTest, CanDescribeSelf) { @@ -1292,6 +1405,25 @@ TEST(HasSubstrTest, WorksForCStrings) {    EXPECT_FALSE(m2.Matches(NULL));  } +#if GTEST_HAS_ABSL +// Tests that HasSubstr() works for matching absl::string_view-typed values. +TEST(HasSubstrTest, WorksForStringViewClasses) { +  const Matcher<absl::string_view> m1 = HasSubstr("foo"); +  EXPECT_TRUE(m1.Matches(absl::string_view("I love food."))); +  EXPECT_FALSE(m1.Matches(absl::string_view("tofo"))); +  EXPECT_FALSE(m1.Matches(absl::string_view())); + +  const Matcher<const absl::string_view&> m2 = HasSubstr("foo"); +  EXPECT_TRUE(m2.Matches(absl::string_view("I love food."))); +  EXPECT_FALSE(m2.Matches(absl::string_view("tofo"))); +  EXPECT_FALSE(m2.Matches(absl::string_view())); + +  const Matcher<const absl::string_view&> m3 = HasSubstr(""); +  EXPECT_TRUE(m3.Matches(absl::string_view("foo"))); +  EXPECT_FALSE(m3.Matches(absl::string_view())); +} +#endif  // GTEST_HAS_ABSL +  // Tests that HasSubstr(s) describes itself properly.  TEST(HasSubstrTest, CanDescribeSelf) {    Matcher<std::string> m = HasSubstr("foo\n\""); @@ -1320,6 +1452,35 @@ TEST(KeyTest, MatchesCorrectly) {    EXPECT_THAT(p, Not(Key(Lt(25))));  } +#if GTEST_LANG_CXX11 +template <size_t I> +struct Tag {}; + +struct PairWithGet { +  int member_1; +  string member_2; +  using first_type = int; +  using second_type = string; + +  const int& GetImpl(Tag<0>) const { return member_1; } +  const string& GetImpl(Tag<1>) const { return member_2; } +}; +template <size_t I> +auto get(const PairWithGet& value) -> decltype(value.GetImpl(Tag<I>())) { +  return value.GetImpl(Tag<I>()); +} +TEST(PairTest, MatchesPairWithGetCorrectly) { +  PairWithGet p{25, "foo"}; +  EXPECT_THAT(p, Key(25)); +  EXPECT_THAT(p, Not(Key(42))); +  EXPECT_THAT(p, Key(Ge(20))); +  EXPECT_THAT(p, Not(Key(Lt(25)))); + +  std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; +  EXPECT_THAT(v, Contains(Key(29))); +} +#endif  // GTEST_LANG_CXX11 +  TEST(KeyTest, SafelyCastsInnerMatcher) {    Matcher<int> is_positive = Gt(0);    Matcher<int> is_negative = Lt(0); @@ -1423,7 +1584,7 @@ TEST(PairTest, MatchesCorrectly) {    EXPECT_THAT(p, Pair(25, "foo"));    EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); -  // 'first' does not match, but 'second' matches. +  // 'first' doesnt' match, but 'second' matches.    EXPECT_THAT(p, Not(Pair(42, "foo")));    EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); @@ -1457,6 +1618,18 @@ TEST(PairTest, InsideContainsUsingMap) {    EXPECT_THAT(container, Not(Contains(Pair(3, _))));  } +#if GTEST_LANG_CXX11 +TEST(PairTest, UseGetInsteadOfMembers) { +  PairWithGet pair{7, "ABC"}; +  EXPECT_THAT(pair, Pair(7, "ABC")); +  EXPECT_THAT(pair, Pair(Ge(7), HasSubstr("AB"))); +  EXPECT_THAT(pair, Not(Pair(Lt(7), "ABC"))); + +  std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; +  EXPECT_THAT(v, ElementsAre(Pair(11, string("Foo")), Pair(Ge(10), Not("")))); +} +#endif  // GTEST_LANG_CXX11 +  // Tests StartsWith(s).  TEST(StartsWithTest, MatchesStringWithGivenPrefix) { @@ -1486,12 +1659,30 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) {    EXPECT_TRUE(m1.Matches(""));    EXPECT_FALSE(m1.Matches(NULL)); -  const Matcher<const string&> m2 = EndsWith(string("Hi")); +  const Matcher<const std::string&> m2 = EndsWith(std::string("Hi"));    EXPECT_TRUE(m2.Matches("Hi"));    EXPECT_TRUE(m2.Matches("Wow Hi Hi"));    EXPECT_TRUE(m2.Matches("Super Hi"));    EXPECT_FALSE(m2.Matches("i"));    EXPECT_FALSE(m2.Matches("Hi ")); + +#if GTEST_HAS_GLOBAL_STRING +  const Matcher<const ::string&> m3 = EndsWith(::string("Hi")); +  EXPECT_TRUE(m3.Matches("Hi")); +  EXPECT_TRUE(m3.Matches("Wow Hi Hi")); +  EXPECT_TRUE(m3.Matches("Super Hi")); +  EXPECT_FALSE(m3.Matches("i")); +  EXPECT_FALSE(m3.Matches("Hi ")); +#endif  // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL +  const Matcher<const absl::string_view&> m4 = EndsWith(""); +  EXPECT_TRUE(m4.Matches("Hi")); +  EXPECT_TRUE(m4.Matches("")); +  // Default-constructed absl::string_view should not match anything, in order +  // to distinguish it from an empty string. +  EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif  // GTEST_HAS_ABSL  }  TEST(EndsWithTest, CanDescribeSelf) { @@ -1511,6 +1702,18 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {    EXPECT_TRUE(m2.Matches("azbz"));    EXPECT_FALSE(m2.Matches("az1"));    EXPECT_FALSE(m2.Matches("1az")); + +#if GTEST_HAS_ABSL +  const Matcher<const absl::string_view&> m3 = MatchesRegex("a.*z"); +  EXPECT_TRUE(m3.Matches(absl::string_view("az"))); +  EXPECT_TRUE(m3.Matches(absl::string_view("abcz"))); +  EXPECT_FALSE(m3.Matches(absl::string_view("1az"))); +  // Default-constructed absl::string_view should not match anything, in order +  // to distinguish it from an empty string. +  EXPECT_FALSE(m3.Matches(absl::string_view())); +  const Matcher<const absl::string_view&> m4 = MatchesRegex(""); +  EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif  // GTEST_HAS_ABSL  }  TEST(MatchesRegexTest, CanDescribeSelf) { @@ -1519,6 +1722,11 @@ TEST(MatchesRegexTest, CanDescribeSelf) {    Matcher<const char*> m2 = MatchesRegex(new RE("a.*"));    EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view> m3 = MatchesRegex(new RE("0.*")); +  EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); +#endif  // GTEST_HAS_ABSL  }  // Tests ContainsRegex(). @@ -1533,6 +1741,18 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) {    EXPECT_TRUE(m2.Matches("azbz"));    EXPECT_TRUE(m2.Matches("az1"));    EXPECT_FALSE(m2.Matches("1a")); + +#if GTEST_HAS_ABSL +  const Matcher<const absl::string_view&> m3 = ContainsRegex(new RE("a.*z")); +  EXPECT_TRUE(m3.Matches(absl::string_view("azbz"))); +  EXPECT_TRUE(m3.Matches(absl::string_view("az1"))); +  EXPECT_FALSE(m3.Matches(absl::string_view("1a"))); +  // Default-constructed absl::string_view should not match anything, in order +  // to distinguish it from an empty string. +  EXPECT_FALSE(m3.Matches(absl::string_view())); +  const Matcher<const absl::string_view&> m4 = ContainsRegex(""); +  EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif  // GTEST_HAS_ABSL  }  TEST(ContainsRegexTest, CanDescribeSelf) { @@ -1541,6 +1761,11 @@ TEST(ContainsRegexTest, CanDescribeSelf) {    Matcher<const char*> m2 = ContainsRegex(new RE("a.*"));    EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); + +#if GTEST_HAS_ABSL +  Matcher<const absl::string_view> m3 = ContainsRegex(new RE("0.*")); +  EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); +#endif  // GTEST_HAS_ABSL  }  // Tests for wide strings.  | 
