diff options
author | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-09-04 18:30:25 (GMT) |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-09-04 18:30:25 (GMT) |
commit | 16e9dd6e28a8a7fb2d611011e7353e042fcb282f (patch) | |
tree | f990763455e874fb887364bbd9c712386824d20d /include | |
parent | 56a2e686e915d483cb22db091140130b23814127 (diff) | |
download | googletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.zip googletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.tar.gz googletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.tar.bz2 |
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).
Diffstat (limited to 'include')
-rw-r--r-- | include/gtest/gtest-test-part.h | 3 | ||||
-rw-r--r-- | include/gtest/gtest.h | 215 | ||||
-rw-r--r-- | include/gtest/internal/gtest-internal.h | 1 | ||||
-rw-r--r-- | include/gtest/internal/gtest-string.h | 54 |
4 files changed, 230 insertions, 43 deletions
diff --git a/include/gtest/gtest-test-part.h b/include/gtest/gtest-test-part.h index d5b2713..14d8e7b 100644 --- a/include/gtest/gtest-test-part.h +++ b/include/gtest/gtest-test-part.h @@ -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. diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index 90c36a5..0727adb 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -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); }; diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h index be37726..f0a7966 100644 --- a/include/gtest/internal/gtest-internal.h +++ b/include/gtest/internal/gtest-internal.h @@ -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 { diff --git a/include/gtest/internal/gtest-string.h b/include/gtest/internal/gtest-string.h index d36146a..39982d1 100644 --- a/include/gtest/internal/gtest-string.h +++ b/include/gtest/internal/gtest-string.h @@ -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 |