diff options
Diffstat (limited to 'googletest/test/googletest-printers-test.cc')
-rw-r--r-- | googletest/test/googletest-printers-test.cc | 408 |
1 files changed, 289 insertions, 119 deletions
diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index bf1e0b59..04635e58 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -32,15 +32,16 @@ // // This file tests the universal value printer. -#include <ctype.h> -#include <string.h> #include <algorithm> +#include <cctype> #include <cstdint> +#include <cstring> #include <deque> #include <forward_list> #include <limits> #include <list> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -228,6 +229,33 @@ class PathLike { } // namespace foo namespace testing { +namespace { +template <typename T> +class Wrapper { + public: + explicit Wrapper(T&& value) : value_(std::forward<T>(value)) {} + + const T& value() const { return value_; } + + private: + T value_; +}; + +} // namespace + +namespace internal { +template <typename T> +class UniversalPrinter<Wrapper<T>> { + public: + static void Print(const Wrapper<T>& w, ::std::ostream* os) { + *os << "Wrapper("; + UniversalPrint(w.value(), os); + *os << ')'; + } +}; +} // namespace internal + + namespace gtest_printers_test { using ::std::deque; @@ -465,6 +493,92 @@ TEST(PrintCStringTest, EscapesProperly) { Print(p)); } +#ifdef __cpp_char8_t +// const char8_t*. +TEST(PrintU8StringTest, Const) { + const char8_t* p = u8"界"; + EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE7\\x95\\x8C\"", Print(p)); +} + +// char8_t*. +TEST(PrintU8StringTest, NonConst) { + char8_t p[] = u8"世"; + EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE4\\xB8\\x96\"", + Print(static_cast<char8_t*>(p))); +} + +// NULL u8 string. +TEST(PrintU8StringTest, Null) { + const char8_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u8 strings are escaped properly. +TEST(PrintU8StringTest, EscapesProperly) { + const char8_t* p = u8"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界"; + EXPECT_EQ(PrintPointer(p) + + " pointing to u8\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", + Print(p)); +} +#endif + +// const char16_t*. +TEST(PrintU16StringTest, Const) { + const char16_t* p = u"界"; + EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x754C\"", Print(p)); +} + +// char16_t*. +TEST(PrintU16StringTest, NonConst) { + char16_t p[] = u"世"; + EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x4E16\"", + Print(static_cast<char16_t*>(p))); +} + +// NULL u16 string. +TEST(PrintU16StringTest, Null) { + const char16_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u16 strings are escaped properly. +TEST(PrintU16StringTest, EscapesProperly) { + const char16_t* p = u"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界"; + EXPECT_EQ(PrintPointer(p) + + " pointing to u\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\x4E16\\x754C\"", + Print(p)); +} + +// const char32_t*. +TEST(PrintU32StringTest, Const) { + const char32_t* p = U"🗺️"; + EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F5FA\\xFE0F\"", Print(p)); +} + +// char32_t*. +TEST(PrintU32StringTest, NonConst) { + char32_t p[] = U"🌌"; + EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F30C\"", + Print(static_cast<char32_t*>(p))); +} + +// NULL u32 string. +TEST(PrintU32StringTest, Null) { + const char32_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u32 strings are escaped properly. +TEST(PrintU32StringTest, EscapesProperly) { + const char32_t* p = U"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 🗺️"; + EXPECT_EQ(PrintPointer(p) + + " pointing to U\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\x1F5FA\\xFE0F\"", + Print(p)); +} + // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, @@ -536,56 +650,6 @@ TEST(PrintCharPointerTest, ConstUnsignedChar) { EXPECT_EQ("NULL", Print(p)); } -#ifdef __cpp_char8_t -// char8_t* -TEST(PrintCharPointerTest, Char8) { - char8_t* p = reinterpret_cast<char8_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char8_t* -TEST(PrintCharPointerTest, ConstChar8) { - const char8_t* p = reinterpret_cast<const char8_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} -#endif - -// char16_t* -TEST(PrintCharPointerTest, Char16) { - char16_t* p = reinterpret_cast<char16_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char16_t* -TEST(PrintCharPointerTest, ConstChar16) { - const char16_t* p = reinterpret_cast<const char16_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// char32_t* -TEST(PrintCharPointerTest, Char32) { - char32_t* p = reinterpret_cast<char32_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char32_t* -TEST(PrintCharPointerTest, ConstChar32) { - const char32_t* p = reinterpret_cast<const char32_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - // Tests printing pointers to simple, built-in types. // bool*. @@ -725,62 +789,68 @@ TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } -// const char array with terminating NUL. -TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { +// char array with terminating NUL. +TEST(PrintArrayTest, CharArrayWithTerminatingNul) { const char a[] = "\0Hi"; EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); } -// const wchar_t array without terminating NUL. -TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { +#ifdef __cpp_char8_t +// char_t array without terminating NUL. +TEST(PrintArrayTest, Char8ArrayWithNoTerminatingNul) { // Array a contains '\0' in the middle and doesn't end with '\0'. - const wchar_t a[] = { L'H', L'\0', L'i' }; - EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); -} - -// wchar_t array with terminating NUL. -TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { - const wchar_t a[] = L"\0Hi"; - EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); + const char8_t a[] = {u8'H', u8'\0', u8'i'}; + EXPECT_EQ("u8\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } -#ifdef __cpp_char8_t -// char8_t array. -TEST(PrintArrayTest, Char8Array) { - const char8_t a[] = u8"Hello, world!"; +// char8_t array with terminating NUL. +TEST(PrintArrayTest, Char8ArrayWithTerminatingNul) { + const char8_t a[] = u8"\0世界"; EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " - "U+006F, U+0072, U+006C, U+0064, U+0021, U+0000 }", + "u8\"\\0\\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", PrintArrayHelper(a)); } #endif -// char16_t array. -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintArrayTest, DISABLED_Char16Array) { -#else -TEST(PrintArrayTest, Char16Array) { -#endif - const char16_t a[] = u"Hello, 世界"; - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C, U+0000 }", - PrintArrayHelper(a)); +// const char16_t array without terminating NUL. +TEST(PrintArrayTest, Char16ArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const char16_t a[] = {u'こ', u'\0', u'ん', u'に', u'ち', u'は'}; + EXPECT_EQ("u\"\\x3053\\0\\x3093\\x306B\\x3061\\x306F\" (no terminating NUL)", + PrintArrayHelper(a)); } -// char32_t array. -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintArrayTest, DISABLED_Char32Array) { -#else -TEST(PrintArrayTest, Char32Array) { -#endif - const char32_t a[] = U"Hello, 世界"; - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C, U+0000 }", - PrintArrayHelper(a)); +// char16_t array with terminating NUL. +TEST(PrintArrayTest, Char16ArrayWithTerminatingNul) { + const char16_t a[] = u"\0こんにちは"; + EXPECT_EQ("u\"\\0\\x3053\\x3093\\x306B\\x3061\\x306F\"", PrintArrayHelper(a)); +} + +// char32_t array without terminating NUL. +TEST(PrintArrayTest, Char32ArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const char32_t a[] = {U'👋', U'\0', U'🌌'}; + EXPECT_EQ("U\"\\x1F44B\\0\\x1F30C\" (no terminating NUL)", + PrintArrayHelper(a)); +} + +// char32_t array with terminating NUL. +TEST(PrintArrayTest, Char32ArrayWithTerminatingNul) { + const char32_t a[] = U"\0👋🌌"; + EXPECT_EQ("U\"\\0\\x1F44B\\x1F30C\"", PrintArrayHelper(a)); +} + +// wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = {L'H', L'\0', L'i'}; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); } // Array of objects. @@ -844,41 +914,22 @@ TEST(PrintWideStringTest, StringAmbiguousHex) { #ifdef __cpp_char8_t TEST(PrintStringTest, U8String) { - std::u8string str = u8"Hello, world!"; + std::u8string str = u8"Hello, 世界"; EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " - "U+006F, U+0072, U+006C, U+0064, U+0021 }", - Print(str)); + EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str)); } #endif -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintStringTest, DISABLED_U16String) { -#else TEST(PrintStringTest, U16String) { -#endif std::u16string str = u"Hello, 世界"; EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C }", - Print(str)); + EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str)); } -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintStringTest, DISABLED_U32String) { -#else TEST(PrintStringTest, U32String) { -#endif - std::u32string str = U"Hello, 世界"; - EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C }", - Print(str)); + std::u32string str = U"Hello, 🗺️"; + EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type + EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str)); } // Tests printing types that support generic streaming (i.e. streaming @@ -1561,6 +1612,61 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { "\n As Text: \"From ä — ẑ\""); } +#if GTEST_HAS_RTTI +template <typename T> +class PrintToStringTest : public testing::Test { + public: + using TestType = T; +}; + +struct PrintBase { + virtual ~PrintBase() = default; +}; +struct PrintDerived : PrintBase {}; + +using PrintToStringTestTypes = + testing::Types<void, int, const volatile int*, PrintBase, PrintDerived>; +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 @@ -1666,6 +1772,13 @@ TEST(UniversalPrintTest, WorksForReference) { EXPECT_EQ("123", ss.str()); } +TEST(UniversalPrintTest, WorksForPairWithConst) { + std::pair<const Wrapper<std::string>, int> p(Wrapper<std::string>("abc"), 1); + ::std::stringstream ss; + UniversalPrint(p, &ss); + EXPECT_EQ("(Wrapper(\"abc\"), 1)", ss.str()); +} + TEST(UniversalPrintTest, WorksForCString) { const char* s1 = "abc"; ::std::stringstream ss1; @@ -1695,6 +1808,63 @@ TEST(UniversalPrintTest, WorksForCharArray) { EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); } +TEST(UniversalPrintTest, IncompleteType) { + struct Incomplete; + char some_object = 0; + EXPECT_EQ("(incomplete type)", + PrintToString(reinterpret_cast<Incomplete&>(some_object))); +} + +TEST(UniversalPrintTest, SmartPointers) { + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>())); + std::unique_ptr<int> p(new int(17)); + EXPECT_EQ("(ptr = " + PrintPointer(p.get()) + ", value = 17)", + PrintToString(p)); + std::unique_ptr<int[]> p2(new int[2]); + EXPECT_EQ("(" + PrintPointer(p2.get()) + ")", PrintToString(p2)); + + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>())); + std::shared_ptr<int> p3(new int(1979)); + EXPECT_EQ("(ptr = " + PrintPointer(p3.get()) + ", value = 1979)", + PrintToString(p3)); +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::shared_ptr<int[]> p4(new int[2]); + EXPECT_EQ("(" + PrintPointer(p4.get()) + ")", PrintToString(p4)); +#endif + + // modifiers + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile const int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int[]>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int[]>())); + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int[]>())); + EXPECT_EQ("(nullptr)", + PrintToString(std::unique_ptr<volatile const int[]>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile const int>())); +#if __cpp_lib_shared_ptr_arrays >= 201611L + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int[]>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int[]>())); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int[]>())); + EXPECT_EQ("(nullptr)", + PrintToString(std::shared_ptr<volatile const int[]>())); +#endif + + // void + EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<void, void (*)(void*)>( + nullptr, nullptr))); + EXPECT_EQ("(" + PrintPointer(p.get()) + ")", + PrintToString( + std::unique_ptr<void, void (*)(void*)>(p.get(), [](void*) {}))); + EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<void>())); + EXPECT_EQ("(" + PrintPointer(p.get()) + ")", + PrintToString(std::shared_ptr<void>(p.get(), [](void*) {}))); +} + TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); EXPECT_EQ(0u, result.size()); |