diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h index 47aaf984..d9a92107 100644 --- a/googlemock/include/gmock/gmock-more-matchers.h +++ b/googlemock/include/gmock/gmock-more-matchers.h @@ -40,6 +40,9 @@ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ +#include +#include + #include "gmock/gmock-matchers.h" namespace testing { @@ -56,14 +59,42 @@ namespace testing { #endif #endif -// Defines a matcher that matches an empty container. The container must -// support both size() and empty(), which all STL-like containers provide. -MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { - if (arg.empty()) { - return true; +namespace internal { + +// Implements the polymorphic IsEmpty matcher, which +// can be used as a Matcher as long as T is either a container that defines +// empty() and size() (e.g. std::vector or std::string), or a C-style string. +class IsEmptyMatcher { + public: + // Matches anything that defines empty() and size(). + template + bool MatchAndExplain(const MatcheeContainerType& c, + MatchResultListener* listener) const { + if (c.empty()) { + return true; + } + *listener << "whose size is " << c.size(); + return false; } - *result_listener << "whose size is " << arg.size(); - return false; + + // Matches C-style strings. + bool MatchAndExplain(const char* s, MatchResultListener* listener) const { + return MatchAndExplain(std::string(s), listener); + } + + // Describes what this matcher matches. + void DescribeTo(std::ostream* os) const { *os << "is empty"; } + + void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; } +}; + +} // namespace internal + +// Creates a polymorphic matcher that matches an empty container or C-style +// string. The container must support both size() and empty(), which all +// STL-like containers provide. +inline PolymorphicMatcher IsEmpty() { + return MakePolymorphicMatcher(internal::IsEmptyMatcher()); } // Define a matcher that matches a value that evaluates in boolean diff --git a/googlemock/test/gmock-matchers-comparisons_test.cc b/googlemock/test/gmock-matchers-comparisons_test.cc index eb8f3f63..c90b0b4e 100644 --- a/googlemock/test/gmock-matchers-comparisons_test.cc +++ b/googlemock/test/gmock-matchers-comparisons_test.cc @@ -39,6 +39,8 @@ #pragma warning(disable : 4100) #endif +#include + #include "test/gmock-matchers_test.h" namespace testing { @@ -983,6 +985,30 @@ TEST(ComparisonBaseTest, WorksWithMoveOnly) { helper.Call(MoveOnly(1)); } +TEST(IsEmptyTest, MatchesContainer) { + const Matcher> m = IsEmpty(); + std::vector a = {}; + std::vector b = {1}; + EXPECT_TRUE(m.Matches(a)); + EXPECT_FALSE(m.Matches(b)); +} + +TEST(IsEmptyTest, MatchesStdString) { + const Matcher m = IsEmpty(); + std::string a = "z"; + std::string b = ""; + EXPECT_FALSE(m.Matches(a)); + EXPECT_TRUE(m.Matches(b)); +} + +TEST(IsEmptyTest, MatchesCString) { + const Matcher m = IsEmpty(); + const char a[] = ""; + const char b[] = "x"; + EXPECT_TRUE(m.Matches(a)); + EXPECT_FALSE(m.Matches(b)); +} + // Tests that IsNull() matches any NULL pointer of any type. TEST(IsNullTest, MatchesNullPointer) { Matcher m1 = IsNull();