More implementation of the event listener interface (by Vlad Losev); Reduces the stack space usage of assertions by moving AssertHelper's fields to the heap (by Jorg Brown); Makes String faster, smaller, and simpler (by Zhanyong Wan); Fixes a bug in String::Format() (by Chandler); Adds the /MD version of VC projects to the distribution (by Vlad Losev).
This commit is contained in:
451
src/gtest.cc
451
src/gtest.cc
@@ -129,9 +129,12 @@
|
||||
|
||||
namespace testing {
|
||||
|
||||
using internal::EventListeners;
|
||||
using internal::EmptyTestEventListener;
|
||||
using internal::TestCase;
|
||||
using internal::TestProperty;
|
||||
using internal::TestResult;
|
||||
using internal::UnitTestEventListenerInterface;
|
||||
|
||||
// Constants.
|
||||
|
||||
@@ -303,14 +306,18 @@ static bool ShouldRunTestCase(const TestCase* test_case) {
|
||||
// AssertHelper constructor.
|
||||
AssertHelper::AssertHelper(TestPartResultType type, const char* file,
|
||||
int line, const char* message)
|
||||
: type_(type), file_(file), line_(line), message_(message) {
|
||||
: data_(new AssertHelperData(type, file, line, message)) {
|
||||
}
|
||||
|
||||
AssertHelper::~AssertHelper() {
|
||||
delete data_;
|
||||
}
|
||||
|
||||
// Message assignment, for assertion streaming support.
|
||||
void AssertHelper::operator=(const Message& message) const {
|
||||
UnitTest::GetInstance()->
|
||||
AddTestPartResult(type_, file_, line_,
|
||||
AppendUserMessage(message_, message),
|
||||
AddTestPartResult(data_->type, data_->file, data_->line,
|
||||
AppendUserMessage(data_->message, message),
|
||||
UnitTest::GetInstance()->impl()
|
||||
->CurrentOsStackTraceExceptTop(1)
|
||||
// Skips the stack frame for this function itself.
|
||||
@@ -476,86 +483,6 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The interface for printing the result of a UnitTest
|
||||
class UnitTestEventListenerInterface {
|
||||
public:
|
||||
// The d'tor is pure virtual as this is an abstract class.
|
||||
virtual ~UnitTestEventListenerInterface() {}
|
||||
|
||||
// Called before the unit test starts.
|
||||
virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called after the unit test ends.
|
||||
virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called before the test case starts.
|
||||
virtual void OnTestCaseStart(const TestCase& test_case) = 0;
|
||||
|
||||
// Called after the test case ends.
|
||||
virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
|
||||
|
||||
// Called before the global set-up starts.
|
||||
virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called after the global set-up ends.
|
||||
virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called before the global tear-down starts.
|
||||
virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called after the global tear-down ends.
|
||||
virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called before the test starts.
|
||||
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
||||
|
||||
// Called after the test ends.
|
||||
virtual void OnTestEnd(const TestInfo& test_info) = 0;
|
||||
|
||||
// Called after an assertion.
|
||||
virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 0;
|
||||
};
|
||||
|
||||
// The convenience class for users who need to override just one or two
|
||||
// methods and are not concerned that a possible change to a signature of
|
||||
// the methods they override will not be caught during the build.
|
||||
class EmptyTestEventListener : public UnitTestEventListenerInterface {
|
||||
public:
|
||||
// Called before the unit test starts.
|
||||
virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called after the unit test ends.
|
||||
virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called before the test case starts.
|
||||
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
|
||||
|
||||
// Called after the test case ends.
|
||||
virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {}
|
||||
|
||||
// Called before the global set-up starts.
|
||||
virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called after the global set-up ends.
|
||||
virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called before the global tear-down starts.
|
||||
virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called after the global tear-down ends.
|
||||
virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
|
||||
|
||||
// Called before the test starts.
|
||||
virtual void OnTestStart(const TestInfo& /*test_info*/) {}
|
||||
|
||||
// Called after the test ends.
|
||||
virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
|
||||
|
||||
// Called after an assertion.
|
||||
virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
|
||||
}
|
||||
};
|
||||
|
||||
// The c'tor sets this object as the test part result reporter used by
|
||||
// Google Test. The 'result' parameter specifies where to report the
|
||||
// results. Intercepts only failures from the current thread.
|
||||
@@ -690,7 +617,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
|
||||
void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
|
||||
const TestPartResult& result) {
|
||||
unit_test_->current_test_result()->AddTestPartResult(result);
|
||||
unit_test_->result_printer()->OnNewTestPartResult(result);
|
||||
unit_test_->listeners()->repeater()->OnNewTestPartResult(result);
|
||||
}
|
||||
|
||||
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
|
||||
@@ -1738,28 +1665,38 @@ bool String::EndsWithCaseInsensitive(const char* suffix) const {
|
||||
// available.
|
||||
//
|
||||
// The result is limited to 4096 characters (including the tailing 0).
|
||||
// If 4096 characters are not enough to format the input,
|
||||
// "<buffer exceeded>" is returned.
|
||||
// If 4096 characters are not enough to format the input, or if
|
||||
// there's an error, "<formatting error or buffer exceeded>" is
|
||||
// returned.
|
||||
String String::Format(const char * format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
char buffer[4096];
|
||||
const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
|
||||
|
||||
// MSVC 8 deprecates vsnprintf(), so we want to suppress warning
|
||||
// 4996 (deprecated function) there.
|
||||
#ifdef _MSC_VER // We are using MSVC.
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
const int size =
|
||||
vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
|
||||
const int size = vsnprintf(buffer, kBufferSize, format, args);
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#else // We are not using MSVC.
|
||||
const int size =
|
||||
vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
|
||||
const int size = vsnprintf(buffer, kBufferSize, format, args);
|
||||
#endif // _MSC_VER
|
||||
va_end(args);
|
||||
|
||||
return (size >= 0) ? String(buffer, size) : String("<buffer exceeded>");
|
||||
// vsnprintf()'s behavior is not portable. When the buffer is not
|
||||
// big enough, it returns a negative value in MSVC, and returns the
|
||||
// needed buffer size on Linux. When there is an output error, it
|
||||
// always returns a negative value. For simplicity, we lump the two
|
||||
// error cases together.
|
||||
if (size < 0 || size >= kBufferSize) {
|
||||
return String("<formatting error or buffer exceeded>");
|
||||
} else {
|
||||
return String(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
// Converts the buffer in a StrStream to a String, converting NUL
|
||||
@@ -2297,11 +2234,11 @@ void TestInfoImpl::Run() {
|
||||
UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
||||
impl->set_current_test_info(parent_);
|
||||
|
||||
// Notifies the unit test event listener that a test is about to
|
||||
// start.
|
||||
UnitTestEventListenerInterface* const result_printer =
|
||||
impl->result_printer();
|
||||
result_printer->OnTestStart(*parent_);
|
||||
UnitTestEventListenerInterface* repeater =
|
||||
UnitTest::GetInstance()->listeners().repeater();
|
||||
|
||||
// Notifies the unit test event listeners that a test is about to start.
|
||||
repeater->OnTestStart(*parent_);
|
||||
|
||||
const TimeInMillis start = GetTimeInMillis();
|
||||
|
||||
@@ -2344,7 +2281,7 @@ void TestInfoImpl::Run() {
|
||||
result_.set_elapsed_time(GetTimeInMillis() - start);
|
||||
|
||||
// Notifies the unit test event listener that a test has just finished.
|
||||
result_printer->OnTestEnd(*parent_);
|
||||
repeater->OnTestEnd(*parent_);
|
||||
|
||||
// Tells UnitTest to stop associating assertion results to this
|
||||
// test.
|
||||
@@ -2425,10 +2362,10 @@ void TestCase::Run() {
|
||||
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
||||
impl->set_current_test_case(this);
|
||||
|
||||
UnitTestEventListenerInterface * const result_printer =
|
||||
impl->result_printer();
|
||||
UnitTestEventListenerInterface* repeater =
|
||||
UnitTest::GetInstance()->listeners().repeater();
|
||||
|
||||
result_printer->OnTestCaseStart(*this);
|
||||
repeater->OnTestCaseStart(*this);
|
||||
impl->os_stack_trace_getter()->UponLeavingGTest();
|
||||
set_up_tc_();
|
||||
|
||||
@@ -2438,7 +2375,7 @@ void TestCase::Run() {
|
||||
|
||||
impl->os_stack_trace_getter()->UponLeavingGTest();
|
||||
tear_down_tc_();
|
||||
result_printer->OnTestCaseEnd(*this);
|
||||
repeater->OnTestCaseEnd(*this);
|
||||
impl->set_current_test_case(NULL);
|
||||
}
|
||||
|
||||
@@ -2471,10 +2408,6 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// A result printer that never prints anything. Used in the child process
|
||||
// of an exec-style death test to avoid needless output clutter.
|
||||
class NullUnitTestResultPrinter : public EmptyTestEventListener {};
|
||||
|
||||
// Formats a countable noun. Depending on its quantity, either the
|
||||
// singular form or the plural form is used. e.g.
|
||||
//
|
||||
@@ -2663,14 +2596,6 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
using internal::ColoredPrintf;
|
||||
using internal::COLOR_DEFAULT;
|
||||
using internal::COLOR_RED;
|
||||
using internal::COLOR_GREEN;
|
||||
using internal::COLOR_YELLOW;
|
||||
|
||||
// This class implements the UnitTestEventListenerInterface interface.
|
||||
//
|
||||
// Class PrettyUnitTestResultPrinter is copyable.
|
||||
@@ -2888,10 +2813,16 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
|
||||
// This class forwards events to other event listeners.
|
||||
class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
|
||||
public:
|
||||
typedef internal::Vector<UnitTestEventListenerInterface *> Listeners;
|
||||
UnitTestEventsRepeater() {}
|
||||
UnitTestEventsRepeater() : forwarding_enabled_(true) {}
|
||||
virtual ~UnitTestEventsRepeater();
|
||||
void AddListener(UnitTestEventListenerInterface *listener);
|
||||
void Append(UnitTestEventListenerInterface *listener);
|
||||
UnitTestEventListenerInterface* Release(
|
||||
UnitTestEventListenerInterface* listener);
|
||||
|
||||
// Controls whether events will be forwarded to listeners_. Set to false
|
||||
// in death test child processes.
|
||||
bool forwarding_enabled() const { return forwarding_enabled_; }
|
||||
void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
|
||||
|
||||
virtual void OnUnitTestStart(const UnitTest& unit_test);
|
||||
virtual void OnUnitTestEnd(const UnitTest& unit_test);
|
||||
@@ -2906,7 +2837,11 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
|
||||
virtual void OnNewTestPartResult(const TestPartResult& result);
|
||||
|
||||
private:
|
||||
Listeners listeners_;
|
||||
// Controls whether events will be forwarded to listeners_. Set to false
|
||||
// in death test child processes.
|
||||
bool forwarding_enabled_;
|
||||
// The list of listeners that receive events.
|
||||
Vector<UnitTestEventListenerInterface*> listeners_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater);
|
||||
};
|
||||
@@ -2917,17 +2852,31 @@ UnitTestEventsRepeater::~UnitTestEventsRepeater() {
|
||||
}
|
||||
}
|
||||
|
||||
void UnitTestEventsRepeater::AddListener(
|
||||
UnitTestEventListenerInterface *listener) {
|
||||
void UnitTestEventsRepeater::Append(UnitTestEventListenerInterface *listener) {
|
||||
listeners_.PushBack(listener);
|
||||
}
|
||||
|
||||
// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
|
||||
UnitTestEventListenerInterface* UnitTestEventsRepeater::Release(
|
||||
UnitTestEventListenerInterface *listener) {
|
||||
for (int i = 0; i < listeners_.size(); ++i) {
|
||||
if (listeners_.GetElement(i) == listener) {
|
||||
listeners_.Erase(i);
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Since the methods are identical, use a macro to reduce boilerplate.
|
||||
// This defines a member that repeats the call to all listeners.
|
||||
#define GTEST_REPEATER_METHOD_(Name, Type) \
|
||||
void UnitTestEventsRepeater::Name(const Type& parameter) { \
|
||||
for (int i = 0; i < listeners_.size(); i++) { \
|
||||
listeners_.GetElement(i)->Name(parameter); \
|
||||
if (forwarding_enabled_) { \
|
||||
for (int i = 0; i < listeners_.size(); i++) { \
|
||||
listeners_.GetElement(i)->Name(parameter); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -2945,7 +2894,7 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult)
|
||||
|
||||
#undef GTEST_REPEATER_METHOD_
|
||||
|
||||
// End PrettyUnitTestResultPrinter
|
||||
// End UnitTestEventsRepeater
|
||||
|
||||
// This class generates an XML output file.
|
||||
class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
@@ -2970,18 +2919,15 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
// is_attribute is true, the text is meant to appear as an attribute
|
||||
// value, and normalizable whitespace is preserved by replacing it
|
||||
// with character references.
|
||||
static internal::String EscapeXml(const char* str,
|
||||
bool is_attribute);
|
||||
static String EscapeXml(const char* str, bool is_attribute);
|
||||
|
||||
// Convenience wrapper around EscapeXml when str is an attribute value.
|
||||
static internal::String EscapeXmlAttribute(const char* str) {
|
||||
static String EscapeXmlAttribute(const char* str) {
|
||||
return EscapeXml(str, true);
|
||||
}
|
||||
|
||||
// Convenience wrapper around EscapeXml when str is not an attribute value.
|
||||
static internal::String EscapeXmlText(const char* str) {
|
||||
return EscapeXml(str, false);
|
||||
}
|
||||
static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
|
||||
|
||||
// Prints an XML representation of a TestInfo object.
|
||||
static void PrintXmlTestInfo(FILE* out,
|
||||
@@ -2998,11 +2944,10 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
// delimited XML attributes based on the property key="value" pairs.
|
||||
// When the String is not empty, it includes a space at the beginning,
|
||||
// to delimit this attribute from prior attributes.
|
||||
static internal::String TestPropertiesAsXmlAttributes(
|
||||
const TestResult& result);
|
||||
static String TestPropertiesAsXmlAttributes(const TestResult& result);
|
||||
|
||||
// The output file.
|
||||
const internal::String output_file_;
|
||||
const String output_file_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
|
||||
};
|
||||
@@ -3020,11 +2965,11 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
|
||||
// Called after the unit test ends.
|
||||
void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
|
||||
FILE* xmlout = NULL;
|
||||
internal::FilePath output_file(output_file_);
|
||||
internal::FilePath output_dir(output_file.RemoveFileName());
|
||||
FilePath output_file(output_file_);
|
||||
FilePath output_dir(output_file.RemoveFileName());
|
||||
|
||||
if (output_dir.CreateDirectoriesRecursively()) {
|
||||
xmlout = internal::posix::FOpen(output_file_.c_str(), "w");
|
||||
xmlout = posix::FOpen(output_file_.c_str(), "w");
|
||||
}
|
||||
if (xmlout == NULL) {
|
||||
// TODO(wan): report the reason of the failure.
|
||||
@@ -3059,8 +3004,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
|
||||
// most invalid characters can be retained using character references.
|
||||
// TODO(wan): It might be nice to have a minimally invasive, human-readable
|
||||
// escaping scheme for invalid characters, rather than dropping them.
|
||||
internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
|
||||
bool is_attribute) {
|
||||
String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
|
||||
Message m;
|
||||
|
||||
if (str != NULL) {
|
||||
@@ -3090,7 +3034,7 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
|
||||
default:
|
||||
if (IsValidXmlCharacter(*src)) {
|
||||
if (is_attribute && IsNormalizableWhitespace(*src))
|
||||
m << internal::String::Format("&#x%02X;", unsigned(*src));
|
||||
m << String::Format("&#x%02X;", unsigned(*src));
|
||||
else
|
||||
m << *src;
|
||||
}
|
||||
@@ -3102,7 +3046,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
|
||||
return m.GetString();
|
||||
}
|
||||
|
||||
|
||||
// The following routines generate an XML representation of a UnitTest
|
||||
// object.
|
||||
//
|
||||
@@ -3119,8 +3062,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
|
||||
// </testsuite>
|
||||
// </testsuites>
|
||||
|
||||
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
|
||||
@@ -3131,8 +3072,6 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
||||
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,
|
||||
@@ -3144,7 +3083,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
|
||||
"classname=\"%s\"%s",
|
||||
EscapeXmlAttribute(test_info.name()).c_str(),
|
||||
test_info.should_run() ? "run" : "notrun",
|
||||
internal::FormatTimeInMillisAsSeconds(result.elapsed_time()),
|
||||
FormatTimeInMillisAsSeconds(result.elapsed_time()),
|
||||
EscapeXmlAttribute(test_case_name).c_str(),
|
||||
TestPropertiesAsXmlAttributes(result).c_str());
|
||||
|
||||
@@ -3152,9 +3091,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
|
||||
for (int i = 0; i < result.total_part_count(); ++i) {
|
||||
const TestPartResult& part = result.GetTestPartResult(i);
|
||||
if (part.failed()) {
|
||||
const internal::String message =
|
||||
internal::String::Format("%s:%d\n%s", part.file_name(),
|
||||
part.line_number(), part.message());
|
||||
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,
|
||||
@@ -3182,7 +3120,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
|
||||
test_case.disabled_test_count());
|
||||
fprintf(out,
|
||||
"errors=\"0\" time=\"%s\">\n",
|
||||
internal::FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
|
||||
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));
|
||||
fprintf(out, " </testsuite>\n");
|
||||
@@ -3198,7 +3136,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
|
||||
unit_test.total_test_count(),
|
||||
unit_test.failed_test_count(),
|
||||
unit_test.disabled_test_count(),
|
||||
internal::FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
|
||||
FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
|
||||
if (GTEST_FLAG(shuffle)) {
|
||||
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
|
||||
}
|
||||
@@ -3210,7 +3148,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
|
||||
|
||||
// Produces a string representing the test properties in a result as space
|
||||
// delimited XML attributes based on the property key="value" pairs.
|
||||
internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
||||
String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
||||
const TestResult& result) {
|
||||
Message attributes;
|
||||
for (int i = 0; i < result.test_property_count(); ++i) {
|
||||
@@ -3223,8 +3161,6 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
||||
|
||||
// End XmlUnitTestResultPrinter
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Class ScopedTrace
|
||||
|
||||
// Pushes the given source file location and message onto a per-thread
|
||||
@@ -3271,6 +3207,84 @@ OsStackTraceGetter::kElidedFramesMarker =
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// class EventListeners
|
||||
|
||||
EventListeners::EventListeners()
|
||||
: repeater_(new internal::UnitTestEventsRepeater()),
|
||||
default_result_printer_(NULL),
|
||||
default_xml_generator_(NULL) {
|
||||
}
|
||||
|
||||
EventListeners::~EventListeners() { 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(UnitTestEventListenerInterface* 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.
|
||||
UnitTestEventListenerInterface* EventListeners::Release(
|
||||
UnitTestEventListenerInterface* listener) {
|
||||
if (listener == default_result_printer_)
|
||||
default_result_printer_ = NULL;
|
||||
else if (listener == default_xml_generator_)
|
||||
default_xml_generator_ = NULL;
|
||||
return repeater_->Release(listener);
|
||||
}
|
||||
|
||||
// Returns repeater that broadcasts the UnitTestEventListenerInterface
|
||||
// events to all subscribers.
|
||||
UnitTestEventListenerInterface* EventListeners::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(
|
||||
UnitTestEventListenerInterface* listener) {
|
||||
if (default_result_printer_ != listener) {
|
||||
// It is an error to pass this method a listener that is already in the
|
||||
// list.
|
||||
delete Release(default_result_printer_);
|
||||
default_result_printer_ = listener;
|
||||
if (listener != NULL)
|
||||
Append(listener);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the default_xml_generator attribute to the provided listener. The
|
||||
// listener is also added to the listener list and previous
|
||||
// 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(
|
||||
UnitTestEventListenerInterface* listener) {
|
||||
if (default_xml_generator_ != listener) {
|
||||
// It is an error to pass this method a listener that is already in the
|
||||
// list.
|
||||
delete Release(default_xml_generator_);
|
||||
default_xml_generator_ = listener;
|
||||
if (listener != NULL)
|
||||
Append(listener);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls whether events will be forwarded by the repeater to the
|
||||
// listeners in the list.
|
||||
bool EventListeners::EventForwardingEnabled() const {
|
||||
return repeater_->forwarding_enabled();
|
||||
}
|
||||
|
||||
void EventListeners::SuppressEventForwarding() {
|
||||
repeater_->set_forwarding_enabled(false);
|
||||
}
|
||||
|
||||
// class UnitTest
|
||||
|
||||
// Gets the singleton UnitTest object. The first time this method is
|
||||
@@ -3359,6 +3373,12 @@ const TestCase* UnitTest::GetTestCase(int i) const {
|
||||
return impl()->GetTestCase(i);
|
||||
}
|
||||
|
||||
// Returns the list of event listeners that can be used to track events
|
||||
// inside Google Test.
|
||||
EventListeners& UnitTest::listeners() {
|
||||
return *impl()->listeners();
|
||||
}
|
||||
|
||||
// Registers and returns a global test environment. When a test
|
||||
// program is run, all global test environments will be set-up in the
|
||||
// order they were registered. After all tests in the program have
|
||||
@@ -3614,8 +3634,8 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
||||
current_test_case_(NULL),
|
||||
current_test_info_(NULL),
|
||||
ad_hoc_test_result_(),
|
||||
result_printer_(NULL),
|
||||
os_stack_trace_getter_(NULL),
|
||||
post_flag_parse_init_performed_(false),
|
||||
random_seed_(0),
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
elapsed_time_(0),
|
||||
@@ -3624,6 +3644,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
||||
#else
|
||||
elapsed_time_(0) {
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
|
||||
}
|
||||
|
||||
UnitTestImpl::~UnitTestImpl() {
|
||||
@@ -3633,12 +3654,58 @@ UnitTestImpl::~UnitTestImpl() {
|
||||
// Deletes every Environment.
|
||||
environments_.ForEach(internal::Delete<Environment>);
|
||||
|
||||
// Deletes the current test result printer.
|
||||
delete result_printer_;
|
||||
|
||||
delete os_stack_trace_getter_;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
// Disables event forwarding if the control is currently in a death test
|
||||
// subprocess. Must not be called before InitGoogleTest.
|
||||
void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
|
||||
if (internal_run_death_test_flag_.get() != NULL)
|
||||
listeners()->SuppressEventForwarding();
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Initializes event listeners performing XML output as specified by
|
||||
// UnitTestOptions. Must not be called before InitGoogleTest.
|
||||
void UnitTestImpl::ConfigureXmlOutput() {
|
||||
const String& output_format = UnitTestOptions::GetOutputFormat();
|
||||
if (output_format == "xml") {
|
||||
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
||||
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
||||
} else if (output_format != "") {
|
||||
printf("WARNING: unrecognized output format \"%s\" ignored.\n",
|
||||
output_format.c_str());
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// Performs initialization dependent upon flag values obtained in
|
||||
// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
|
||||
// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
|
||||
// this function is also called from RunAllTests. Since this function can be
|
||||
// called more than once, it has to be idempotent.
|
||||
void UnitTestImpl::PostFlagParsingInit() {
|
||||
// Ensures that this function does not execute more than once.
|
||||
if (!post_flag_parse_init_performed_) {
|
||||
post_flag_parse_init_performed_ = true;
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
InitDeathTestSubprocessControlInfo();
|
||||
SuppressTestEventsIfInSubprocess();
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Registers parameterized tests. This makes parameterized tests
|
||||
// available to the UnitTest reflection API without running
|
||||
// RUN_ALL_TESTS.
|
||||
RegisterParameterizedTests();
|
||||
|
||||
// Configures listeners for XML output. This makes it possible for users
|
||||
// to shut down the default XML output before invoking RUN_ALL_TESTS.
|
||||
ConfigureXmlOutput();
|
||||
}
|
||||
}
|
||||
|
||||
// A predicate that checks the name of a TestCase against a known
|
||||
// value.
|
||||
//
|
||||
@@ -3726,7 +3793,8 @@ int UnitTestImpl::RunAllTests() {
|
||||
if (g_help_flag)
|
||||
return 0;
|
||||
|
||||
RegisterParameterizedTests();
|
||||
// TODO(vladl@google.com): Add a call to PostFlagParsingInit() here when
|
||||
// merging into the main branch.
|
||||
|
||||
// Even if sharding is not on, test runners may want to use the
|
||||
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
||||
@@ -3738,12 +3806,9 @@ int UnitTestImpl::RunAllTests() {
|
||||
bool in_subprocess_for_death_test = false;
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
|
||||
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
UnitTestEventListenerInterface * const printer = result_printer();
|
||||
|
||||
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
|
||||
in_subprocess_for_death_test);
|
||||
|
||||
@@ -3766,6 +3831,8 @@ int UnitTestImpl::RunAllTests() {
|
||||
// True iff at least one test has failed.
|
||||
bool failed = false;
|
||||
|
||||
UnitTestEventListenerInterface* repeater = listeners()->repeater();
|
||||
|
||||
// How many times to repeat the tests? We don't want to repeat them
|
||||
// when we are inside the subprocess of a death test.
|
||||
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
|
||||
@@ -3773,21 +3840,24 @@ int UnitTestImpl::RunAllTests() {
|
||||
const bool forever = repeat < 0;
|
||||
for (int i = 0; forever || i != repeat; i++) {
|
||||
if (repeat != 1) {
|
||||
// TODO(vladl@google.com): Move this output to
|
||||
// PrettyUnitTestResultPrinter. Add the iteration number parameter to
|
||||
// OnUnitTestStart.
|
||||
printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1);
|
||||
}
|
||||
|
||||
// Tells the unit test event listener that the tests are about to
|
||||
// start.
|
||||
printer->OnUnitTestStart(*parent_);
|
||||
// Tells the unit test event listeners that the tests are about to start.
|
||||
repeater->OnUnitTestStart(*parent_);
|
||||
|
||||
// TODO(vladl@google.com): Move to before the OnUnitTestStart notification?
|
||||
const TimeInMillis start = GetTimeInMillis();
|
||||
|
||||
// Runs each test case if there is at least one test to run.
|
||||
if (has_tests_to_run) {
|
||||
// Sets up all environments beforehand.
|
||||
printer->OnGlobalSetUpStart(*parent_);
|
||||
repeater->OnGlobalSetUpStart(*parent_);
|
||||
environments_.ForEach(SetUpEnvironment);
|
||||
printer->OnGlobalSetUpEnd(*parent_);
|
||||
repeater->OnGlobalSetUpEnd(*parent_);
|
||||
|
||||
// Runs the tests only if there was no fatal failure during global
|
||||
// set-up.
|
||||
@@ -3796,16 +3866,15 @@ int UnitTestImpl::RunAllTests() {
|
||||
}
|
||||
|
||||
// Tears down all environments in reverse order afterwards.
|
||||
printer->OnGlobalTearDownStart(*parent_);
|
||||
repeater->OnGlobalTearDownStart(*parent_);
|
||||
environments_in_reverse_order_.ForEach(TearDownEnvironment);
|
||||
printer->OnGlobalTearDownEnd(*parent_);
|
||||
repeater->OnGlobalTearDownEnd(*parent_);
|
||||
}
|
||||
|
||||
elapsed_time_ = GetTimeInMillis() - start;
|
||||
|
||||
// Tells the unit test event listener that the tests have just
|
||||
// finished.
|
||||
printer->OnUnitTestEnd(*parent_);
|
||||
// Tells the unit test event listener that the tests have just finished.
|
||||
repeater->OnUnitTestEnd(*parent_);
|
||||
|
||||
// Gets the result and clears it.
|
||||
if (!Passed()) {
|
||||
@@ -3997,49 +4066,6 @@ void UnitTestImpl::ListTestsMatchingFilter() {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Sets the unit test result printer.
|
||||
//
|
||||
// Does nothing if the input and the current printer object are the
|
||||
// same; otherwise, deletes the old printer object and makes the
|
||||
// input the current printer.
|
||||
void UnitTestImpl::set_result_printer(
|
||||
UnitTestEventListenerInterface* result_printer) {
|
||||
if (result_printer_ != result_printer) {
|
||||
delete result_printer_;
|
||||
result_printer_ = result_printer;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the current unit test result printer if it is not NULL;
|
||||
// otherwise, creates an appropriate result printer, makes it the
|
||||
// current printer, and returns it.
|
||||
UnitTestEventListenerInterface* UnitTestImpl::result_printer() {
|
||||
if (result_printer_ != NULL) {
|
||||
return result_printer_;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
if (internal_run_death_test_flag_.get() != NULL) {
|
||||
result_printer_ = new NullUnitTestResultPrinter;
|
||||
return result_printer_;
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater;
|
||||
const String& output_format = internal::UnitTestOptions::GetOutputFormat();
|
||||
if (output_format == "xml") {
|
||||
repeater->AddListener(new XmlUnitTestResultPrinter(
|
||||
internal::UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
||||
} else if (output_format != "") {
|
||||
printf("WARNING: unrecognized output format \"%s\" ignored.\n",
|
||||
output_format.c_str());
|
||||
fflush(stdout);
|
||||
}
|
||||
repeater->AddListener(new PrettyUnitTestResultPrinter);
|
||||
result_printer_ = repeater;
|
||||
return result_printer_;
|
||||
}
|
||||
|
||||
// Sets the OS stack trace getter.
|
||||
//
|
||||
// Does nothing if the input and the current OS stack trace getter are
|
||||
@@ -4420,6 +4446,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
ParseGoogleTestFlagsOnly(argc, argv);
|
||||
GetUnitTestImpl()->PostFlagParsingInit();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
Reference in New Issue
Block a user