mirror of
https://github.com/google/googletest.git
synced 2024-12-28 11:10:44 +08: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:
parent
56a2e686e9
commit
16e9dd6e28
19
CHANGES
19
CHANGES
@ -1,3 +1,20 @@
|
||||
Changes for 1.4.0 (up to r300):
|
||||
|
||||
* New feature: the XML report format is closer to junitreport and can
|
||||
be parsed by Hudson now.
|
||||
* New feature: when a test runs under Visual Studio, its failures are
|
||||
integrated in the IDE.
|
||||
* New feature: /MD(d) versions of VC++ projects.
|
||||
* New feature: elapsed time for the tests is printed by default.
|
||||
* New feature: comes with a TR1 tuple implementation such that Boost
|
||||
is no longer needed for Combine().
|
||||
* New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends.
|
||||
* New feature: the Xcode project can now produce static gtest
|
||||
libraries in addition to a framework.
|
||||
* Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile,
|
||||
Symbian, gcc, and C++Builder.
|
||||
* Bug fixes and implementation clean-ups.
|
||||
|
||||
Changes for 1.3.0:
|
||||
|
||||
* New feature: death tests on Windows, Cygwin, and Mac.
|
||||
@ -11,7 +28,7 @@ Changes for 1.3.0:
|
||||
.cc file for easy deployment.
|
||||
* New feature: support for distributing test functions to multiple
|
||||
machines (requires support from the test runner).
|
||||
* Bug fixes and implementation clean-up.
|
||||
* Bug fixes and implementation clean-ups.
|
||||
|
||||
Changes for 1.2.1:
|
||||
|
||||
|
17
Makefile.am
17
Makefile.am
@ -12,6 +12,8 @@ EXTRA_DIST = \
|
||||
include/gtest/internal/gtest-param-util-generated.h.pump \
|
||||
make/Makefile \
|
||||
scons/SConscript \
|
||||
scons/SConstruct \
|
||||
scons/SConstruct.common \
|
||||
scripts/fuse_gtest_files.py \
|
||||
scripts/gen_gtest_pred_impl.py \
|
||||
scripts/test/Makefile \
|
||||
@ -24,10 +26,15 @@ EXTRA_DIST += \
|
||||
msvc/gtest_color_test_.vcproj \
|
||||
msvc/gtest_env_var_test_.vcproj \
|
||||
msvc/gtest_environment_test.vcproj \
|
||||
msvc/gtest_main-md.vcproj \
|
||||
msvc/gtest_main.vcproj \
|
||||
msvc/gtest-md.sln \
|
||||
msvc/gtest-md.vcproj \
|
||||
msvc/gtest_output_test_.vcproj \
|
||||
msvc/gtest_prod_test-md.vcproj \
|
||||
msvc/gtest_prod_test.vcproj \
|
||||
msvc/gtest_uninitialized_test_.vcproj \
|
||||
msvc/gtest_unittest-md.vcproj \
|
||||
msvc/gtest_unittest.vcproj
|
||||
|
||||
# xcode project files
|
||||
@ -36,9 +43,8 @@ EXTRA_DIST += \
|
||||
xcode/Config/FrameworkTarget.xcconfig \
|
||||
xcode/Config/General.xcconfig \
|
||||
xcode/Config/ReleaseProject.xcconfig \
|
||||
xcode/Config/StaticLibraryTarget.xcconfig \
|
||||
xcode/Config/TestTarget.xcconfig \
|
||||
xcode/Config/InternalTestTarget.xcconfig \
|
||||
xcode/Config/InternalPythonTestTarget.xcconfig \
|
||||
xcode/Resources/Info.plist \
|
||||
xcode/Scripts/versiongenerate.py \
|
||||
xcode/Scripts/runtests.sh \
|
||||
@ -299,6 +305,11 @@ check_PROGRAMS += test/gtest-unittest-api_test
|
||||
test_gtest_unittest_api_test_SOURCES = test/gtest-unittest-api_test.cc
|
||||
test_gtest_unittest_api_test_LDADD = lib/libgtest_main.la
|
||||
|
||||
TESTS += test/gtest-listener_test
|
||||
check_PROGRAMS += test/gtest-listener_test
|
||||
test_gtest_listener_test_SOURCES = test/gtest-listener_test.cc
|
||||
test_gtest_listener_test_LDADD = lib/libgtest_main.la
|
||||
|
||||
# Verifies that Google Test works when RTTI is disabled.
|
||||
TESTS += test/gtest_no_rtti_test
|
||||
check_PROGRAMS += test/gtest_no_rtti_test
|
||||
@ -407,7 +418,7 @@ TESTS += test/gtest_xml_outfiles_test.py
|
||||
|
||||
check_PROGRAMS += test/gtest_xml_output_unittest_
|
||||
test_gtest_xml_output_unittest__SOURCES = test/gtest_xml_output_unittest_.cc
|
||||
test_gtest_xml_output_unittest__LDADD = lib/libgtest_main.la
|
||||
test_gtest_xml_output_unittest__LDADD = lib/libgtest.la
|
||||
check_SCRIPTS += test/gtest_xml_output_unittest.py
|
||||
TESTS += test/gtest_xml_output_unittest.py
|
||||
|
||||
|
21
README
21
README
@ -190,9 +190,16 @@ see 'gtest-config --help' for more detailed information.
|
||||
g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
|
||||
|
||||
### Windows ###
|
||||
Open the gtest.sln file in the msvc/ folder using Visual Studio, and
|
||||
you are ready to build Google Test the same way you build any Visual
|
||||
Studio project.
|
||||
The msvc\ folder contains two solutions with Visual C++ projects. Open the
|
||||
gtest.sln or gtest-md.sln file using Visual Studio, and you are ready to
|
||||
build Google Test the same way you build any Visual Studio project. Files
|
||||
that have names ending with -md use DLL versions of Microsoft runtime
|
||||
libraries (the /MD or the /MDd compiler option). Files without that suffix
|
||||
use static versions of the runtime libraries (the /MT or the /MTd option).
|
||||
Please note that one must use the same option to compile both gtest and his
|
||||
test code. If you use Visual Studio 2005 or above, we recommend the -md
|
||||
version as /MD is the default for new projects in these versions of Visual
|
||||
Studio.
|
||||
|
||||
### Mac OS X (universal-binary framework) ###
|
||||
Open the gtest.xcodeproj in the xcode/ folder using Xcode. Build the "gtest"
|
||||
@ -201,7 +208,7 @@ directory (selected in the Xcode "Preferences..." -> "Building" pane and
|
||||
defaults to xcode/build). Alternatively, at the command line, enter:
|
||||
|
||||
xcodebuild
|
||||
|
||||
|
||||
This will build the "Release" configuration of gtest.framework in your
|
||||
default build location. See the "xcodebuild" man page for more information about
|
||||
building different configurations and building in different locations.
|
||||
@ -213,7 +220,7 @@ ones) as errors. However, you should see a "Build succeeded" message at the end
|
||||
of the build log. To run all of the tests from the command line, enter:
|
||||
|
||||
xcodebuild -target Check
|
||||
|
||||
|
||||
Installation with xcodebuild requires specifying an installation desitination
|
||||
directory, known as the DSTROOT. Three items will be installed when using
|
||||
xcodebuild:
|
||||
@ -221,12 +228,12 @@ xcodebuild:
|
||||
$DSTROOT/Library/Frameworks/gtest.framework
|
||||
$DSTROOT/usr/local/lib/libgtest.a
|
||||
$DSTROOT/usr/local/lib/libgtest_main.a
|
||||
|
||||
|
||||
You specify the installation directory on the command line with the other
|
||||
xcodebuild options. Here's how you would install in a user-visible location:
|
||||
|
||||
xcodebuild install DSTROOT=~
|
||||
|
||||
|
||||
To perform a system-wide inistall, escalate to an administrator and specify
|
||||
the file system root as the DSTROOT:
|
||||
|
||||
|
@ -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
|
||||
|
@ -318,8 +318,9 @@ GtestTest(env, 'gtest_list_tests_unittest_', gtest)
|
||||
GtestTest(env, 'gtest_throw_on_failure_test_', gtest)
|
||||
GtestTest(env, 'gtest_xml_outfile1_test_', gtest_main)
|
||||
GtestTest(env, 'gtest_xml_outfile2_test_', gtest_main)
|
||||
GtestTest(env, 'gtest_xml_output_unittest_', gtest_main)
|
||||
GtestTest(env, 'gtest_xml_output_unittest_', gtest)
|
||||
GtestTest(env, 'gtest-unittest-api_test', gtest)
|
||||
GtestTest(env, 'gtest-listener_test', gtest)
|
||||
|
||||
############################################################
|
||||
# Tests targets using custom environments.
|
||||
|
@ -469,7 +469,8 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
||||
break;
|
||||
case DIED:
|
||||
if (status_ok) {
|
||||
if (RE::PartialMatch(error_message.c_str(), *regex())) {
|
||||
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
|
||||
if (matched) {
|
||||
success = true;
|
||||
} else {
|
||||
buffer << " Result: died but not with expected error.\n"
|
||||
@ -767,6 +768,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
||||
// concurrent writes to the log files. We capture stderr in the parent
|
||||
// process and append the child process' output to a log.
|
||||
LogToStderr();
|
||||
// Event forwarding to the listeners of event listener API mush be shut
|
||||
// down in death test subprocesses.
|
||||
GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
||||
return EXECUTE_TEST;
|
||||
} else {
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||
|
@ -741,6 +741,9 @@ class UnitTestImpl {
|
||||
return test_cases_.GetElementOr(i, NULL);
|
||||
}
|
||||
|
||||
// Provides access to the event listener list.
|
||||
EventListeners* 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.
|
||||
TestResult* current_test_result();
|
||||
@ -748,18 +751,6 @@ class UnitTestImpl {
|
||||
// Returns the TestResult for the ad hoc test.
|
||||
const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
|
||||
|
||||
// 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 set_result_printer(UnitTestEventListenerInterface* 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* result_printer();
|
||||
|
||||
// Sets the OS stack trace getter.
|
||||
//
|
||||
// Does nothing if the input and the current OS stack trace getter
|
||||
@ -907,9 +898,13 @@ class UnitTestImpl {
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
void InitDeathTestSubprocessControlInfo() {
|
||||
internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
|
||||
}
|
||||
// Returns a pointer to the parsed --gtest_internal_run_death_test
|
||||
// flag, or NULL if that flag was not specified.
|
||||
// This information is useful only in a death test child process.
|
||||
// Must not be called before a call to InitGoogleTest.
|
||||
const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
|
||||
return internal_run_death_test_flag_.get();
|
||||
}
|
||||
@ -919,9 +914,22 @@ class UnitTestImpl {
|
||||
return death_test_factory_.get();
|
||||
}
|
||||
|
||||
void SuppressTestEventsIfInSubprocess();
|
||||
|
||||
friend class ReplaceDeathTestFactory;
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Initializes the event listener performing XML output as specified by
|
||||
// UnitTestOptions. Must not be called before InitGoogleTest.
|
||||
void ConfigureXmlOutput();
|
||||
|
||||
// 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 PostFlagParsingInit();
|
||||
|
||||
// Gets the random seed used at the start of the current test run.
|
||||
int random_seed() const { return random_seed_; }
|
||||
|
||||
@ -992,11 +1000,9 @@ class UnitTestImpl {
|
||||
// test, and records the result in ad_hoc_test_result_.
|
||||
TestResult ad_hoc_test_result_;
|
||||
|
||||
// The unit test result printer. Will be deleted when the UnitTest
|
||||
// object is destructed. By default, a plain text printer is used,
|
||||
// but the user can set this field to use a custom printer if that
|
||||
// is desired.
|
||||
UnitTestEventListenerInterface* result_printer_;
|
||||
// The list of event listeners that can be used to track events inside
|
||||
// Google Test.
|
||||
EventListeners listeners_;
|
||||
|
||||
// The OS stack trace getter. Will be deleted when the UnitTest
|
||||
// object is destructed. By default, an OsStackTraceGetter is used,
|
||||
@ -1004,6 +1010,9 @@ class UnitTestImpl {
|
||||
// desired.
|
||||
OsStackTraceGetterInterface* os_stack_trace_getter_;
|
||||
|
||||
// True iff PostFlagParsingInit() has been called.
|
||||
bool post_flag_parse_init_performed_;
|
||||
|
||||
// The random number seed used at the beginning of the test run.
|
||||
int random_seed_;
|
||||
|
||||
|
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
|
||||
|
230
test/gtest-listener_test.cc
Normal file
230
test/gtest-listener_test.cc
Normal file
@ -0,0 +1,230 @@
|
||||
// Copyright 2009 Google Inc. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vladl@google.com (Vlad Losev)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This file verifies Google Test event listeners receive events at the
|
||||
// right times.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// his code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h" // For Vector.
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
using ::testing::AddGlobalTestEnvironment;
|
||||
using ::testing::Environment;
|
||||
using ::testing::InitGoogleTest;
|
||||
using ::testing::Test;
|
||||
using ::testing::TestInfo;
|
||||
using ::testing::TestPartResult;
|
||||
using ::testing::UnitTest;
|
||||
using ::testing::internal::String;
|
||||
using ::testing::internal::TestCase;
|
||||
using ::testing::internal::UnitTestEventListenerInterface;
|
||||
using ::testing::internal::Vector;
|
||||
|
||||
// Used by tests to register their events.
|
||||
Vector<String>* g_events = NULL;
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// TODO(vladl@google.com): Remove this and use UnitTest::listeners()
|
||||
// directly after it is published.
|
||||
class UnitTestAccessor {
|
||||
public:
|
||||
static EventListeners& GetEventListeners() {
|
||||
return UnitTest::GetInstance()->listeners();
|
||||
}
|
||||
static bool UnitTestFailed() { return UnitTest::GetInstance()->Failed(); }
|
||||
};
|
||||
|
||||
class EventRecordingListener : public UnitTestEventListenerInterface {
|
||||
protected:
|
||||
virtual void OnUnitTestStart(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnUnitTestStart"));
|
||||
}
|
||||
|
||||
virtual void OnGlobalSetUpStart(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnGlobalSetUpStart"));
|
||||
}
|
||||
|
||||
virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnGlobalSetUpEnd"));
|
||||
}
|
||||
|
||||
virtual void OnTestCaseStart(const TestCase& test_case) {
|
||||
g_events->PushBack(String("TestEventListener::OnTestCaseStart"));
|
||||
}
|
||||
|
||||
virtual void OnTestStart(const TestInfo& test_info) {
|
||||
g_events->PushBack(String("TestEventListener::OnTestStart"));
|
||||
}
|
||||
|
||||
virtual void OnNewTestPartResult(const TestPartResult& test_part_result) {
|
||||
g_events->PushBack(String("TestEventListener::OnNewTestPartResult"));
|
||||
}
|
||||
|
||||
virtual void OnTestEnd(const TestInfo& test_info) {
|
||||
g_events->PushBack(String("TestEventListener::OnTestEnd"));
|
||||
}
|
||||
|
||||
virtual void OnTestCaseEnd(const TestCase& test_case) {
|
||||
g_events->PushBack(String("TestEventListener::OnTestCaseEnd"));
|
||||
}
|
||||
|
||||
virtual void OnGlobalTearDownStart(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnGlobalTearDownStart"));
|
||||
}
|
||||
|
||||
virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnGlobalTearDownEnd"));
|
||||
}
|
||||
|
||||
virtual void OnUnitTestEnd(const UnitTest& unit_test) {
|
||||
g_events->PushBack(String("TestEventListener::OnUnitTestEnd"));
|
||||
}
|
||||
};
|
||||
|
||||
class EnvironmentInvocationCatcher : public Environment {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
g_events->PushBack(String("Environment::SetUp"));
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
g_events->PushBack(String("Environment::TearDown"));
|
||||
}
|
||||
};
|
||||
|
||||
class ListenerTest : public Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {
|
||||
g_events->PushBack(String("ListenerTest::SetUpTestCase"));
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {
|
||||
g_events->PushBack(String("ListenerTest::TearDownTestCase"));
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
g_events->PushBack(String("ListenerTest::SetUp"));
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
g_events->PushBack(String("ListenerTest::TearDown"));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ListenerTest, DoesFoo) {
|
||||
// Test execution order within a test case is not guaranteed so we are not
|
||||
// recording the test name.
|
||||
g_events->PushBack(String("ListenerTest::* Test Body"));
|
||||
SUCCEED(); // Triggers OnTestPartResult.
|
||||
}
|
||||
|
||||
TEST_F(ListenerTest, DoesBar) {
|
||||
g_events->PushBack(String("ListenerTest::* Test Body"));
|
||||
SUCCEED(); // Triggers OnTestPartResult.
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
using ::testing::internal::EnvironmentInvocationCatcher;
|
||||
using ::testing::internal::EventRecordingListener;
|
||||
using ::testing::internal::UnitTestAccessor;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Vector<String> events;
|
||||
g_events = &events;
|
||||
InitGoogleTest(&argc, argv);
|
||||
|
||||
UnitTestEventListenerInterface* listener = new EventRecordingListener;
|
||||
UnitTestAccessor::GetEventListeners().Append(listener);
|
||||
|
||||
AddGlobalTestEnvironment(new EnvironmentInvocationCatcher);
|
||||
|
||||
GTEST_CHECK_(events.size() == 0)
|
||||
<< "AddGlobalTestEnvironment should not generate any events itself.";
|
||||
|
||||
int ret_val = RUN_ALL_TESTS();
|
||||
|
||||
const char* const expected_events[] = {
|
||||
"TestEventListener::OnUnitTestStart",
|
||||
"TestEventListener::OnGlobalSetUpStart",
|
||||
"Environment::SetUp",
|
||||
"TestEventListener::OnGlobalSetUpEnd",
|
||||
"TestEventListener::OnTestCaseStart",
|
||||
"ListenerTest::SetUpTestCase",
|
||||
"TestEventListener::OnTestStart",
|
||||
"ListenerTest::SetUp",
|
||||
"ListenerTest::* Test Body",
|
||||
"TestEventListener::OnNewTestPartResult",
|
||||
"ListenerTest::TearDown",
|
||||
"TestEventListener::OnTestEnd",
|
||||
"TestEventListener::OnTestStart",
|
||||
"ListenerTest::SetUp",
|
||||
"ListenerTest::* Test Body",
|
||||
"TestEventListener::OnNewTestPartResult",
|
||||
"ListenerTest::TearDown",
|
||||
"TestEventListener::OnTestEnd",
|
||||
"ListenerTest::TearDownTestCase",
|
||||
"TestEventListener::OnTestCaseEnd",
|
||||
"TestEventListener::OnGlobalTearDownStart",
|
||||
"Environment::TearDown",
|
||||
"TestEventListener::OnGlobalTearDownEnd",
|
||||
"TestEventListener::OnUnitTestEnd"
|
||||
};
|
||||
const int kExpectedEventsSize =
|
||||
sizeof(expected_events)/sizeof(expected_events[0]);
|
||||
|
||||
// Cannot use ASSERT_EQ() here because it requires the scoping function to
|
||||
// return void.
|
||||
GTEST_CHECK_(events.size() == kExpectedEventsSize);
|
||||
|
||||
for (int i = 0; i < events.size(); ++i)
|
||||
GTEST_CHECK_(String(events.GetElement(i)) == expected_events[i])
|
||||
<< "At position " << i;
|
||||
|
||||
// We need to check manually for ad hoc test failures that happen after
|
||||
// RUN_ALL_TESTS finishes.
|
||||
if (UnitTestAccessor::UnitTestFailed())
|
||||
ret_val = 1;
|
||||
|
||||
return ret_val;
|
||||
}
|
@ -85,7 +85,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
|
||||
TestFlag('break_on_failure', '1', '0')
|
||||
TestFlag('color', 'yes', 'auto')
|
||||
TestFlag('filter', 'FooTest.Bar', '*')
|
||||
TestFlag('output', 'tmp/foo.xml', '')
|
||||
TestFlag('output', 'xml:tmp/foo.xml', '')
|
||||
TestFlag('print_time', '0', '1')
|
||||
TestFlag('repeat', '999', '1')
|
||||
TestFlag('throw_on_failure', '1', '0')
|
||||
|
@ -84,11 +84,38 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms);
|
||||
|
||||
bool ParseInt32Flag(const char* str, const char* flag, Int32* value);
|
||||
|
||||
// Provides access to otherwise private parts of the EventListeners class
|
||||
// that are needed to test it.
|
||||
class EventListenersAccessor {
|
||||
public:
|
||||
static UnitTestEventListenerInterface* GetRepeater(
|
||||
EventListeners* listeners) { return listeners->repeater(); }
|
||||
|
||||
static void SetDefaultResultPrinter(
|
||||
EventListeners* listeners,
|
||||
UnitTestEventListenerInterface* listener) {
|
||||
listeners->SetDefaultResultPrinter(listener);
|
||||
}
|
||||
static void SetDefaultXmlGenerator(EventListeners* listeners,
|
||||
UnitTestEventListenerInterface* listener) {
|
||||
listeners->SetDefaultXmlGenerator(listener);
|
||||
}
|
||||
|
||||
static bool EventForwardingEnabled(const EventListeners& listeners) {
|
||||
return listeners.EventForwardingEnabled();
|
||||
}
|
||||
|
||||
static void SuppressEventForwarding(EventListeners* listeners) {
|
||||
listeners->SuppressEventForwarding();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
using testing::internal::FormatTimeInMillisAsSeconds;
|
||||
using testing::internal::ParseInt32Flag;
|
||||
using testing::internal::EventListenersAccessor;
|
||||
|
||||
namespace testing {
|
||||
|
||||
@ -136,7 +163,9 @@ using testing::internal::kMaxRandomSeed;
|
||||
using testing::internal::kTestTypeIdInGoogleTest;
|
||||
using testing::internal::AppendUserMessage;
|
||||
using testing::internal::CodePointToUtf8;
|
||||
using testing::internal::EmptyTestEventListener;
|
||||
using testing::internal::EqFailure;
|
||||
using testing::internal::EventListeners;
|
||||
using testing::internal::FloatingPoint;
|
||||
using testing::internal::GTestFlagSaver;
|
||||
using testing::internal::GetCurrentOsStackTraceExceptTop;
|
||||
@ -160,6 +189,7 @@ using testing::internal::ThreadLocal;
|
||||
using testing::internal::Vector;
|
||||
using testing::internal::WideStringToUtf8;
|
||||
using testing::internal::kTestTypeIdInGoogleTest;
|
||||
using testing::internal::scoped_ptr;
|
||||
|
||||
// This line tests that we can define tests in an unnamed namespace.
|
||||
namespace {
|
||||
@ -695,14 +725,16 @@ TEST(ListDeathTest, GetElement) {
|
||||
"Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
|
||||
}
|
||||
|
||||
// Tests the String class.
|
||||
// Tests the size of the AssertHelper class.
|
||||
|
||||
TEST(StringTest, SizeIsSmall) {
|
||||
TEST(AssertHelperTest, AssertHelperIsSmall) {
|
||||
// To avoid breaking clients that use lots of assertions in one
|
||||
// function, we cannot grow the size of String.
|
||||
EXPECT_LE(sizeof(String), sizeof(void*));
|
||||
// function, we cannot grow the size of AssertHelper.
|
||||
EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*));
|
||||
}
|
||||
|
||||
// Tests the String class.
|
||||
|
||||
// Tests String's constructors.
|
||||
TEST(StringTest, Constructors) {
|
||||
// Default ctor.
|
||||
@ -1037,6 +1069,33 @@ TEST(StringTest, Streams) {
|
||||
EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b");
|
||||
}
|
||||
|
||||
// Tests that String::Format() works.
|
||||
TEST(StringTest, FormatWorks) {
|
||||
// Normal case: the format spec is valid, the arguments match the
|
||||
// spec, and the result is < 4095 characters.
|
||||
EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str());
|
||||
|
||||
// Edge case: the result is 4095 characters.
|
||||
char buffer[4096];
|
||||
const size_t kSize = sizeof(buffer);
|
||||
memset(buffer, 'a', kSize - 1);
|
||||
buffer[kSize - 1] = '\0';
|
||||
EXPECT_STREQ(buffer, String::Format("%s", buffer).c_str());
|
||||
|
||||
// The result needs to be 4096 characters, exceeding Format()'s limit.
|
||||
EXPECT_STREQ("<formatting error or buffer exceeded>",
|
||||
String::Format("x%s", buffer).c_str());
|
||||
|
||||
#if GTEST_OS_LINUX
|
||||
// On Linux, invalid format spec should lead to an error message.
|
||||
// In other environment (e.g. MSVC on Windows), String::Format() may
|
||||
// simply ignore a bad format spec, so this assertion is run on
|
||||
// Linux only.
|
||||
EXPECT_STREQ("<formatting error or buffer exceeded>",
|
||||
String::Format("%").c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
|
||||
// Tests String::ShowWideCString().
|
||||
@ -6142,3 +6201,275 @@ TEST(HasFailureTest, WorksOutsideOfTestBody2) {
|
||||
ClearCurrentTestPartResults();
|
||||
EXPECT_TRUE(has_failure);
|
||||
}
|
||||
|
||||
class TestListener : public EmptyTestEventListener {
|
||||
public:
|
||||
TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {}
|
||||
TestListener(int* on_start_counter, bool* is_destroyed)
|
||||
: on_start_counter_(on_start_counter),
|
||||
is_destroyed_(is_destroyed) {}
|
||||
|
||||
virtual ~TestListener() {
|
||||
if (is_destroyed_)
|
||||
*is_destroyed_ = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {
|
||||
if (on_start_counter_ != NULL)
|
||||
(*on_start_counter_)++;
|
||||
}
|
||||
|
||||
private:
|
||||
int* on_start_counter_;
|
||||
bool* is_destroyed_;
|
||||
};
|
||||
|
||||
// Tests the constructor.
|
||||
TEST(EventListenersTest, ConstructionWorks) {
|
||||
EventListeners listeners;
|
||||
|
||||
EXPECT_TRUE(EventListenersAccessor::GetRepeater(&listeners) != NULL);
|
||||
EXPECT_TRUE(listeners.default_result_printer() == NULL);
|
||||
EXPECT_TRUE(listeners.default_xml_generator() == NULL);
|
||||
}
|
||||
|
||||
// Tests that the EventListeners destructor deletes all the listeners it
|
||||
// owns.
|
||||
TEST(EventListenersTest, DestructionWorks) {
|
||||
bool default_result_printer_is_destroyed = false;
|
||||
bool default_xml_printer_is_destroyed = false;
|
||||
bool extra_listener_is_destroyed = false;
|
||||
TestListener* default_result_printer = new TestListener(
|
||||
NULL, &default_result_printer_is_destroyed);
|
||||
TestListener* default_xml_printer = new TestListener(
|
||||
NULL, &default_xml_printer_is_destroyed);
|
||||
TestListener* extra_listener = new TestListener(
|
||||
NULL, &extra_listener_is_destroyed);
|
||||
|
||||
{
|
||||
EventListeners listeners;
|
||||
EventListenersAccessor::SetDefaultResultPrinter(&listeners,
|
||||
default_result_printer);
|
||||
EventListenersAccessor::SetDefaultXmlGenerator(&listeners,
|
||||
default_xml_printer);
|
||||
listeners.Append(extra_listener);
|
||||
}
|
||||
EXPECT_TRUE(default_result_printer_is_destroyed);
|
||||
EXPECT_TRUE(default_xml_printer_is_destroyed);
|
||||
EXPECT_TRUE(extra_listener_is_destroyed);
|
||||
}
|
||||
|
||||
// Tests that a listener Append'ed to an EventListeners list starts
|
||||
// receiving events.
|
||||
TEST(EventListenersTest, Append) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
{
|
||||
EventListeners listeners;
|
||||
listeners.Append(listener);
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(1, on_start_counter);
|
||||
}
|
||||
EXPECT_TRUE(is_destroyed);
|
||||
}
|
||||
|
||||
// Tests that listeners receive requests in the order they were appended to
|
||||
// the list.
|
||||
class SequenceTestingListener : public EmptyTestEventListener {
|
||||
public:
|
||||
SequenceTestingListener(Vector<const char*>* vector, const char* signature)
|
||||
: vector_(vector), signature_(signature) {}
|
||||
|
||||
protected:
|
||||
virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {
|
||||
if (vector_ != NULL)
|
||||
vector_->PushBack(signature_);
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<const char*>* vector_;
|
||||
const char* const signature_;
|
||||
};
|
||||
|
||||
TEST(EventListenerTest, AppendKeepsOrder) {
|
||||
Vector<const char*> vec;
|
||||
EventListeners listeners;
|
||||
listeners.Append(new SequenceTestingListener(&vec, "0"));
|
||||
listeners.Append(new SequenceTestingListener(&vec, "1"));
|
||||
listeners.Append(new SequenceTestingListener(&vec, "2"));
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
ASSERT_EQ(3, vec.size());
|
||||
ASSERT_STREQ("0", vec.GetElement(0));
|
||||
ASSERT_STREQ("1", vec.GetElement(1));
|
||||
ASSERT_STREQ("2", vec.GetElement(2));
|
||||
}
|
||||
|
||||
// Tests that a listener removed from an EventListeners list stops receiving
|
||||
// events and is not deleted when the list is destroyed.
|
||||
TEST(EventListenersTest, Release) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
// Although Append passes the ownership of this object to the list,
|
||||
// the following calls release it, and we need to delete it before the
|
||||
// test ends.
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
{
|
||||
EventListeners listeners;
|
||||
listeners.Append(listener);
|
||||
EXPECT_EQ(listener, listeners.Release(listener));
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_TRUE(listeners.Release(listener) == NULL);
|
||||
}
|
||||
EXPECT_EQ(0, on_start_counter);
|
||||
EXPECT_FALSE(is_destroyed);
|
||||
delete listener;
|
||||
}
|
||||
|
||||
// Tests that no events are forwarded when event forwarding is disabled.
|
||||
TEST(EventListenerTest, SuppressEventForwarding) {
|
||||
int on_start_counter = 0;
|
||||
TestListener* listener = new TestListener(&on_start_counter, NULL);
|
||||
|
||||
EventListeners listeners;
|
||||
listeners.Append(listener);
|
||||
ASSERT_TRUE(EventListenersAccessor::EventForwardingEnabled(listeners));
|
||||
EventListenersAccessor::SuppressEventForwarding(&listeners);
|
||||
ASSERT_FALSE(EventListenersAccessor::EventForwardingEnabled(listeners));
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(0, on_start_counter);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
// Tests that events generated by Google Test are not forwarded in
|
||||
// death test subprocesses.
|
||||
TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) {
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
GTEST_CHECK_(EventListenersAccessor::EventForwardingEnabled(
|
||||
*GetUnitTestImpl()->listeners())) << "expected failure";},
|
||||
"expected failure");
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that a listener installed via SetDefaultResultPrinter() starts
|
||||
// receiving events and is returned via default_result_printer() and that
|
||||
// the previous default_result_printer is removed from the list and deleted.
|
||||
TEST(EventListenerTest, default_result_printer) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
|
||||
EventListeners listeners;
|
||||
EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener);
|
||||
|
||||
EXPECT_EQ(listener, listeners.default_result_printer());
|
||||
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
|
||||
EXPECT_EQ(1, on_start_counter);
|
||||
|
||||
// Replacing default_result_printer with something else should remove it
|
||||
// from the list and destroy it.
|
||||
EventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL);
|
||||
|
||||
EXPECT_TRUE(listeners.default_result_printer() == NULL);
|
||||
EXPECT_TRUE(is_destroyed);
|
||||
|
||||
// After broadcasting an event the counter is still the same, indicating
|
||||
// the listener is not in the list anymore.
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(1, on_start_counter);
|
||||
}
|
||||
|
||||
// Tests that the default_result_printer listener stops receiving events
|
||||
// when removed via Release and that is not owned by the list anymore.
|
||||
TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
// Although Append passes the ownership of this object to the list,
|
||||
// the following calls release it, and we need to delete it before the
|
||||
// test ends.
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
{
|
||||
EventListeners listeners;
|
||||
EventListenersAccessor::SetDefaultResultPrinter(&listeners, listener);
|
||||
|
||||
EXPECT_EQ(listener, listeners.Release(listener));
|
||||
EXPECT_TRUE(listeners.default_result_printer() == NULL);
|
||||
EXPECT_FALSE(is_destroyed);
|
||||
|
||||
// Broadcasting events now should not affect default_result_printer.
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(0, on_start_counter);
|
||||
}
|
||||
// Destroying the list should not affect the listener now, too.
|
||||
EXPECT_FALSE(is_destroyed);
|
||||
delete listener;
|
||||
}
|
||||
|
||||
// Tests that a listener installed via SetDefaultXmlGenerator() starts
|
||||
// receiving events and is returned via default_xml_generator() and that
|
||||
// the previous default_xml_generator is removed from the list and deleted.
|
||||
TEST(EventListenerTest, default_xml_generator) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
|
||||
EventListeners listeners;
|
||||
EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener);
|
||||
|
||||
EXPECT_EQ(listener, listeners.default_xml_generator());
|
||||
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
|
||||
EXPECT_EQ(1, on_start_counter);
|
||||
|
||||
// Replacing default_xml_generator with something else should remove it
|
||||
// from the list and destroy it.
|
||||
EventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL);
|
||||
|
||||
EXPECT_TRUE(listeners.default_xml_generator() == NULL);
|
||||
EXPECT_TRUE(is_destroyed);
|
||||
|
||||
// After broadcasting an event the counter is still the same, indicating
|
||||
// the listener is not in the list anymore.
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(1, on_start_counter);
|
||||
}
|
||||
|
||||
// Tests that the default_xml_generator listener stops receiving events
|
||||
// when removed via Release and that is not owned by the list anymore.
|
||||
TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) {
|
||||
int on_start_counter = 0;
|
||||
bool is_destroyed = false;
|
||||
// Although Append passes the ownership of this object to the list,
|
||||
// the following calls release it, and we need to delete it before the
|
||||
// test ends.
|
||||
TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
|
||||
{
|
||||
EventListeners listeners;
|
||||
EventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener);
|
||||
|
||||
EXPECT_EQ(listener, listeners.Release(listener));
|
||||
EXPECT_TRUE(listeners.default_xml_generator() == NULL);
|
||||
EXPECT_FALSE(is_destroyed);
|
||||
|
||||
// Broadcasting events now should not affect default_xml_generator.
|
||||
EventListenersAccessor::GetRepeater(&listeners)->OnUnitTestStart(
|
||||
*UnitTest::GetInstance());
|
||||
EXPECT_EQ(0, on_start_counter);
|
||||
}
|
||||
// Destroying the list should not affect the listener now, too.
|
||||
EXPECT_FALSE(is_destroyed);
|
||||
delete listener;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import gtest_xml_test_utils
|
||||
|
||||
GTEST_OUTPUT_FLAG = "--gtest_output"
|
||||
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
|
||||
GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
|
||||
|
||||
SUPPORTS_STACK_TRACES = False
|
||||
|
||||
@ -108,8 +109,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
|
||||
Runs a test program that generates a non-empty XML output, and
|
||||
tests that the XML output is expected.
|
||||
"""
|
||||
self._TestXmlOutput("gtest_xml_output_unittest_",
|
||||
EXPECTED_NON_EMPTY_XML, 1)
|
||||
self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
|
||||
|
||||
def testEmptyXmlOutput(self):
|
||||
"""
|
||||
@ -142,6 +142,35 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
|
||||
self.assertEquals(0, p.exit_code)
|
||||
self.assert_(os.path.isfile(output_file))
|
||||
|
||||
def testSuppressedXmlOutput(self):
|
||||
"""
|
||||
Tests that no XML file is generated if the default XML listener is
|
||||
shut down before RUN_ALL_TESTS is invoked.
|
||||
"""
|
||||
|
||||
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
|
||||
GTEST_PROGRAM_NAME + "out.xml")
|
||||
if os.path.isfile(xml_path):
|
||||
os.remove(xml_path)
|
||||
|
||||
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
|
||||
|
||||
command = [gtest_prog_path,
|
||||
"%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path),
|
||||
"--shut_down_xml"]
|
||||
p = gtest_test_utils.Subprocess(command)
|
||||
if p.terminated_by_signal:
|
||||
self.assert_(False,
|
||||
"%s was killed by signal %d" % (gtest_prog_name, p.signal))
|
||||
else:
|
||||
self.assert_(p.exited)
|
||||
self.assertEquals(1, p.exit_code,
|
||||
"'%s' exited with code %s, which doesn't match "
|
||||
"the expected exit code %s."
|
||||
% (command, p.exit_code, 1))
|
||||
|
||||
self.assert_(not os.path.isfile(xml_path))
|
||||
|
||||
|
||||
def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code):
|
||||
"""
|
||||
|
@ -40,6 +40,20 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// TODO(vladl@google.com): Remove this include when the event listener API is
|
||||
// published and GetUnitTestImpl is no longer needed.
|
||||
//
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// his code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
using ::testing::InitGoogleTest;
|
||||
|
||||
class SuccessfulTest : public testing::Test {
|
||||
};
|
||||
|
||||
@ -118,3 +132,17 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) {
|
||||
TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) {
|
||||
ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
InitGoogleTest(&argc, argv);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) {
|
||||
// TODO(vladl@google.com): Replace GetUnitTestImpl()->listeners() with
|
||||
// UnitTest::GetInstance()->listeners() when the event listener API is
|
||||
// published.
|
||||
::testing::internal::EventListeners& listeners =
|
||||
*::testing::internal::GetUnitTestImpl()->listeners();
|
||||
delete listeners.Release(listeners.default_xml_generator());
|
||||
}
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user