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