mirror of
https://github.com/google/googletest.git
synced 2025-11-13 08:15:04 -05:00
More implementation of the event listener interface (by Vlad Losev); Reduces the stack space usage of assertions by moving AssertHelper's fields to the heap (by Jorg Brown); Makes String faster, smaller, and simpler (by Zhanyong Wan); Fixes a bug in String::Format() (by Chandler); Adds the /MD version of VC projects to the distribution (by Vlad Losev).
This commit is contained in:
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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user