Merge pull request #2837 from inazarenko:duck_type_protos
PiperOrigin-RevId: 336087297
This commit is contained in:
		@@ -235,8 +235,9 @@ struct ProtobufPrinter {
 | 
				
			|||||||
  // DebugString() for better readability.
 | 
					  // DebugString() for better readability.
 | 
				
			||||||
  static const size_t kProtobufOneLinerMaxLength = 50;
 | 
					  static const size_t kProtobufOneLinerMaxLength = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename T, typename = typename std::enable_if<
 | 
					  template <typename T,
 | 
				
			||||||
                            internal::IsAProtocolMessage<T>::value>::type>
 | 
					            typename = typename std::enable_if<
 | 
				
			||||||
 | 
					                internal::HasDebugStringAndShortDebugString<T>::value>::type>
 | 
				
			||||||
  static void PrintValue(const T& value, ::std::ostream* os) {
 | 
					  static void PrintValue(const T& value, ::std::ostream* os) {
 | 
				
			||||||
    std::string pretty_str = value.ShortDebugString();
 | 
					    std::string pretty_str = value.ShortDebugString();
 | 
				
			||||||
    if (pretty_str.length() > kProtobufOneLinerMaxLength) {
 | 
					    if (pretty_str.length() > kProtobufOneLinerMaxLength) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -892,11 +892,34 @@ class GTEST_API_ Random {
 | 
				
			|||||||
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
 | 
					#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
 | 
				
			||||||
  typename std::remove_const<typename std::remove_reference<T>::type>::type
 | 
					  typename std::remove_const<typename std::remove_reference<T>::type>::type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
 | 
					// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant
 | 
				
			||||||
// true if and only if T is type proto2::MessageLite or a subclass of it.
 | 
					// that's true if and only if T has methods DebugString() and ShortDebugString()
 | 
				
			||||||
 | 
					// that return std::string.
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct IsAProtocolMessage
 | 
					class HasDebugStringAndShortDebugString {
 | 
				
			||||||
    : public std::is_convertible<const T*, const ::proto2::MessageLite*> {};
 | 
					 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
 | 
					// When the compiler sees expression IsContainerTest<C>(0), if C is an
 | 
				
			||||||
// STL-style container class, the first overload of IsContainerTest
 | 
					// STL-style container class, the first overload of IsContainerTest
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,8 +254,8 @@ using testing::internal::GetTimeInMillis;
 | 
				
			|||||||
using testing::internal::GetTypeId;
 | 
					using testing::internal::GetTypeId;
 | 
				
			||||||
using testing::internal::GetUnitTestImpl;
 | 
					using testing::internal::GetUnitTestImpl;
 | 
				
			||||||
using testing::internal::GTestFlagSaver;
 | 
					using testing::internal::GTestFlagSaver;
 | 
				
			||||||
 | 
					using testing::internal::HasDebugStringAndShortDebugString;
 | 
				
			||||||
using testing::internal::Int32FromEnvOrDie;
 | 
					using testing::internal::Int32FromEnvOrDie;
 | 
				
			||||||
using testing::internal::IsAProtocolMessage;
 | 
					 | 
				
			||||||
using testing::internal::IsContainer;
 | 
					using testing::internal::IsContainer;
 | 
				
			||||||
using testing::internal::IsContainerTest;
 | 
					using testing::internal::IsContainerTest;
 | 
				
			||||||
using testing::internal::IsNotContainer;
 | 
					using testing::internal::IsNotContainer;
 | 
				
			||||||
@@ -7185,24 +7185,71 @@ GTEST_TEST(AlternativeNameTest, Works) {  // GTEST_TEST is the same as TEST.
 | 
				
			|||||||
class ConversionHelperBase {};
 | 
					class ConversionHelperBase {};
 | 
				
			||||||
class ConversionHelperDerived : public ConversionHelperBase {};
 | 
					class ConversionHelperDerived : public ConversionHelperBase {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that IsAProtocolMessage<T>::value is a compile-time constant.
 | 
					struct HasDebugStringMethods {
 | 
				
			||||||
TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) {
 | 
					  std::string DebugString() const { return ""; }
 | 
				
			||||||
  GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::MessageLite>::value,
 | 
					  std::string ShortDebugString() const { return ""; }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct InheritsDebugStringMethods : public HasDebugStringMethods {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
					                        const_true);
 | 
				
			||||||
  GTEST_COMPILE_ASSERT_(!IsAProtocolMessage<int>::value, const_false);
 | 
					  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 IsAProtocolMessage<T>::value is true when T is
 | 
					// Tests that HasDebugStringAndShortDebugString<T>::value is true when T has
 | 
				
			||||||
// proto2::Message or a sub-class of it.
 | 
					// needed methods.
 | 
				
			||||||
TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) {
 | 
					TEST(HasDebugStringAndShortDebugStringTest,
 | 
				
			||||||
  EXPECT_TRUE(IsAProtocolMessage<::proto2::MessageLite>::value);
 | 
					     ValueIsTrueWhenTypeHasDebugStringAndShortDebugString) {
 | 
				
			||||||
 | 
					  EXPECT_TRUE(
 | 
				
			||||||
 | 
					      HasDebugStringAndShortDebugString<InheritsDebugStringMethods>::value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that IsAProtocolMessage<T>::value is false when T is neither
 | 
					// Tests that HasDebugStringAndShortDebugString<T>::value is false when T
 | 
				
			||||||
// ::proto2::Message nor a sub-class of it.
 | 
					// doesn't have needed methods.
 | 
				
			||||||
TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) {
 | 
					TEST(HasDebugStringAndShortDebugStringTest,
 | 
				
			||||||
  EXPECT_FALSE(IsAProtocolMessage<int>::value);
 | 
					     ValueIsFalseWhenTypeIsNotAProtocolMessage) {
 | 
				
			||||||
  EXPECT_FALSE(IsAProtocolMessage<const ConversionHelperBase>::value);
 | 
					  EXPECT_FALSE(HasDebugStringAndShortDebugString<int>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(
 | 
				
			||||||
 | 
					      HasDebugStringAndShortDebugString<const ConversionHelperBase>::value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests GTEST_REMOVE_REFERENCE_AND_CONST_.
 | 
					// Tests GTEST_REMOVE_REFERENCE_AND_CONST_.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user