Lots of changes:
* changes the XML report format to match JUnit/Ant's. * improves file path handling. * allows the user to disable RTTI using the GTEST_HAS_RTTI macro. * makes the code compile with -Wswitch-enum.
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
46
src/gtest.cc
46
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 =
|
||||
|
||||
Reference in New Issue
Block a user