From 01e18376efe643a82cff468734f87f8c60e314b6 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 21 Jul 2023 10:35:31 -0700 Subject: [PATCH] Make `AbslStringify` usage public in GoogleTest Fixes #4314 PiperOrigin-RevId: 549986457 Change-Id: Iff74f02ab1c106696f288540e9c623d56b76e3f7 --- googletest/include/gtest/gtest-printers.h | 22 ++++++++++++++++ googletest/test/googletest-printers-test.cc | 28 +++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 1ba5178e..d1766e64 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -43,6 +43,9 @@ // 1. foo::PrintTo(const T&, ostream*) // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. +// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215. +// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an +// alternative presentation in test results is of interest. // // However if T is an STL-style container then it is printed element-wise // unless foo::PrintTo(const T&, ostream*) is defined. Note that @@ -112,6 +115,10 @@ #include #include +#ifdef GTEST_HAS_ABSL +#include "absl/strings/internal/has_absl_stringify.h" +#include "absl/strings/str_cat.h" +#endif // GTEST_HAS_ABSL #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" @@ -260,6 +267,18 @@ struct ConvertibleToStringViewPrinter { #endif }; +#ifdef GTEST_HAS_ABSL +struct ConvertibleToAbslStringifyPrinter { + template < + typename T, + typename = typename std::enable_if< + absl::strings_internal::HasAbslStringify::value>::type> // NOLINT + static void PrintValue(const T& value, ::std::ostream* os) { + *os << absl::StrCat(value); + } +}; +#endif // GTEST_HAS_ABSL + // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, @@ -308,6 +327,9 @@ void PrintWithFallback(const T& value, ::std::ostream* os) { using Printer = typename FindFirstPrinter< T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter, ProtobufPrinter, +#ifdef GTEST_HAS_ABSL + ConvertibleToAbslStringifyPrinter, +#endif // GTEST_HAS_ABSL internal_stream_operator_without_lexical_name_lookup::StreamPrinter, ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter, RawBytesPrinter, FallbackPrinter>::type; diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index f44f29a5..bee0ca4a 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -55,6 +55,10 @@ #include "gtest/gtest-printers.h" #include "gtest/gtest.h" +#ifdef GTEST_HAS_ABSL +#include "absl/strings/str_format.h" +#endif + // Some user-defined types for testing the universal value printer. // An anonymous enum type. @@ -119,6 +123,19 @@ void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { os << "StreamableInGlobal*"; } +#ifdef GTEST_HAS_ABSL +// A user-defined type with AbslStringify +struct Point { + template + friend void AbslStringify(Sink& sink, const Point& p) { + absl::Format(&sink, "(%d, %d)", p.x, p.y); + } + + int x = 10; + int y = 20; +}; +#endif + namespace foo { // A user-defined unprintable type in a user namespace. @@ -317,6 +334,11 @@ TEST(PrintEnumTest, EnumWithPrintTo) { EXPECT_EQ("invalid", Print(static_cast(0))); } +#ifdef GTEST_HAS_ABSL +// Tests printing a class that defines AbslStringify +TEST(PrintClassTest, AbslStringify) { EXPECT_EQ("(10, 20)", Print(Point())); } +#endif + // Tests printing a class implicitly convertible to BiggestInt. TEST(PrintClassTest, BiggestIntConvertible) { @@ -1636,6 +1658,12 @@ TEST(PrintToStringTest, PrintReferenceToStreamableInGlobal) { EXPECT_STREQ("StreamableInGlobal", PrintToString(r).c_str()); } +#ifdef GTEST_HAS_ABSL +TEST(PrintToStringTest, AbslStringify) { + EXPECT_PRINT_TO_STRING_(Point(), "(10, 20)"); +} +#endif + 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