Merge pull request #2837 from inazarenko:duck_type_protos
PiperOrigin-RevId: 336087297
This commit is contained in:
commit
4abb012c70
@ -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_.
|
||||||
|
Loading…
Reference in New Issue
Block a user