aboutsummaryrefslogtreecommitdiffstats
path: root/include/gtest
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-09-04 18:30:25 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-09-04 18:30:25 +0000
commit16e9dd6e28a8a7fb2d611011e7353e042fcb282f (patch)
treef990763455e874fb887364bbd9c712386824d20d /include/gtest
parent56a2e686e915d483cb22db091140130b23814127 (diff)
downloadgoogletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.tar.gz
googletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.tar.bz2
googletest-16e9dd6e28a8a7fb2d611011e7353e042fcb282f.zip
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/gtest')
-rw-r--r--include/gtest/gtest-test-part.h3
-rw-r--r--include/gtest/gtest.h215
-rw-r--r--include/gtest/internal/gtest-internal.h1
-rw-r--r--include/gtest/internal/gtest-string.h54
4 files changed, 230 insertions, 43 deletions
diff --git a/include/gtest/gtest-test-part.h b/include/gtest/gtest-test-part.h
index d5b27130..14d8e7b6 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 90c36a53..0727adbd 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 be37726a..f0a7966b 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 d36146ab..39982d1b 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