diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 688ce64f..e2beff4e 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -621,6 +621,19 @@ GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ne, !=, "not equal to"); #undef GMOCK_IMPLEMENT_COMPARISON_MATCHER_ +// Implements the polymorphic IsNull() matcher, which matches any +// pointer that is NULL. +class IsNullMatcher { + public: + template + bool Matches(T* p) const { return p == NULL; } + + void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "is not NULL"; + } +}; + // Implements the polymorphic NotNull() matcher, which matches any // pointer that is not NULL. class NotNullMatcher { @@ -2319,6 +2332,11 @@ inline internal::NeMatcher Ne(Rhs x) { return internal::NeMatcher(x); } +// Creates a polymorphic matcher that matches any NULL pointer. +inline PolymorphicMatcher IsNull() { + return MakePolymorphicMatcher(internal::IsNullMatcher()); +} + // Creates a polymorphic matcher that matches any non-NULL pointer. // This is convenient as Not(NULL) doesn't compile (the compiler // thinks that that expression is comparing a pointer with an integer). diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc index ef878898..fe88c643 100644 --- a/test/gmock-matchers_test.cc +++ b/test/gmock-matchers_test.cc @@ -78,6 +78,7 @@ using testing::FloatEq; using testing::Ge; using testing::Gt; using testing::HasSubstr; +using testing::IsNull; using testing::Key; using testing::Le; using testing::Lt; @@ -685,6 +686,32 @@ TEST(NeTest, CanDescribeSelf) { EXPECT_EQ("is not equal to 5", Describe(m)); } +// Tests that IsNull() matches any NULL pointer of any type. +TEST(IsNullTest, MatchesNullPointer) { + Matcher m1 = IsNull(); + int* p1 = NULL; + int n = 0; + EXPECT_TRUE(m1.Matches(p1)); + EXPECT_FALSE(m1.Matches(&n)); + + Matcher m2 = IsNull(); + const char* p2 = NULL; + EXPECT_TRUE(m2.Matches(p2)); + EXPECT_FALSE(m2.Matches("hi")); + + Matcher m3 = IsNull(); + void* p3 = NULL; + EXPECT_TRUE(m3.Matches(p3)); + EXPECT_FALSE(m3.Matches(reinterpret_cast(0xbeef))); +} + +// Tests that IsNull() describes itself properly. +TEST(IsNullTest, CanDescribeSelf) { + Matcher m = IsNull(); + EXPECT_EQ("is NULL", Describe(m)); + EXPECT_EQ("is not NULL", DescribeNegation(m)); +} + // Tests that NotNull() matches any non-NULL pointer of any type. TEST(NotNullTest, MatchesNonNullPointer) { Matcher m1 = NotNull(); diff --git a/test/gmock_link_test.h b/test/gmock_link_test.h index bbac8ae2..40554bfe 100644 --- a/test/gmock_link_test.h +++ b/test/gmock_link_test.h @@ -147,6 +147,7 @@ using testing::IgnoreResult; using testing::Invoke; using testing::InvokeArgument; using testing::InvokeWithoutArgs; +using testing::IsNull; using testing::Le; using testing::Lt; using testing::Matcher; @@ -491,6 +492,13 @@ TEST(LinkTest, TestMatcherNotNull) { ON_CALL(mock, VoidFromString(NotNull())).WillByDefault(Return()); } +// Tests the linkage of the IsNull matcher. +TEST(LinkTest, TestMatcherIsNull) { + Mock mock; + + ON_CALL(mock, VoidFromString(IsNull())).WillByDefault(Return()); +} + // Tests the linkage of the Ref matcher. TEST(LinkTest, TestMatcherRef) { Mock mock;