Improves gtest's failure messages. In particulars, char pointers and
char arrays are not escapped properly.
This commit is contained in:
		| @@ -630,9 +630,12 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { | ||||
|   } | ||||
| } | ||||
| // This overload prints a (const) char array compactly. | ||||
| GTEST_API_ void UniversalPrintArray(const char* begin, | ||||
|                                     size_t len, | ||||
|                                     ::std::ostream* os); | ||||
| GTEST_API_ void UniversalPrintArray( | ||||
|     const char* begin, size_t len, ::std::ostream* os); | ||||
|  | ||||
| // This overload prints a (const) wchar_t array compactly. | ||||
| GTEST_API_ void UniversalPrintArray( | ||||
|     const wchar_t* begin, size_t len, ::std::ostream* os); | ||||
|  | ||||
| // Implements printing an array type T[N]. | ||||
| template <typename T, size_t N> | ||||
| @@ -673,19 +676,72 @@ class UniversalPrinter<T&> { | ||||
| // Prints a value tersely: for a reference type, the referenced value | ||||
| // (but not the address) is printed; for a (const) char pointer, the | ||||
| // NUL-terminated string (but not the pointer) is printed. | ||||
|  | ||||
| template <typename T> | ||||
| class UniversalTersePrinter { | ||||
|  public: | ||||
|   static void Print(const T& value, ::std::ostream* os) { | ||||
|     UniversalPrint(value, os); | ||||
|   } | ||||
| }; | ||||
| template <typename T> | ||||
| class UniversalTersePrinter<T&> { | ||||
|  public: | ||||
|   static void Print(const T& value, ::std::ostream* os) { | ||||
|     UniversalPrint(value, os); | ||||
|   } | ||||
| }; | ||||
| template <typename T, size_t N> | ||||
| class UniversalTersePrinter<T[N]> { | ||||
|  public: | ||||
|   static void Print(const T (&value)[N], ::std::ostream* os) { | ||||
|     UniversalPrinter<T[N]>::Print(value, os); | ||||
|   } | ||||
| }; | ||||
| template <> | ||||
| class UniversalTersePrinter<const char*> { | ||||
|  public: | ||||
|   static void Print(const char* str, ::std::ostream* os) { | ||||
|     if (str == NULL) { | ||||
|       *os << "NULL"; | ||||
|     } else { | ||||
|       UniversalPrint(string(str), os); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| template <> | ||||
| class UniversalTersePrinter<char*> { | ||||
|  public: | ||||
|   static void Print(char* str, ::std::ostream* os) { | ||||
|     UniversalTersePrinter<const char*>::Print(str, os); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| #if GTEST_HAS_STD_WSTRING | ||||
| template <> | ||||
| class UniversalTersePrinter<const wchar_t*> { | ||||
|  public: | ||||
|   static void Print(const wchar_t* str, ::std::ostream* os) { | ||||
|     if (str == NULL) { | ||||
|       *os << "NULL"; | ||||
|     } else { | ||||
|       UniversalPrint(::std::wstring(str), os); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template <> | ||||
| class UniversalTersePrinter<wchar_t*> { | ||||
|  public: | ||||
|   static void Print(wchar_t* str, ::std::ostream* os) { | ||||
|     UniversalTersePrinter<const wchar_t*>::Print(str, os); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| void UniversalTersePrint(const T& value, ::std::ostream* os) { | ||||
|   UniversalPrint(value, os); | ||||
| } | ||||
| inline void UniversalTersePrint(const char* str, ::std::ostream* os) { | ||||
|   if (str == NULL) { | ||||
|     *os << "NULL"; | ||||
|   } else { | ||||
|     UniversalPrint(string(str), os); | ||||
|   } | ||||
| } | ||||
| inline void UniversalTersePrint(char* str, ::std::ostream* os) { | ||||
|   UniversalTersePrint(static_cast<const char*>(str), os); | ||||
|   UniversalTersePrinter<T>::Print(value, os); | ||||
| } | ||||
|  | ||||
| // Prints a value using the type inferred by the compiler.  The | ||||
| @@ -790,7 +846,7 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { | ||||
| template <typename T> | ||||
| ::std::string PrintToString(const T& value) { | ||||
|   ::std::stringstream ss; | ||||
|   internal::UniversalTersePrint(value, &ss); | ||||
|   internal::UniversalTersePrinter<T>::Print(value, &ss); | ||||
|   return ss.str(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1291,24 +1291,101 @@ GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a | ||||
| // value of type ToPrint that is an operand of a comparison assertion | ||||
| // (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in | ||||
| // the comparison, and is used to help determine the best way to | ||||
| // format the value.  In particular, when the value is a C string | ||||
| // (char pointer) and the other operand is an STL string object, we | ||||
| // want to format the C string as a string, since we know it is | ||||
| // compared by value with the string object.  If the value is a char | ||||
| // pointer but the other operand is not an STL string object, we don't | ||||
| // know whether the pointer is supposed to point to a NUL-terminated | ||||
| // string, and thus want to print it as a pointer to be safe. | ||||
| // | ||||
| // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. | ||||
|  | ||||
| // The default case. | ||||
| template <typename ToPrint, typename OtherOperand> | ||||
| class FormatForComparison { | ||||
|  public: | ||||
|   static ::std::string Format(const ToPrint& value) { | ||||
|     return ::testing::PrintToString(value); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Array. | ||||
| template <typename ToPrint, size_t N, typename OtherOperand> | ||||
| class FormatForComparison<ToPrint[N], OtherOperand> { | ||||
|  public: | ||||
|   static ::std::string Format(const ToPrint* value) { | ||||
|     return FormatForComparison<const ToPrint*, OtherOperand>::Format(value); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // By default, print C string as pointers to be safe, as we don't know | ||||
| // whether they actually point to a NUL-terminated string. | ||||
|  | ||||
| #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \ | ||||
|   template <typename OtherOperand>                                      \ | ||||
|   class FormatForComparison<CharType*, OtherOperand> {                  \ | ||||
|    public:                                                              \ | ||||
|     static ::std::string Format(CharType* value) {                      \ | ||||
|       return ::testing::PrintToString(static_cast<const void*>(value)); \ | ||||
|     }                                                                   \ | ||||
|   } | ||||
|  | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); | ||||
|  | ||||
| #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ | ||||
|  | ||||
| // If a C string is compared with an STL string object, we know it's meant | ||||
| // to point to a NUL-terminated string, and thus can print it as a string. | ||||
|  | ||||
| #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ | ||||
|   template <>                                                           \ | ||||
|   class FormatForComparison<CharType*, OtherStringType> {               \ | ||||
|    public:                                                              \ | ||||
|     static ::std::string Format(CharType* value) {                      \ | ||||
|       return ::testing::PrintToString(value);                           \ | ||||
|     }                                                                   \ | ||||
|   } | ||||
|  | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); | ||||
|  | ||||
| #if GTEST_HAS_GLOBAL_STRING | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); | ||||
| #endif | ||||
|  | ||||
| #if GTEST_HAS_GLOBAL_WSTRING | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); | ||||
| #endif | ||||
|  | ||||
| #if GTEST_HAS_STD_WSTRING | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); | ||||
| GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); | ||||
| #endif | ||||
|  | ||||
| #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ | ||||
|  | ||||
| // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) | ||||
| // operand to be used in a failure message.  The type (but not value) | ||||
| // of the other operand may affect the format.  This allows us to | ||||
| // print a char* as a raw pointer when it is compared against another | ||||
| // char*, and print it as a C string when it is compared against an | ||||
| // std::string object, for example. | ||||
| // | ||||
| // The default implementation ignores the type of the other operand. | ||||
| // Some specialized versions are used to handle formatting wide or | ||||
| // narrow C strings. | ||||
| // char* or void*, and print it as a C string when it is compared | ||||
| // against an std::string object, for example. | ||||
| // | ||||
| // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. | ||||
| template <typename T1, typename T2> | ||||
| String FormatForComparisonFailureMessage(const T1& value, | ||||
|                                          const T2& /* other_operand */) { | ||||
|   // C++Builder compiles this incorrectly if the namespace isn't explicitly | ||||
|   // given. | ||||
|   return ::testing::PrintToString(value); | ||||
|   return FormatForComparison<T1, T2>::Format(value); | ||||
| } | ||||
|  | ||||
| // The helper function for {ASSERT|EXPECT}_EQ. | ||||
| @@ -1320,7 +1397,7 @@ AssertionResult CmpHelperEQ(const char* expected_expression, | ||||
| #ifdef _MSC_VER | ||||
| # pragma warning(push)          // Saves the current warning state. | ||||
| # pragma warning(disable:4389)  // Temporarily disables warning on | ||||
|                                // signed/unsigned mismatch. | ||||
|                                 // signed/unsigned mismatch. | ||||
| #endif | ||||
|  | ||||
|   if (expected == actual) { | ||||
|   | ||||
| @@ -195,67 +195,6 @@ class GTEST_API_ ScopedTrace { | ||||
| template <typename T> | ||||
| String StreamableToString(const T& streamable); | ||||
|  | ||||
| // The Symbian compiler has a bug that prevents it from selecting the | ||||
| // correct overload of FormatForComparisonFailureMessage (see below) | ||||
| // unless we pass the first argument by reference.  If we do that, | ||||
| // however, Visual Age C++ 10.1 generates a compiler error.  Therefore | ||||
| // we only apply the work-around for Symbian. | ||||
| #if defined(__SYMBIAN32__) | ||||
| # define GTEST_CREF_WORKAROUND_ const& | ||||
| #else | ||||
| # define GTEST_CREF_WORKAROUND_ | ||||
| #endif | ||||
|  | ||||
| // When this operand is a const char* or char*, if the other operand | ||||
| // is a ::std::string or ::string, we print this operand as a C string | ||||
| // rather than a pointer (we do the same for wide strings); otherwise | ||||
| // we print it as a pointer to be safe. | ||||
|  | ||||
| // This internal macro is used to avoid duplicated code. | ||||
| #define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ | ||||
| inline String FormatForComparisonFailureMessage(\ | ||||
|     operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ | ||||
|     const operand2_type& /*operand2*/) {\ | ||||
|   return operand1_printer(str);\ | ||||
| }\ | ||||
| inline String FormatForComparisonFailureMessage(\ | ||||
|     const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ | ||||
|     const operand2_type& /*operand2*/) {\ | ||||
|   return operand1_printer(str);\ | ||||
| } | ||||
|  | ||||
| GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) | ||||
| #if GTEST_HAS_STD_WSTRING | ||||
| GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) | ||||
| #endif  // GTEST_HAS_STD_WSTRING | ||||
|  | ||||
| #if GTEST_HAS_GLOBAL_STRING | ||||
| GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) | ||||
| #endif  // GTEST_HAS_GLOBAL_STRING | ||||
| #if GTEST_HAS_GLOBAL_WSTRING | ||||
| GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) | ||||
| #endif  // GTEST_HAS_GLOBAL_WSTRING | ||||
|  | ||||
| #undef GTEST_FORMAT_IMPL_ | ||||
|  | ||||
| // The next four overloads handle the case where the operand being | ||||
| // printed is a char/wchar_t pointer and the other operand is not a | ||||
| // string/wstring object.  In such cases, we just print the operand as | ||||
| // a pointer to be safe. | ||||
| #define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType)                       \ | ||||
|   template <typename T>                                             \ | ||||
|   String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \ | ||||
|                                            const T&) { \ | ||||
|     return PrintToString(static_cast<const void*>(p));              \ | ||||
|   } | ||||
|  | ||||
| GTEST_FORMAT_CHAR_PTR_IMPL_(char) | ||||
| GTEST_FORMAT_CHAR_PTR_IMPL_(const char) | ||||
| GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t) | ||||
| GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t) | ||||
|  | ||||
| #undef GTEST_FORMAT_CHAR_PTR_IMPL_ | ||||
|  | ||||
| // Constructs and returns the message for an equality assertion | ||||
| // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. | ||||
| // | ||||
|   | ||||
| @@ -1585,6 +1585,10 @@ inline bool IsUpper(char ch) { | ||||
| inline bool IsXDigit(char ch) { | ||||
|   return isxdigit(static_cast<unsigned char>(ch)) != 0; | ||||
| } | ||||
| inline bool IsXDigit(wchar_t ch) { | ||||
|   const unsigned char low_byte = static_cast<unsigned char>(ch); | ||||
|   return ch == low_byte && isxdigit(low_byte) != 0; | ||||
| } | ||||
|  | ||||
| inline char ToLower(char ch) { | ||||
|   return static_cast<char>(tolower(static_cast<unsigned char>(ch))); | ||||
|   | ||||
| @@ -82,15 +82,6 @@ class GTEST_API_ String { | ||||
|  public: | ||||
|   // Static utility methods | ||||
|  | ||||
|   // Returns the input enclosed in double quotes if it's not NULL; | ||||
|   // otherwise returns "(null)".  For example, "\"Hello\"" is returned | ||||
|   // for input "Hello". | ||||
|   // | ||||
|   // This is useful for printing a C string in the syntax of a literal. | ||||
|   // | ||||
|   // Known issue: escape sequences are not handled yet. | ||||
|   static String ShowCStringQuoted(const char* c_str); | ||||
|  | ||||
|   // Clones a 0-terminated C string, allocating memory using new.  The | ||||
|   // caller is responsible for deleting the return value using | ||||
|   // delete[].  Returns the cloned string, or NULL if the input is | ||||
| @@ -139,10 +130,6 @@ class GTEST_API_ String { | ||||
|   // returned. | ||||
|   static String ShowWideCString(const wchar_t* wide_c_str); | ||||
|  | ||||
|   // Similar to ShowWideCString(), except that this function encloses | ||||
|   // the converted string in double quotes. | ||||
|   static String ShowWideCStringQuoted(const wchar_t* wide_c_str); | ||||
|  | ||||
|   // Compares two wide C strings.  Returns true iff they have the same | ||||
|   // content. | ||||
|   // | ||||
|   | ||||
| @@ -183,9 +183,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { | ||||
|   return kSpecialEscape; | ||||
| } | ||||
|  | ||||
| // Prints a char c as if it's part of a string literal, escaping it when | ||||
| // Prints a wchar_t c as if it's part of a string literal, escaping it when | ||||
| // necessary; returns how c was formatted. | ||||
| static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { | ||||
| static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { | ||||
|   switch (c) { | ||||
|     case L'\'': | ||||
|       *os << "'"; | ||||
| @@ -200,8 +200,9 @@ static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { | ||||
|  | ||||
| // Prints a char c as if it's part of a string literal, escaping it when | ||||
| // necessary; returns how c was formatted. | ||||
| static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { | ||||
|   return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os); | ||||
| static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { | ||||
|   return PrintAsStringLiteralTo( | ||||
|       static_cast<wchar_t>(static_cast<unsigned char>(c)), os); | ||||
| } | ||||
|  | ||||
| // Prints a wide or narrow character c and its code.  '\0' is printed | ||||
| @@ -247,48 +248,63 @@ void PrintTo(wchar_t wc, ostream* os) { | ||||
|   PrintCharAndCodeTo<wchar_t>(wc, os); | ||||
| } | ||||
|  | ||||
| // Prints the given array of characters to the ostream. | ||||
| // The array starts at *begin, the length is len, it may include '\0' characters | ||||
| // and may not be null-terminated. | ||||
| static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { | ||||
|   *os << "\""; | ||||
| // Prints the given array of characters to the ostream.  CharType must be either | ||||
| // char or wchar_t. | ||||
| // The array starts at begin, the length is len, it may include '\0' characters | ||||
| // and may not be NUL-terminated. | ||||
| template <typename CharType> | ||||
| static void PrintCharsAsStringTo( | ||||
|     const CharType* begin, size_t len, ostream* os) { | ||||
|   const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; | ||||
|   *os << kQuoteBegin; | ||||
|   bool is_previous_hex = false; | ||||
|   for (size_t index = 0; index < len; ++index) { | ||||
|     const char cur = begin[index]; | ||||
|     const CharType cur = begin[index]; | ||||
|     if (is_previous_hex && IsXDigit(cur)) { | ||||
|       // Previous character is of '\x..' form and this character can be | ||||
|       // interpreted as another hexadecimal digit in its number. Break string to | ||||
|       // disambiguate. | ||||
|       *os << "\" \""; | ||||
|       *os << "\" " << kQuoteBegin; | ||||
|     } | ||||
|     is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; | ||||
|     is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; | ||||
|   } | ||||
|   *os << "\""; | ||||
| } | ||||
|  | ||||
| // Prints a (const) char/wchar_t array of 'len' elements, starting at address | ||||
| // 'begin'.  CharType must be either char or wchar_t. | ||||
| template <typename CharType> | ||||
| static void UniversalPrintCharArray( | ||||
|     const CharType* begin, size_t len, ostream* os) { | ||||
|   // The code | ||||
|   //   const char kFoo[] = "foo"; | ||||
|   // generates an array of 4, not 3, elements, with the last one being '\0'. | ||||
|   // | ||||
|   // Therefore when printing a char array, we don't print the last element if | ||||
|   // it's '\0', such that the output matches the string literal as it's | ||||
|   // written in the source code. | ||||
|   if (len > 0 && begin[len - 1] == '\0') { | ||||
|     PrintCharsAsStringTo(begin, len - 1, os); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // If, however, the last element in the array is not '\0', e.g. | ||||
|   //    const char kFoo[] = { 'f', 'o', 'o' }; | ||||
|   // we must print the entire array.  We also print a message to indicate | ||||
|   // that the array is not NUL-terminated. | ||||
|   PrintCharsAsStringTo(begin, len, os); | ||||
|   *os << " (no terminating NUL)"; | ||||
| } | ||||
|  | ||||
| // Prints a (const) char array of 'len' elements, starting at address 'begin'. | ||||
| void UniversalPrintArray(const char* begin, size_t len, ostream* os) { | ||||
|   PrintCharsAsStringTo(begin, len, os); | ||||
|   UniversalPrintCharArray(begin, len, os); | ||||
| } | ||||
|  | ||||
| // Prints the given array of wide characters to the ostream. | ||||
| // The array starts at *begin, the length is len, it may include L'\0' | ||||
| // characters and may not be null-terminated. | ||||
| static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, | ||||
|                                      ostream* os) { | ||||
|   *os << "L\""; | ||||
|   bool is_previous_hex = false; | ||||
|   for (size_t index = 0; index < len; ++index) { | ||||
|     const wchar_t cur = begin[index]; | ||||
|     if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) { | ||||
|       // Previous character is of '\x..' form and this character can be | ||||
|       // interpreted as another hexadecimal digit in its number. Break string to | ||||
|       // disambiguate. | ||||
|       *os << "\" L\""; | ||||
|     } | ||||
|     is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape; | ||||
|   } | ||||
|   *os << "\""; | ||||
| // Prints a (const) wchar_t array of 'len' elements, starting at address | ||||
| // 'begin'. | ||||
| void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { | ||||
|   UniversalPrintCharArray(begin, len, os); | ||||
| } | ||||
|  | ||||
| // Prints the given C string to the ostream. | ||||
| @@ -314,7 +330,7 @@ void PrintTo(const wchar_t* s, ostream* os) { | ||||
|     *os << "NULL"; | ||||
|   } else { | ||||
|     *os << ImplicitCast_<const void*>(s) << " pointing to "; | ||||
|     PrintWideCharsAsStringTo(s, wcslen(s), os); | ||||
|     PrintCharsAsStringTo(s, wcslen(s), os); | ||||
|   } | ||||
| } | ||||
| #endif  // wchar_t is native | ||||
| @@ -333,13 +349,13 @@ void PrintStringTo(const ::std::string& s, ostream* os) { | ||||
| // Prints a ::wstring object. | ||||
| #if GTEST_HAS_GLOBAL_WSTRING | ||||
| void PrintWideStringTo(const ::wstring& s, ostream* os) { | ||||
|   PrintWideCharsAsStringTo(s.data(), s.size(), os); | ||||
|   PrintCharsAsStringTo(s.data(), s.size(), os); | ||||
| } | ||||
| #endif  // GTEST_HAS_GLOBAL_WSTRING | ||||
|  | ||||
| #if GTEST_HAS_STD_WSTRING | ||||
| void PrintWideStringTo(const ::std::wstring& s, ostream* os) { | ||||
|   PrintWideCharsAsStringTo(s.data(), s.size(), os); | ||||
|   PrintCharsAsStringTo(s.data(), s.size(), os); | ||||
| } | ||||
| #endif  // GTEST_HAS_STD_WSTRING | ||||
|  | ||||
|   | ||||
							
								
								
									
										36
									
								
								src/gtest.cc
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								src/gtest.cc
									
									
									
									
									
								
							| @@ -818,17 +818,6 @@ TimeInMillis GetTimeInMillis() { | ||||
|  | ||||
| // class String | ||||
|  | ||||
| // Returns the input enclosed in double quotes if it's not NULL; | ||||
| // otherwise returns "(null)".  For example, "\"Hello\"" is returned | ||||
| // for input "Hello". | ||||
| // | ||||
| // This is useful for printing a C string in the syntax of a literal. | ||||
| // | ||||
| // Known issue: escape sequences are not handled yet. | ||||
| String String::ShowCStringQuoted(const char* c_str) { | ||||
|   return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); | ||||
| } | ||||
|  | ||||
| // Copies at most length characters from str into a newly-allocated | ||||
| // piece of memory of size length+1.  The memory is allocated with new[]. | ||||
| // A terminating null byte is written to the memory, and a pointer to it | ||||
| @@ -1169,8 +1158,8 @@ AssertionResult CmpHelperSTREQ(const char* expected_expression, | ||||
|  | ||||
|   return EqFailure(expected_expression, | ||||
|                    actual_expression, | ||||
|                    String::ShowCStringQuoted(expected), | ||||
|                    String::ShowCStringQuoted(actual), | ||||
|                    PrintToString(expected), | ||||
|                    PrintToString(actual), | ||||
|                    false); | ||||
| } | ||||
|  | ||||
| @@ -1185,8 +1174,8 @@ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, | ||||
|  | ||||
|   return EqFailure(expected_expression, | ||||
|                    actual_expression, | ||||
|                    String::ShowCStringQuoted(expected), | ||||
|                    String::ShowCStringQuoted(actual), | ||||
|                    PrintToString(expected), | ||||
|                    PrintToString(actual), | ||||
|                    true); | ||||
| } | ||||
|  | ||||
| @@ -1534,15 +1523,6 @@ String String::ShowWideCString(const wchar_t * wide_c_str) { | ||||
|   return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); | ||||
| } | ||||
|  | ||||
| // Similar to ShowWideCString(), except that this function encloses | ||||
| // the converted string in double quotes. | ||||
| String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { | ||||
|   if (wide_c_str == NULL) return String("(null)"); | ||||
|  | ||||
|   return String::Format("L\"%s\"", | ||||
|                         String::ShowWideCString(wide_c_str).c_str()); | ||||
| } | ||||
|  | ||||
| // Compares two wide C strings.  Returns true iff they have the same | ||||
| // content. | ||||
| // | ||||
| @@ -1568,8 +1548,8 @@ AssertionResult CmpHelperSTREQ(const char* expected_expression, | ||||
|  | ||||
|   return EqFailure(expected_expression, | ||||
|                    actual_expression, | ||||
|                    String::ShowWideCStringQuoted(expected), | ||||
|                    String::ShowWideCStringQuoted(actual), | ||||
|                    PrintToString(expected), | ||||
|                    PrintToString(actual), | ||||
|                    false); | ||||
| } | ||||
|  | ||||
| @@ -1584,8 +1564,8 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, | ||||
|  | ||||
|   return AssertionFailure() << "Expected: (" << s1_expression << ") != (" | ||||
|                             << s2_expression << "), actual: " | ||||
|                             << String::ShowWideCStringQuoted(s1) | ||||
|                             << " vs " << String::ShowWideCStringQuoted(s2); | ||||
|                             << PrintToString(s1) | ||||
|                             << " vs " << PrintToString(s2); | ||||
| } | ||||
|  | ||||
| // Compares two C strings, ignoring case.  Returns true iff they have | ||||
|   | ||||
| @@ -61,6 +61,43 @@ using std::pair; | ||||
| namespace testing { | ||||
| namespace internal { | ||||
|  | ||||
| TEST(IsXDigitTest, WorksForNarrowAscii) { | ||||
|   EXPECT_TRUE(IsXDigit('0')); | ||||
|   EXPECT_TRUE(IsXDigit('9')); | ||||
|   EXPECT_TRUE(IsXDigit('A')); | ||||
|   EXPECT_TRUE(IsXDigit('F')); | ||||
|   EXPECT_TRUE(IsXDigit('a')); | ||||
|   EXPECT_TRUE(IsXDigit('f')); | ||||
|  | ||||
|   EXPECT_FALSE(IsXDigit('-')); | ||||
|   EXPECT_FALSE(IsXDigit('g')); | ||||
|   EXPECT_FALSE(IsXDigit('G')); | ||||
| } | ||||
|  | ||||
| TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { | ||||
|   EXPECT_FALSE(IsXDigit(static_cast<char>(0x80))); | ||||
|   EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80))); | ||||
| } | ||||
|  | ||||
| TEST(IsXDigitTest, WorksForWideAscii) { | ||||
|   EXPECT_TRUE(IsXDigit(L'0')); | ||||
|   EXPECT_TRUE(IsXDigit(L'9')); | ||||
|   EXPECT_TRUE(IsXDigit(L'A')); | ||||
|   EXPECT_TRUE(IsXDigit(L'F')); | ||||
|   EXPECT_TRUE(IsXDigit(L'a')); | ||||
|   EXPECT_TRUE(IsXDigit(L'f')); | ||||
|  | ||||
|   EXPECT_FALSE(IsXDigit(L'-')); | ||||
|   EXPECT_FALSE(IsXDigit(L'g')); | ||||
|   EXPECT_FALSE(IsXDigit(L'G')); | ||||
| } | ||||
|  | ||||
| TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { | ||||
|   EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(0x80))); | ||||
|   EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x80))); | ||||
|   EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x100))); | ||||
| } | ||||
|  | ||||
| class Base { | ||||
|  public: | ||||
|   // Copy constructor and assignment operator do exactly what we need, so we | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -27,8 +27,11 @@ | ||||
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // A unit test for Google Test itself.  This verifies that the basic | ||||
| // constructs of Google Test work. | ||||
| // The purpose of this file is to generate Google Test output under | ||||
| // various conditions.  The output will then be verified by | ||||
| // gtest_output_test.py to ensure that Google Test generates the | ||||
| // desired messages.  Therefore, most tests in this file are MEANT TO | ||||
| // FAIL. | ||||
| // | ||||
| // Author: wan@google.com (Zhanyong Wan) | ||||
|  | ||||
| @@ -101,6 +104,16 @@ INSTANTIATE_TEST_CASE_P(PrintingFailingParams, | ||||
|                         FailingParamTest, | ||||
|                         testing::Values(2)); | ||||
|  | ||||
| static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; | ||||
|  | ||||
| TEST(NonfatalFailureTest, EscapesStringOperands) { | ||||
|   std::string actual = "actual \"string\""; | ||||
|   EXPECT_EQ(kGoldenString, actual); | ||||
|  | ||||
|   const char* golden = kGoldenString; | ||||
|   EXPECT_EQ(golden, actual); | ||||
| } | ||||
|  | ||||
| // Tests catching a fatal failure in a subroutine. | ||||
| TEST(FatalFailureTest, FatalFailureInSubroutine) { | ||||
|   printf("(expecting a failure that x should be 1)\n"); | ||||
|   | ||||
| @@ -7,7 +7,7 @@ Expected: true | ||||
| gtest_output_test_.cc:#: Failure | ||||
| Value of: 3 | ||||
| Expected: 2 | ||||
| [0;32m[==========] [mRunning 62 tests from 27 test cases. | ||||
| [0;32m[==========] [mRunning 63 tests from 28 test cases. | ||||
| [0;32m[----------] [mGlobal test environment set-up. | ||||
| FooEnvironment::SetUp() called. | ||||
| BarEnvironment::SetUp() called. | ||||
| @@ -31,6 +31,19 @@ BarEnvironment::SetUp() called. | ||||
| [0;32m[       OK ] [mPassingTest.PassingTest1 | ||||
| [0;32m[ RUN      ] [mPassingTest.PassingTest2 | ||||
| [0;32m[       OK ] [mPassingTest.PassingTest2 | ||||
| [0;32m[----------] [m1 test from NonfatalFailureTest | ||||
| [0;32m[ RUN      ] [mNonfatalFailureTest.EscapesStringOperands | ||||
| gtest_output_test_.cc:#: Failure | ||||
| Value of: actual | ||||
|   Actual: "actual \"string\"" | ||||
| Expected: kGoldenString | ||||
| Which is: "\"Line" | ||||
| gtest_output_test_.cc:#: Failure | ||||
| Value of: actual | ||||
|   Actual: "actual \"string\"" | ||||
| Expected: golden | ||||
| Which is: "\"Line" | ||||
| [0;31m[  FAILED  ] [mNonfatalFailureTest.EscapesStringOperands | ||||
| [0;32m[----------] [m3 tests from FatalFailureTest | ||||
| [0;32m[ RUN      ] [mFatalFailureTest.FatalFailureInSubroutine | ||||
| (expecting a failure that x should be 1) | ||||
| @@ -586,9 +599,10 @@ FooEnvironment::TearDown() called. | ||||
| gtest_output_test_.cc:#: Failure | ||||
| Failed | ||||
| Expected fatal failure. | ||||
| [0;32m[==========] [m62 tests from 27 test cases ran. | ||||
| [0;32m[==========] [m63 tests from 28 test cases ran. | ||||
| [0;32m[  PASSED  ] [m21 tests. | ||||
| [0;31m[  FAILED  ] [m41 tests, listed below: | ||||
| [0;31m[  FAILED  ] [m42 tests, listed below: | ||||
| [0;31m[  FAILED  ] [mNonfatalFailureTest.EscapesStringOperands | ||||
| [0;31m[  FAILED  ] [mFatalFailureTest.FatalFailureInSubroutine | ||||
| [0;31m[  FAILED  ] [mFatalFailureTest.FatalFailureInNestedSubroutine | ||||
| [0;31m[  FAILED  ] [mFatalFailureTest.NonfatalFailureInSubroutine | ||||
| @@ -631,7 +645,7 @@ Expected fatal failure. | ||||
| [0;31m[  FAILED  ] [mScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread | ||||
| [0;31m[  FAILED  ] [mPrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 | ||||
|  | ||||
| 41 FAILED TESTS | ||||
| 42 FAILED TESTS | ||||
| [0;33m  YOU HAVE 1 DISABLED TEST | ||||
|  | ||||
| [mNote: Google Test filter = FatalFailureTest.*:LoggingTest.* | ||||
|   | ||||
| @@ -1065,16 +1065,6 @@ TEST(StringTest, ConvertsToGlobalString) { | ||||
|  | ||||
| #endif  // GTEST_HAS_GLOBAL_STRING | ||||
|  | ||||
| // Tests String::ShowCStringQuoted(). | ||||
| TEST(StringTest, ShowCStringQuoted) { | ||||
|   EXPECT_STREQ("(null)", | ||||
|                String::ShowCStringQuoted(NULL).c_str()); | ||||
|   EXPECT_STREQ("\"\"", | ||||
|                String::ShowCStringQuoted("").c_str()); | ||||
|   EXPECT_STREQ("\"foo\"", | ||||
|                String::ShowCStringQuoted("foo").c_str()); | ||||
| } | ||||
|  | ||||
| // Tests String::empty(). | ||||
| TEST(StringTest, Empty) { | ||||
|   EXPECT_TRUE(String("").empty()); | ||||
| @@ -1305,16 +1295,6 @@ TEST(StringTest, ShowWideCString) { | ||||
|   EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); | ||||
| } | ||||
|  | ||||
| // Tests String::ShowWideCStringQuoted(). | ||||
| TEST(StringTest, ShowWideCStringQuoted) { | ||||
|   EXPECT_STREQ("(null)", | ||||
|                String::ShowWideCStringQuoted(NULL).c_str()); | ||||
|   EXPECT_STREQ("L\"\"", | ||||
|                String::ShowWideCStringQuoted(L"").c_str()); | ||||
|   EXPECT_STREQ("L\"foo\"", | ||||
|                String::ShowWideCStringQuoted(L"foo").c_str()); | ||||
| } | ||||
|  | ||||
| # if GTEST_OS_WINDOWS_MOBILE | ||||
| TEST(StringTest, AnsiAndUtf16Null) { | ||||
|   EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 zhanyong.wan
					zhanyong.wan