Improves gtest's failure messages. In particulars, char pointers and
char arrays are not escapped properly.
This commit is contained in:
@@ -197,14 +197,15 @@ using ::std::pair;
|
||||
using ::std::set;
|
||||
using ::std::vector;
|
||||
using ::testing::PrintToString;
|
||||
using ::testing::internal::FormatForComparisonFailureMessage;
|
||||
using ::testing::internal::ImplicitCast_;
|
||||
using ::testing::internal::NativeArray;
|
||||
using ::testing::internal::RE;
|
||||
using ::testing::internal::Strings;
|
||||
using ::testing::internal::UniversalTersePrint;
|
||||
using ::testing::internal::UniversalPrint;
|
||||
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
|
||||
using ::testing::internal::UniversalPrinter;
|
||||
using ::testing::internal::UniversalTersePrint;
|
||||
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
|
||||
using ::testing::internal::kReference;
|
||||
using ::testing::internal::string;
|
||||
|
||||
@@ -613,17 +614,30 @@ TEST(PrintArrayTest, ConstArray) {
|
||||
EXPECT_EQ("{ false }", PrintArrayHelper(a));
|
||||
}
|
||||
|
||||
// Char array.
|
||||
TEST(PrintArrayTest, CharArray) {
|
||||
// char array without terminating NUL.
|
||||
TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) {
|
||||
// Array a contains '\0' in the middle and doesn't end with '\0'.
|
||||
char a[3] = { 'H', '\0', 'i' };
|
||||
EXPECT_EQ("\"H\\0i\"", PrintArrayHelper(a));
|
||||
char a[] = { 'H', '\0', 'i' };
|
||||
EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
|
||||
}
|
||||
|
||||
// Const char array.
|
||||
TEST(PrintArrayTest, ConstCharArray) {
|
||||
const char a[4] = "\0Hi";
|
||||
EXPECT_EQ("\"\\0Hi\\0\"", PrintArrayHelper(a));
|
||||
// const char array with terminating NUL.
|
||||
TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) {
|
||||
const char a[] = "\0Hi";
|
||||
EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a));
|
||||
}
|
||||
|
||||
// const 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, WConstCharArrayWithTerminatingNul) {
|
||||
const wchar_t a[] = L"\0Hi";
|
||||
EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a));
|
||||
}
|
||||
|
||||
// Array of objects.
|
||||
@@ -1186,6 +1200,207 @@ TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
|
||||
"@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object "));
|
||||
}
|
||||
|
||||
// Tests that FormatForComparisonFailureMessage(), which is used to print
|
||||
// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion
|
||||
// fails, formats the operand in the desired way.
|
||||
|
||||
// scalar
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForScalar) {
|
||||
EXPECT_STREQ("123",
|
||||
FormatForComparisonFailureMessage(123, 124).c_str());
|
||||
}
|
||||
|
||||
// non-char pointer
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) {
|
||||
int n = 0;
|
||||
EXPECT_EQ(PrintPointer(&n),
|
||||
FormatForComparisonFailureMessage(&n, &n).c_str());
|
||||
}
|
||||
|
||||
// non-char array
|
||||
TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
|
||||
// In expression 'array == x', 'array' is compared by pointer.
|
||||
// Therefore we want to print an array operand as a pointer.
|
||||
int n[] = { 1, 2, 3 };
|
||||
EXPECT_EQ(PrintPointer(n),
|
||||
FormatForComparisonFailureMessage(n, n).c_str());
|
||||
}
|
||||
|
||||
// Tests formatting a char pointer when it's compared with another pointer.
|
||||
// In this case we want to print it as a raw pointer, as the comparision is by
|
||||
// pointer.
|
||||
|
||||
// char pointer vs pointer
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) {
|
||||
// In expression 'p == x', where 'p' and 'x' are (const or not) char
|
||||
// pointers, the operands are compared by pointer. Therefore we
|
||||
// want to print 'p' as a pointer instead of a C string (we don't
|
||||
// even know if it's supposed to point to a valid C string).
|
||||
|
||||
// const char*
|
||||
const char* s = "hello";
|
||||
EXPECT_EQ(PrintPointer(s),
|
||||
FormatForComparisonFailureMessage(s, s).c_str());
|
||||
|
||||
// char*
|
||||
char ch = 'a';
|
||||
EXPECT_EQ(PrintPointer(&ch),
|
||||
FormatForComparisonFailureMessage(&ch, &ch).c_str());
|
||||
}
|
||||
|
||||
// wchar_t pointer vs pointer
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) {
|
||||
// In expression 'p == x', where 'p' and 'x' are (const or not) char
|
||||
// pointers, the operands are compared by pointer. Therefore we
|
||||
// want to print 'p' as a pointer instead of a wide C string (we don't
|
||||
// even know if it's supposed to point to a valid wide C string).
|
||||
|
||||
// const wchar_t*
|
||||
const wchar_t* s = L"hello";
|
||||
EXPECT_EQ(PrintPointer(s),
|
||||
FormatForComparisonFailureMessage(s, s).c_str());
|
||||
|
||||
// wchar_t*
|
||||
wchar_t ch = L'a';
|
||||
EXPECT_EQ(PrintPointer(&ch),
|
||||
FormatForComparisonFailureMessage(&ch, &ch).c_str());
|
||||
}
|
||||
|
||||
// Tests formatting a char pointer when it's compared to a string object.
|
||||
// In this case we want to print the char pointer as a C string.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
// char pointer vs ::string
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) {
|
||||
const char* s = "hello \"world";
|
||||
EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(s, ::string()).c_str());
|
||||
|
||||
// char*
|
||||
char str[] = "hi\1";
|
||||
char* p = str;
|
||||
EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(p, ::string()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// char pointer vs std::string
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) {
|
||||
const char* s = "hello \"world";
|
||||
EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(s, ::std::string()).c_str());
|
||||
|
||||
// char*
|
||||
char str[] = "hi\1";
|
||||
char* p = str;
|
||||
EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(p, ::std::string()).c_str());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// wchar_t pointer vs ::wstring
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) {
|
||||
const wchar_t* s = L"hi \"world";
|
||||
EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(s, ::wstring()).c_str());
|
||||
|
||||
// wchar_t*
|
||||
wchar_t str[] = L"hi\1";
|
||||
wchar_t* p = str;
|
||||
EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(p, ::wstring()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// wchar_t pointer vs std::wstring
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) {
|
||||
const wchar_t* s = L"hi \"world";
|
||||
EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(s, ::std::wstring()).c_str());
|
||||
|
||||
// wchar_t*
|
||||
wchar_t str[] = L"hi\1";
|
||||
wchar_t* p = str;
|
||||
EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped.
|
||||
FormatForComparisonFailureMessage(p, ::std::wstring()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tests formatting a char array when it's compared with a pointer or array.
|
||||
// In this case we want to print the array as a row pointer, as the comparison
|
||||
// is by pointer.
|
||||
|
||||
// char array vs pointer
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) {
|
||||
char str[] = "hi \"world\"";
|
||||
char* p = NULL;
|
||||
EXPECT_EQ(PrintPointer(str),
|
||||
FormatForComparisonFailureMessage(str, p).c_str());
|
||||
}
|
||||
|
||||
// char array vs char array
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) {
|
||||
const char str[] = "hi \"world\"";
|
||||
EXPECT_EQ(PrintPointer(str),
|
||||
FormatForComparisonFailureMessage(str, str).c_str());
|
||||
}
|
||||
|
||||
// wchar_t array vs pointer
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) {
|
||||
wchar_t str[] = L"hi \"world\"";
|
||||
wchar_t* p = NULL;
|
||||
EXPECT_EQ(PrintPointer(str),
|
||||
FormatForComparisonFailureMessage(str, p).c_str());
|
||||
}
|
||||
|
||||
// wchar_t array vs wchar_t array
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) {
|
||||
const wchar_t str[] = L"hi \"world\"";
|
||||
EXPECT_EQ(PrintPointer(str),
|
||||
FormatForComparisonFailureMessage(str, str).c_str());
|
||||
}
|
||||
|
||||
// Tests formatting a char array when it's compared with a string object.
|
||||
// In this case we want to print the array as a C string.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
// char array vs string
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) {
|
||||
const char str[] = "hi \"w\0rld\"";
|
||||
EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped.
|
||||
// Embedded NUL terminates the string.
|
||||
FormatForComparisonFailureMessage(str, ::string()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// char array vs std::string
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) {
|
||||
const char str[] = "hi \"world\"";
|
||||
EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped.
|
||||
FormatForComparisonFailureMessage(str, ::std::string()).c_str());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// wchar_t array vs wstring
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) {
|
||||
const wchar_t str[] = L"hi \"world\"";
|
||||
EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped.
|
||||
FormatForComparisonFailureMessage(str, ::wstring()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// wchar_t array vs std::wstring
|
||||
TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) {
|
||||
const wchar_t str[] = L"hi \"w\0rld\"";
|
||||
EXPECT_STREQ(
|
||||
"L\"hi \\\"w\"", // The content should be escaped.
|
||||
// Embedded NUL terminates the string.
|
||||
FormatForComparisonFailureMessage(str, ::std::wstring()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Useful for testing PrintToString(). We cannot use EXPECT_EQ()
|
||||
// there as its implementation uses PrintToString(). The caller must
|
||||
// ensure that 'value' has no side effect.
|
||||
@@ -1208,11 +1423,35 @@ TEST(PrintToStringTest, WorksForPointerToNonConstChar) {
|
||||
EXPECT_PRINT_TO_STRING_(p, "\"hello\"");
|
||||
}
|
||||
|
||||
TEST(PrintToStringTest, EscapesForPointerToConstChar) {
|
||||
const char* p = "hello\n";
|
||||
EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\"");
|
||||
}
|
||||
|
||||
TEST(PrintToStringTest, EscapesForPointerToNonConstChar) {
|
||||
char s[] = "hello\1";
|
||||
char* p = s;
|
||||
EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\"");
|
||||
}
|
||||
|
||||
TEST(PrintToStringTest, WorksForArray) {
|
||||
int n[3] = { 1, 2, 3 };
|
||||
EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }");
|
||||
}
|
||||
|
||||
TEST(PrintToStringTest, WorksForCharArray) {
|
||||
char s[] = "hello";
|
||||
EXPECT_PRINT_TO_STRING_(s, "\"hello\"");
|
||||
}
|
||||
|
||||
TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
|
||||
const char str_with_nul[] = "hello\0 world";
|
||||
EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\"");
|
||||
|
||||
char mutable_str_with_nul[] = "hello\0 world";
|
||||
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
|
||||
}
|
||||
|
||||
#undef EXPECT_PRINT_TO_STRING_
|
||||
|
||||
TEST(UniversalTersePrintTest, WorksForNonReference) {
|
||||
@@ -1275,6 +1514,17 @@ TEST(UniversalPrintTest, WorksForCString) {
|
||||
EXPECT_EQ("NULL", ss3.str());
|
||||
}
|
||||
|
||||
TEST(UniversalPrintTest, WorksForCharArray) {
|
||||
const char str[] = "\"Line\0 1\"\nLine 2";
|
||||
::std::stringstream ss1;
|
||||
UniversalPrint(str, &ss1);
|
||||
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str());
|
||||
|
||||
const char mutable_str[] = "\"Line\0 1\"\nLine 2";
|
||||
::std::stringstream ss2;
|
||||
UniversalPrint(mutable_str, &ss2);
|
||||
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user