diff options
author | Derek Mauro <dmauro@google.com> | 2020-10-14 22:25:04 (GMT) |
---|---|---|
committer | Derek Mauro <dmauro@google.com> | 2020-10-14 22:25:04 (GMT) |
commit | 4abb012c70a20500967fa88b55f552a4267258dd (patch) | |
tree | bb61f8303a42b2e25dfce279a8e351f67f9466fd /googletest | |
parent | 07f4869221012b16b7f9ee685d94856e1fc9f361 (diff) | |
parent | 4c9ad191e14e5926ce0213d7dddb7a35529c2756 (diff) | |
download | googletest-4abb012c70a20500967fa88b55f552a4267258dd.zip googletest-4abb012c70a20500967fa88b55f552a4267258dd.tar.gz googletest-4abb012c70a20500967fa88b55f552a4267258dd.tar.bz2 |
Merge pull request #2837 from inazarenko:duck_type_protos
PiperOrigin-RevId: 336087297
Diffstat (limited to 'googletest')
-rw-r--r-- | googletest/include/gtest/gtest-printers.h | 5 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-internal.h | 31 | ||||
-rw-r--r-- | googletest/test/gtest_unittest.cc | 79 |
3 files changed, 93 insertions, 22 deletions
diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index f24512a..99129a5 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -235,8 +235,9 @@ struct ProtobufPrinter { // DebugString() for better readability. static const size_t kProtobufOneLinerMaxLength = 50; - template <typename T, typename = typename std::enable_if< - internal::IsAProtocolMessage<T>::value>::type> + template <typename T, + typename = typename std::enable_if< + internal::HasDebugStringAndShortDebugString<T>::value>::type> static void PrintValue(const T& value, ::std::ostream* os) { std::string pretty_str = value.ShortDebugString(); if (pretty_str.length() > kProtobufOneLinerMaxLength) { diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 233724c..bd4e419 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -892,11 +892,34 @@ class GTEST_API_ Random { #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ typename std::remove_const<typename std::remove_reference<T>::type>::type -// IsAProtocolMessage<T>::value is a compile-time bool constant that's -// true if and only if T is type proto2::MessageLite or a subclass of it. +// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant +// that's true if and only if T has methods DebugString() and ShortDebugString() +// that return std::string. template <typename T> -struct IsAProtocolMessage - : public std::is_convertible<const T*, const ::proto2::MessageLite*> {}; +class HasDebugStringAndShortDebugString { + private: + template <typename C> + static constexpr auto CheckDebugString(C*) -> typename std::is_same< + std::string, decltype(std::declval<const C>().DebugString())>::type; + template <typename> + static constexpr std::false_type CheckDebugString(...); + + template <typename C> + static constexpr auto CheckShortDebugString(C*) -> typename std::is_same< + std::string, decltype(std::declval<const C>().ShortDebugString())>::type; + template <typename> + static constexpr std::false_type CheckShortDebugString(...); + + using HasDebugStringType = decltype(CheckDebugString<T>(nullptr)); + using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr)); + + public: + static constexpr bool value = + HasDebugStringType::value && HasShortDebugStringType::value; +}; + +template <typename T> +constexpr bool HasDebugStringAndShortDebugString<T>::value; // When the compiler sees expression IsContainerTest<C>(0), if C is an // STL-style container class, the first overload of IsContainerTest diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 7aa884a..4995d07 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -254,8 +254,8 @@ using testing::internal::GetTimeInMillis; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; using testing::internal::GTestFlagSaver; +using testing::internal::HasDebugStringAndShortDebugString; using testing::internal::Int32FromEnvOrDie; -using testing::internal::IsAProtocolMessage; using testing::internal::IsContainer; using testing::internal::IsContainerTest; using testing::internal::IsNotContainer; @@ -7185,24 +7185,71 @@ GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. class ConversionHelperBase {}; class ConversionHelperDerived : public ConversionHelperBase {}; -// Tests that IsAProtocolMessage<T>::value is a compile-time constant. -TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { - GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::MessageLite>::value, - const_true); - GTEST_COMPILE_ASSERT_(!IsAProtocolMessage<int>::value, const_false); -} +struct HasDebugStringMethods { + std::string DebugString() const { return ""; } + std::string ShortDebugString() const { return ""; } +}; + +struct InheritsDebugStringMethods : public HasDebugStringMethods {}; -// Tests that IsAProtocolMessage<T>::value is true when T is -// proto2::Message or a sub-class of it. -TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { - EXPECT_TRUE(IsAProtocolMessage<::proto2::MessageLite>::value); +struct WrongTypeDebugStringMethod { + std::string DebugString() const { return ""; } + int ShortDebugString() const { return 1; } +}; + +struct NotConstDebugStringMethod { + std::string DebugString() { return ""; } + std::string ShortDebugString() const { return ""; } +}; + +struct MissingDebugStringMethod { + std::string DebugString() { return ""; } +}; + +struct IncompleteType; + +// Tests that HasDebugStringAndShortDebugString<T>::value is a compile-time +// constant. +TEST(HasDebugStringAndShortDebugStringTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_( + HasDebugStringAndShortDebugString<HasDebugStringMethods>::value, + const_true); + GTEST_COMPILE_ASSERT_( + HasDebugStringAndShortDebugString<InheritsDebugStringMethods>::value, + const_true); + GTEST_COMPILE_ASSERT_(HasDebugStringAndShortDebugString< + const InheritsDebugStringMethods>::value, + const_true); + GTEST_COMPILE_ASSERT_( + !HasDebugStringAndShortDebugString<WrongTypeDebugStringMethod>::value, + const_false); + GTEST_COMPILE_ASSERT_( + !HasDebugStringAndShortDebugString<NotConstDebugStringMethod>::value, + const_false); + GTEST_COMPILE_ASSERT_( + !HasDebugStringAndShortDebugString<MissingDebugStringMethod>::value, + const_false); + GTEST_COMPILE_ASSERT_( + !HasDebugStringAndShortDebugString<IncompleteType>::value, const_false); + GTEST_COMPILE_ASSERT_(!HasDebugStringAndShortDebugString<int>::value, + const_false); +} + +// Tests that HasDebugStringAndShortDebugString<T>::value is true when T has +// needed methods. +TEST(HasDebugStringAndShortDebugStringTest, + ValueIsTrueWhenTypeHasDebugStringAndShortDebugString) { + EXPECT_TRUE( + HasDebugStringAndShortDebugString<InheritsDebugStringMethods>::value); } -// Tests that IsAProtocolMessage<T>::value is false when T is neither -// ::proto2::Message nor a sub-class of it. -TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { - EXPECT_FALSE(IsAProtocolMessage<int>::value); - EXPECT_FALSE(IsAProtocolMessage<const ConversionHelperBase>::value); +// Tests that HasDebugStringAndShortDebugString<T>::value is false when T +// doesn't have needed methods. +TEST(HasDebugStringAndShortDebugStringTest, + ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(HasDebugStringAndShortDebugString<int>::value); + EXPECT_FALSE( + HasDebugStringAndShortDebugString<const ConversionHelperBase>::value); } // Tests GTEST_REMOVE_REFERENCE_AND_CONST_. |