Allow implicit matcher construction from nullptr. This allows "nullptr" to be used as a valid matcher for smart pointer types.

PiperOrigin-RevId: 861759501
Change-Id: I09ff55cd532014015725ec61356f480760819b29
This commit is contained in:
Abseil Team 2026-01-27 09:34:35 -08:00 committed by Copybara-Service
parent 5fd443cdc3
commit 56efe39831
2 changed files with 30 additions and 1 deletions

View File

@ -798,6 +798,7 @@ TEST(ExpectThat, TakesLiterals) {
EXPECT_THAT(1, 1);
EXPECT_THAT(1.0, 1.0);
EXPECT_THAT(std::string(), "");
EXPECT_THAT(std::shared_ptr<int>(), nullptr);
}
TEST(ExpectThat, TakesFunctions) {
@ -1126,6 +1127,16 @@ TEST(IsNullTest, CanDescribeSelf) {
EXPECT_EQ("isn't NULL", DescribeNegation(m));
}
struct SmartPtrHelper {
MOCK_METHOD(void, Call, (std::shared_ptr<int>));
};
TEST(IsNullTest, WorksWithSmartPtr) {
SmartPtrHelper helper;
EXPECT_CALL(helper, Call(nullptr));
helper.Call(nullptr);
}
// Tests that NotNull() matches any non-NULL pointer of any type.
TEST(NotNullTest, MatchesNonNullPointer) {
Matcher<int*> m1 = NotNull();

View File

@ -40,6 +40,7 @@
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic>
#include <cstddef>
#include <functional>
#include <memory>
#include <ostream>
@ -485,6 +486,15 @@ class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
// Implicit constructor here allows people to write
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT
// Implicit constructor here allows people to write
// EXPECT_THAT(foo, nullptr) instead of EXPECT_THAT(foo, IsNull()) for smart
// pointer types.
//
// The second argument is needed to avoid capturing literal '0'.
template <typename U>
Matcher(U, // NOLINT
std::enable_if_t<std::is_same_v<U, std::nullptr_t>>* = nullptr);
};
// The following two specializations allow the user to write str
@ -895,13 +905,21 @@ inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x);
}
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'.
template <typename T>
Matcher<T>::Matcher(T value) {
*this = Eq(value);
}
// Constructs a Matcher<T> from nullptr. The constructed matcher matches any
// value that is equal to nullptr.
template <typename T>
template <typename U>
Matcher<T>::Matcher(U, std::enable_if_t<std::is_same_v<U, std::nullptr_t>>*) {
*this = Eq(nullptr);
}
// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity.