aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gtest-death-test.cc25
-rw-r--r--src/gtest-internal-inl.h4
-rw-r--r--src/gtest.cc127
3 files changed, 104 insertions, 52 deletions
diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc
index bf4cbc67..106b01c7 100644
--- a/src/gtest-death-test.cc
+++ b/src/gtest-death-test.cc
@@ -220,12 +220,12 @@ void DeathTestAbort(const String& message) {
// fails.
#define GTEST_DEATH_TEST_CHECK_(expression) \
do { \
- if (!(expression)) { \
- DeathTestAbort(::testing::internal::String::Format(\
+ if (!::testing::internal::IsTrue(expression)) { \
+ DeathTestAbort(::testing::internal::String::Format( \
"CHECK failed: File %s, line %d: %s", \
__FILE__, __LINE__, #expression)); \
} \
- } while (0)
+ } while (::testing::internal::AlwaysFalse())
// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
// evaluating any system call that fulfills two conditions: it must return
@@ -241,11 +241,11 @@ void DeathTestAbort(const String& message) {
gtest_retval = (expression); \
} while (gtest_retval == -1 && errno == EINTR); \
if (gtest_retval == -1) { \
- DeathTestAbort(::testing::internal::String::Format(\
+ DeathTestAbort(::testing::internal::String::Format( \
"CHECK failed: File %s, line %d: %s != -1", \
__FILE__, __LINE__, #expression)); \
} \
- } while (0)
+ } while (::testing::internal::AlwaysFalse())
// Returns the message describing the last system error in errno.
String GetLastErrnoDescription() {
@@ -581,8 +581,8 @@ int WindowsDeathTest::Wait() {
WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
INFINITE));
DWORD status;
- GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(),
- &status));
+ GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+ != FALSE);
child_handle_.Reset();
set_status(static_cast<int>(status));
return this->status();
@@ -612,9 +612,10 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
SECURITY_ATTRIBUTES handles_are_inheritable = {
sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE read_handle, write_handle;
- GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,
- &handles_are_inheritable,
- 0)); // Default buffer size.
+ GTEST_DEATH_TEST_CHECK_(
+ ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+ 0) // Default buffer size.
+ != FALSE);
set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
O_RDONLY));
write_handle_.Reset(write_handle);
@@ -677,7 +678,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
NULL, // Inherit the parent's environment.
UnitTest::GetInstance()->original_working_dir(),
&startup_info,
- &process_info));
+ &process_info) != FALSE);
child_handle_.Reset(process_info.hProcess);
::CloseHandle(process_info.hThread);
set_spawned(true);
@@ -1042,7 +1043,7 @@ static void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest) {
::std::vector< ::std::string> parsed;
::std::string::size_type pos = 0;
- while (true) {
+ while (::testing::internal::AlwaysTrue()) {
const ::std::string::size_type colon = str.find(delimiter, pos);
if (colon == ::std::string::npos) {
parsed.push_back(str.substr(pos));
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h
index 9826bdd3..d593e82c 100644
--- a/src/gtest-internal-inl.h
+++ b/src/gtest-internal-inl.h
@@ -742,7 +742,7 @@ class UnitTestImpl {
}
// Provides access to the event listener list.
- EventListeners* listeners() { return &listeners_; }
+ TestEventListeners* listeners() { return &listeners_; }
// Returns the TestResult for the test that's currently running, or
// the TestResult for the ad hoc test if no test is running.
@@ -1002,7 +1002,7 @@ class UnitTestImpl {
// The list of event listeners that can be used to track events inside
// Google Test.
- EventListeners listeners_;
+ TestEventListeners listeners_;
// The OS stack trace getter. Will be deleted when the UnitTest
// object is destructed. By default, an OsStackTraceGetter is used,
diff --git a/src/gtest.cc b/src/gtest.cc
index 44ec9496..f0d8c38c 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -42,6 +42,8 @@
#include <wchar.h>
#include <wctype.h>
+#include <ostream>
+
#if GTEST_OS_LINUX
// TODO(kenton@google.com): Use autoconf to detect availability of
@@ -2966,6 +2968,9 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// with character references.
static String EscapeXml(const char* str, bool is_attribute);
+ // Returns the given string with all characters invalid in XML removed.
+ static String RemoveInvalidXmlCharacters(const char* str);
+
// Convenience wrapper around EscapeXml when str is an attribute value.
static String EscapeXmlAttribute(const char* str) {
return EscapeXml(str, true);
@@ -2974,10 +2979,13 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// Convenience wrapper around EscapeXml when str is not an attribute value.
static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
- // Prints an XML representation of a TestInfo object.
- static void PrintXmlTestInfo(FILE* out,
- const char* test_case_name,
- const TestInfo& test_info);
+ // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+ static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+ // Streams an XML representation of a TestInfo object.
+ static void OutputXmlTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info);
// Prints an XML representation of a TestCase object
static void PrintXmlTestCase(FILE* out, const TestCase& test_case);
@@ -3092,6 +3100,22 @@ String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
return m.GetString();
}
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+ char* const output = new char[strlen(str) + 1];
+ char* appender = output;
+ for (char ch = *str; ch != '\0'; ch = *++str)
+ if (IsValidXmlCharacter(ch))
+ *appender++ = ch;
+ *appender = '\0';
+
+ String ret_value(output);
+ delete[] output;
+ return ret_value;
+}
+
// The following routines generate an XML representation of a UnitTest
// object.
//
@@ -3118,40 +3142,62 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) {
return str.c_str();
}
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+ const char* data) {
+ const char* segment = data;
+ *stream << "<![CDATA[";
+ for (;;) {
+ const char* const next_segment = strstr(segment, "]]>");
+ if (next_segment != NULL) {
+ stream->write(segment, next_segment - segment);
+ *stream << "]]>]]&gt;<![CDATA[";
+ segment = next_segment + strlen("]]>");
+ } else {
+ *stream << segment;
+ break;
+ }
+ }
+ *stream << "]]>";
+}
+
// 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,
- const char* test_case_name,
- const TestInfo& test_info) {
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info) {
const TestResult& result = *test_info.result();
- fprintf(out,
- " <testcase name=\"%s\" status=\"%s\" time=\"%s\" "
- "classname=\"%s\"%s",
- EscapeXmlAttribute(test_info.name()).c_str(),
- test_info.should_run() ? "run" : "notrun",
- FormatTimeInMillisAsSeconds(result.elapsed_time()),
- EscapeXmlAttribute(test_case_name).c_str(),
- TestPropertiesAsXmlAttributes(result).c_str());
+ *stream << " <testcase name=\""
+ << EscapeXmlAttribute(test_info.name()).c_str()
+ << "\" status=\""
+ << (test_info.should_run() ? "run" : "notrun")
+ << "\" time=\""
+ << FormatTimeInMillisAsSeconds(result.elapsed_time())
+ << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+ << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) {
- const String message = String::Format("%s:%d\n%s", part.file_name(),
- part.line_number(), part.message());
if (++failures == 1)
- fprintf(out, ">\n");
- fprintf(out,
- " <failure message=\"%s\" type=\"\"><![CDATA[%s]]>"
- "</failure>\n",
- EscapeXmlAttribute(part.summary()).c_str(), message.c_str());
+ *stream << ">\n";
+ *stream << " <failure message=\""
+ << EscapeXmlAttribute(part.summary()).c_str()
+ << "\" type=\"\">";
+ const String message = RemoveInvalidXmlCharacters(String::Format(
+ "%s:%d\n%s",
+ part.file_name(), part.line_number(),
+ part.message()).c_str());
+ OutputXmlCDataSection(stream, message.c_str());
+ *stream << "</failure>\n";
}
}
if (failures == 0)
- fprintf(out, " />\n");
+ *stream << " />\n";
else
- fprintf(out, " </testcase>\n");
+ *stream << " </testcase>\n";
}
// Prints an XML representation of a TestCase object
@@ -3167,8 +3213,11 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
fprintf(out,
"errors=\"0\" time=\"%s\">\n",
FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
- for (int i = 0; i < test_case.total_test_count(); ++i)
- PrintXmlTestInfo(out, test_case.name(), *test_case.GetTestInfo(i));
+ for (int i = 0; i < test_case.total_test_count(); ++i) {
+ StrStream stream;
+ OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+ fprintf(out, "%s", StrStreamToString(&stream).c_str());
+ }
fprintf(out, " </testsuite>\n");
}
@@ -3253,28 +3302,28 @@ OsStackTraceGetter::kElidedFramesMarker =
} // namespace internal
-// class EventListeners
+// class TestEventListeners
-EventListeners::EventListeners()
+TestEventListeners::TestEventListeners()
: repeater_(new internal::TestEventRepeater()),
default_result_printer_(NULL),
default_xml_generator_(NULL) {
}
-EventListeners::~EventListeners() { delete repeater_; }
+TestEventListeners::~TestEventListeners() { delete repeater_; }
// Returns the standard listener responsible for the default console
// output. Can be removed from the listeners list to shut down default
// console output. Note that removing this object from the listener list
// with Release transfers its ownership to the user.
-void EventListeners::Append(TestEventListener* listener) {
+void TestEventListeners::Append(TestEventListener* listener) {
repeater_->Append(listener);
}
// Removes the given event listener from the list and returns it. It then
// becomes the caller's responsibility to delete the listener. Returns
// NULL if the listener is not found in the list.
-TestEventListener* EventListeners::Release(TestEventListener* listener) {
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
if (listener == default_result_printer_)
default_result_printer_ = NULL;
else if (listener == default_xml_generator_)
@@ -3284,14 +3333,14 @@ TestEventListener* EventListeners::Release(TestEventListener* listener) {
// Returns repeater that broadcasts the TestEventListener events to all
// subscribers.
-TestEventListener* EventListeners::repeater() { return repeater_; }
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
// Sets the default_result_printer attribute to the provided listener.
// The listener is also added to the listener list and previous
// default_result_printer is removed from it and deleted. The listener can
// also be NULL in which case it will not be added to the list. Does
// nothing if the previous and the current listener objects are the same.
-void EventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
if (default_result_printer_ != listener) {
// It is an error to pass this method a listener that is already in the
// list.
@@ -3307,7 +3356,7 @@ void EventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
// default_xml_generator is removed from it and deleted. The listener can
// also be NULL in which case it will not be added to the list. Does
// nothing if the previous and the current listener objects are the same.
-void EventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
if (default_xml_generator_ != listener) {
// It is an error to pass this method a listener that is already in the
// list.
@@ -3320,11 +3369,11 @@ void EventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
// Controls whether events will be forwarded by the repeater to the
// listeners in the list.
-bool EventListeners::EventForwardingEnabled() const {
+bool TestEventListeners::EventForwardingEnabled() const {
return repeater_->forwarding_enabled();
}
-void EventListeners::SuppressEventForwarding() {
+void TestEventListeners::SuppressEventForwarding() {
repeater_->set_forwarding_enabled(false);
}
@@ -3418,7 +3467,7 @@ const TestCase* UnitTest::GetTestCase(int i) const {
// Returns the list of event listeners that can be used to track events
// inside Google Test.
-EventListeners& UnitTest::listeners() {
+TestEventListeners& UnitTest::listeners() {
return *impl()->listeners();
}
@@ -4187,11 +4236,13 @@ namespace {
class ClassUniqueToAlwaysTrue {};
}
+bool IsTrue(bool condition) { return condition; }
+
bool AlwaysTrue() {
#if GTEST_HAS_EXCEPTIONS
// This condition is always false so AlwaysTrue() never actually throws,
// but it makes the compiler think that it may throw.
- if (atoi("42") == 36) // NOLINT
+ if (IsTrue(false))
throw ClassUniqueToAlwaysTrue();
#endif // GTEST_HAS_EXCEPTIONS
return true;