Make AbslStringify usage public in GoogleTest

Fixes #4314

PiperOrigin-RevId: 549986457
Change-Id: Iff74f02ab1c106696f288540e9c623d56b76e3f7
This commit is contained in:
Abseil Team 2023-07-21 10:35:31 -07:00 committed by Copybara-Service
parent 1ed6a8c67a
commit 01e18376ef
2 changed files with 50 additions and 0 deletions

View File

@ -43,6 +43,9 @@
// 1. foo::PrintTo(const T&, ostream*) // 1. foo::PrintTo(const T&, ostream*)
// 2. operator<<(ostream&, const T&) defined in either foo or the // 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace. // 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 // However if T is an STL-style container then it is printed element-wise
// unless foo::PrintTo(const T&, ostream*) is defined. Note that // unless foo::PrintTo(const T&, ostream*) is defined. Note that
@ -112,6 +115,10 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#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-internal.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
@ -260,6 +267,18 @@ struct ConvertibleToStringViewPrinter {
#endif #endif
}; };
#ifdef GTEST_HAS_ABSL
struct ConvertibleToAbslStringifyPrinter {
template <
typename T,
typename = typename std::enable_if<
absl::strings_internal::HasAbslStringify<T>::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 // Prints the given number of bytes in the given object to the given
// ostream. // ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, 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< using Printer = typename FindFirstPrinter<
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter, T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
ProtobufPrinter, ProtobufPrinter,
#ifdef GTEST_HAS_ABSL
ConvertibleToAbslStringifyPrinter,
#endif // GTEST_HAS_ABSL
internal_stream_operator_without_lexical_name_lookup::StreamPrinter, internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter, ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
RawBytesPrinter, FallbackPrinter>::type; RawBytesPrinter, FallbackPrinter>::type;

View File

@ -55,6 +55,10 @@
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include "gtest/gtest.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. // Some user-defined types for testing the universal value printer.
// An anonymous enum type. // An anonymous enum type.
@ -119,6 +123,19 @@ void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) {
os << "StreamableInGlobal*"; os << "StreamableInGlobal*";
} }
#ifdef GTEST_HAS_ABSL
// A user-defined type with AbslStringify
struct Point {
template <typename Sink>
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 { namespace foo {
// A user-defined unprintable type in a user namespace. // A user-defined unprintable type in a user namespace.
@ -317,6 +334,11 @@ TEST(PrintEnumTest, EnumWithPrintTo) {
EXPECT_EQ("invalid", Print(static_cast<EnumWithPrintTo>(0))); EXPECT_EQ("invalid", Print(static_cast<EnumWithPrintTo>(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. // Tests printing a class implicitly convertible to BiggestInt.
TEST(PrintClassTest, BiggestIntConvertible) { TEST(PrintClassTest, BiggestIntConvertible) {
@ -1636,6 +1658,12 @@ TEST(PrintToStringTest, PrintReferenceToStreamableInGlobal) {
EXPECT_STREQ("StreamableInGlobal", PrintToString(r).c_str()); 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) { TEST(IsValidUTF8Test, IllFormedUTF8) {
// The following test strings are ill-formed UTF-8 and are printed // 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 // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is