diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gtest-death-test.cc | 1 | ||||
| -rw-r--r-- | src/gtest-filepath.cc | 54 | ||||
| -rw-r--r-- | src/gtest.cc | 46 | 
3 files changed, 87 insertions, 14 deletions
| diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index 971c3005..fa800879 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -416,6 +416,7 @@ bool ForkingDeathTest::Passed(bool status_ok) {                 << "            " << ExitSummary(status_) << "\n";        }        break; +    case IN_PROGRESS:      default:        GTEST_LOG(FATAL,                  "DeathTest::Passed somehow called before conclusion of test"); diff --git a/src/gtest-filepath.cc b/src/gtest-filepath.cc index 2a5be8ce..dc0d78f0 100644 --- a/src/gtest-filepath.cc +++ b/src/gtest-filepath.cc @@ -161,10 +161,13 @@ bool FilePath::FileOrDirectoryExists() const {  // that exists.  bool FilePath::DirectoryExists() const {    bool result = false; -#ifdef _WIN32 -  FilePath removed_sep(this->RemoveTrailingPathSeparator()); +#ifdef GTEST_OS_WINDOWS +  // Don't strip off trailing separator if path is a root directory on +  // Windows (like "C:\\"). +  const FilePath& path(IsRootDirectory() ? *this : +                                           RemoveTrailingPathSeparator());  #ifdef _WIN32_WCE -  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); +  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());    const DWORD attributes = GetFileAttributes(unicode);    delete [] unicode;    if ((attributes != kInvalidFileAttributes) && @@ -173,17 +176,32 @@ bool FilePath::DirectoryExists() const {    }  #else    struct _stat file_stat = {}; -  result = _stat(removed_sep.c_str(), &file_stat) == 0 && +  result = _stat(path.c_str(), &file_stat) == 0 &&        (_S_IFDIR & file_stat.st_mode) != 0;  #endif  // _WIN32_WCE  #else    struct stat file_stat = {};    result = stat(pathname_.c_str(), &file_stat) == 0 &&        S_ISDIR(file_stat.st_mode); -#endif  // _WIN32 +#endif  // GTEST_OS_WINDOWS    return result;  } +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#ifdef GTEST_OS_WINDOWS +  const char* const name = pathname_.c_str(); +  return pathname_.GetLength() == 3 && +     ((name[0] >= 'a' && name[0] <= 'z') || +      (name[0] >= 'A' && name[0] <= 'Z')) && +     name[1] == ':' && +     name[2] == kPathSeparator; +#else +  return pathname_ == kPathSeparatorString; +#endif +} +  // Returns a pathname for a file that does not currently exist. The pathname  // will be directory/base_name.extension or  // directory/base_name_<number>.extension if directory/base_name.extension @@ -258,5 +276,31 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {        : *this;  } +// Normalize removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +void FilePath::Normalize() { +  if (pathname_.c_str() == NULL) { +    pathname_ = ""; +    return; +  } +  const char* src = pathname_.c_str(); +  char* const dest = new char[pathname_.GetLength() + 1]; +  char* dest_ptr = dest; +  memset(dest_ptr, 0, pathname_.GetLength() + 1); + +  while (*src != '\0') { +    *dest_ptr++ = *src; +    if (*src != kPathSeparator) +      src++; +    else +      while (*src == kPathSeparator) +        src++; +  } +  *dest_ptr = '\0'; +  pathname_ = dest; +  delete[] dest; +} +  }  // namespace internal  }  // namespace testing diff --git a/src/gtest.cc b/src/gtest.cc index 8d2d2a2a..f8c11997 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -134,6 +134,10 @@ static const char kUniversalFilter[] = "*";  // The default output file for XML output.  static const char kDefaultOutputFile[] = "test_detail.xml"; +// The text used in failure messages to indicate the start of the +// stack trace. +static const char kStackTraceMarker[] = "\nStack trace:\n"; +  GTEST_DEFINE_bool(      break_on_failure,      internal::BoolFromGTestEnv("break_on_failure", false), @@ -200,6 +204,14 @@ GTEST_DEFINE_bool(      "True iff " GTEST_NAME " should include internal stack frames when "      "printing test failure stack traces."); +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { +  const char* const stack_trace = strstr(message, kStackTraceMarker); +  return stack_trace == NULL ? internal::String(message) : +      internal::String(message, stack_trace - message); +} +  namespace internal {  // GTestIsInitialized() returns true iff the user has initialized @@ -2923,13 +2935,28 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,  // <testsuite name="AllTests">         <-- corresponds to a UnitTest object  //   <testsuite name="testcase-name">  <-- corresponds to a TestCase object  //     <testcase name="test-name">     <-- corresponds to a TestInfo object -//       <failure message="..." /> -//       <failure message="..." />     <-- individual assertion failures -//       <failure message="..." /> +//       <failure message="...">...</failure> +//       <failure message="...">...</failure> +//       <failure message="...">...</failure> +//                                     <-- individual assertion failures  //     </testcase>  //   </testsuite>  // </testsuite> +namespace internal { + +// Formats the given time in milliseconds as seconds.  The returned +// C-string is owned by this function and cannot be released by the +// caller.  Calling the function again invalidates the previous +// result. +const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) { +  static String str; +  str = (Message() << (ms/1000.0)).GetString(); +  return str.c_str(); +} + +}  // namespace internal +  // Prints an XML representation of a TestInfo object.  // TODO(wan): There is also value in printing properties with the plain printer.  void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, @@ -2942,7 +2969,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,            "classname=\"%s\"%s",            EscapeXmlAttribute(test_info->name()).c_str(),            test_info->should_run() ? "run" : "notrun", -          internal::StreamableToString(result->elapsed_time()).c_str(), +          internal::FormatTimeInMillisAsSeconds(result->elapsed_time()),            EscapeXmlAttribute(test_case_name).c_str(),            TestPropertiesAsXmlAttributes(result).c_str()); @@ -2958,8 +2985,9 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,        if (++failures == 1)          fprintf(out, ">\n");        fprintf(out, -              "      <failure message=\"%s\" type=\"\"/>\n", -              EscapeXmlAttribute(message.c_str()).c_str()); +              "      <failure message=\"%s\" type=\"\"><![CDATA[%s]]>" +              "</failure>\n", +              EscapeXmlAttribute(part.summary()).c_str(), message.c_str());      }    } @@ -2981,7 +3009,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,            test_case->disabled_test_count());    fprintf(out,            "errors=\"0\" time=\"%s\">\n", -          internal::StreamableToString(test_case->elapsed_time()).c_str()); +          internal::FormatTimeInMillisAsSeconds(test_case->elapsed_time()));    for (const internal::ListNode<TestInfo*>* info_node =           test_case->test_info_list().Head();         info_node != NULL; @@ -3002,7 +3030,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,            impl->total_test_count(),            impl->failed_test_count(),            impl->disabled_test_count(), -          internal::StreamableToString(impl->elapsed_time()).c_str()); +          internal::FormatTimeInMillisAsSeconds(impl->elapsed_time()));    fprintf(out, "name=\"AllTests\">\n");    for (const internal::ListNode<TestCase*>* case_node =         impl->test_cases()->Head(); @@ -3153,7 +3181,7 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type,    }    if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { -    msg << "\nStack trace:\n" << os_stack_trace; +    msg << kStackTraceMarker << os_stack_trace;    }    const TestPartResult result = | 
