diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index cd094949..a7e0a3c9 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -113,6 +113,11 @@ #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" +#if GTEST_HAS_RTTI +#include +#include +#endif // GTEST_HAS_RTTI + namespace testing { // Definitions in the internal* namespaces are subject to change without notice. @@ -650,6 +655,18 @@ void PrintTo(const ::std::pair& value, ::std::ostream* os) { *os << ')'; } +#if GTEST_HAS_RTTI +inline void PrintTo(const ::std::type_info& value, ::std::ostream* os) { + internal::PrintTo<::std::type_info>(value, os); + *os << " (\"" << value.name() << "\")"; +} + +inline void PrintTo(const ::std::type_index& value, ::std::ostream* os) { + internal::PrintTo<::std::type_index>(value, os); + *os << " (\"" << value.name() << "\")"; +} +#endif // GTEST_HAS_RTTI + // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index 8247d4e1..f037480b 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -1589,6 +1589,61 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { "\n As Text: \"From ä — ẑ\""); } +#if GTEST_HAS_RTTI +template +class PrintToStringTest : public testing::Test { + public: + using TestType = T; +}; + +struct PrintBase { + virtual ~PrintBase() = default; +}; +struct PrintDerived : PrintBase {}; + +using PrintToStringTestTypes = + testing::Types; +TYPED_TEST_SUITE(PrintToStringTest, PrintToStringTestTypes); + +// Returns `true` if `haystack` contains `needle`. +// +// FIXME: Replace with `EXPECT_THAT(haystack, HasSubstr(needle))` once +// GoogleTest starts depending on GoogleMock. +bool ContainsSubstr(const std::string& haystack, const std::string& needle) { + return haystack.find(needle) != std::string::npos; +} + +TYPED_TEST(PrintToStringTest, IncludesNameWithTypeInfoAndTypeIndex) { + const ::std::type_info& info = typeid(typename TestFixture::TestType); + SCOPED_TRACE(info.name()); + EXPECT_TRUE(ContainsSubstr(PrintToString(info), info.name())); + EXPECT_TRUE( + ContainsSubstr(PrintToString(::std::type_index{info}), info.name())); +} + +TEST(PrintToStringTest, IncludesNameWithTypeInfoAndTypeIndexViaBaseRef) { + PrintDerived derived; + PrintBase& base = derived; + + { + const ::std::type_info& derived_info = typeid(derived); + SCOPED_TRACE(derived_info.name()); + EXPECT_TRUE( + ContainsSubstr(PrintToString(derived_info), derived_info.name())); + EXPECT_TRUE(ContainsSubstr(PrintToString(::std::type_index{derived_info}), + derived_info.name())); + } + { + const ::std::type_info& base_ref_info = typeid(base); + SCOPED_TRACE(base_ref_info.name()); + EXPECT_TRUE( + ContainsSubstr(PrintToString(base_ref_info), base_ref_info.name())); + EXPECT_TRUE(ContainsSubstr(PrintToString(::std::type_index{base_ref_info}), + base_ref_info.name())); + } +} +#endif // GTEST_HAS_RTTI + TEST(IsValidUTF8Test, IllFormedUTF8) { // The following test strings are ill-formed UTF-8 and are printed // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is