diff options
author | shiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925> | 2008-10-11 07:20:02 +0000 |
---|---|---|
committer | shiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925> | 2008-10-11 07:20:02 +0000 |
commit | e0865dd9199e8fffd5c2f95a68de6c1851f77c15 (patch) | |
tree | 975905bb872df284353ddfc50f930f48979ec4d3 /src | |
parent | 0cbe322d372e7f3463c7d49628ddad871334691d (diff) | |
download | googletest-e0865dd9199e8fffd5c2f95a68de6c1851f77c15.tar.gz googletest-e0865dd9199e8fffd5c2f95a68de6c1851f77c15.tar.bz2 googletest-e0865dd9199e8fffd5c2f95a68de6c1851f77c15.zip |
Many changes:
- appends "_" to internal macro names (by Markus Heule).
- makes Google Test work with newer versions of tools on Symbian and Windows CE (by Mika Raento).
- adds the (ASSERT|EXPECT)_NO_FATAL_FAILURE macros (by Markus Heule).
- changes EXPECT_(NON|)FATAL_FAILURE to catch failures in the current thread only (by Markus Heule).
- adds the EXPECT_(NON|)FATAL_FAILURE_ON_ALL_THREADS macros (by Markus Heule).
- adds GTEST_HAS_PTHREAD and GTEST_IS_THREADSAFE to indicate the availability of <pthread.h> and Google Test's thread-safety (by Zhanyong Wan).
- adds scons/SConscript for building with scons (by Joi Sigurdsson).
- adds src/gtest-all.cc for building Google Test from a single file (by Markus Heule).
- updates the xcode project to include new tests (by Preston Jackson).
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest-all.cc | 41 | ||||
-rw-r--r-- | src/gtest-death-test.cc | 68 | ||||
-rw-r--r-- | src/gtest-filepath.cc | 8 | ||||
-rw-r--r-- | src/gtest-internal-inl.h | 109 | ||||
-rw-r--r-- | src/gtest-port.cc | 2 | ||||
-rw-r--r-- | src/gtest-test-part.cc | 124 | ||||
-rw-r--r-- | src/gtest.cc | 256 |
7 files changed, 421 insertions, 187 deletions
diff --git a/src/gtest-all.cc b/src/gtest-all.cc new file mode 100644 index 00000000..a67ea0fa --- /dev/null +++ b/src/gtest-all.cc @@ -0,0 +1,41 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index fa800879..b667682f 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -59,7 +59,7 @@ namespace testing { // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; -GTEST_DEFINE_string( +GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " @@ -69,7 +69,7 @@ GTEST_DEFINE_string( "after forking)."); namespace internal { -GTEST_DEFINE_string( +GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " @@ -188,7 +188,7 @@ void DeathTestAbort(const char* format, ...) { // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. -#define GTEST_DEATH_TEST_CHECK(expression) \ +#define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!(expression)) { \ DeathTestAbort("CHECK failed: File %s, line %d: %s", \ @@ -196,14 +196,14 @@ void DeathTestAbort(const char* format, ...) { } \ } while (0) -// This macro is similar to GTEST_DEATH_TEST_CHECK, but it is meant for +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. -#define GTEST_DEATH_TEST_CHECK_SYSCALL(expression) \ +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int retval; \ do { \ @@ -303,11 +303,11 @@ static void FailFromInternalError(int fd) { // TODO(smcafee): Maybe just FAIL the test instead? if (num_read == 0) { - GTEST_LOG(FATAL, error); + GTEST_LOG_(FATAL, error); } else { - GTEST_LOG(FATAL, - Message() << "Error while reading death test internal: " - << strerror(errno) << " [" << errno << "]"); + GTEST_LOG_(FATAL, + Message() << "Error while reading death test internal: " + << strerror(errno) << " [" << errno << "]"); } } @@ -343,19 +343,19 @@ int ForkingDeathTest::Wait() { FailFromInternalError(read_fd_); // Does not return. break; default: - GTEST_LOG(FATAL, - Message() << "Death test child process reported unexpected " - << "status byte (" << static_cast<unsigned int>(flag) - << ")"); + GTEST_LOG_(FATAL, + Message() << "Death test child process reported unexpected " + << "status byte (" << static_cast<unsigned int>(flag) + << ")"); } } else { - GTEST_LOG(FATAL, - Message() << "Read from death test child process failed: " - << strerror(errno)); + GTEST_LOG_(FATAL, + Message() << "Read from death test child process failed: " + << strerror(errno)); } - GTEST_DEATH_TEST_CHECK_SYSCALL(close(read_fd_)); - GTEST_DEATH_TEST_CHECK_SYSCALL(waitpid(child_pid_, &status_, 0)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_, 0)); return status_; } @@ -418,8 +418,8 @@ bool ForkingDeathTest::Passed(bool status_ok) { break; case IN_PROGRESS: default: - GTEST_LOG(FATAL, - "DeathTest::Passed somehow called before conclusion of test"); + GTEST_LOG_(FATAL, + "DeathTest::Passed somehow called before conclusion of test"); } last_death_test_message = buffer.GetString(); @@ -436,8 +436,8 @@ void ForkingDeathTest::Abort(AbortReason reason) { // to the pipe, then exit. const char flag = reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; - GTEST_DEATH_TEST_CHECK_SYSCALL(write(write_fd_, &flag, 1)); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(write_fd_)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(write(write_fd_, &flag, 1)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(write_fd_)); _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } @@ -455,11 +455,11 @@ class NoExecDeathTest : public ForkingDeathTest { DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { - GTEST_LOG(WARNING, DeathTestThreadWarning(thread_count)); + GTEST_LOG_(WARNING, DeathTestThreadWarning(thread_count)); } int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1); + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); last_death_test_message = ""; CaptureStderr(); @@ -473,10 +473,10 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { FlushInfoLog(); const pid_t child_pid = fork(); - GTEST_DEATH_TEST_CHECK(child_pid != -1); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[0])); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent @@ -484,7 +484,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { LogToStderr(); return EXECUTE_TEST; } else { - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1])); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_forked(true); return OVERSEE_TEST; @@ -551,7 +551,7 @@ struct ExecDeathTestArgs { // any potentially unsafe operations like malloc or libc functions. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(args->close_fd)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original @@ -599,14 +599,14 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { const size_t stack_size = getpagesize(); void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - GTEST_DEATH_TEST_CHECK(stack != MAP_FAILED); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); void* const stack_top = static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); ExecDeathTestArgs args = { argv, close_fd }; const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); - GTEST_DEATH_TEST_CHECK(child_pid != -1); - GTEST_DEATH_TEST_CHECK(munmap(stack, stack_size) != -1); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); return child_pid; } @@ -627,10 +627,10 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { } int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1); + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: - GTEST_DEATH_TEST_CHECK(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const String filter_flag = String::Format("--%s%s=%s.%s", @@ -654,7 +654,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { FlushInfoLog(); const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1])); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); set_forked(true); diff --git a/src/gtest-filepath.cc b/src/gtest-filepath.cc index dc0d78f0..fdb05629 100644 --- a/src/gtest-filepath.cc +++ b/src/gtest-filepath.cc @@ -36,10 +36,14 @@ #ifdef _WIN32_WCE #include <windows.h> -#elif defined(_WIN32) +#elif defined(GTEST_OS_WINDOWS) #include <direct.h> #include <io.h> #include <sys/stat.h> +#elif defined(GTEST_OS_SYMBIAN) +// Symbian OpenC has PATH_MAX in sys/syslimits.h +#include <sys/syslimits.h> +#include <unistd.h> #else #include <sys/stat.h> #include <unistd.h> @@ -249,7 +253,7 @@ bool FilePath::CreateDirectoriesRecursively() const { // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { -#ifdef _WIN32 +#ifdef GTEST_OS_WINDOWS #ifdef _WIN32_WCE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index d4889483..ce1d0f4f 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -64,16 +64,16 @@ namespace testing { // We don't want the users to modify these flags in the code, but want // Google Test's own unit tests to be able to access them. Therefore we // declare them here as opposed to in gtest.h. -GTEST_DECLARE_bool(break_on_failure); -GTEST_DECLARE_bool(catch_exceptions); -GTEST_DECLARE_string(color); -GTEST_DECLARE_string(filter); -GTEST_DECLARE_bool(list_tests); -GTEST_DECLARE_string(output); -GTEST_DECLARE_bool(print_time); -GTEST_DECLARE_int32(repeat); -GTEST_DECLARE_int32(stack_trace_depth); -GTEST_DECLARE_bool(show_internal_stack_frames); +GTEST_DECLARE_bool_(break_on_failure); +GTEST_DECLARE_bool_(catch_exceptions); +GTEST_DECLARE_string_(color); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_bool_(list_tests); +GTEST_DECLARE_string_(output); +GTEST_DECLARE_bool_(print_time); +GTEST_DECLARE_int32_(repeat); +GTEST_DECLARE_int32_(stack_trace_depth); +GTEST_DECLARE_bool_(show_internal_stack_frames); namespace internal { @@ -131,7 +131,7 @@ class GTestFlagSaver { bool print_time_; bool pretty_; internal::Int32 repeat_; -} GTEST_ATTRIBUTE_UNUSED; +} GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be @@ -200,7 +200,7 @@ class ListNode { explicit ListNode(const E & element) : element_(element), next_(NULL) {} // We disallow copying ListNode - GTEST_DISALLOW_COPY_AND_ASSIGN(ListNode); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ListNode); public: @@ -399,7 +399,7 @@ class List { int size_; // The number of elements in the list. // We disallow copying List. - GTEST_DISALLOW_COPY_AND_ASSIGN(List); + GTEST_DISALLOW_COPY_AND_ASSIGN_(List); }; // The virtual destructor of List. @@ -557,7 +557,7 @@ class TestResult { TimeInMillis elapsed_time_; // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN(TestResult); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult class TestInfoImpl { @@ -633,7 +633,7 @@ class TestInfoImpl { // test for the second time. internal::TestResult result_; - GTEST_DISALLOW_COPY_AND_ASSIGN(TestInfoImpl); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); }; } // namespace internal @@ -765,7 +765,7 @@ class TestCase { internal::TimeInMillis elapsed_time_; // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN(TestCase); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; namespace internal { @@ -843,7 +843,7 @@ class OsStackTraceGetterInterface { virtual void UponLeavingGTest() = 0; private: - GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetterInterface); + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implemenation of the OsStackTraceGetterInterface interface. @@ -866,7 +866,7 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface { // and any calls to CurrentStackTrace() from within the user code. void* caller_frame_; - GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. @@ -876,24 +876,63 @@ struct TraceInfo { String message; }; +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; +}; + // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. -class UnitTestImpl : public TestPartResultReporterInterface { +class UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); - // Reports a test part result. This method is from the - // TestPartResultReporterInterface interface. - virtual void ReportTestPartResult(const TestPartResult& result); + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); - // Returns the current test part result reporter. - TestPartResultReporterInterface* test_part_result_reporter(); + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); - // Sets the current test part result reporter. - void set_test_part_result_reporter(TestPartResultReporterInterface* reporter); + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); // Gets the number of successful test cases. int successful_test_case_count() const; @@ -1107,8 +1146,20 @@ class UnitTestImpl : public TestPartResultReporterInterface { // executed. internal::FilePath original_working_dir_; - // Points to (but doesn't own) the test part result reporter. - TestPartResultReporterInterface* test_part_result_reporter_; + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal<TestPartResultReporterInterface*> + per_thread_test_part_result_reporter_; // The list of environments that need to be set-up/torn-down // before/after the tests are run. environments_in_reverse_order_ @@ -1168,7 +1219,7 @@ class UnitTestImpl : public TestPartResultReporterInterface { // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal<internal::List<TraceInfo> > gtest_trace_stack_; - GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestImpl); + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest diff --git a/src/gtest-port.cc b/src/gtest-port.cc index b2871b8b..000a4ab1 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -172,7 +172,7 @@ static ::std::string ReadEntireFile(FILE * file) { // Starts capturing stderr. void CaptureStderr() { if (g_captured_stderr != NULL) { - GTEST_LOG(FATAL, "Only one stderr capturer can exist at one time."); + GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time."); } g_captured_stderr = new CapturedStderr; } diff --git a/src/gtest-test-part.cc b/src/gtest-test-part.cc new file mode 100644 index 00000000..dcd30b25 --- /dev/null +++ b/src/gtest-test-part.cc @@ -0,0 +1,124 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include <gtest/gtest-test-part.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 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? internal::String(message) : + internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os << result.file_name() << ":" + << result.line_number() << ": " + << (result.type() == TPRT_SUCCESS ? "Success" : + result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Constructs an empty TestPartResultArray. +TestPartResultArray::TestPartResultArray() + : list_(new internal::List<TestPartResult>) { +} + +// Destructs a TestPartResultArray. +TestPartResultArray::~TestPartResultArray() { + delete list_; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + list_->PushBack(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::abort(); + } + + const internal::ListNode<TestPartResult>* p = list_->Head(); + for (int i = 0; i < index; i++) { + p = p->next(); + } + + return p->element(); +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return list_->size(); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(UnitTest::GetInstance()->impl()-> + GetTestPartResultReporterForCurrentThread()) { + UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( + this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/src/gtest.cc b/src/gtest.cc index f8c11997..9cc50e05 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -60,11 +60,16 @@ #include <string> #include <vector> +#elif defined(GTEST_OS_SYMBIAN) +// No autoconf on Symbian +#define GTEST_HAS_GETTIMEOFDAY +#include <sys/time.h> // NOLINT + #elif defined(_WIN32_WCE) // We are on Windows CE. #include <windows.h> // NOLINT -#elif defined(_WIN32) // We are on Windows proper. +#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. #include <io.h> // NOLINT #include <sys/timeb.h> // NOLINT @@ -134,22 +139,26 @@ static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; +namespace internal { + // The text used in failure messages to indicate the start of the // stack trace. -static const char kStackTraceMarker[] = "\nStack trace:\n"; +const char kStackTraceMarker[] = "\nStack trace:\n"; + +} // namespace internal -GTEST_DEFINE_bool( +GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); -GTEST_DEFINE_bool( +GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", false), "True iff " GTEST_NAME " should catch exceptions and treat them as test failures."); -GTEST_DEFINE_string( +GTEST_DEFINE_string_( color, internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " @@ -157,7 +166,7 @@ GTEST_DEFINE_string( "being sent to a terminal and the TERM environment variable " "is set to xterm or xterm-color."); -GTEST_DEFINE_string( +GTEST_DEFINE_string_( filter, internal::StringFromGTestEnv("filter", kUniversalFilter), "A colon-separated list of glob (not regex) patterns " @@ -166,10 +175,10 @@ GTEST_DEFINE_string( "exclude). A test is run if it matches one of the positive " "patterns and does not match any of the negative patterns."); -GTEST_DEFINE_bool(list_tests, false, - "List all tests without running them."); +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); -GTEST_DEFINE_string( +GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), "A format (currently must be \"xml\"), optionally followed " @@ -181,37 +190,29 @@ GTEST_DEFINE_string( "executable's name and, if necessary, made unique by adding " "digits."); -GTEST_DEFINE_bool( +GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", false), "True iff " GTEST_NAME " should display elapsed time in text output."); -GTEST_DEFINE_int32( +GTEST_DEFINE_int32_( repeat, internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); -GTEST_DEFINE_int32( +GTEST_DEFINE_int32_( stack_trace_depth, internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); -GTEST_DEFINE_bool( +GTEST_DEFINE_bool_( show_internal_stack_frames, false, "True iff " GTEST_NAME " should include internal stack frames when " "printing test failure stack traces."); -// Gets the summary of the failure message by omitting the stack trace -// in it. -internal::String TestPartResult::ExtractSummary(const char* message) { - const char* const stack_trace = strstr(message, kStackTraceMarker); - return stack_trace == NULL ? internal::String(message) : - internal::String(message, stack_trace - message); -} - namespace internal { // GTestIsInitialized() returns true iff the user has initialized @@ -280,11 +281,11 @@ String g_executable_path; FilePath GetCurrentExecutableName() { FilePath result; -#if defined(_WIN32_WCE) || defined(_WIN32) +#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); -#endif // _WIN32_WCE || _WIN32 +#endif // _WIN32_WCE || GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } @@ -456,58 +457,46 @@ class UnitTestEventListenerInterface { virtual void OnNewTestPartResult(const TestPartResult*) {} }; -// Constructs an empty TestPartResultArray. -TestPartResultArray::TestPartResultArray() - : list_(new internal::List<TestPartResult>) { -} - -// Destructs a TestPartResultArray. -TestPartResultArray::~TestPartResultArray() { - delete list_; -} - -// Appends a TestPartResult to the array. -void TestPartResultArray::Append(const TestPartResult& result) { - list_->PushBack(result); -} - -// Returns the TestPartResult at the given index (0-based). -const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { - if (index < 0 || index >= size()) { - printf("\nInvalid index (%d) into TestPartResultArray.\n", index); - internal::abort(); - } - - const internal::ListNode<TestPartResult>* p = list_->Head(); - for (int i = 0; i < index; i++) { - p = p->next(); - } - - return p->element(); -} - -// Returns the number of TestPartResult objects in the array. -int TestPartResultArray::size() const { - return list_->size(); +// 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. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); } // 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. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - TestPartResultArray* result) - : old_reporter_(UnitTest::GetInstance()->impl()-> - test_part_result_reporter()), + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); - impl->set_test_part_result_reporter(this); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } } // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - UnitTest::GetInstance()->impl()-> - set_test_part_result_reporter(old_reporter_); + internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } } // Increments the test part result count and remembers the result. @@ -579,21 +568,47 @@ SingleFailureChecker::~SingleFailureChecker() { EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); } -// Reports a test part result. -void UnitTestImpl::ReportTestPartResult(const TestPartResult& result) { - current_test_result()->AddTestPartResult(result); - result_printer()->OnNewTestPartResult(&result); +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->result_printer()->OnNewTestPartResult(&result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; } -// Returns the current test part result reporter. -TestPartResultReporterInterface* UnitTestImpl::test_part_result_reporter() { - return test_part_result_reporter_; +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); } -// Sets the current test part result reporter. -void UnitTestImpl::set_test_part_result_reporter( +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter) { - test_part_result_reporter_ = reporter; + per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. @@ -678,7 +693,7 @@ static TimeInMillis GetTimeInMillis() { return now_int64.QuadPart; } return 0; -#elif defined(_WIN32) && !defined(GTEST_HAS_GETTIMEOFDAY) +#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_HAS_GETTIMEOFDAY) __timeb64 now; #ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 @@ -1039,7 +1054,7 @@ AssertionResult CmpHelperEQ(const char* expected_expression, // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. -#define GTEST_IMPL_CMP_HELPER(op_name, op)\ +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ BiggestInt val1, BiggestInt val2) {\ if (val1 op val2) {\ @@ -1055,21 +1070,21 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. -GTEST_IMPL_CMP_HELPER(NE, !=) +GTEST_IMPL_CMP_HELPER_(NE, !=) // Implements the helper function for {ASSERT|EXPECT}_LE with int or // enum arguments. -GTEST_IMPL_CMP_HELPER(LE, <=) +GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. -GTEST_IMPL_CMP_HELPER(LT, < ) +GTEST_IMPL_CMP_HELPER_(LT, < ) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. -GTEST_IMPL_CMP_HELPER(GE, >=) +GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. -GTEST_IMPL_CMP_HELPER(GT, > ) +GTEST_IMPL_CMP_HELPER_(GT, > ) -#undef GTEST_IMPL_CMP_HELPER +#undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, @@ -1722,19 +1737,6 @@ String AppendUserMessage(const String& gtest_msg, return msg.GetString(); } -} // namespace internal - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os << result.file_name() << ":" - << result.line_number() << ": " - << (result.type() == TPRT_SUCCESS ? "Success" : - result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" : - "Non-fatal failure") << ":\n" - << result.message() << std::endl; -} - -namespace internal { // class TestResult // Creates an empty TestResult. @@ -2380,7 +2382,7 @@ enum GTestColor { COLOR_YELLOW }; -#if defined(_WIN32) && !defined(_WIN32_WCE) +#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -2404,14 +2406,14 @@ const char* GetAnsiColorCode(GTestColor color) { return NULL; } -#endif // _WIN32 && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !_WIN32_WCE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { -#ifdef _WIN32 +#ifdef GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; @@ -2423,7 +2425,7 @@ bool ShouldUseColor(bool stdout_is_tty) { String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; -#endif // _WIN32 +#endif // GTEST_OS_WINDOWS } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || @@ -2443,7 +2445,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(GTEST_OS_SYMBIAN) static const bool use_color = false; #else static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0); @@ -2456,7 +2458,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(_WIN32) && !defined(_WIN32_WCE) +#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -2474,7 +2476,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. -#endif // _WIN32 && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !_WIN32_WCE va_end(args); } @@ -2718,7 +2720,7 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface { private: Listeners listeners_; - GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestEventsRepeater); + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater); }; UnitTestEventsRepeater::~UnitTestEventsRepeater() { @@ -2736,7 +2738,7 @@ void UnitTestEventsRepeater::AddListener( // 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) \ +#define GTEST_REPEATER_METHOD_(Name, Type) \ void UnitTestEventsRepeater::Name(const Type* parameter) { \ for (ListenersNode* listener = listeners_.Head(); \ listener != NULL; \ @@ -2745,19 +2747,19 @@ void UnitTestEventsRepeater::Name(const Type* parameter) { \ } \ } -GTEST_REPEATER_METHOD(OnUnitTestStart, UnitTest) -GTEST_REPEATER_METHOD(OnUnitTestEnd, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalSetUpStart, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalSetUpEnd, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalTearDownStart, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalTearDownEnd, UnitTest) -GTEST_REPEATER_METHOD(OnTestCaseStart, TestCase) -GTEST_REPEATER_METHOD(OnTestCaseEnd, TestCase) -GTEST_REPEATER_METHOD(OnTestStart, TestInfo) -GTEST_REPEATER_METHOD(OnTestEnd, TestInfo) -GTEST_REPEATER_METHOD(OnNewTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnUnitTestStart, UnitTest) +GTEST_REPEATER_METHOD_(OnUnitTestEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalSetUpEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalTearDownStart, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalTearDownEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult) -#undef GTEST_REPEATER_METHOD +#undef GTEST_REPEATER_METHOD_ // End PrettyUnitTestResultPrinter @@ -2818,7 +2820,7 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { // The output file. const internal::String output_file_; - GTEST_DISALLOW_COPY_AND_ASSIGN(XmlUnitTestResultPrinter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. @@ -3181,13 +3183,14 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, } if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { - msg << kStackTraceMarker << os_stack_trace; + msg << internal::kStackTraceMarker << os_stack_trace; } const TestPartResult result = TestPartResult(result_type, file_name, line_number, msg.GetString().c_str()); - impl_->test_part_result_reporter()->ReportTestPartResult(result); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); // If this is a failure and the user wants the debugger to break on // failures ... @@ -3291,6 +3294,21 @@ namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), test_cases_(), last_death_test_case_(NULL), current_test_case_(NULL), @@ -3305,10 +3323,6 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) #else elapsed_time_(0) { #endif // GTEST_HAS_DEATH_TEST - // We do the assignment here instead of in the initializer list, as - // doing that latter causes MSVC to issue a warning about using - // 'this' in initializers. - test_part_result_reporter_ = this; } UnitTestImpl::~UnitTestImpl() { |