googletest-printers-test.cc (googletest-release-1.10.0) | : | googletest-printers-test.cc (googletest-release-1.11.0) | ||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
// Google Test - The Google C++ Testing and Mocking Framework | // Google Test - The Google C++ Testing and Mocking Framework | |||
// | // | |||
// This file tests the universal value printer. | // This file tests the universal value printer. | |||
#include <ctype.h> | ||||
#include <limits.h> | ||||
#include <string.h> | ||||
#include <algorithm> | #include <algorithm> | |||
#include <cctype> | ||||
#include <cstdint> | ||||
#include <cstring> | ||||
#include <deque> | #include <deque> | |||
#include <forward_list> | #include <forward_list> | |||
#include <limits> | ||||
#include <list> | #include <list> | |||
#include <map> | #include <map> | |||
#include <memory> | ||||
#include <set> | #include <set> | |||
#include <sstream> | #include <sstream> | |||
#include <string> | #include <string> | |||
#include <unordered_map> | #include <unordered_map> | |||
#include <unordered_set> | #include <unordered_set> | |||
#include <utility> | #include <utility> | |||
#include <vector> | #include <vector> | |||
#include "gtest/gtest-printers.h" | #include "gtest/gtest-printers.h" | |||
#include "gtest/gtest.h" | #include "gtest/gtest.h" | |||
skipping to change at line 91 | skipping to change at line 93 | |||
void PrintTo(EnumWithPrintTo e, std::ostream* os) { | void PrintTo(EnumWithPrintTo e, std::ostream* os) { | |||
*os << (e == kEWPT1 ? "kEWPT1" : "invalid"); | *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); | |||
} | } | |||
// A class implicitly convertible to BiggestInt. | // A class implicitly convertible to BiggestInt. | |||
class BiggestIntConvertible { | class BiggestIntConvertible { | |||
public: | public: | |||
operator ::testing::internal::BiggestInt() const { return 42; } | operator ::testing::internal::BiggestInt() const { return 42; } | |||
}; | }; | |||
// A parent class with two child classes. The parent and one of the kids have | ||||
// stream operators. | ||||
class ParentClass {}; | ||||
class ChildClassWithStreamOperator : public ParentClass {}; | ||||
class ChildClassWithoutStreamOperator : public ParentClass {}; | ||||
static void operator<<(std::ostream& os, const ParentClass&) { | ||||
os << "ParentClass"; | ||||
} | ||||
static void operator<<(std::ostream& os, const ChildClassWithStreamOperator&) { | ||||
os << "ChildClassWithStreamOperator"; | ||||
} | ||||
// A user-defined unprintable class template in the global namespace. | // A user-defined unprintable class template in the global namespace. | |||
template <typename T> | template <typename T> | |||
class UnprintableTemplateInGlobal { | class UnprintableTemplateInGlobal { | |||
public: | public: | |||
UnprintableTemplateInGlobal() : value_() {} | UnprintableTemplateInGlobal() : value_() {} | |||
private: | private: | |||
T value_; | T value_; | |||
}; | }; | |||
// A user-defined streamable type in the global namespace. | // A user-defined streamable type in the global namespace. | |||
skipping to change at line 178 | skipping to change at line 192 | |||
private: | private: | |||
T value_; | T value_; | |||
}; | }; | |||
template <typename T> | template <typename T> | |||
inline ::std::ostream& operator<<(::std::ostream& os, | inline ::std::ostream& operator<<(::std::ostream& os, | |||
const StreamableTemplateInFoo<T>& x) { | const StreamableTemplateInFoo<T>& x) { | |||
return os << "StreamableTemplateInFoo: " << x.value(); | return os << "StreamableTemplateInFoo: " << x.value(); | |||
} | } | |||
// A user-defined streamable but recursivly-defined container type in | // A user-defined streamable type in a user namespace whose operator<< is | |||
// templated on the type of the output stream. | ||||
struct TemplatedStreamableInFoo {}; | ||||
template <typename OutputStream> | ||||
OutputStream& operator<<(OutputStream& os, | ||||
const TemplatedStreamableInFoo& /*ts*/) { | ||||
os << "TemplatedStreamableInFoo"; | ||||
return os; | ||||
} | ||||
// A user-defined streamable but recursively-defined container type in | ||||
// a user namespace, it mimics therefore std::filesystem::path or | // a user namespace, it mimics therefore std::filesystem::path or | |||
// boost::filesystem::path. | // boost::filesystem::path. | |||
class PathLike { | class PathLike { | |||
public: | public: | |||
struct iterator { | struct iterator { | |||
typedef PathLike value_type; | typedef PathLike value_type; | |||
iterator& operator++(); | iterator& operator++(); | |||
PathLike& operator*(); | PathLike& operator*(); | |||
}; | }; | |||
skipping to change at line 206 | skipping to change at line 231 | |||
iterator end() const { return iterator(); } | iterator end() const { return iterator(); } | |||
friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) { | friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) { | |||
return os << "Streamable-PathLike"; | return os << "Streamable-PathLike"; | |||
} | } | |||
}; | }; | |||
} // namespace foo | } // namespace foo | |||
namespace testing { | 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 { | namespace gtest_printers_test { | |||
using ::std::deque; | using ::std::deque; | |||
using ::std::list; | using ::std::list; | |||
using ::std::make_pair; | using ::std::make_pair; | |||
using ::std::map; | using ::std::map; | |||
using ::std::multimap; | using ::std::multimap; | |||
using ::std::multiset; | using ::std::multiset; | |||
using ::std::pair; | using ::std::pair; | |||
using ::std::set; | using ::std::set; | |||
using ::std::vector; | using ::std::vector; | |||
using ::testing::PrintToString; | using ::testing::PrintToString; | |||
using ::testing::internal::FormatForComparisonFailureMessage; | using ::testing::internal::FormatForComparisonFailureMessage; | |||
using ::testing::internal::ImplicitCast_; | using ::testing::internal::ImplicitCast_; | |||
using ::testing::internal::NativeArray; | using ::testing::internal::NativeArray; | |||
using ::testing::internal::RE; | ||||
using ::testing::internal::RelationToSourceReference; | using ::testing::internal::RelationToSourceReference; | |||
using ::testing::internal::Strings; | using ::testing::internal::Strings; | |||
using ::testing::internal::UniversalPrint; | using ::testing::internal::UniversalPrint; | |||
using ::testing::internal::UniversalPrinter; | using ::testing::internal::UniversalPrinter; | |||
using ::testing::internal::UniversalTersePrint; | using ::testing::internal::UniversalTersePrint; | |||
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; | using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; | |||
// Prints a value to a string using the universal value printer. This | // Prints a value to a string using the universal value printer. This | |||
// is a helper for testing UniversalPrinter<T>::Print() for various types. | // is a helper for testing UniversalPrinter<T>::Print() for various types. | |||
template <typename T> | template <typename T> | |||
skipping to change at line 312 | skipping to change at line 362 | |||
Print(static_cast<signed char>(-50))); | Print(static_cast<signed char>(-50))); | |||
} | } | |||
// unsigned char. | // unsigned char. | |||
TEST(PrintCharTest, UnsignedChar) { | TEST(PrintCharTest, UnsignedChar) { | |||
EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0'))); | EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0'))); | |||
EXPECT_EQ("'b' (98, 0x62)", | EXPECT_EQ("'b' (98, 0x62)", | |||
Print(static_cast<unsigned char>('b'))); | Print(static_cast<unsigned char>('b'))); | |||
} | } | |||
TEST(PrintCharTest, Char16) { | ||||
EXPECT_EQ("U+0041", Print(u'A')); | ||||
} | ||||
TEST(PrintCharTest, Char32) { | ||||
EXPECT_EQ("U+0041", Print(U'A')); | ||||
} | ||||
#ifdef __cpp_char8_t | ||||
TEST(PrintCharTest, Char8) { | ||||
EXPECT_EQ("U+0041", Print(u8'A')); | ||||
} | ||||
#endif | ||||
// Tests printing other simple, built-in types. | // Tests printing other simple, built-in types. | |||
// bool. | // bool. | |||
TEST(PrintBuiltInTypeTest, Bool) { | TEST(PrintBuiltInTypeTest, Bool) { | |||
EXPECT_EQ("false", Print(false)); | EXPECT_EQ("false", Print(false)); | |||
EXPECT_EQ("true", Print(true)); | EXPECT_EQ("true", Print(true)); | |||
} | } | |||
// wchar_t. | // wchar_t. | |||
TEST(PrintBuiltInTypeTest, Wchar_t) { | TEST(PrintBuiltInTypeTest, Wchar_t) { | |||
skipping to change at line 342 | skipping to change at line 406 | |||
EXPECT_EQ("L'\\t' (9)", Print(L'\t')); | EXPECT_EQ("L'\\t' (9)", Print(L'\t')); | |||
EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); | EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); | |||
EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); | EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); | |||
EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); | EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); | |||
EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); | EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); | |||
EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); | EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); | |||
EXPECT_EQ("L'\\x576' (1398)", Print(static_cast<wchar_t>(0x576))); | EXPECT_EQ("L'\\x576' (1398)", Print(static_cast<wchar_t>(0x576))); | |||
EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast<wchar_t>(0xC74D))); | EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast<wchar_t>(0xC74D))); | |||
} | } | |||
// Test that Int64 provides more storage than wchar_t. | // Test that int64_t provides more storage than wchar_t. | |||
TEST(PrintTypeSizeTest, Wchar_t) { | TEST(PrintTypeSizeTest, Wchar_t) { | |||
EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); | EXPECT_LT(sizeof(wchar_t), sizeof(int64_t)); | |||
} | } | |||
// Various integer types. | // Various integer types. | |||
TEST(PrintBuiltInTypeTest, Integer) { | TEST(PrintBuiltInTypeTest, Integer) { | |||
EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8 | EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8 | |||
EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8 | EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8 | |||
EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 | EXPECT_EQ("65535", Print(std::numeric_limits<uint16_t>::max())); // uint16 | |||
EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 | EXPECT_EQ("-32768", Print(std::numeric_limits<int16_t>::min())); // int16 | |||
EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 | EXPECT_EQ("4294967295", | |||
EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 | Print(std::numeric_limits<uint32_t>::max())); // uint32 | |||
EXPECT_EQ("-2147483648", | ||||
Print(std::numeric_limits<int32_t>::min())); // int32 | ||||
EXPECT_EQ("18446744073709551615", | EXPECT_EQ("18446744073709551615", | |||
Print(static_cast<testing::internal::UInt64>(-1))); // uint64 | Print(std::numeric_limits<uint64_t>::max())); // uint64 | |||
EXPECT_EQ("-9223372036854775808", | EXPECT_EQ("-9223372036854775808", | |||
Print(static_cast<testing::internal::Int64>(1) << 63)); // int64 | Print(std::numeric_limits<int64_t>::min())); // int64 | |||
#ifdef __cpp_char8_t | ||||
EXPECT_EQ("U+0000", | ||||
Print(std::numeric_limits<char8_t>::min())); // char8_t | ||||
EXPECT_EQ("U+00FF", | ||||
Print(std::numeric_limits<char8_t>::max())); // char8_t | ||||
#endif | ||||
EXPECT_EQ("U+0000", | ||||
Print(std::numeric_limits<char16_t>::min())); // char16_t | ||||
EXPECT_EQ("U+FFFF", | ||||
Print(std::numeric_limits<char16_t>::max())); // char16_t | ||||
EXPECT_EQ("U+0000", | ||||
Print(std::numeric_limits<char32_t>::min())); // char32_t | ||||
EXPECT_EQ("U+FFFFFFFF", | ||||
Print(std::numeric_limits<char32_t>::max())); // char32_t | ||||
} | } | |||
// Size types. | // Size types. | |||
TEST(PrintBuiltInTypeTest, Size_t) { | TEST(PrintBuiltInTypeTest, Size_t) { | |||
EXPECT_EQ("1", Print(sizeof('a'))); // size_t. | EXPECT_EQ("1", Print(sizeof('a'))); // size_t. | |||
#if !GTEST_OS_WINDOWS | #if !GTEST_OS_WINDOWS | |||
// Windows has no ssize_t type. | // Windows has no ssize_t type. | |||
EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2))); // ssize_t. | EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2))); // ssize_t. | |||
#endif // !GTEST_OS_WINDOWS | #endif // !GTEST_OS_WINDOWS | |||
} | } | |||
skipping to change at line 414 | skipping to change at line 494 | |||
} | } | |||
// Tests that C strings are escaped properly. | // Tests that C strings are escaped properly. | |||
TEST(PrintCStringTest, EscapesProperly) { | TEST(PrintCStringTest, EscapesProperly) { | |||
const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; | const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; | |||
EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" | EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" | |||
"\\n\\r\\t\\v\\x7F\\xFF a\"", | "\\n\\r\\t\\v\\x7F\\xFF a\"", | |||
Print(p)); | 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 | // 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 | // of unsigned short. Defining an overload for const wchar_t* in that case | |||
// would cause pointers to unsigned shorts be printed as wide strings, | // would cause pointers to unsigned shorts be printed as wide strings, | |||
// possibly accessing more memory than intended and causing invalid | // possibly accessing more memory than intended and causing invalid | |||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when | // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when | |||
// wchar_t is implemented as a native type. | // wchar_t is implemented as a native type. | |||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) | #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) | |||
// const wchar_t*. | // const wchar_t*. | |||
TEST(PrintWideCStringTest, Const) { | TEST(PrintWideCStringTest, Const) { | |||
skipping to change at line 624 | skipping to change at line 790 | |||
EXPECT_EQ("{ false }", PrintArrayHelper(a)); | EXPECT_EQ("{ false }", PrintArrayHelper(a)); | |||
} | } | |||
// char array without terminating NUL. | // char array without terminating NUL. | |||
TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { | TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { | |||
// Array a contains '\0' in the middle and doesn't end with '\0'. | // Array a contains '\0' in the middle and doesn't end with '\0'. | |||
char a[] = { 'H', '\0', 'i' }; | char a[] = { 'H', '\0', 'i' }; | |||
EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | |||
} | } | |||
// const char array with terminating NUL. | // char array with terminating NUL. | |||
TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { | TEST(PrintArrayTest, CharArrayWithTerminatingNul) { | |||
const char a[] = "\0Hi"; | const char a[] = "\0Hi"; | |||
EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); | EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); | |||
} | } | |||
// const wchar_t array without terminating NUL. | #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 char8_t a[] = {u8'H', u8'\0', u8'i'}; | ||||
EXPECT_EQ("u8\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | ||||
} | ||||
// char8_t array with terminating NUL. | ||||
TEST(PrintArrayTest, Char8ArrayWithTerminatingNul) { | ||||
const char8_t a[] = u8"\0世界"; | ||||
EXPECT_EQ( | ||||
"u8\"\\0\\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", | ||||
PrintArrayHelper(a)); | ||||
} | ||||
#endif | ||||
// 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)); | ||||
} | ||||
// 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) { | TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { | |||
// Array a contains '\0' in the middle and doesn't end with '\0'. | // Array a contains '\0' in the middle and doesn't end with '\0'. | |||
const wchar_t a[] = { L'H', L'\0', L'i' }; | const wchar_t a[] = {L'H', L'\0', L'i'}; | |||
EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | |||
} | } | |||
// wchar_t array with terminating NUL. | // wchar_t array with terminating NUL. | |||
TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { | TEST(PrintArrayTest, WCharArrayWithTerminatingNul) { | |||
const wchar_t a[] = L"\0Hi"; | const wchar_t a[] = L"\0Hi"; | |||
EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); | EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); | |||
} | } | |||
// Array of objects. | // Array of objects. | |||
TEST(PrintArrayTest, ObjectArray) { | TEST(PrintArrayTest, ObjectArray) { | |||
std::string a[3] = {"Hi", "Hello", "Ni hao"}; | std::string a[3] = {"Hi", "Hello", "Ni hao"}; | |||
EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); | EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); | |||
} | } | |||
skipping to change at line 702 | skipping to change at line 913 | |||
// same for wide strings. | // same for wide strings. | |||
EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); | EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); | |||
EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", | EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", | |||
Print(::std::wstring(L"mm\x6" L"bananas"))); | Print(::std::wstring(L"mm\x6" L"bananas"))); | |||
EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", | EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", | |||
Print(::std::wstring(L"NOM\x6" L"BANANA"))); | Print(::std::wstring(L"NOM\x6" L"BANANA"))); | |||
EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); | EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); | |||
} | } | |||
#endif // GTEST_HAS_STD_WSTRING | #endif // GTEST_HAS_STD_WSTRING | |||
#ifdef __cpp_char8_t | ||||
TEST(PrintStringTest, U8String) { | ||||
std::u8string str = u8"Hello, 世界"; | ||||
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. | ||||
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str)); | ||||
} | ||||
#endif | ||||
TEST(PrintStringTest, U16String) { | ||||
std::u16string str = u"Hello, 世界"; | ||||
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. | ||||
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str)); | ||||
} | ||||
TEST(PrintStringTest, U32String) { | ||||
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 | // Tests printing types that support generic streaming (i.e. streaming | |||
// to std::basic_ostream<Char, CharTraits> for any valid Char and | // to std::basic_ostream<Char, CharTraits> for any valid Char and | |||
// CharTraits types). | // CharTraits types). | |||
// Tests printing a non-template type that supports generic streaming. | // Tests printing a non-template type that supports generic streaming. | |||
class AllowsGenericStreaming {}; | class AllowsGenericStreaming {}; | |||
template <typename Char, typename CharTraits> | template <typename Char, typename CharTraits> | |||
std::basic_ostream<Char, CharTraits>& operator<<( | std::basic_ostream<Char, CharTraits>& operator<<( | |||
skipping to change at line 760 | skipping to change at line 991 | |||
std::basic_ostream<Char, CharTraits>& os, | std::basic_ostream<Char, CharTraits>& os, | |||
const AllowsGenericStreamingAndImplicitConversionTemplate<T>& /* a */) { | const AllowsGenericStreamingAndImplicitConversionTemplate<T>& /* a */) { | |||
return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; | return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; | |||
} | } | |||
TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { | TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { | |||
AllowsGenericStreamingAndImplicitConversionTemplate<int> a; | AllowsGenericStreamingAndImplicitConversionTemplate<int> a; | |||
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); | EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); | |||
} | } | |||
#if GTEST_HAS_ABSL | #if GTEST_INTERNAL_HAS_STRING_VIEW | |||
// Tests printing ::absl::string_view. | // Tests printing internal::StringView. | |||
TEST(PrintStringViewTest, SimpleStringView) { | TEST(PrintStringViewTest, SimpleStringView) { | |||
const ::absl::string_view sp = "Hello"; | const internal::StringView sp = "Hello"; | |||
EXPECT_EQ("\"Hello\"", Print(sp)); | EXPECT_EQ("\"Hello\"", Print(sp)); | |||
} | } | |||
TEST(PrintStringViewTest, UnprintableCharacters) { | TEST(PrintStringViewTest, UnprintableCharacters) { | |||
const char str[] = "NUL (\0) and \r\t"; | const char str[] = "NUL (\0) and \r\t"; | |||
const ::absl::string_view sp(str, sizeof(str) - 1); | const internal::StringView sp(str, sizeof(str) - 1); | |||
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); | EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); | |||
} | } | |||
#endif // GTEST_HAS_ABSL | #endif // GTEST_INTERNAL_HAS_STRING_VIEW | |||
// Tests printing STL containers. | // Tests printing STL containers. | |||
TEST(PrintStlContainerTest, EmptyDeque) { | TEST(PrintStlContainerTest, EmptyDeque) { | |||
deque<char> empty; | deque<char> empty; | |||
EXPECT_EQ("{}", Print(empty)); | EXPECT_EQ("{}", Print(empty)); | |||
} | } | |||
TEST(PrintStlContainerTest, NonEmptyDeque) { | TEST(PrintStlContainerTest, NonEmptyDeque) { | |||
deque<int> non_empty; | deque<int> non_empty; | |||
skipping to change at line 975 | skipping to change at line 1206 | |||
::std::tuple<char, bool> t2('a', true); | ::std::tuple<char, bool> t2('a', true); | |||
EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); | EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); | |||
::std::tuple<bool, int, int> t3(false, 2, 3); | ::std::tuple<bool, int, int> t3(false, 2, 3); | |||
EXPECT_EQ("(false, 2, 3)", Print(t3)); | EXPECT_EQ("(false, 2, 3)", Print(t3)); | |||
::std::tuple<bool, int, int, int> t4(false, 2, 3, 4); | ::std::tuple<bool, int, int, int> t4(false, 2, 3, 4); | |||
EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); | EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); | |||
const char* const str = "8"; | const char* const str = "8"; | |||
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT | ::std::tuple<bool, char, short, int32_t, int64_t, float, double, // NOLINT | |||
testing::internal::Int64, float, double, const char*, void*, | const char*, void*, std::string> | |||
std::string> | ||||
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT | t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT | |||
nullptr, "10"); | nullptr, "10"); | |||
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + | EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + | |||
" pointing to \"8\", NULL, \"10\")", | " pointing to \"8\", NULL, \"10\")", | |||
Print(t10)); | Print(t10)); | |||
} | } | |||
// Nested tuples. | // Nested tuples. | |||
TEST(PrintStdTupleTest, NestedTuple) { | TEST(PrintStdTupleTest, NestedTuple) { | |||
::std::tuple< ::std::tuple<int, bool>, char> nested( | ::std::tuple< ::std::tuple<int, bool>, char> nested( | |||
skipping to change at line 1061 | skipping to change at line 1291 | |||
EXPECT_EQ("StreamableInGlobal", Print(x)); | EXPECT_EQ("StreamableInGlobal", Print(x)); | |||
EXPECT_EQ("StreamableInGlobal*", Print(&x)); | EXPECT_EQ("StreamableInGlobal*", Print(&x)); | |||
} | } | |||
// Printable template types in a user namespace. | // Printable template types in a user namespace. | |||
TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { | TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { | |||
EXPECT_EQ("StreamableTemplateInFoo: 0", | EXPECT_EQ("StreamableTemplateInFoo: 0", | |||
Print(::foo::StreamableTemplateInFoo<int>())); | Print(::foo::StreamableTemplateInFoo<int>())); | |||
} | } | |||
TEST(PrintStreamableTypeTest, TypeInUserNamespaceWithTemplatedStreamOperator) { | ||||
EXPECT_EQ("TemplatedStreamableInFoo", | ||||
Print(::foo::TemplatedStreamableInFoo())); | ||||
} | ||||
TEST(PrintStreamableTypeTest, SubclassUsesSuperclassStreamOperator) { | ||||
ParentClass parent; | ||||
ChildClassWithStreamOperator child_stream; | ||||
ChildClassWithoutStreamOperator child_no_stream; | ||||
EXPECT_EQ("ParentClass", Print(parent)); | ||||
EXPECT_EQ("ChildClassWithStreamOperator", Print(child_stream)); | ||||
EXPECT_EQ("ParentClass", Print(child_no_stream)); | ||||
} | ||||
// Tests printing a user-defined recursive container type that has a << | // Tests printing a user-defined recursive container type that has a << | |||
// operator. | // operator. | |||
TEST(PrintStreamableTypeTest, PathLikeInUserNamespace) { | TEST(PrintStreamableTypeTest, PathLikeInUserNamespace) { | |||
::foo::PathLike x; | ::foo::PathLike x; | |||
EXPECT_EQ("Streamable-PathLike", Print(x)); | EXPECT_EQ("Streamable-PathLike", Print(x)); | |||
const ::foo::PathLike cx; | const ::foo::PathLike cx; | |||
EXPECT_EQ("Streamable-PathLike", Print(cx)); | EXPECT_EQ("Streamable-PathLike", Print(cx)); | |||
} | } | |||
// Tests printing user-defined types that have a PrintTo() function. | // Tests printing user-defined types that have a PrintTo() function. | |||
skipping to change at line 1469 | skipping to change at line 1713 | |||
EXPECT_EQ("123", ss.str()); | EXPECT_EQ("123", ss.str()); | |||
} | } | |||
TEST(UniversalPrintTest, WorksForReference) { | TEST(UniversalPrintTest, WorksForReference) { | |||
const int& n = 123; | const int& n = 123; | |||
::std::stringstream ss; | ::std::stringstream ss; | |||
UniversalPrint(n, &ss); | UniversalPrint(n, &ss); | |||
EXPECT_EQ("123", ss.str()); | 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) { | TEST(UniversalPrintTest, WorksForCString) { | |||
const char* s1 = "abc"; | const char* s1 = "abc"; | |||
::std::stringstream ss1; | ::std::stringstream ss1; | |||
UniversalPrint(s1, &ss1); | UniversalPrint(s1, &ss1); | |||
EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", std::string(ss1.str())); | EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", std::string(ss1.str())); | |||
char* s2 = const_cast<char*>(s1); | char* s2 = const_cast<char*>(s1); | |||
::std::stringstream ss2; | ::std::stringstream ss2; | |||
UniversalPrint(s2, &ss2); | UniversalPrint(s2, &ss2); | |||
EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", std::string(ss2.str())); | EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", std::string(ss2.str())); | |||
skipping to change at line 1498 | skipping to change at line 1749 | |||
::std::stringstream ss1; | ::std::stringstream ss1; | |||
UniversalPrint(str, &ss1); | UniversalPrint(str, &ss1); | |||
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); | EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); | |||
const char mutable_str[] = "\"Line\0 1\"\nLine 2"; | const char mutable_str[] = "\"Line\0 1\"\nLine 2"; | |||
::std::stringstream ss2; | ::std::stringstream ss2; | |||
UniversalPrint(mutable_str, &ss2); | UniversalPrint(mutable_str, &ss2); | |||
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); | 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) { | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { | |||
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); | Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); | |||
EXPECT_EQ(0u, result.size()); | EXPECT_EQ(0u, result.size()); | |||
} | } | |||
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { | |||
Strings result = UniversalTersePrintTupleFieldsToStrings( | Strings result = UniversalTersePrintTupleFieldsToStrings( | |||
::std::make_tuple(1)); | ::std::make_tuple(1)); | |||
ASSERT_EQ(1u, result.size()); | ASSERT_EQ(1u, result.size()); | |||
EXPECT_EQ("1", result[0]); | EXPECT_EQ("1", result[0]); | |||
skipping to change at line 1527 | skipping to change at line 1835 | |||
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { | |||
const int n = 1; | const int n = 1; | |||
Strings result = UniversalTersePrintTupleFieldsToStrings( | Strings result = UniversalTersePrintTupleFieldsToStrings( | |||
::std::tuple<const int&, const char*>(n, "a")); | ::std::tuple<const int&, const char*>(n, "a")); | |||
ASSERT_EQ(2u, result.size()); | ASSERT_EQ(2u, result.size()); | |||
EXPECT_EQ("1", result[0]); | EXPECT_EQ("1", result[0]); | |||
EXPECT_EQ("\"a\"", result[1]); | EXPECT_EQ("\"a\"", result[1]); | |||
} | } | |||
#if GTEST_HAS_ABSL | #if GTEST_INTERNAL_HAS_ANY | |||
class PrintAnyTest : public ::testing::Test { | ||||
protected: | ||||
template <typename T> | ||||
static std::string ExpectedTypeName() { | ||||
#if GTEST_HAS_RTTI | ||||
return internal::GetTypeName<T>(); | ||||
#else | ||||
return "<unknown_type>"; | ||||
#endif // GTEST_HAS_RTTI | ||||
} | ||||
}; | ||||
TEST_F(PrintAnyTest, Empty) { | ||||
internal::Any any; | ||||
EXPECT_EQ("no value", PrintToString(any)); | ||||
} | ||||
TEST_F(PrintAnyTest, NonEmpty) { | ||||
internal::Any any; | ||||
constexpr int val1 = 10; | ||||
const std::string val2 = "content"; | ||||
any = val1; | ||||
EXPECT_EQ("value of type " + ExpectedTypeName<int>(), PrintToString(any)); | ||||
any = val2; | ||||
EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(), | ||||
PrintToString(any)); | ||||
} | ||||
#endif // GTEST_INTERNAL_HAS_ANY | ||||
#if GTEST_INTERNAL_HAS_OPTIONAL | ||||
TEST(PrintOptionalTest, Basic) { | TEST(PrintOptionalTest, Basic) { | |||
absl::optional<int> value; | internal::Optional<int> value; | |||
EXPECT_EQ("(nullopt)", PrintToString(value)); | EXPECT_EQ("(nullopt)", PrintToString(value)); | |||
value = {7}; | value = {7}; | |||
EXPECT_EQ("(7)", PrintToString(value)); | EXPECT_EQ("(7)", PrintToString(value)); | |||
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1})); | EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1})); | |||
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"})); | EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"})); | |||
} | } | |||
#endif // GTEST_INTERNAL_HAS_OPTIONAL | ||||
#if GTEST_INTERNAL_HAS_VARIANT | ||||
struct NonPrintable { | struct NonPrintable { | |||
unsigned char contents = 17; | unsigned char contents = 17; | |||
}; | }; | |||
TEST(PrintOneofTest, Basic) { | TEST(PrintOneofTest, Basic) { | |||
using Type = absl::variant<int, StreamableInGlobal, NonPrintable>; | using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>; | |||
EXPECT_EQ("('int' with value 7)", PrintToString(Type(7))); | EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7))); | |||
EXPECT_EQ("('StreamableInGlobal' with value StreamableInGlobal)", | EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)", | |||
PrintToString(Type(StreamableInGlobal{}))); | PrintToString(Type(StreamableInGlobal{}))); | |||
EXPECT_EQ( | EXPECT_EQ( | |||
"('testing::gtest_printers_test::NonPrintable' with value 1-byte object " | "('testing::gtest_printers_test::NonPrintable(index = 2)' with value " | |||
"<11>)", | "1-byte object <11>)", | |||
PrintToString(Type(NonPrintable{}))); | PrintToString(Type(NonPrintable{}))); | |||
} | } | |||
#endif // GTEST_HAS_ABSL | #endif // GTEST_INTERNAL_HAS_VARIANT | |||
namespace { | namespace { | |||
class string_ref; | class string_ref; | |||
/** | /** | |||
* This is a synthetic pointer to a fixed size string. | * This is a synthetic pointer to a fixed size string. | |||
*/ | */ | |||
class string_ptr { | class string_ptr { | |||
public: | public: | |||
string_ptr(const char* data, size_t size) : data_(data), size_(size) {} | string_ptr(const char* data, size_t size) : data_(data), size_(size) {} | |||
End of changes. 38 change blocks. | ||||
36 lines changed or deleted | 377 lines changed or added |