mirror of
https://github.com/google/googletest.git
synced 2025-11-13 08:15:04 -05:00
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:
@@ -41,6 +41,9 @@ namespace testing {
|
||||
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
// TODO(vladl@google.com): Rename the enum values to kSuccess,
|
||||
// kNonFatalFailure, and kFatalFailure before publishing the event listener
|
||||
// API (see issue http://code.google.com/p/googletest/issues/detail?id=165).
|
||||
enum TestPartResultType {
|
||||
TPRT_SUCCESS, // Succeeded.
|
||||
TPRT_NONFATAL_FAILURE, // Failed but the test can continue.
|
||||
|
||||
@@ -149,17 +149,23 @@ namespace internal {
|
||||
|
||||
class AssertHelper;
|
||||
class DefaultGlobalTestPartResultReporter;
|
||||
class EventListenersAccessor;
|
||||
class ExecDeathTest;
|
||||
class NoExecDeathTest;
|
||||
class FinalSuccessChecker;
|
||||
class GTestFlagSaver;
|
||||
class TestCase;
|
||||
class TestInfoImpl;
|
||||
class TestResultAccessor;
|
||||
class UnitTestAccessor;
|
||||
// TODO(vladl@google.com): Rename to TestEventRepeater.
|
||||
class UnitTestEventsRepeater;
|
||||
class WindowsDeathTest;
|
||||
class UnitTestImpl* GetUnitTestImpl();
|
||||
void ReportFailureInUnknownLocation(TestPartResultType result_type,
|
||||
const String& message);
|
||||
class PrettyUnitTestResultPrinter;
|
||||
class XmlUnitTestResultPrinter;
|
||||
|
||||
// Converts a streamable value to a String. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
@@ -766,6 +772,178 @@ class Environment {
|
||||
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// TODO(vladl@google.com): Order the methods the way they are invoked by
|
||||
// Google Test.
|
||||
// The interface for tracing execution of tests.
|
||||
class UnitTestEventListenerInterface {
|
||||
public:
|
||||
virtual ~UnitTestEventListenerInterface() {}
|
||||
|
||||
// TODO(vladl@google.com): Add events for test program start and test program
|
||||
// end: OnTestIterationStart(const UnitTest&); // Start of one iteration.
|
||||
// Add tests, too.
|
||||
// TODO(vladl@google.com): Rename OnUnitTestStart() and OnUnitTestEnd() to
|
||||
// OnTestProgramStart() and OnTestProgramEnd().
|
||||
// Called before any test activity starts.
|
||||
virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Called after all test activities have ended.
|
||||
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;
|
||||
|
||||
// TODO(vladl@google.com): Rename OnGlobalSetUpStart to
|
||||
// OnEnvironmentsSetUpStart. Make similar changes for the rest of
|
||||
// environment-related events.
|
||||
// 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 a failed assertion or a SUCCESS().
|
||||
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 a failed assertion or a SUCCESS().
|
||||
virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
|
||||
}
|
||||
};
|
||||
|
||||
// EventListeners lets users add listeners to track events in Google Test.
|
||||
class EventListeners {
|
||||
public:
|
||||
EventListeners();
|
||||
~EventListeners();
|
||||
|
||||
// Appends an event listener to the end of the list. Google Test assumes
|
||||
// the ownership of the listener (i.e. it will delete the listener when
|
||||
// the test program finishes).
|
||||
void Append(UnitTestEventListenerInterface* 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* Release(
|
||||
UnitTestEventListenerInterface* listener);
|
||||
|
||||
// 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 caller and makes this
|
||||
// function return NULL the next time.
|
||||
UnitTestEventListenerInterface* default_result_printer() const {
|
||||
return default_result_printer_;
|
||||
}
|
||||
|
||||
// Returns the standard listener responsible for the default XML output
|
||||
// controlled by the --gtest_output=xml flag. Can be removed from the
|
||||
// listeners list by users who want to shut down the default XML output
|
||||
// controlled by this flag and substitute it with custom one. Note that
|
||||
// removing this object from the listener list with Release transfers its
|
||||
// ownership to the caller and makes this function return NULL the next
|
||||
// time.
|
||||
UnitTestEventListenerInterface* default_xml_generator() const {
|
||||
return default_xml_generator_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class internal::DefaultGlobalTestPartResultReporter;
|
||||
friend class internal::EventListenersAccessor;
|
||||
friend class internal::NoExecDeathTest;
|
||||
friend class internal::TestCase;
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::UnitTestImpl;
|
||||
|
||||
// Returns repeater that broadcasts the UnitTestEventListenerInterface
|
||||
// events to all subscribers.
|
||||
UnitTestEventListenerInterface* 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 SetDefaultResultPrinter(UnitTestEventListenerInterface* 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 SetDefaultXmlGenerator(UnitTestEventListenerInterface* listener);
|
||||
|
||||
// Controls whether events will be forwarded by the repeater to the
|
||||
// listeners in the list.
|
||||
bool EventForwardingEnabled() const;
|
||||
void SuppressEventForwarding();
|
||||
|
||||
// The actual list of listeners.
|
||||
internal::UnitTestEventsRepeater* repeater_;
|
||||
// Listener responsible for the standard result output.
|
||||
UnitTestEventListenerInterface* default_result_printer_;
|
||||
// Listener responsible for the creation of the XML output file.
|
||||
UnitTestEventListenerInterface* default_xml_generator_;
|
||||
|
||||
// We disallow copying EventListeners.
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(EventListeners);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// A UnitTest consists of a vector of TestCases.
|
||||
//
|
||||
// This is a singleton class. The only instance of UnitTest is
|
||||
@@ -886,6 +1064,10 @@ class UnitTest {
|
||||
// total_test_case_count() - 1. If i is not in that range, returns NULL.
|
||||
const internal::TestCase* GetTestCase(int i) const;
|
||||
|
||||
// Returns the list of event listeners that can be used to track events
|
||||
// inside Google Test.
|
||||
internal::EventListeners& listeners();
|
||||
|
||||
// ScopedTrace is a friend as it needs to modify the per-thread
|
||||
// trace stack, which is a private member of UnitTest.
|
||||
// TODO(vladl@google.com): Order all declarations according to the style
|
||||
@@ -899,9 +1081,12 @@ class UnitTest {
|
||||
TestPartResultType result_type,
|
||||
const internal::String& message);
|
||||
// TODO(vladl@google.com): Remove these when publishing the new accessors.
|
||||
friend class PrettyUnitTestResultPrinter;
|
||||
friend class XmlUnitTestResultPrinter;
|
||||
friend class internal::PrettyUnitTestResultPrinter;
|
||||
friend class internal::TestCase;
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::UnitTestAccessor;
|
||||
friend class internal::UnitTestImpl;
|
||||
friend class internal::XmlUnitTestResultPrinter;
|
||||
friend class FinalSuccessChecker;
|
||||
FRIEND_TEST(ApiTest, UnitTestImmutableAccessorsWork);
|
||||
FRIEND_TEST(ApiTest, TestCaseImmutableAccessorsWork);
|
||||
@@ -1299,14 +1484,32 @@ class AssertHelper {
|
||||
// Constructor.
|
||||
AssertHelper(TestPartResultType type, const char* file, int line,
|
||||
const char* message);
|
||||
~AssertHelper();
|
||||
|
||||
// Message assignment is a semantic trick to enable assertion
|
||||
// streaming; see the GTEST_MESSAGE_ macro below.
|
||||
void operator=(const Message& message) const;
|
||||
|
||||
private:
|
||||
TestPartResultType const type_;
|
||||
const char* const file_;
|
||||
int const line_;
|
||||
String const message_;
|
||||
// We put our data in a struct so that the size of the AssertHelper class can
|
||||
// be as small as possible. This is important because gcc is incapable of
|
||||
// re-using stack space even for temporary variables, so every EXPECT_EQ
|
||||
// reserves stack space for another AssertHelper.
|
||||
struct AssertHelperData {
|
||||
AssertHelperData(TestPartResultType t, const char* srcfile, int line_num,
|
||||
const char* msg)
|
||||
: type(t), file(srcfile), line(line_num), message(msg) { }
|
||||
|
||||
TestPartResultType const type;
|
||||
const char* const file;
|
||||
int const line;
|
||||
String const message;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
|
||||
};
|
||||
|
||||
AssertHelperData* const data_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
|
||||
};
|
||||
|
||||
@@ -107,7 +107,6 @@ class Test; // Represents a test.
|
||||
class TestInfo; // Information about a test.
|
||||
class TestPartResult; // Result of a test part.
|
||||
class UnitTest; // A collection of test cases.
|
||||
class UnitTestEventListenerInterface; // Listens to Google Test events.
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
@@ -51,22 +51,6 @@
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Holds data in a String object. We need this class in order to put
|
||||
// String's data members on the heap instead of on the stack.
|
||||
// Otherwise tests using many assertions (and thus Strings) in one
|
||||
// function may need too much stack frame space to compile.
|
||||
class StringData {
|
||||
StringData() : c_str_(NULL), length_(0) {}
|
||||
~StringData() { delete[] c_str_; }
|
||||
|
||||
private:
|
||||
friend class String;
|
||||
|
||||
const char* c_str_;
|
||||
size_t length_; // Length of the string (excluding the terminating
|
||||
// '\0' character).
|
||||
};
|
||||
|
||||
// String - a UTF-8 string class.
|
||||
//
|
||||
// We cannot use std::string as Microsoft's STL implementation in
|
||||
@@ -202,14 +186,14 @@ class String {
|
||||
|
||||
// C'tors
|
||||
|
||||
// The default c'tor constructs a NULL string, which is represented
|
||||
// by data_ being NULL.
|
||||
String() : data_(NULL) {}
|
||||
// The default c'tor constructs a NULL string.
|
||||
String() : c_str_(NULL), length_(0) {}
|
||||
|
||||
// Constructs a String by cloning a 0-terminated C string.
|
||||
String(const char* c_str) { // NOLINT
|
||||
if (c_str == NULL) {
|
||||
data_ = NULL;
|
||||
c_str_ = NULL;
|
||||
length_ = 0;
|
||||
} else {
|
||||
ConstructNonNull(c_str, strlen(c_str));
|
||||
}
|
||||
@@ -225,13 +209,11 @@ class String {
|
||||
|
||||
// The copy c'tor creates a new copy of the string. The two
|
||||
// String objects do not share content.
|
||||
String(const String& str) : data_(NULL) { *this = str; }
|
||||
String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
|
||||
|
||||
// D'tor. String is intended to be a final class, so the d'tor
|
||||
// doesn't need to be virtual.
|
||||
~String() {
|
||||
delete data_;
|
||||
}
|
||||
~String() { delete[] c_str_; }
|
||||
|
||||
// Allows a String to be implicitly converted to an ::std::string or
|
||||
// ::string, and vice versa. Converting a String containing a NULL
|
||||
@@ -285,12 +267,12 @@ class String {
|
||||
|
||||
// Returns the length of the encapsulated string, or 0 if the
|
||||
// string is NULL.
|
||||
size_t length() const { return (data_ == NULL) ? 0 : data_->length_; }
|
||||
size_t length() const { return length_; }
|
||||
|
||||
// Gets the 0-terminated C string this String object represents.
|
||||
// The String object still owns the string. Therefore the caller
|
||||
// should NOT delete the return value.
|
||||
const char* c_str() const { return (data_ == NULL) ? NULL : data_->c_str_; }
|
||||
const char* c_str() const { return c_str_; }
|
||||
|
||||
// Assigns a C string to this object. Self-assignment works.
|
||||
const String& operator=(const char* c_str) { return *this = String(c_str); }
|
||||
@@ -298,10 +280,12 @@ class String {
|
||||
// Assigns a String object to this object. Self-assignment works.
|
||||
const String& operator=(const String& rhs) {
|
||||
if (this != &rhs) {
|
||||
delete data_;
|
||||
data_ = NULL;
|
||||
if (rhs.data_ != NULL) {
|
||||
ConstructNonNull(rhs.data_->c_str_, rhs.data_->length_);
|
||||
delete[] c_str_;
|
||||
if (rhs.c_str() == NULL) {
|
||||
c_str_ = NULL;
|
||||
length_ = 0;
|
||||
} else {
|
||||
ConstructNonNull(rhs.c_str(), rhs.length());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,17 +298,15 @@ class String {
|
||||
// ConstructNonNull(NULL, 0) results in an empty string ("").
|
||||
// ConstructNonNull(NULL, non_zero) is undefined behavior.
|
||||
void ConstructNonNull(const char* buffer, size_t length) {
|
||||
data_ = new StringData;
|
||||
char* const str = new char[length + 1];
|
||||
memcpy(str, buffer, length);
|
||||
str[length] = '\0';
|
||||
data_->c_str_ = str;
|
||||
data_->length_ = length;
|
||||
c_str_ = str;
|
||||
length_ = length;
|
||||
}
|
||||
|
||||
// Points to the representation of the String. A NULL String is
|
||||
// represented by data_ == NULL.
|
||||
StringData* data_;
|
||||
const char* c_str_;
|
||||
size_t length_;
|
||||
}; // class String
|
||||
|
||||
// Streams a String to an ostream. Each '\0' character in the String
|
||||
|
||||
Reference in New Issue
Block a user