diff options
Diffstat (limited to 'utils/unittest/googletest')
26 files changed, 6852 insertions, 2621 deletions
diff --git a/utils/unittest/googletest/Makefile b/utils/unittest/googletest/Makefile index 1ec979d..21b29ff 100644 --- a/utils/unittest/googletest/Makefile +++ b/utils/unittest/googletest/Makefile @@ -23,9 +23,12 @@ CPP.Flags += $(NO_MISSING_FIELD_INITIALIZERS) $(NO_VARIADIC_MACROS) CPP.Flags += -DGTEST_HAS_RTTI=0 # libstdc++'s TR1 <tuple> header depends on RTTI and uses C++'0x features not # supported by Clang, so force googletest to use its own tuple implementation. -# When we import googletest >=1.4.0, we can drop this line. -CPP.Flags += -DGTEST_HAS_TR1_TUPLE=0 +CPP.Flags += -DGTEST_USE_OWN_TR1_TUPLE +# Disable pthreads if LLVM was configured without them. +ifneq ($(HAVE_PTHREAD), 1) + CPP.Flags += -DGTEST_HAS_PTHREAD=0 +endif ifeq ($(HOST_OS),MingW) CPP.Flags += -DGTEST_OS_WINDOWS=1 diff --git a/utils/unittest/googletest/README.LLVM b/utils/unittest/googletest/README.LLVM index e907a5e..d6e6f98 100644 --- a/utils/unittest/googletest/README.LLVM +++ b/utils/unittest/googletest/README.LLVM @@ -1,14 +1,14 @@ LLVM notes ---------- -This directory contains Google Test 1.2.1, with all elements removed except for +This directory contains Google Test 1.5.0, with all elements removed except for the actual source code, to minimize the addition to the LLVM distribution. Cleaned up as follows: # Remove all the unnecessary files and directories -$ rm -f aclocal* configure* Makefile* CHANGES CONTRIBUTORS README -$ rm -rf build-aux m4 make msvc samples scons scripts test xcode +$ rm -f aclocal* CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README +$ rm -rf build-aux codegear fused-src m4 make msvc samples scripts test xcode $ rm -f `find . -name \*\.pump` # Move all the source files to the current directory @@ -21,11 +21,11 @@ $ mv *.h include/gtest/internal/ # Update paths to the included files $ perl -pi -e 's|^#include "src/|#include "gtest/internal/|' *.cc -$ rm -f gtest-all.cc gtest_main.cc - $ mv COPYING LICENSE.TXT Modified as follows: * To GTestStreamToHelper in include/gtest/internal/gtest-internal.h, added the ability to stream with raw_os_ostream. +* To refresh Haiku support in include/gtest/internal/gtest-port.h, + see http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20100621/102898.html diff --git a/utils/unittest/googletest/gtest-death-test.cc b/utils/unittest/googletest/gtest-death-test.cc index 617e301..e4199de 100644 --- a/utils/unittest/googletest/gtest-death-test.cc +++ b/utils/unittest/googletest/gtest-death-test.cc @@ -27,17 +27,31 @@ // (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: wan@google.com (Zhanyong Wan) +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #include <gtest/gtest-death-test.h> #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST + +#if GTEST_OS_MAC +#include <crt_externs.h> +#endif // GTEST_OS_MAC + #include <errno.h> +#include <fcntl.h> #include <limits.h> #include <stdarg.h> + +#if GTEST_OS_WINDOWS +#include <windows.h> +#else +#include <sys/mman.h> +#include <sys/wait.h> +#endif // GTEST_OS_WINDOWS + #endif // GTEST_HAS_DEATH_TEST #include <gtest/gtest-message.h> @@ -48,9 +62,9 @@ // 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 +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { @@ -68,6 +82,18 @@ GTEST_DEFINE_string_( "\"fast\" (child process runs the death test immediately " "after forking)."); +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", @@ -79,7 +105,7 @@ GTEST_DEFINE_string_( "death test. FOR INTERNAL USE ONLY."); } // namespace internal -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { @@ -87,9 +113,14 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { +#if GTEST_OS_WINDOWS + return exit_status == exit_code_; +#else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +#endif // GTEST_OS_WINDOWS } +#if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } @@ -98,6 +129,7 @@ KilledBySignal::KilledBySignal(int signum) : signum_(signum) { bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } +#endif // !GTEST_OS_WINDOWS namespace internal { @@ -107,6 +139,9 @@ namespace internal { // specified by wait(2). static String ExitSummary(int exit_code) { Message m; +#if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; +#else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { @@ -117,6 +152,7 @@ static String ExitSummary(int exit_code) { m << " (core dumped)"; } #endif +#endif // GTEST_OS_WINDOWS return m.GetString(); } @@ -126,6 +162,7 @@ bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } +#if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the @@ -133,17 +170,14 @@ bool ExitedUnsuccessfully(int exit_status) { static String DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" - << " in a threaded context. For this test, " << GTEST_NAME << " "; + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } - -// Static string containing a description of the outcome of the -// last death test. -static String last_death_test_message; +#endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; @@ -159,29 +193,25 @@ static const char kDeathTestInternalError = 'I'; enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; // Routine for aborting the program which is safe to call from an -// exec-style death test child process, in which case the the error +// exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. -void DeathTestAbort(const char* format, ...) { - // This function may be called from a threadsafe-style death test - // child process, which operates on a very small stack. Use the - // heap for any additional non-miniscule memory requirements. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); - va_list args; - va_start(args, format); - if (flag != NULL) { - FILE* parent = fdopen(flag->status_fd, "w"); + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); - vfprintf(parent, format, args); - fclose(parent); - va_end(args); + fprintf(parent, "%s", message.c_str()); + fflush(parent); _exit(1); } else { - vfprintf(stderr, format, args); - va_end(args); + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); abort(); } } @@ -190,11 +220,12 @@ void DeathTestAbort(const char* format, ...) { // fails. #define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ - if (!(expression)) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s", \ - __FILE__, __LINE__, #expression); \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ } \ - } while (0) + } while (::testing::internal::AlwaysFalse()) // 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 @@ -205,15 +236,46 @@ void DeathTestAbort(const char* format, ...) { // something other than EINTR, DeathTestAbort is called. #define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ - int retval; \ + int gtest_retval; \ do { \ - retval = (expression); \ - } while (retval == -1 && errno == EINTR); \ - if (retval == -1) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s != -1", \ - __FILE__, __LINE__, #expression); \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ } \ - } while (0) + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +String GetLastErrnoDescription() { + return String(errno == 0 ? "" : posix::StrError(errno)); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} // Death test constructor. Increments the running death test count // for the current test. @@ -234,143 +296,146 @@ bool DeathTest::Create(const char* statement, const RE* regex, } const char* DeathTest::LastMessage() { - return last_death_test_message.c_str(); + return last_death_test_message_.c_str(); } -// ForkingDeathTest provides implementations for most of the abstract -// methods of the DeathTest interface. Only the AssumeRole method is -// left undefined. -class ForkingDeathTest : public DeathTest { - public: - ForkingDeathTest(const char* statement, const RE* regex); +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - virtual bool Passed(bool status_ok); - virtual void Abort(AbortReason reason); +String DeathTest::last_death_test_message_; +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { protected: - void set_forked(bool forked) { forked_ = forked; } - void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + private: - // The textual content of the code this object is testing. + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. const char* const statement_; - // The regular expression which test output must match. + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. const RE* const regex_; - // True if the death test successfully forked. - bool forked_; - // PID of child process during death test; 0 in the child process itself. - pid_t child_pid_; - // File descriptors for communicating the death test's status byte. - int read_fd_; // Always -1 in the child process. - int write_fd_; // Always -1 in the parent process. + // True if the death test child process has been successfully spawned. + bool spawned_; // The exit status of the child process. int status_; // How the death test concluded. DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; }; -// Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) - : DeathTest(), - statement_(statement), - regex_(regex), - forked_(false), - child_pid_(-1), - read_fd_(-1), - write_fd_(-1), - status_(-1), - outcome_(IN_PROGRESS) { -} - -// Reads an internal failure message from a file descriptor, then calls -// LOG(FATAL) with that message. Called from a death test parent process -// to read a failure message from the death test child process. -static void FailFromInternalError(int fd) { - Message error; - char buffer[256]; - ssize_t num_read; - - do { - while ((num_read = read(fd, buffer, 255)) > 0) { - buffer[num_read] = '\0'; - error << buffer; - } - } while (num_read == -1 && errno == EINTR); - - // TODO(smcafee): Maybe just FAIL the test instead? - if (num_read == 0) { - GTEST_LOG_(FATAL, error); - } else { - GTEST_LOG_(FATAL, - Message() << "Error while reading death test internal: " - << strerror(errno) << " [" << errno << "]"); - } -} - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int ForkingDeathTest::Wait() { - if (!forked_) - return 0; +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; // The read() here blocks until data is available (signifying the // failure of the death test) or until the pipe is closed (signifying // its success), so it's okay to call this in the parent before // the child process has exited. - char flag; - ssize_t bytes_read; - do { - bytes_read = read(read_fd_, &flag, 1); + bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { - outcome_ = DIED; + set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: - outcome_ = RETURNED; + set_outcome(RETURNED); break; case kDeathTestLived: - outcome_ = LIVED; + set_outcome(LIVED); break; case kDeathTestInternalError: - FailFromInternalError(read_fd_); // Does not return. + 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) << "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) << "Read from death test child process failed: " + << GetLastErrnoDescription(); } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_, 0)); - return status_; +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd())); + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: -// outcome: an enumeration describing how the death test +// outcome: An enumeration describing how the death test // concluded: DIED, LIVED, or RETURNED. The death test fails -// in the latter two cases -// status: the exit status of the child process, in the format -// specified by wait(2) -// regex: a regular expression object to be applied to +// in the latter two cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to // the test's captured standard error output; the death test -// fails if it does not match +// fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of @@ -378,22 +443,18 @@ int ForkingDeathTest::Wait() { // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is -// reported. Also sets the static variable last_death_test_message. -bool ForkingDeathTest::Passed(bool status_ok) { - if (!forked_) +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) return false; -#if GTEST_HAS_GLOBAL_STRING - const ::string error_message = GetCapturedStderr(); -#else - const ::std::string error_message = GetCapturedStderr(); -#endif // GTEST_HAS_GLOBAL_STRING + const String error_message = GetCapturedStderr(); bool success = false; Message buffer; - buffer << "Death test: " << statement_ << "\n"; - switch (outcome_) { + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg: " << error_message; @@ -404,49 +465,271 @@ bool ForkingDeathTest::Passed(bool status_ok) { break; case DIED: if (status_ok) { - if (RE::PartialMatch(error_message, *regex_)) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" - << " Expected: " << regex_->pattern() << "\n" + << " Expected: " << regex()->pattern() << "\n" << "Actual msg: " << error_message; } } else { buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status_) << "\n"; + << " " << ExitSummary(status()) << "\n"; } 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(); + DeathTest::set_last_death_test_message(buffer.GetString()); return success; } -// Signals that the death test code which should have exited, didn't. -// Should be called only in a death test child process. -// Writes a status byte to the child's status file desriptor, then -// calls _exit(1). -void ForkingDeathTest::Abort(AbortReason reason) { - // The parent process considers the death test to be a failure if - // it finds any data in our pipe. So, here we write a single flag byte - // 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_)); - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +#if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* statement, + const RE* regex, + const char* file, + int line) + : DeathTestImpl(statement, regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status; + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) + != FALSE); + child_handle_.Reset(); + set_status(static_cast<int>(status)); + return this->status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast<unsigned int>(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast<size_t>(write_handle), + reinterpret_cast<size_t>(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast<char*>(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +#else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: - NoExecDeathTest(const char* statement, const RE* regex) : - ForkingDeathTest(statement, regex) { } + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; @@ -455,13 +738,13 @@ 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); - last_death_test_message = ""; + DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing @@ -482,11 +765,14 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); - set_forked(true); + set_spawned(true); return OVERSEE_TEST; } } @@ -496,9 +782,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: - ExecDeathTest(const char* statement, const RE* regex, + ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : - ForkingDeathTest(statement, regex), file_(file), line_(line) { } + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. @@ -513,15 +799,15 @@ class Arguments { Arguments() { args_.push_back(NULL); } + ~Arguments() { - for (std::vector<char*>::iterator i = args_.begin(); - i + 1 != args_.end(); + for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, strdup(argument)); + args_.insert(args_.end() - 1, posix::StrDup(argument)); } template <typename Str> @@ -529,7 +815,7 @@ class Arguments { for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { - args_.insert(args_.end() - 1, strdup(i->c_str())); + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { @@ -546,6 +832,20 @@ struct ExecDeathTestArgs { int close_fd; // File descriptor to close; the read end of a pipe }; +#if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +#else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +#endif // GTEST_OS_MAC + // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. @@ -560,8 +860,9 @@ static int ExecDeathTestChildMain(void* child_arg) { UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { - DeathTestAbort("chdir(\"%s\") failed: %s", - original_dir, strerror(errno)); + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastErrnoDescription().c_str())); return EXIT_FAILURE; } @@ -570,9 +871,11 @@ static int ExecDeathTestChildMain(void* child_arg) { // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. - execve(args->argv[0], args->argv, environ); - DeathTestAbort("execve(%s, ...) in %s failed: %s", - args->argv[0], original_dir, strerror(errno)); + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastErrnoDescription().c_str())); return EXIT_FAILURE; } @@ -581,12 +884,12 @@ static int ExecDeathTestChildMain(void* child_arg) { // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. -static bool StackLowerThanAddress(const void* ptr) { +bool StackLowerThanAddress(const void* ptr) { int dummy; return &dummy < ptr; } -static bool StackGrowsDown() { +bool StackGrowsDown() { int dummy; return StackLowerThanAddress(&dummy); } @@ -595,18 +898,36 @@ static bool StackGrowsDown() { // that uses clone(2). It dies with an error message if anything goes // wrong. static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { - static const bool stack_grows_down = StackGrowsDown(); - 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); - 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); + pid_t child_pid = -1; + +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + void* const stack_top = + static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +#else + const bool use_fork = true; +#endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + GTEST_DEATH_TEST_CHECK_(child_pid != -1); - GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); return child_pid; } @@ -622,7 +943,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { - set_write_fd(flag->status_fd); + set_write_fd(flag->write_fd()); return EXECUTE_TEST; } @@ -634,19 +955,18 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { const String filter_flag = String::Format("--%s%s=%s.%s", - GTEST_FLAG_PREFIX, kFilterFlag, + GTEST_FLAG_PREFIX_, kFilterFlag, info->test_case_name(), info->name()); const String internal_flag = - String::Format("--%s%s=%s:%d:%d:%d", - GTEST_FLAG_PREFIX, kInternalRunDeathTestFlag, file_, line_, - death_test_index, pipe_fd[1]); + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); Arguments args; args.AddArguments(GetArgvs()); - args.AddArgument("--logtostderr"); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); - last_death_test_message = ""; + DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line @@ -657,10 +977,12 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); - set_forked(true); + set_spawned(true); return OVERSEE_TEST; } +#endif // !GTEST_OS_WINDOWS + // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be @@ -676,28 +998,36 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, ->increment_death_test_count(); if (flag != NULL) { - if (death_test_index > flag->index) { - last_death_test_message = String::Format( + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( "Death test count (%d) somehow exceeded expected maximum (%d)", - death_test_index, flag->index); + death_test_index, flag->index())); return false; } - if (!(flag->file == file && flag->line == line && - flag->index == death_test_index)) { + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { *test = NULL; return true; } } +#if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } +#else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); - } else { - last_death_test_message = String::Format( + } +#endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( "Unknown death test style \"%s\" encountered", - GTEST_FLAG(death_test_style).c_str()); + GTEST_FLAG(death_test_style).c_str())); return false; } @@ -711,7 +1041,7 @@ static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; - while (true) { + while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); @@ -724,25 +1054,71 @@ static void SplitString(const ::std::string& str, char delimiter, dest->swap(parsed); } -// Attempts to parse a string into a positive integer. Returns true -// if that is possible. GTEST_HAS_DEATH_TEST implies that we have -// ::std::string, so we can use it here. -static bool ParsePositiveInt(const ::std::string& str, int* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtol's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !isdigit(str[0])) { - return false; +#if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); } - char* endptr; - const long parsed = strtol(str.c_str(), &endptr, 10); // NOLINT - if (*endptr == '\0' && parsed <= INT_MAX) { - *number = static_cast<int>(parsed); - return true; - } else { - return false; + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast<HANDLE>(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); } + + const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; } +#endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if @@ -750,22 +1126,43 @@ static bool ParsePositiveInt(const ::std::string& str, int* number) { InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; - InternalRunDeathTestFlag* const internal_run_death_test_flag = - new InternalRunDeathTestFlag; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. + int line = -1; + int index = -1; ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), ':', &fields); + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +#if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +#else if (fields.size() != 4 - || !ParsePositiveInt(fields[1], &internal_run_death_test_flag->line) - || !ParsePositiveInt(fields[2], &internal_run_death_test_flag->index) - || !ParsePositiveInt(fields[3], - &internal_run_death_test_flag->status_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: %s", - GTEST_FLAG(internal_run_death_test).c_str()); + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); } - internal_run_death_test_flag->file = fields[0].c_str(); - return internal_run_death_test_flag; +#endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal diff --git a/utils/unittest/googletest/gtest-filepath.cc b/utils/unittest/googletest/gtest-filepath.cc index 493ba0b..c1ef918 100644 --- a/utils/unittest/googletest/gtest-filepath.cc +++ b/utils/unittest/googletest/gtest-filepath.cc @@ -34,23 +34,20 @@ #include <stdlib.h> -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include <windows.h> -#elif defined(GTEST_OS_WINDOWS) +#elif GTEST_OS_WINDOWS #include <direct.h> #include <io.h> -#include <sys/stat.h> -#elif defined(GTEST_OS_SYMBIAN) +#elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h #include <sys/syslimits.h> -#include <unistd.h> #else #include <limits.h> -#include <sys/stat.h> -#include <unistd.h> -#endif // _WIN32_WCE or _WIN32 +#include <climits> // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) #define GTEST_PATH_MAX_ PATH_MAX @@ -65,10 +62,16 @@ namespace testing { namespace internal { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; -#ifdef _WIN32_WCE +const char kAlternatePathSeparatorString[] = "/"; +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. @@ -77,26 +80,35 @@ const char kCurrentDirectoryString[] = "\\"; const DWORD kInvalidFileAttributes = 0xffffffff; #else const char kCurrentDirectoryString[] = ".\\"; -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { -#ifdef _WIN32_WCE -// Windows CE doesn't have a current directory, so we just return -// something reasonable. +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. return FilePath(kCurrentDirectoryString); -#elif defined(GTEST_OS_WINDOWS) - char cwd[GTEST_PATH_MAX_ + 1] = {}; +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else - char cwd[GTEST_PATH_MAX_ + 1] = {}; + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. @@ -106,11 +118,27 @@ FilePath FilePath::GetCurrentDir() { FilePath FilePath::RemoveExtension(const char* extension) const { String dot_extension(String::Format(".%s", extension)); if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { - return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4)); + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); } return *this; } +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns @@ -118,7 +146,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const { // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); + const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(String(last_sep + 1)) : *this; } @@ -129,9 +157,14 @@ FilePath FilePath::RemoveDirectoryName() const { // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); - return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str()) - : String(kCurrentDirectoryString)); + const char* const last_sep = FindLastPathSeparator(); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); } // Helper functions for naming files in a directory for xml output. @@ -144,44 +177,54 @@ FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { - FilePath dir(directory.RemoveTrailingPathSeparator()); + String file; if (number == 0) { - return FilePath(String::Format("%s%c%s.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), extension)); + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); } - return FilePath(String::Format("%s%c%s_%d.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), number, extension)); + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { -#ifdef GTEST_OS_WINDOWS -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; return attributes != kInvalidFileAttributes; #else - struct _stat file_stat = {}; - return _stat(pathname_.c_str(), &file_stat) == 0; -#endif // _WIN32_WCE -#else - struct stat file_stat; - return stat(pathname_.c_str(), &file_stat) == 0; -#endif // GTEST_OS_WINDOWS + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. bool FilePath::DirectoryExists() const { bool result = false; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); -#ifdef _WIN32_WCE +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; @@ -190,30 +233,38 @@ bool FilePath::DirectoryExists() const { result = true; } #else - struct _stat file_stat = {}; - result = _stat(path.c_str(), &file_stat) == 0 && - (_S_IFDIR & file_stat.st_mode) != 0; -#endif // _WIN32_WCE -#else - struct stat file_stat; - result = stat(pathname_.c_str(), &file_stat) == 0 && - S_ISDIR(file_stat.st_mode); -#endif // GTEST_OS_WINDOWS + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); - return pathname_.GetLength() == 3 && +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && - name[2] == kPathSeparator; + IsPathSeparator(name[2]); #else - return pathname_ == kPathSeparatorString; + return IsPathSeparator(name[0]); #endif } @@ -240,7 +291,8 @@ FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { - return pathname_.EndsWith(kPathSeparatorString); + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if @@ -251,7 +303,7 @@ bool FilePath::CreateDirectoriesRecursively() const { return false; } - if (pathname_.GetLength() == 0 || this->DirectoryExists()) { + if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } @@ -264,18 +316,17 @@ 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 GTEST_OS_WINDOWS -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; -#else +#elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); -#endif // !WIN32_WCE #else int result = mkdir(pathname_.c_str(), 0777); -#endif // _WIN32 +#endif // GTEST_OS_WINDOWS_MOBILE + if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } @@ -286,31 +337,39 @@ bool FilePath::CreateFolder() const { // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { - return pathname_.EndsWith(kPathSeparatorString) - ? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1)) + return IsDirectory() + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) : *this; } -// Normalize removes any redundant separators that might be in the pathname. +// Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; return; } const char* src = pathname_.c_str(); - char* const dest = new char[pathname_.GetLength() + 1]; + char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; - memset(dest_ptr, 0, pathname_.GetLength() + 1); + memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { - *dest_ptr++ = *src; - if (*src != kPathSeparator) + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { src++; - else - while (*src == kPathSeparator) + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) src++; + } + dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; diff --git a/utils/unittest/googletest/gtest-port.cc b/utils/unittest/googletest/gtest-port.cc index 9878cae..5609599 100644 --- a/utils/unittest/googletest/gtest-port.cc +++ b/utils/unittest/googletest/gtest-port.cc @@ -35,29 +35,90 @@ #include <stdlib.h> #include <stdio.h> -#ifdef GTEST_HAS_DEATH_TEST -#include <regex.h> -#endif // GTEST_HAS_DEATH_TEST - -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include <windows.h> // For TerminateProcess() -#endif // _WIN32_WCE +#elif GTEST_OS_WINDOWS +#include <io.h> +#include <sys/stat.h> +#else +#include <unistd.h> +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +#include <mach/mach_init.h> +#include <mach/task.h> +#include <mach/vm_map.h> +#endif // GTEST_OS_MAC #include <gtest/gtest-spi.h> #include <gtest/gtest-message.h> #include <gtest/internal/gtest-string.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 "gtest/internal/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { -#ifdef GTEST_HAS_DEATH_TEST +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast<vm_address_t>(thread_list), + sizeof(thread_t) * thread_count); + return static_cast<size_t>(thread_count); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { - regfree(&partial_regex_); - regfree(&full_regex_); + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } free(const_cast<char*>(pattern_)); } @@ -80,7 +141,7 @@ bool RE::PartialMatch(const char* str, const RE& re) { // Initializes an RE from its string representation. void RE::Init(const char* regex) { - pattern_ = strdup(regex); + pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. @@ -93,7 +154,14 @@ void RE::Init(const char* regex) { // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. - is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_; + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; @@ -101,77 +169,362 @@ void RE::Init(const char* regex) { delete[] full_pattern; } -#endif // GTEST_HAS_DEATH_TEST +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in <ctype.h>, these aren't affected by the +// current locale. +bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsDigit(ch); + case 'D': return !IsDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsWhiteSpace(ch); + case 'S': return !IsWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsWordChar(ch); + case 'W': return !IsWordChar(ch); + } + return IsPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast<size_t>(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast<char*>(pattern_)); + free(const_cast<char*>(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast<char*>(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. -// Logs a message at the given severity level. -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg) { + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg); - if (severity == GTEST_FATAL) { - abort(); - } + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; } -#ifdef GTEST_HAS_DEATH_TEST +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER -// Defines the stderr capturer. +#if GTEST_HAS_STREAM_REDIRECTION_ -class CapturedStderr { +// Object that captures an output stream (stdout/stderr). +class CapturedStream { public: - // The ctor redirects stderr to a temporary file. - CapturedStderr() { - uncaptured_fd_ = dup(STDERR_FILENO); - + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +#else // There's no guarantee that a test has write access to the // current directory, so we create the temporary file in the /tmp // directory instead. - char name_template[] = "/tmp/captured_stderr.XXXXXX"; + char name_template[] = "/tmp/captured_stream.XXXXXX"; const int captured_fd = mkstemp(name_template); filename_ = name_template; +#endif // GTEST_OS_WINDOWS fflush(NULL); - dup2(captured_fd, STDERR_FILENO); + dup2(captured_fd, fd_); close(captured_fd); } - ~CapturedStderr() { + ~CapturedStream() { remove(filename_.c_str()); } - // Stops redirecting stderr. - void StopCapture() { - // Restores the original stream. - fflush(NULL); - dup2(uncaptured_fd_, STDERR_FILENO); - close(uncaptured_fd_); - uncaptured_fd_ = -1; + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; } - // Returns the name of the temporary file holding the stderr output. - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - ::std::string filename() const { return filename_; } - private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. int uncaptured_fd_; + // Name of the temporary file holding the stderr output. ::std::string filename_; -}; -static CapturedStderr* g_captured_stderr = NULL; + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; // Returns the size (in bytes) of a file. -static size_t GetFileSize(FILE * file) { +size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast<size_t>(ftell(file)); } // Reads the entire content of a file as a string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. -static ::std::string ReadEntireFile(FILE * file) { +String CapturedStream::ReadEntireFile(FILE* file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; @@ -187,35 +540,58 @@ static ::std::string ReadEntireFile(FILE * file) { bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); - const ::std::string content(buffer, buffer+bytes_read); + const String content(buffer, bytes_read); delete[] buffer; return content; } -// Starts capturing stderr. -void CaptureStderr() { - if (g_captured_stderr != NULL) { - GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time."); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; } - g_captured_stderr = new CapturedStderr; + *stream = new CapturedStream(fd); } -// Stops capturing stderr and returns the captured string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. -::std::string GetCapturedStderr() { - g_captured_stderr->StopCapture(); - FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r"); - const ::std::string content = ReadEntireFile(file); - fclose(file); +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); - delete g_captured_stderr; - g_captured_stderr = NULL; + delete *captured_stream; + *captured_stream = NULL; return content; } +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + +#if GTEST_HAS_DEATH_TEST + // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector<String> g_argvs; @@ -224,38 +600,30 @@ const ::std::vector<String>& GetArgvs() { return g_argvs; } #endif // GTEST_HAS_DEATH_TEST -#ifdef _WIN32_WCE -void abort() { +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } -#endif // _WIN32_WCE +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static String FlagToEnvVar(const char* flag) { - const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString(); + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; - for (int i = 0; i != full_flag.GetLength(); i++) { + for (size_t i = 0; i != full_flag.length(); i++) { env_var << static_cast<char>(toupper(full_flag.c_str()[i])); } return env_var.GetString(); } -// Reads and returns the Boolean environment variable corresponding to -// the given flag; if it's not set, returns default_value. -// -// The value is considered true iff it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { - const String env_var = FlagToEnvVar(flag); - const char* const string_value = GetEnv(env_var.c_str()); - return string_value == NULL ? - default_value : strcmp(string_value, "0") != 0; -} - // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. @@ -297,12 +665,23 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) { return true; } +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { const String env_var = FlagToEnvVar(flag); - const char* const string_value = GetEnv(env_var.c_str()); + const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; @@ -324,7 +703,7 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { const String env_var = FlagToEnvVar(flag); - const char* const value = GetEnv(env_var.c_str()); + const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; } diff --git a/utils/unittest/googletest/gtest-test-part.cc b/utils/unittest/googletest/gtest-test-part.cc index 2e80f21..8249afe 100644 --- a/utils/unittest/googletest/gtest-test-part.cc +++ b/utils/unittest/googletest/gtest-test-part.cc @@ -38,12 +38,14 @@ // 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 +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { +using internal::GetUnitTestImpl; + // Gets the summary of the failure message by omitting the stack trace // in it. internal::String TestPartResult::ExtractSummary(const char* message) { @@ -54,61 +56,45 @@ internal::String TestPartResult::ExtractSummary(const char* 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_; + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; } // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { - list_->PushBack(result); + array_.push_back(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(); + internal::posix::Abort(); } - return p->element(); + return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { - return list_->size(); + return static_cast<int>(array_.size()); } namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), - original_reporter_(UnitTest::GetInstance()->impl()-> + original_reporter_(GetUnitTestImpl()-> GetTestPartResultReporterForCurrentThread()) { - UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( - this); + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { - UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( original_reporter_); } diff --git a/utils/unittest/googletest/gtest-typed-test.cc b/utils/unittest/googletest/gtest-typed-test.cc index d42a159..3cc4b5d 100644 --- a/utils/unittest/googletest/gtest-typed-test.cc +++ b/utils/unittest/googletest/gtest-typed-test.cc @@ -35,7 +35,15 @@ namespace testing { namespace internal { -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (isspace(*str)) + str++; + return str; +} // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or @@ -45,6 +53,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( typedef ::std::set<const char*>::const_iterator DefinedTestIter; registered_ = true; + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + Message errors; ::std::set<String> tests; for (const char* names = registered_tests; names != NULL; @@ -85,7 +97,8 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); - abort(); + fflush(stderr); + posix::Abort(); } return registered_tests; diff --git a/utils/unittest/googletest/gtest.cc b/utils/unittest/googletest/gtest.cc index b5a654f..aa2d5bb 100644 --- a/utils/unittest/googletest/gtest.cc +++ b/utils/unittest/googletest/gtest.cc @@ -39,15 +39,19 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <wchar.h> #include <wctype.h> -#ifdef GTEST_OS_LINUX +#include <algorithm> +#include <ostream> +#include <sstream> +#include <vector> + +#if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <fcntl.h> #include <limits.h> @@ -60,38 +64,38 @@ #include <string> #include <vector> -#elif defined(GTEST_OS_SYMBIAN) -#define GTEST_HAS_GETTIMEOFDAY +#elif GTEST_OS_SYMBIAN +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT -#elif defined(GTEST_OS_ZOS) -#define GTEST_HAS_GETTIMEOFDAY +#elif GTEST_OS_ZOS +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT // On z/OS we additionally need strings.h for strcasecmp. -#include <strings.h> +#include <strings.h> // NOLINT -#elif defined(_WIN32_WCE) // We are on Windows CE. +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. #include <windows.h> // NOLINT -#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. +#elif GTEST_OS_WINDOWS // We are on Windows proper. #include <io.h> // NOLINT #include <sys/timeb.h> // NOLINT #include <sys/types.h> // NOLINT #include <sys/stat.h> // NOLINT -#if defined(__MINGW__) || defined(__MINGW32__) +#if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT -#endif +#endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. @@ -102,13 +106,17 @@ // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. #include <sys/time.h> // NOLINT #include <unistd.h> // NOLINT +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +#include <stdexcept> #endif // Indicates that this translation unit is part of Google Test's @@ -116,18 +124,21 @@ // 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 +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ -#ifdef GTEST_OS_WINDOWS -#define fileno _fileno -#define isatty _isatty +#if GTEST_OS_WINDOWS #define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + // Constants. // A test whose test case name or test name matches this filter is @@ -145,15 +156,31 @@ static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + namespace internal { // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + } // namespace internal GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); @@ -161,7 +188,7 @@ GTEST_DEFINE_bool_( GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", false), - "True iff " GTEST_NAME + "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( @@ -170,7 +197,7 @@ GTEST_DEFINE_string_( "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " - "is set to xterm or xterm-color."); + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); GTEST_DEFINE_string_( filter, @@ -198,29 +225,67 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_( print_time, - internal::BoolFromGTestEnv("print_time", false), - "True iff " GTEST_NAME + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +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_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + GTEST_DEFINE_int32_( stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + 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_( - show_internal_stack_frames, false, - "True iff " GTEST_NAME " should include internal stack frames when " - "printing test failure stack traces."); + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); namespace internal { +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). @@ -232,16 +297,14 @@ namespace internal { int g_init_gtest_count = 0; static bool GTestIsInitialized() { return g_init_gtest_count != 0; } -// Iterates over a list of TestCases, keeping a running sum of the +// Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. -static int SumOverTestCaseList(const internal::List<TestCase*>& case_list, +static int SumOverTestCaseList(const std::vector<TestCase*>& case_list, int (TestCase::*method)() const) { int sum = 0; - for (const internal::ListNode<TestCase*>* node = case_list.Head(); - node != NULL; - node = node->next()) { - sum += (node->element()->*method)(); + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); } return sum; } @@ -263,16 +326,22 @@ static bool ShouldRunTestCase(const TestCase* test_case) { } // AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResultType type, const char* file, - int line, const char* message) - : type_(type), file_(file), line_(line), message_(message) { +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> - AddTestPartResult(type_, file_, line_, - AppendUserMessage(message_, message), + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. @@ -280,7 +349,7 @@ void AssertHelper::operator=(const Message& message) const { } // Mutex for linked pointers. -Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. String g_executable_path; @@ -290,11 +359,11 @@ String g_executable_path; FilePath GetCurrentExecutableName() { FilePath result; -#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) +#if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); -#endif // _WIN32_WCE || GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } @@ -314,16 +383,28 @@ String UnitTestOptions::GetOutputFormat() { // Returns the name of the requested output file, or the default if none // was explicitly specified. -String UnitTestOptions::GetOutputFile() { +String UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return String(""); const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) - return String(kDefaultOutputFile); + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + if (!output_name.IsDirectory()) return output_name.ToString(); @@ -357,7 +438,7 @@ bool UnitTestOptions::PatternMatchesString(const char *pattern, bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { const char *cur_pattern = filter; - while (true) { + for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } @@ -395,7 +476,7 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = String(""); } else { - positive.Set(p, dash - p); // Everything up to the dash + positive = String(p, dash - p); // Everything up to the dash negative = String(dash+1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' @@ -409,7 +490,7 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, !MatchesFilter(full_name, negative.c_str())); } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. @@ -426,46 +507,6 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { } // namespace internal -// The interface for printing the result of a UnitTest -class UnitTestEventListenerInterface { - public: - // The d'tor is pure virtual as this is an abstract class. - virtual ~UnitTestEventListenerInterface() = 0; - - // Called before the unit test starts. - virtual void OnUnitTestStart(const UnitTest*) {} - - // Called after the unit test ends. - virtual void OnUnitTestEnd(const UnitTest*) {} - - // Called before the test case starts. - virtual void OnTestCaseStart(const TestCase*) {} - - // Called after the test case ends. - virtual void OnTestCaseEnd(const TestCase*) {} - - // Called before the global set-up starts. - virtual void OnGlobalSetUpStart(const UnitTest*) {} - - // Called after the global set-up ends. - virtual void OnGlobalSetUpEnd(const UnitTest*) {} - - // Called before the global tear-down starts. - virtual void OnGlobalTearDownStart(const UnitTest*) {} - - // Called after the global tear-down ends. - virtual void OnGlobalTearDownEnd(const UnitTest*) {} - - // Called before the test starts. - virtual void OnTestStart(const TestInfo*) {} - - // Called after the test ends. - virtual void OnTestEnd(const TestInfo*) {} - - // Called after an assertion. - virtual void OnNewTestPartResult(const TestPartResult*) {} -}; - // 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. @@ -487,7 +528,7 @@ ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( } void ScopedFakeTestPartResultReporter::Init() { - internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { old_reporter_ = impl->GetGlobalTestPartResultReporter(); impl->SetGlobalTestPartResultReporter(this); @@ -500,7 +541,7 @@ void ScopedFakeTestPartResultReporter::Init() { // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { impl->SetGlobalTestPartResultReporter(old_reporter_); } else { @@ -541,11 +582,11 @@ AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, - TestPartResultType type, + TestPartResult::Type type, const char* substr) { - const String expected( - type == TPRT_FATAL_FAILURE ? "1 fatal failure" : - "1 non-fatal failure"); + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" @@ -580,7 +621,7 @@ AssertionResult HasOneFailure(const char* /* results_expr */, // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, - TestPartResultType type, + TestPartResult::Type type, const char* substr) : results_(results), type_(type), @@ -600,7 +641,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); - unit_test_->result_printer()->OnNewTestPartResult(&result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( @@ -639,23 +680,23 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread( // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { - return test_cases_.CountIf(TestCasePassed); + return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { - return test_cases_.CountIf(TestCaseFailed); + return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { - return test_cases_.size(); + return static_cast<int>(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { - return test_cases_.CountIf(ShouldRunTestCase); + return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. @@ -698,11 +739,13 @@ String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { return String(""); } -static TimeInMillis GetTimeInMillis() { -#ifdef _WIN32_WCE // We are on Windows CE - // Difference between 1970-01-01 and 1601-01-01 in miliseconds. +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html - const TimeInMillis kJavaEpochToWinFileTimeDelta = 11644473600000UL; + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast<TimeInMillis>(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; @@ -719,7 +762,7 @@ static TimeInMillis GetTimeInMillis() { return now_int64.QuadPart; } return 0; -#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_HAS_GETTIMEOFDAY) +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; #ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 @@ -734,7 +777,7 @@ static TimeInMillis GetTimeInMillis() { _ftime64(&now); #endif // _MSC_VER return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; -#elif defined(GTEST_HAS_GETTIMEOFDAY) +#elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; @@ -767,16 +810,7 @@ static char* CloneString(const char* str, size_t length) { return NULL; } else { char* const clone = new char[length + 1]; - // MSVC 8 deprecates strncpy(), so we want to suppress warning - // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - strncpy(clone, str, length); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - strncpy(clone, str, length); -#endif // GTEST_OS_WINDOWS + posix::StrNCpy(clone, str, length); clone[length] = '\0'; return clone; } @@ -790,7 +824,7 @@ const char * String::CloneCString(const char* c_str) { NULL : CloneString(c_str, strlen(c_str)); } -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the @@ -824,7 +858,7 @@ const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { return ansi; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // @@ -843,17 +877,17 @@ bool String::CStringEquals(const char * lhs, const char * rhs) { // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. -static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len, +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { // TODO(wan): consider allowing a testing::String object to // contain '\0'. This will make it behave more like std::string, // and will allow ToUtf8String() to return the correct encoding // for '\0' s.t. we can get rid of the conditional here (and in // several other places). - for (size_t i = 0; i != len; ) { // NOLINT + for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i)); - while (i != len && wstr[i] != L'\0') + *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i)); + while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; @@ -926,21 +960,37 @@ String FormatForFailureMessage(wchar_t wchar) { } // namespace internal -// AssertionResult constructor. -AssertionResult::AssertionResult(const internal::String& failure_message) - : failure_message_(failure_message) { +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new internal::String(*other.message_) : + static_cast<internal::String*>(NULL)) { } +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} // Makes a successful assertion result. AssertionResult AssertionSuccess() { - return AssertionResult(); + return AssertionResult(true); } +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} // Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { - return AssertionResult(message.GetString()); + return AssertionFailure() << message; } namespace internal { @@ -982,6 +1032,20 @@ AssertionResult EqFailure(const char* expected_expression, return AssertionFailure(msg); } +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, @@ -1260,7 +1324,6 @@ AssertionResult IsNotSubstring( return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -#if GTEST_HAS_STD_STRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { @@ -1272,7 +1335,6 @@ AssertionResult IsNotSubstring( const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( @@ -1290,7 +1352,7 @@ AssertionResult IsNotSubstring( namespace internal { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS namespace { @@ -1298,7 +1360,7 @@ namespace { AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; #else @@ -1322,7 +1384,7 @@ AssertionResult HRESULTFailureHelper(const char* expr, --message_length) { error_text[message_length - 1] = '\0'; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE const String error_hex(String::Format("0x%08X ", hr)); Message msg; @@ -1416,17 +1478,8 @@ char* CodePointToUtf8(UInt32 code_point, char* str) { // the terminating nul character). We are asking for 32 character // buffer just in case. This is also enough for strncpy to // null-terminate the destination string. - // MSVC 8 deprecates strncpy(), so we want to suppress warning - // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. -#endif - strncpy(str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), - 32); -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(pop) // Restores the warning state. -#endif + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); str[31] = '\0'; // Makes sure no change in the format to strncpy leaves // the result unterminated. } @@ -1441,23 +1494,19 @@ char* CodePointToUtf8(UInt32 code_point, char* str) { // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - if (sizeof(wchar_t) == 2) - return (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; - else - return false; + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { - if (sizeof(wchar_t) == 2) { - const UInt32 mask = (1 << 10) - 1; - return (((first & mask) << 10) | (second & mask)) + 0x10000; - } else { - // This should not be called, but we provide a sensible default - // in case it is. - return static_cast<UInt32>(first); - } + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast<UInt32>(first); } // Converts a wide string to a narrow string in UTF-8 encoding. @@ -1568,15 +1617,11 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, // NULL C string is considered different to any non-NULL C string, // including the empty string. bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { - if ( lhs == NULL ) return rhs == NULL; - - if ( rhs == NULL ) return false; - -#ifdef GTEST_OS_WINDOWS - return _stricmp(lhs, rhs) == 0; -#else // GTEST_OS_WINDOWS - return strcasecmp(lhs, rhs) == 0; -#endif // GTEST_OS_WINDOWS + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; } // Compares two wide C strings, ignoring case. Returns true iff they @@ -1597,9 +1642,9 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, if ( rhs == NULL ) return false; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; -#elif defined(GTEST_OS_LINUX) +#elif GTEST_OS_LINUX return wcscasecmp(lhs, rhs) == 0; #else // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes @@ -1610,27 +1655,33 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, right = towlower(*rhs++); } while (left && left == right); return left == right; -#endif // OS selector -} - -// Constructs a String by copying a given number of chars from a -// buffer. E.g. String("hello", 3) will create the string "hel". -String::String(const char * buffer, size_t len) { - char * const temp = new char[ len + 1 ]; - memcpy(temp, buffer, len); - temp[ len ] = '\0'; - c_str_ = temp; +#endif // OS selector } // Compares this with another String. // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 // if this is greater than rhs. int String::Compare(const String & rhs) const { - if ( c_str_ == NULL ) { - return rhs.c_str_ == NULL ? 0 : -1; // NULL < anything except NULL + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; } - return rhs.c_str_ == NULL ? 1 : strcmp(c_str_, rhs.c_str_); + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; } // Returns true iff this String ends with the given suffix. *Any* @@ -1638,12 +1689,12 @@ int String::Compare(const String & rhs) const { bool String::EndsWith(const char* suffix) const { if (suffix == NULL || CStringEquals(suffix, "")) return true; - if (c_str_ == NULL) return false; + if (c_str() == NULL) return false; - const size_t this_len = strlen(c_str_); + const size_t this_len = strlen(c_str()); const size_t suffix_len = strlen(suffix); return (this_len >= suffix_len) && - CStringEquals(c_str_ + this_len - suffix_len, suffix); + CStringEquals(c_str() + this_len - suffix_len, suffix); } // Returns true iff this String ends with the given suffix, ignoring case. @@ -1651,37 +1702,12 @@ bool String::EndsWith(const char* suffix) const { bool String::EndsWithCaseInsensitive(const char* suffix) const { if (suffix == NULL || CStringEquals(suffix, "")) return true; - if (c_str_ == NULL) return false; + if (c_str() == NULL) return false; - const size_t this_len = strlen(c_str_); + const size_t this_len = strlen(c_str()); const size_t suffix_len = strlen(suffix); return (this_len >= suffix_len) && - CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix); -} - -// Sets the 0-terminated C string this String object represents. The -// old string in this object is deleted, and this object will own a -// clone of the input string. This function copies only up to length -// bytes (plus a terminating null byte), or until the first null byte, -// whichever comes first. -// -// This function works even when the c_str parameter has the same -// value as that of the c_str_ field. -void String::Set(const char * c_str, size_t length) { - // Makes sure this works when c_str == c_str_ - const char* const temp = CloneString(c_str, length); - delete[] c_str_; - c_str_ = temp; -} - -// Assigns a C string to this object. Self-assignment works. -const String& String::operator=(const char* c_str) { - // Makes sure this works when c_str == c_str_ - if (c_str != c_str_) { - delete[] c_str_; - c_str_ = CloneCString(c_str); - } - return *this; + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); } // Formats a list of arguments to a String, using the same format @@ -1691,41 +1717,46 @@ const String& String::operator=(const char* c_str) { // available. // // The result is limited to 4096 characters (including the tailing 0). -// If 4096 characters are not enough to format the input, -// "<buffer exceeded>" is returned. +// If 4096 characters are not enough to format the input, or if +// there's an error, "<formatting error or buffer exceeded>" is +// returned. String String::Format(const char * format, ...) { va_list args; va_start(args, format); char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#ifdef _MSC_VER // We are using MSVC. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); + const int size = vsnprintf(buffer, kBufferSize, format, args); #pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); -#endif // GTEST_OS_WINDOWS +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER va_end(args); - return String(size >= 0 ? buffer : "<buffer exceeded>"); + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String("<formatting error or buffer exceeded>"); + } else { + return String(buffer, size); + } } // Converts the buffer in a StrStream to a String, converting NUL // bytes to "\\0" along the way. String StrStreamToString(StrStream* ss) { -#if GTEST_HAS_STD_STRING const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); -#else - const char* const start = ss->str(); - const char* const end = start + ss->pcount(); -#endif // GTEST_HAS_STD_STRING // We need to use a helper StrStream to do this transformation // because String doesn't support push_back(). @@ -1738,14 +1769,7 @@ String StrStreamToString(StrStream* ss) { } } -#if GTEST_HAS_STD_STRING return String(helper.str().c_str()); -#else - const String str(helper.str(), helper.pcount()); - helper.freeze(false); - ss->freeze(false); - return str; -#endif // GTEST_HAS_STD_STRING } // Appends the user-supplied message to the Google-Test-generated message. @@ -1763,6 +1787,8 @@ String AppendUserMessage(const String& gtest_msg, return msg.GetString(); } +} // namespace internal + // class TestResult // Creates an empty TestResult. @@ -1775,9 +1801,32 @@ TestResult::TestResult() TestResult::~TestResult() { } +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_.PushBack(test_part_result); + test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the @@ -1787,27 +1836,27 @@ void TestResult::RecordProperty(const TestProperty& test_property) { if (!ValidateTestProperty(test_property)) { return; } - MutexLock lock(&test_properites_mutex_); - ListNode<TestProperty>* const node_with_matching_key = - test_properties_.FindIf(TestPropertyKeyIs(test_property.key())); - if (node_with_matching_key == NULL) { - test_properties_.PushBack(test_property); + internal::MutexLock lock(&test_properites_mutex_); + const std::vector<TestProperty>::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); return; } - TestProperty& property_with_matching_key = node_with_matching_key->element(); - property_with_matching_key.SetValue(test_property.value()); + property_with_matching_key->SetValue(test_property.value()); } // Adds a failure if the key is a reserved attribute of Google Test // testcase tags. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const TestProperty& test_property) { - String key(test_property.key()); + internal::String key(test_property.key()); if (key == "name" || key == "status" || key == "time" || key == "classname") { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << key << " ('name', 'status', 'time', and 'classname' are reserved by " - << GTEST_NAME << ")"; + << GTEST_NAME_ << ")"; return false; } return true; @@ -1815,49 +1864,51 @@ bool TestResult::ValidateTestProperty(const TestProperty& test_property) { // Clears the object. void TestResult::Clear() { - test_part_results_.Clear(); - test_properties_.Clear(); + test_part_results_.clear(); + test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } -// Returns true iff the test part passed. -static bool TestPartPassed(const TestPartResult & result) { - return result.passed(); -} - -// Gets the number of successful test parts. -int TestResult::successful_part_count() const { - return test_part_results_.CountIf(TestPartPassed); -} - -// Returns true iff the test part failed. -static bool TestPartFailed(const TestPartResult & result) { - return result.failed(); -} - -// Gets the number of failed test parts. -int TestResult::failed_part_count() const { - return test_part_results_.CountIf(TestPartFailed); +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; } // Returns true iff the test part fatally failed. -static bool TestPartFatallyFailed(const TestPartResult & result) { +static bool TestPartFatallyFailed(const TestPartResult& result) { return result.fatally_failed(); } // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { - return test_part_results_.CountIf(TestPartFatallyFailed) > 0; + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { - return test_part_results_.size(); + return static_cast<int>(test_part_results_.size()); } -} // namespace internal +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast<int>(test_properties_.size()); +} // class Test @@ -1897,7 +1948,23 @@ void Test::RecordProperty(const char* key, int value) { RecordProperty(key, value_message.GetString().c_str()); } -#ifdef GTEST_OS_WINDOWS +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + String()); // No stack trace, either. +} + +} // namespace internal + +#if GTEST_OS_WINDOWS // We are on Windows. // Adds an "exception thrown" fatal failure to the current test. @@ -1907,15 +1974,8 @@ static void AddExceptionThrownFailure(DWORD exception_code, message << "Exception thrown with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " in " << location << "."; - UnitTest* const unit_test = UnitTest::GetInstance(); - unit_test->AddTestPartResult( - TPRT_FATAL_FAILURE, - static_cast<const char *>(NULL), - // We have no info about the source file where the exception - // occurred. - -1, // We have no info on which line caused the exception. - message.GetString(), - internal::String("")); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + message.GetString()); } #endif // GTEST_OS_WINDOWS @@ -1931,7 +1991,7 @@ bool Test::HasSameFixtureClass() { // Info about the first test in the current test case. const internal::TestInfoImpl* const first_test_info = - test_case->test_info_list().Head()->element()->impl(); + test_case->test_info_list()[0]->impl(); const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); const char* const first_test_name = first_test_info->name(); @@ -1993,8 +2053,8 @@ void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) - // We are on Windows. +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. impl->os_stack_trace_getter()->UponLeavingGTest(); __try { SetUp(); @@ -2025,7 +2085,7 @@ void Test::Run() { AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); } -#else // We are on Linux, Mac or MingW - exceptions are disabled. +#else // We are on a compiler or platform that doesn't support SEH. impl->os_stack_trace_getter()->UponLeavingGTest(); SetUp(); @@ -2040,7 +2100,7 @@ void Test::Run() { // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); TearDown(); -#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_SEH } @@ -2049,18 +2109,24 @@ bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory // object via impl_. -TestInfo::TestInfo(const char* test_case_name, - const char* name, - const char* test_case_comment, - const char* comment, +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) { - impl_ = new internal::TestInfoImpl(this, test_case_name, name, - test_case_comment, comment, + impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, + a_test_case_comment, a_comment, fixture_class_id, factory); } @@ -2102,7 +2168,7 @@ TestInfo* MakeAndRegisterTestInfo( return test_info; } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; @@ -2146,8 +2212,11 @@ const char* TestInfo::comment() const { // Returns true if this test should run. bool TestInfo::should_run() const { return impl_->should_run(); } +// Returns true if this test matches the user-specified filter. +bool TestInfo::matches_filter() const { return impl_->matches_filter(); } + // Returns the result of the test. -const internal::TestResult* TestInfo::result() const { return impl_->result(); } +const TestResult* TestInfo::result() const { return impl_->result(); } // Increments the number of death tests encountered in this test so // far. @@ -2184,24 +2253,13 @@ class TestNameIs { } // namespace -// Finds and returns a TestInfo with the given name. If one doesn't -// exist, returns NULL. -TestInfo * TestCase::GetTestInfo(const char* test_name) { - // Can we find a TestInfo with the given name? - internal::ListNode<TestInfo *> * const node = test_info_list_->FindIf( - TestNameIs(test_name)); - - // Returns the TestInfo found. - return node ? node->element() : NULL; -} - namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; @@ -2218,17 +2276,16 @@ void TestInfoImpl::Run() { UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(parent_); - // Notifies the unit test event listener that a test is about to - // start. - UnitTestEventListenerInterface* const result_printer = - impl->result_printer(); - result_printer->OnTestStart(parent_); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*parent_); const TimeInMillis start = GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) - // We are on Windows. +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. Test* test = NULL; __try { @@ -2240,7 +2297,7 @@ void TestInfoImpl::Run() { "the test fixture's constructor"); return; } -#else // We are on Linux, Mac OS or MingW - exceptions are disabled. +#else // We are on a compiler or platform that doesn't support SEH. // TODO(wan): If test->Run() throws, test won't be deleted. This is // not a problem now as we don't use exceptions. If we were to @@ -2249,7 +2306,7 @@ void TestInfoImpl::Run() { // Creates the test object. Test* test = factory_->CreateTest(); -#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_SEH // Runs the test only if the constructor of the test fixture didn't // generate a fatal failure. @@ -2265,7 +2322,7 @@ void TestInfoImpl::Run() { result_.set_elapsed_time(GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. - result_printer->OnTestEnd(parent_); + repeater->OnTestEnd(*parent_); // Tells UnitTest to stop associating assertion results to this // test. @@ -2278,26 +2335,26 @@ void TestInfoImpl::Run() { // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { - return test_info_list_->CountIf(TestPassed); + return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { - return test_info_list_->CountIf(TestFailed); + return CountIf(test_info_list_, TestFailed); } int TestCase::disabled_test_count() const { - return test_info_list_->CountIf(TestDisabled); + return CountIf(test_info_list_, TestDisabled); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { - return test_info_list_->CountIf(ShouldRunTest); + return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { - return test_info_list_->size(); + return static_cast<int>(test_info_list_.size()); } // Creates a TestCase with the given name. @@ -2307,32 +2364,42 @@ int TestCase::total_test_count() const { // name: name of the test case // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case -TestCase::TestCase(const char* name, const char* comment, +TestCase::TestCase(const char* a_name, const char* a_comment, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) - : name_(name), - comment_(comment), + : name_(a_name), + comment_(a_comment), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { - test_info_list_ = new internal::List<TestInfo *>; } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. - test_info_list_->ForEach(internal::Delete<TestInfo>); + ForEach(test_info_list_, internal::Delete<TestInfo>); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} - // Then deletes the Test collection. - delete test_info_list_; - test_info_list_ = NULL; +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { - test_info_list_->PushBack(test_info); + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast<int>(test_indices_.size())); } // Runs every test in this TestCase. @@ -2342,38 +2409,62 @@ void TestCase::Run() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); - UnitTestEventListenerInterface * const result_printer = - impl->result_printer(); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - result_printer->OnTestCaseStart(this); + repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); set_up_tc_(); const internal::TimeInMillis start = internal::GetTimeInMillis(); - test_info_list_->ForEach(internal::TestInfoImpl::RunTest); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->impl()->Run(); + } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); tear_down_tc_(); - result_printer->OnTestCaseEnd(this); + repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { - test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult); + ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); +} + +// Returns true iff test passed. +bool TestCase::TestPassed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Passed(); } +// Returns true iff test failed. +bool TestCase::TestFailed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Failed(); +} -// class UnitTestEventListenerInterface +// Returns true iff test is disabled. +bool TestCase::TestDisabled(const TestInfo * test_info) { + return test_info->impl()->is_disabled(); +} -// The virtual d'tor. -UnitTestEventListenerInterface::~UnitTestEventListenerInterface() { +// Returns true if the given test should run. +bool TestCase::ShouldRunTest(const TestInfo *test_info) { + return test_info->impl()->should_run(); } -// A result printer that never prints anything. Used in the child process -// of an exec-style death test to avoid needless output clutter. -class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {}; +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast<int>(i); + } +} // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. @@ -2397,17 +2488,17 @@ static internal::String FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } -// Converts a TestPartResultType enum to human-friendly string -// representation. Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE -// are translated to "Failure", as the user usually doesn't care about -// the difference between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResultType type) { +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { - case TPRT_SUCCESS: + case TestPartResult::kSuccess: return "Success"; - case TPRT_NONFATAL_FAILURE: - case TPRT_FATAL_FAILURE: + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else @@ -2418,15 +2509,33 @@ static const char * TestPartResultTypeToString(TestPartResultType type) { return "Unknown result type"; } +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + // Prints a TestPartResult. -static void PrintTestPartResult( - const TestPartResult & test_part_result) { - printf("%s %s%s\n", - internal::FormatFileLocation(test_part_result.file_name(), - test_part_result.line_number()).c_str(), - TestPartResultTypeToString(test_part_result.type()), - test_part_result.message()); +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const internal::String& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif } // class PrettyUnitTestResultPrinter @@ -2434,12 +2543,13 @@ static void PrintTestPartResult( namespace internal { enum GTestColor { + COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; -#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -2447,39 +2557,42 @@ WORD GetColorAttribute(GTestColor color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; } - return 0; } #else -// Returns the ANSI color code for the given color. +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; + default: return NULL; }; - return NULL; } -#endif // GTEST_OS_WINDOWS && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // 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 GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; #else // On non-Windows platforms, we rely on the TERM variable. - const char* const term = GetEnv("TERM"); + const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS @@ -2502,11 +2615,13 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -#if defined(_WIN32_WCE) || defined(GTEST_OS_SYMBIAN) || defined(GTEST_OS_ZOS) - static const bool use_color = false; +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; #else - static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0); -#endif // !_WIN32_WCE + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { @@ -2515,7 +2630,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -2523,220 +2638,229 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); + fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. -#endif // GTEST_OS_WINDOWS && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } -} // namespace internal - -using internal::ColoredPrintf; -using internal::COLOR_RED; -using internal::COLOR_GREEN; -using internal::COLOR_YELLOW; - -// This class implements the UnitTestEventListenerInterface interface. +// This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { +class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } - // The following methods override what's in the - // UnitTestEventListenerInterface class. - virtual void OnUnitTestStart(const UnitTest * unit_test); - virtual void OnGlobalSetUpStart(const UnitTest*); - virtual void OnTestCaseStart(const TestCase * test_case); - virtual void OnTestCaseEnd(const TestCase * test_case); - virtual void OnTestStart(const TestInfo * test_info); - virtual void OnNewTestPartResult(const TestPartResult * result); - virtual void OnTestEnd(const TestInfo * test_info); - virtual void OnGlobalTearDownStart(const UnitTest*); - virtual void OnUnitTestEnd(const UnitTest * unit_test); + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: + static void PrintFailedTests(const UnitTest& unit_test); + internal::String test_case_name_; }; -// Called before the unit test starts. -void PrettyUnitTestResultPrinter::OnUnitTestStart( - const UnitTest * unit_test) { - const char * const filter = GTEST_FLAG(filter).c_str(); + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!internal::String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME, filter); + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %s of %s.\n", + internal::posix::GetEnv(kTestShardIndex), + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); } - const internal::UnitTestImpl* const impl = unit_test->impl(); ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", - FormatTestCount(impl->test_to_run_count()).c_str(), - FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); fflush(stdout); } -void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) { +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestCaseStart( - const TestCase * test_case) { - test_case_name_ = test_case->name(); +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + test_case_name_ = test_case.name(); const internal::String counts = - FormatCountableNoun(test_case->test_to_run_count(), "test", "tests"); + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case_name_.c_str()); - if (test_case->comment()[0] == '\0') { + if (test_case.comment()[0] == '\0') { printf("\n"); } else { - printf(", where %s\n", test_case->comment()); + printf(", where %s\n", test_case.comment()); } fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestCaseEnd( - const TestCase * test_case) { - if (!GTEST_FLAG(print_time)) return; - - test_case_name_ = test_case->name(); - const internal::String counts = - FormatCountableNoun(test_case->test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s (%s ms total)\n\n", - counts.c_str(), test_case_name_.c_str(), - internal::StreamableToString(test_case->elapsed_time()).c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) { +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); - PrintTestName(test_case_name_.c_str(), test_info->name()); - if (test_info->comment()[0] == '\0') { + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.comment()[0] == '\0') { printf("\n"); } else { - printf(", where %s\n", test_info->comment()); + printf(", where %s\n", test_info.comment()); } fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) { - if (test_info->result()->Passed()) { +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); } else { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } - PrintTestName(test_case_name_.c_str(), test_info->name()); + PrintTestName(test_case_name_.c_str(), test_info.name()); if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( - test_info->result()->elapsed_time()).c_str()); + test_info.result()->elapsed_time()).c_str()); } else { printf("\n"); } fflush(stdout); } -// Called after an assertion failure. -void PrettyUnitTestResultPrinter::OnNewTestPartResult( - const TestPartResult * result) { - // If the test part succeeded, we don't need to do anything. - if (result->type() == TPRT_SUCCESS) - return; +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; - // Print failure message from the assertion (e.g. expected this and got that). - PrintTestPartResult(*result); + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } -void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) { +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } -namespace internal { - // Internal helper for printing the list of failed tests. -static void PrintFailedTestsPretty(const UnitTestImpl* impl) { - const int failed_test_count = impl->failed_test_count(); +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); if (failed_test_count == 0) { return; } - for (const internal::ListNode<TestCase*>* node = impl->test_cases()->Head(); - node != NULL; node = node->next()) { - const TestCase* const tc = node->element(); - if (!tc->should_run() || (tc->failed_test_count() == 0)) { + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { continue; } - for (const internal::ListNode<TestInfo*>* tinode = - tc->test_info_list().Head(); - tinode != NULL; tinode = tinode->next()) { - const TestInfo* const ti = tinode->element(); - if (!tc->ShouldRunTest(ti) || tc->TestPassed(ti)) { + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { continue; } ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s.%s", ti->test_case_name(), ti->name()); - if (ti->test_case_comment()[0] != '\0' || - ti->comment()[0] != '\0') { - printf(", where %s", ti->test_case_comment()); - if (ti->test_case_comment()[0] != '\0' && - ti->comment()[0] != '\0') { + printf("%s.%s", test_case.name(), test_info.name()); + if (test_case.comment()[0] != '\0' || + test_info.comment()[0] != '\0') { + printf(", where %s", test_case.comment()); + if (test_case.comment()[0] != '\0' && + test_info.comment()[0] != '\0') { printf(" and "); } } - printf("%s\n", ti->comment()); + printf("%s\n", test_info.comment()); } } } -} // namespace internal - -void PrettyUnitTestResultPrinter::OnUnitTestEnd( - const UnitTest * unit_test) { - const internal::UnitTestImpl* const impl = unit_test->impl(); - + void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", - FormatTestCount(impl->test_to_run_count()).c_str(), - FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); if (GTEST_FLAG(print_time)) { printf(" (%s ms total)", - internal::StreamableToString(impl->elapsed_time()).c_str()); + internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(impl->successful_test_count()).c_str()); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); - int num_failures = impl->failed_test_count(); - if (!impl->Passed()) { - const int failed_test_count = impl->failed_test_count(); + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); - internal::PrintFailedTestsPretty(impl); + PrintFailedTests(unit_test); printf("\n%2d FAILED %s\n", num_failures, num_failures == 1 ? "TEST" : "TESTS"); } - int num_disabled = impl->disabled_test_count(); - if (num_disabled) { + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } @@ -2751,81 +2875,127 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd( // End PrettyUnitTestResultPrinter -// class UnitTestEventsRepeater +// class TestEventRepeater // // This class forwards events to other event listeners. -class UnitTestEventsRepeater : public UnitTestEventListenerInterface { +class TestEventRepeater : public TestEventListener { public: - typedef internal::List<UnitTestEventListenerInterface *> Listeners; - typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode; - UnitTestEventsRepeater() {} - virtual ~UnitTestEventsRepeater(); - void AddListener(UnitTestEventListenerInterface *listener); - - virtual void OnUnitTestStart(const UnitTest* unit_test); - virtual void OnUnitTestEnd(const UnitTest* unit_test); - virtual void OnGlobalSetUpStart(const UnitTest* unit_test); - virtual void OnGlobalSetUpEnd(const UnitTest* unit_test); - virtual void OnGlobalTearDownStart(const UnitTest* unit_test); - virtual void OnGlobalTearDownEnd(const UnitTest* unit_test); - virtual void OnTestCaseStart(const TestCase* test_case); - virtual void OnTestCaseEnd(const TestCase* test_case); - virtual void OnTestStart(const TestInfo* test_info); - virtual void OnTestEnd(const TestInfo* test_info); - virtual void OnNewTestPartResult(const TestPartResult* result); + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); private: - Listeners listeners_; + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector<TestEventListener*> listeners_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; -UnitTestEventsRepeater::~UnitTestEventsRepeater() { - for (ListenersNode* listener = listeners_.Head(); - listener != NULL; - listener = listener->next()) { - delete listener->element(); - } +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete<TestEventListener>); } -void UnitTestEventsRepeater::AddListener( - UnitTestEventListenerInterface *listener) { - listeners_.PushBack(listener); +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); } -// Since the methods are identical, use a macro to reduce boilerplate. -// This defines a member that repeats the call to all listeners. +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ -void UnitTestEventsRepeater::Name(const Type* parameter) { \ - for (ListenersNode* listener = listeners_.Head(); \ - listener != NULL; \ - listener = listener->next()) { \ - listener->element()->Name(parameter); \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(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_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, 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_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ -// End PrettyUnitTestResultPrinter +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater // This class generates an XML output file. -class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { +class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); - virtual void OnUnitTestEnd(const UnitTest* unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character @@ -2843,39 +3013,41 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. - static internal::String EscapeXml(const char* str, - bool is_attribute); + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static String RemoveInvalidXmlCharacters(const char* str); // Convenience wrapper around EscapeXml when str is an attribute value. - static internal::String EscapeXmlAttribute(const char* str) { + static String EscapeXmlAttribute(const char* str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. - static internal::String EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); - // Prints an XML representation of a TestInfo object. - static void PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo* test_info); + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); // Prints an XML representation of a TestCase object - static void PrintXmlTestCase(FILE* out, const TestCase* test_case); + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); // Prints an XML summary of unit_test to output stream out. - static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test); + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. // When the String is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. - static internal::String TestPropertiesAsXmlAttributes( - const internal::TestResult* result); + static String TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. - const internal::String output_file_; + const String output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; @@ -2891,23 +3063,14 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) } // Called after the unit test ends. -void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { FILE* xmlout = NULL; - internal::FilePath output_file(output_file_); - internal::FilePath output_dir(output_file.RemoveFileName()); + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { - // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 - // (deprecated function) there. -#ifdef GTEST_OS_WINDOWS - // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - xmlout = fopen(output_file_.c_str(), "w"); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - xmlout = fopen(output_file_.c_str(), "w"); -#endif // GTEST_OS_WINDOWS + xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. @@ -2942,8 +3105,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. -internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, - bool is_attribute) { +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { Message m; if (str != NULL) { @@ -2973,7 +3135,7 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, default: if (IsValidXmlCharacter(*src)) { if (is_attribute && IsNormalizableWhitespace(*src)) - m << internal::String::Format("&#x%02X;", unsigned(*src)); + m << String::Format("&#x%02X;", unsigned(*src)); else m << *src; } @@ -2985,13 +3147,28 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, return m.GetString(); } +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { + char* const output = new char[strlen(str) + 1]; + char* appender = output; + for (char ch = *str; ch != '\0'; ch = *++str) + if (IsValidXmlCharacter(ch)) + *appender++ = ch; + *appender = '\0'; + + String ret_value(output); + delete[] output; + return ret_value; +} // The following routines generate an XML representation of a UnitTest // object. // // This is how Google Test concepts map to the DTD: // -// <testsuite name="AllTests"> <-- corresponds to a UnitTest object +// <testsuites name="AllTests"> <-- corresponds to a UnitTest object // <testsuite name="testcase-name"> <-- corresponds to a TestCase object // <testcase name="test-name"> <-- corresponds to a TestInfo object // <failure message="...">...</failure> @@ -3000,118 +3177,122 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, // <-- individual assertion failures // </testcase> // </testsuite> -// </testsuite> - -namespace internal { - -// Formats the given time in milliseconds as seconds. The returned -// C-string is owned by this function and cannot be released by the -// caller. Calling the function again invalidates the previous -// result. -const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) { - static String str; - str = (Message() << (ms/1000.0)).GetString(); - return str.c_str(); +// </testsuites> + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << "<![CDATA["; + for (;;) { + const char* const next_segment = strstr(segment, "]]>"); + if (next_segment != NULL) { + stream->write( + segment, static_cast<std::streamsize>(next_segment - segment)); + *stream << "]]>]]><![CDATA["; + segment = next_segment + strlen("]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; } -} // namespace internal - // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. -void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo* test_info) { - const internal::TestResult * const result = test_info->result(); - const internal::List<TestPartResult> &results = result->test_part_results(); - fprintf(out, - " <testcase name=\"%s\" status=\"%s\" time=\"%s\" " - "classname=\"%s\"%s", - EscapeXmlAttribute(test_info->name()).c_str(), - test_info->should_run() ? "run" : "notrun", - internal::FormatTimeInMillisAsSeconds(result->elapsed_time()), - EscapeXmlAttribute(test_case_name).c_str(), - TestPropertiesAsXmlAttributes(result).c_str()); +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " <testcase name=\"" + << EscapeXmlAttribute(test_info.name()).c_str() + << "\" status=\"" + << (test_info.should_run() ? "run" : "notrun") + << "\" time=\"" + << FormatTimeInMillisAsSeconds(result.elapsed_time()) + << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str() + << "\"" << TestPropertiesAsXmlAttributes(result).c_str(); int failures = 0; - for (const internal::ListNode<TestPartResult>* part_node = results.Head(); - part_node != NULL; - part_node = part_node->next()) { - const TestPartResult& part = part_node->element(); + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); if (part.failed()) { - const internal::String message = - internal::String::Format("%s:%d\n%s", part.file_name(), - part.line_number(), part.message()); if (++failures == 1) - fprintf(out, ">\n"); - fprintf(out, - " <failure message=\"%s\" type=\"\"><![CDATA[%s]]>" - "</failure>\n", - EscapeXmlAttribute(part.summary()).c_str(), message.c_str()); + *stream << ">\n"; + *stream << " <failure message=\"" + << EscapeXmlAttribute(part.summary()).c_str() + << "\" type=\"\">"; + const String message = RemoveInvalidXmlCharacters(String::Format( + "%s:%d\n%s", + part.file_name(), part.line_number(), + part.message()).c_str()); + OutputXmlCDataSection(stream, message.c_str()); + *stream << "</failure>\n"; } } if (failures == 0) - fprintf(out, " />\n"); + *stream << " />\n"; else - fprintf(out, " </testcase>\n"); + *stream << " </testcase>\n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, - const TestCase* test_case) { + const TestCase& test_case) { fprintf(out, " <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" " "disabled=\"%d\" ", - EscapeXmlAttribute(test_case->name()).c_str(), - test_case->total_test_count(), - test_case->failed_test_count(), - test_case->disabled_test_count()); + EscapeXmlAttribute(test_case.name()).c_str(), + test_case.total_test_count(), + test_case.failed_test_count(), + test_case.disabled_test_count()); fprintf(out, "errors=\"0\" time=\"%s\">\n", - internal::FormatTimeInMillisAsSeconds(test_case->elapsed_time())); - for (const internal::ListNode<TestInfo*>* info_node = - test_case->test_info_list().Head(); - info_node != NULL; - info_node = info_node->next()) { - PrintXmlTestInfo(out, test_case->name(), info_node->element()); + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + StrStream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StrStreamToString(&stream).c_str()); } fprintf(out, " </testsuite>\n"); } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, - const UnitTest* unit_test) { - const internal::UnitTestImpl* const impl = unit_test->impl(); + const UnitTest& unit_test) { fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(out, - "<testsuite tests=\"%d\" failures=\"%d\" disabled=\"%d\" " + "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" " "errors=\"0\" time=\"%s\" ", - impl->total_test_count(), - impl->failed_test_count(), - impl->disabled_test_count(), - internal::FormatTimeInMillisAsSeconds(impl->elapsed_time())); - fprintf(out, "name=\"AllTests\">\n"); - for (const internal::ListNode<TestCase*>* case_node = - impl->test_cases()->Head(); - case_node != NULL; - case_node = case_node->next()) { - PrintXmlTestCase(out, case_node->element()); + unit_test.total_test_count(), + unit_test.failed_test_count(), + unit_test.disabled_test_count(), + FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str()); + if (GTEST_FLAG(shuffle)) { + fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); } - fprintf(out, "</testsuite>\n"); + fprintf(out, "name=\"AllTests\">\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "</testsuites>\n"); } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. -internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( - const internal::TestResult* result) { - using internal::TestProperty; +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { Message attributes; - const internal::List<TestProperty>& properties = result->test_properties(); - for (const internal::ListNode<TestProperty>* property_node = - properties.Head(); - property_node != NULL; - property_node = property_node->next()) { - const TestProperty& property = property_node->element(); + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" << "\"" << EscapeXmlAttribute(property.value()) << "\""; } @@ -3120,8 +3301,6 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // End XmlUnitTestResultPrinter -namespace internal { - // Class ScopedTrace // Pushes the given source file location and message onto a per-thread @@ -3164,10 +3343,85 @@ void OsStackTraceGetter::UponLeavingGTest() { const char* const OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME " internal frames ..."; + "... " GTEST_NAME_ " internal frames ..."; } // namespace internal +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + // class UnitTest // Gets the singleton UnitTest object. The first time this method is @@ -3184,13 +3438,88 @@ UnitTest * UnitTest::GetInstance() { // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. -#if _MSC_VER == 1310 && !defined(_DEBUG) // MSVC 7.1 and optimized build. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; -#endif // _MSC_VER==1310 && !defined(_DEBUG) +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); } // Registers and returns a global test environment. When a test @@ -3208,17 +3537,29 @@ Environment* UnitTest::AddEnvironment(Environment* env) { return NULL; } - impl_->environments()->PushBack(env); - impl_->environments_in_reverse_order()->PushFront(env); + impl_->environments().push_back(env); return env; } +#if GTEST_HAS_EXCEPTIONS +// A failed Google Test assertion will throw an exception of this type +// when exceptions are enabled. We derive it from std::runtime_error, +// which is for errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif + // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. // L < mutex_ -void UnitTest::AddTestPartResult(TestPartResultType result_type, +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const internal::String& message, @@ -3227,15 +3568,14 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, msg << message; internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack()->size() > 0) { - msg << "\n" << GTEST_NAME << " trace:"; - - for (internal::ListNode<internal::TraceInfo>* node = - impl_->gtest_trace_stack()->Head(); - node != NULL; - node = node->next()) { - const internal::TraceInfo& trace = node->element(); - msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message; + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast<int>(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; } } @@ -3249,11 +3589,30 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); - // If this is a failure and the user wants the debugger to break on - // failures ... - if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) { - // ... then we generate a seg fault. - *static_cast<int*>(NULL) = 1; + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + abort(); +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } } } @@ -3261,7 +3620,7 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, // the supplied value already exists, updates its value instead. void UnitTest::RecordPropertyForCurrentTest(const char* key, const char* value) { - const internal::TestProperty test_property(key, value); + const TestProperty test_property(key, value); impl_->current_test_result()->RecordProperty(test_property); } @@ -3271,18 +3630,48 @@ void UnitTest::RecordPropertyForCurrentTest(const char* key, // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) - -#if !defined(_WIN32_WCE) - // SetErrorMode doesn't exist on CE. - if (GTEST_FLAG(catch_exceptions)) { - // The user wants Google Test to catch exceptions thrown by the tests. - - // This lets fatal errors be handled by us, instead of causing pop-ups. +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { +#if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +#endif // !GTEST_OS_WINDOWS_MOBILE + +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +#endif + +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif } -#endif // _WIN32_WCE __try { return impl_->RunAllTests(); @@ -3293,11 +3682,10 @@ int UnitTest::Run() { return 1; } -#else - // We are on Linux, Mac OS or MingW. There is no exception of any kind. +#else // We are on a compiler or platform that doesn't support SEH. return impl_->RunAllTests(); -#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_SEH } // Returns the working directory when the first TEST() or TEST_F() was @@ -3322,7 +3710,10 @@ const TestInfo* UnitTest::current_test_info() const { return impl_->current_test_info(); } -#ifdef GTEST_HAS_PARAM_TEST +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // L < mutex_ @@ -3347,14 +3738,14 @@ UnitTest::~UnitTest() { // L < mutex_ void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PushFront(trace); + impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. // L < mutex_ void UnitTest::PopGTestTrace() { internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PopFront(NULL); + impl_->gtest_trace_stack().pop_back(); } namespace internal { @@ -3376,39 +3767,87 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), - test_cases_(), -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST - last_death_test_case_(NULL), + last_death_test_case_(-1), current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), - result_printer_(NULL), os_stack_trace_getter_(NULL), -#ifdef GTEST_HAS_DEATH_TEST + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. +#if GTEST_HAS_DEATH_TEST elapsed_time_(0), internal_run_death_test_flag_(NULL), death_test_factory_(new DefaultDeathTestFactory) { #else elapsed_time_(0) { #endif // GTEST_HAS_DEATH_TEST + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. - test_cases_.ForEach(internal::Delete<TestCase>); + ForEach(test_cases_, internal::Delete<TestCase>); // Deletes every Environment. - environments_.ForEach(internal::Delete<Environment>); - - // Deletes the current test result printer. - delete result_printer_; + ForEach(environments_, internal::Delete<Environment>); delete os_stack_trace_getter_; } +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + } +} + // A predicate that checks the name of a TestCase against a known // value. // @@ -3433,7 +3872,9 @@ class TestCaseNameIs { }; // Finds and returns a TestCase with the given name. If one doesn't -// exist, creates one and returns it. +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. // // Arguments: // @@ -3445,34 +3886,38 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? - internal::ListNode<TestCase*>* node = test_cases_.FindIf( - TestCaseNameIs(test_case_name)); + const std::vector<TestCase*>::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; - if (node == NULL) { - // No. Let's create one. - TestCase* const test_case = + // No. Let's create one. + TestCase* const new_test_case = new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); - // Is this a death test case? - if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), - kDeathTestCaseFilter)) { - // Yes. Inserts the test case after the last death test case - // defined so far. - node = test_cases_.InsertAfter(last_death_test_case_, test_case); - last_death_test_case_ = node; - } else { - // No. Appends to the end of the list. - test_cases_.PushBack(test_case); - node = test_cases_.Last(); - } + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); } - // Returns the TestCase found. - return node->element(); + test_case_indices_.push_back(static_cast<int>(test_case_indices_.size())); + return new_test_case; } // Helpers for setting up / tearing down the given environment. They -// are for use in the List::ForEach() method. +// are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } @@ -3482,7 +3927,7 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } // considered to be failed, but the rest of the tests will still be // run. (We disable exceptions on Linux and Mac OS X, so the issue // doesn't apply there.) -// When parameterized tests are enabled, it explands and registers +// When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. @@ -3495,189 +3940,300 @@ int UnitTestImpl::RunAllTests() { return 1; } - RegisterParameterizedTests(); - - // Lists all the tests and exits if the --gtest_list_tests - // flag was specified. - if (GTEST_FLAG(list_tests)) { - ListAllTests(); + // Do not run any test if the --help flag was specified. + if (g_help_flag) return 0; - } + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); // True iff we are in a subprocess for running a thread-safe-style // death test. bool in_subprocess_for_death_test = false; -#ifdef GTEST_HAS_DEATH_TEST - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); +#if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST - UnitTestEventListenerInterface * const printer = result_printer(); + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); // Compares the full test names with the filter to decide which // tests to run. - const bool has_tests_to_run = FilterTests() > 0; + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return 0; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + // True iff at least one test has failed. bool failed = false; + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { - if (repeat != 1) { - printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1); - } - - // Tells the unit test event listener that the tests are about to - // start. - printer->OnUnitTestStart(parent_); + ClearResult(); const TimeInMillis start = GetTimeInMillis(); + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. - printer->OnGlobalSetUpStart(parent_); - environments_.ForEach(SetUpEnvironment); - printer->OnGlobalSetUpEnd(parent_); + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { - test_cases_.ForEach(TestCase::RunTestCase); + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } } // Tears down all environments in reverse order afterwards. - printer->OnGlobalTearDownStart(parent_); - environments_in_reverse_order_.ForEach(TearDownEnvironment); - printer->OnGlobalTearDownEnd(parent_); + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; - // Tells the unit test event listener that the tests have just - // finished. - printer->OnUnitTestEnd(parent_); + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } - ClearResult(); + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } } + repeater->OnTestProgramEnd(*parent_); + // Returns 0 if all tests passed, or 1 other wise. return failed ? 1 : 0; } +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. -int UnitTestImpl::FilterTests() { +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. int num_runnable_tests = 0; - for (const internal::ListNode<TestCase *> *test_case_node = - test_cases_.Head(); - test_case_node != NULL; - test_case_node = test_case_node->next()) { - TestCase * const test_case = test_case_node->element(); + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; const String &test_case_name = test_case->name(); test_case->set_should_run(false); - for (const internal::ListNode<TestInfo *> *test_info_node = - test_case->test_info_list().Head(); - test_info_node != NULL; - test_info_node = test_info_node->next()) { - TestInfo * const test_info = test_info_node->element(); + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; const String test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = - internal::UnitTestOptions::MatchesFilter(test_case_name, - kDisableTestFilter) || - internal::UnitTestOptions::MatchesFilter(test_name, - kDisableTestFilter); + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); test_info->impl()->set_is_disabled(is_disabled); - const bool should_run = !is_disabled && + const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); - test_info->impl()->set_should_run(should_run); - test_case->set_should_run(test_case->should_run() || should_run); - if (should_run) { - num_runnable_tests++; - } - } - } - return num_runnable_tests; -} + test_info->impl()->set_matches_filter(matches_filter); -// Lists all tests by name. -void UnitTestImpl::ListAllTests() { - for (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head(); - test_case_node != NULL; - test_case_node = test_case_node->next()) { - const TestCase* const test_case = test_case_node->element(); + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; - // Prints the test case name following by an indented list of test nodes. - printf("%s.\n", test_case->name()); + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); - for (const internal::ListNode<TestInfo*>* test_info_node = - test_case->test_info_list().Head(); - test_info_node != NULL; - test_info_node = test_info_node->next()) { - const TestInfo* const test_info = test_info_node->element(); + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; - printf(" %s\n", test_info->name()); + test_info->impl()->set_should_run(is_selected); + test_case->set_should_run(test_case->should_run() || is_selected); } } - fflush(stdout); -} - -// Sets the unit test result printer. -// -// Does nothing if the input and the current printer object are the -// same; otherwise, deletes the old printer object and makes the -// input the current printer. -void UnitTestImpl::set_result_printer( - UnitTestEventListenerInterface* result_printer) { - if (result_printer_ != result_printer) { - delete result_printer_; - result_printer_ = result_printer; - } -} - -// Returns the current unit test result printer if it is not NULL; -// otherwise, creates an appropriate result printer, makes it the -// current printer, and returns it. -UnitTestEventListenerInterface* UnitTestImpl::result_printer() { - if (result_printer_ != NULL) { - return result_printer_; - } - -#ifdef GTEST_HAS_DEATH_TEST - if (internal_run_death_test_flag_.get() != NULL) { - result_printer_ = new NullUnitTestResultPrinter; - return result_printer_; - } -#endif // GTEST_HAS_DEATH_TEST - - UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater; - const String& output_format = internal::UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - repeater->AddListener(new XmlUnitTestResultPrinter( - internal::UnitTestOptions::GetOutputFile().c_str())); - } else if (output_format != "") { - printf("WARNING: unrecognized output format \"%s\" ignored.\n", - output_format.c_str()); - fflush(stdout); + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter()) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } } - repeater->AddListener(new PrettyUnitTestResultPrinter); - result_printer_ = repeater; - return result_printer_; + fflush(stdout); } // Sets the OS stack trace getter. @@ -3706,28 +4262,55 @@ OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. -internal::TestResult* UnitTestImpl::current_test_result() { +TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? current_test_info_->impl()->result() : &ad_hoc_test_result_; } +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast<int>(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast<int>(i); + } +} + // TestInfoImpl constructor. The new instance assumes ownership of the test // factory object. TestInfoImpl::TestInfoImpl(TestInfo* parent, - const char* test_case_name, - const char* name, - const char* test_case_comment, - const char* comment, - TypeId fixture_class_id, + const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + TypeId a_fixture_class_id, internal::TestFactoryBase* factory) : parent_(parent), - test_case_name_(String(test_case_name)), - name_(String(name)), - test_case_comment_(String(test_case_comment)), - comment_(String(comment)), - fixture_class_id_(fixture_class_id), + test_case_name_(String(a_test_case_name)), + name_(String(a_name)), + test_case_comment_(String(a_test_case_comment)), + comment_(String(a_comment)), + fixture_class_id_(a_fixture_class_id), should_run_(false), is_disabled_(false), + matches_filter_(false), factory_(factory) { } @@ -3746,15 +4329,41 @@ TestInfoImpl::~TestInfoImpl() { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) { +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. - return unit_test->impl()->CurrentOsStackTraceExceptTop(skip_count + 1); + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } -// Returns the number of failed test parts in the given test result object. -int GetFailedPartCount(const TestResult* result) { - return result->failed_part_count(); +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; } // Parses a string as a command line flag. The string should have @@ -3768,9 +4377,9 @@ const char* ParseFlagValue(const char* str, // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; - // The flag must start with "--" followed by GTEST_FLAG_PREFIX. - const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX, flag); - const size_t flag_len = flag_str.GetLength(); + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); + const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. @@ -3846,6 +4455,127 @@ bool ParseStringFlag(const char* str, const char* flag, String* value) { return true; } +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +#if GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" +" Suppress pop-ups caused by exceptions.\n" +#endif // GTEST_OS_WINDOWS +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. @@ -3860,20 +4590,29 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { using internal::ParseStringFlag; // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kBreakOnFailureFlag, + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being @@ -3889,8 +4628,21 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // We also need to decrement the iterator as we just removed // an element. i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; } } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } } // Parses the command line for Google Test flags, without initializing @@ -3917,7 +4669,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { internal::g_executable_path = internal::StreamableToString(argv[0]); -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); @@ -3925,6 +4677,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal diff --git a/utils/unittest/googletest/include/gtest/gtest-death-test.h b/utils/unittest/googletest/include/gtest/gtest-death-test.h index f0e109a3..121dc1f 100644 --- a/utils/unittest/googletest/include/gtest/gtest-death-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-death-test.h @@ -49,7 +49,7 @@ namespace testing { // after forking. GTEST_DECLARE_string_(death_test_style); -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // The following macros are useful for writing death tests. @@ -86,6 +86,57 @@ GTEST_DECLARE_string_(death_test_style); // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the <regex.h> library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// // Known caveats: // // A "threadsafe" style death test obtains the path to the test @@ -125,23 +176,28 @@ GTEST_DECLARE_string_(death_test_style); // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. -class ExitedWithCode { +class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + const int exit_code_; }; +#if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. -class KilledBySignal { +class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; private: const int signum_; }; +#endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, @@ -189,10 +245,10 @@ class KilledBySignal { #ifdef NDEBUG #define EXPECT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) + do { statement; } while (::testing::internal::AlwaysFalse()) #define ASSERT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) + do { statement; } while (::testing::internal::AlwaysFalse()) #else @@ -204,6 +260,24 @@ class KilledBySignal { #endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/utils/unittest/googletest/include/gtest/gtest-message.h b/utils/unittest/googletest/include/gtest/gtest-message.h index 7effd08..f135b69 100644 --- a/utils/unittest/googletest/include/gtest/gtest-message.h +++ b/utils/unittest/googletest/include/gtest/gtest-message.h @@ -46,6 +46,8 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#include <limits> + #include <gtest/internal/gtest-string.h> #include <gtest/internal/gtest-internal.h> @@ -77,7 +79,7 @@ namespace testing { // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". -class Message { +class GTEST_API_ Message { private: // The type of basic IO manipulators (endl, ends, and flush) for // narrow streams. @@ -89,7 +91,11 @@ class Message { // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. - Message() : ss_(new internal::StrStream) {} + Message() : ss_(new internal::StrStream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2); + } // Copy constructor. Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT @@ -102,7 +108,7 @@ class Message { } ~Message() { delete ss_; } -#ifdef GTEST_OS_SYMBIAN +#if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template <typename T> inline Message& operator <<(const T& value) { @@ -187,13 +193,13 @@ class Message { } private: -#ifdef GTEST_OS_SYMBIAN +#if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a // tr1::type_traits-like is_pointer works, and we can overload on that. template <typename T> - inline void StreamHelper(internal::true_type dummy, T* pointer) { + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { if (pointer == NULL) { *ss_ << "(null)"; } else { @@ -201,7 +207,7 @@ class Message { } } template <typename T> - inline void StreamHelper(internal::false_type dummy, const T& value) { + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { ::GTestStreamToHelper(ss_, value); } #endif // GTEST_OS_SYMBIAN diff --git a/utils/unittest/googletest/include/gtest/gtest-param-test.h b/utils/unittest/googletest/include/gtest/gtest-param-test.h index 0cf05dc..3184d07 100644 --- a/utils/unittest/googletest/include/gtest/gtest-param-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-param-test.h @@ -133,9 +133,12 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // -// Please also note that generator expressions are evaluated in -// RUN_ALL_TESTS(), after main() has started. This allows evaluation of -// parameter list based on command line parameters. +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. @@ -146,16 +149,20 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); #endif // 0 - -#include <utility> - #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST +#if !GTEST_OS_SYMBIAN +#include <utility> +#endif +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. #include <gtest/internal/gtest-internal.h> #include <gtest/internal/gtest-param-util.h> +#if GTEST_HAS_PARAM_TEST + namespace testing { // Functions producing parameter generators. @@ -1190,7 +1197,7 @@ inline internal::ParamGenerator<bool> Bool() { return Values(false, true); } -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // diff --git a/utils/unittest/googletest/include/gtest/gtest-spi.h b/utils/unittest/googletest/include/gtest/gtest-spi.h index a4e387a..c41da48 100644 --- a/utils/unittest/googletest/include/gtest/gtest-spi.h +++ b/utils/unittest/googletest/include/gtest/gtest-spi.h @@ -48,7 +48,7 @@ namespace testing { // generated in the same thread that created this object or it can intercept // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. -class ScopedFakeTestPartResultReporter +class GTEST_API_ ScopedFakeTestPartResultReporter : public TestPartResultReporterInterface { public: // The two possible mocking modes of this object. @@ -93,16 +93,16 @@ namespace internal { // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. -class SingleFailureChecker { +class GTEST_API_ SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, - TestPartResultType type, + TestPartResult::Type type, const char* substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; - const TestPartResultType type_; + const TestPartResult::Type type_; const String substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); @@ -143,14 +143,14 @@ class SingleFailureChecker { };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ @@ -160,14 +160,14 @@ class SingleFailureChecker { };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given @@ -190,32 +190,43 @@ class SingleFailureChecker { // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor -// works. The AcceptsMacroThatExpandsToUnprotectedComma test in -// gtest_unittest.cc will fail to compile if we do that. +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - statement;\ + if (::testing::internal::AlwaysTrue()) { statement; }\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ >est_failures);\ - statement;\ + if (::testing::internal::AlwaysTrue()) { statement; }\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/utils/unittest/googletest/include/gtest/gtest-test-part.h b/utils/unittest/googletest/include/gtest/gtest-test-part.h index 1a281af..f714759 100644 --- a/utils/unittest/googletest/include/gtest/gtest-test-part.h +++ b/utils/unittest/googletest/include/gtest/gtest-test-part.h @@ -34,41 +34,42 @@ #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include <iosfwd> +#include <vector> #include <gtest/internal/gtest-internal.h> #include <gtest/internal/gtest-string.h> namespace testing { -// The possible outcomes of a test part (i.e. an assertion or an -// explicit SUCCEED(), FAIL(), or ADD_FAILURE()). -enum TestPartResultType { - TPRT_SUCCESS, // Succeeded. - TPRT_NONFATAL_FAILURE, // Failed but the test can continue. - TPRT_FATAL_FAILURE // Failed and the test should be terminated. -}; - // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. -class TestPartResult { +class GTEST_API_ TestPartResult { public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. - TestPartResult(TestPartResultType type, - const char* file_name, - int line_number, - const char* message) - : type_(type), - file_name_(file_name), - line_number_(line_number), - summary_(ExtractSummary(message)), - message_(message) { + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { } // Gets the outcome of the test part. - TestPartResultType type() const { return type_; } + Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. @@ -85,18 +86,18 @@ class TestPartResult { const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. - bool passed() const { return type_ == TPRT_SUCCESS; } + bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. - bool failed() const { return type_ != TPRT_SUCCESS; } + bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; } + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. - bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; } + bool fatally_failed() const { return type_ == kFatalFailure; } private: - TestPartResultType type_; + Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. @@ -117,15 +118,11 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // An array of TestPartResult objects. // -// We define this class as we cannot use STL containers when compiling -// Google Test with MSVC 7.1 and exceptions disabled. -// // Don't inherit from TestPartResultArray as its destructor is not // virtual. -class TestPartResultArray { +class GTEST_API_ TestPartResultArray { public: - TestPartResultArray(); - ~TestPartResultArray(); + TestPartResultArray() {} // Appends the given TestPartResult to the array. void Append(const TestPartResult& result); @@ -135,10 +132,9 @@ class TestPartResultArray { // Returns the number of TestPartResult objects in the array. int size() const; + private: - // Internally we use a list to simulate the array. Yes, this means - // that random access is O(N) in time, but it's OK for its purpose. - internal::List<TestPartResult>* const list_; + std::vector<TestPartResult> array_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; @@ -159,7 +155,8 @@ namespace internal { // reported, it only delegates the reporting to the former result reporter. // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -class HasNewFatalFailureHelper : public TestPartResultReporterInterface { +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { public: HasNewFatalFailureHelper(); virtual ~HasNewFatalFailureHelper(); diff --git a/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/utils/unittest/googletest/include/gtest/gtest-typed-test.h index dec42cf..1ec8eb8 100644 --- a/utils/unittest/googletest/include/gtest/gtest-typed-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-typed-test.h @@ -151,7 +151,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Implements typed tests. -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // @@ -159,8 +159,11 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // given test case. #define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) #define TYPED_TEST_CASE(CaseName, Types) \ - typedef ::testing::internal::TypeList<Types>::type \ + typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) #define TYPED_TEST(CaseName, TestName) \ @@ -186,7 +189,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Implements type-parameterized tests. -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // @@ -241,11 +244,14 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ __FILE__, __LINE__, #__VA_ARGS__) +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) #define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ bool gtest_##Prefix##_##CaseName = \ ::testing::internal::TypeParameterizedTestCase<CaseName, \ GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ - ::testing::internal::TypeList<Types>::type>::Register(\ + ::testing::internal::TypeList< Types >::type>::Register(\ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P diff --git a/utils/unittest/googletest/include/gtest/gtest.h b/utils/unittest/googletest/include/gtest/gtest.h index ebd3123..921fad1 100644 --- a/utils/unittest/googletest/include/gtest/gtest.h +++ b/utils/unittest/googletest/include/gtest/gtest.h @@ -51,17 +51,9 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ -// The following platform macros are used throughout Google Test: -// _WIN32_WCE Windows CE (set in project files) -// -// Note that even though _MSC_VER and _WIN32_WCE really indicate a compiler -// and a Win32 implementation, respectively, we use them to indicate the -// combination of compiler - Win 32 API - C library, since the code currently -// only supports: -// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and -// Windows Mobile with Visual C++ and no C library (_WIN32_WCE). - #include <limits> +#include <vector> + #include <gtest/internal/gtest-internal.h> #include <gtest/internal/gtest-string.h> #include <gtest/gtest-death-test.h> @@ -72,41 +64,99 @@ #include <gtest/gtest-typed-test.h> // Depending on the platform, different string classes are available. -// On Windows, ::std::string compiles only when exceptions are -// enabled. On Linux, in addition to ::std::string, Google also makes -// use of class ::string, which has the same interface as -// ::std::string, but has a different implementation. -// -// The user can tell us whether ::std::string is available in his -// environment by defining the macro GTEST_HAS_STD_STRING to either 1 -// or 0 on the compiler command line. He can also define -// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available -// AND is a distinct type to ::std::string, or define it to 0 to -// indicate otherwise. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. // // If the user's ::std::string and ::string are the same class due to -// aliasing, he should define GTEST_HAS_STD_STRING to 1 and -// GTEST_HAS_GLOBAL_STRING to 0. +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. // -// If the user doesn't define GTEST_HAS_STD_STRING and/or -// GTEST_HAS_GLOBAL_STRING, they are defined heuristically. +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. namespace testing { -// The upper limit for valid stack trace depths. -const int kMaxStackTraceDepth = 100; +// Declares the flags. -// This flag specifies the maximum number of stack frames to be -// printed in a failure message. -GTEST_DECLARE_int32_(stack_trace_depth); +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + namespace internal { +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; class GTestFlagSaver; +class TestInfoImpl; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message); +class PrettyUnitTestResultPrinter; +class XmlUnitTestResultPrinter; // Converts a streamable value to a String. A NULL pointer is // converted to "(null)". When the input value is a ::string, @@ -124,64 +174,146 @@ String StreamableToString(const T& streamable) { // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object -// remembers a non-empty message that described how it failed. +// remembers a non-empty message that describes how it failed. // -// This class is useful for defining predicate-format functions to be -// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). -// -// The constructor of AssertionResult is private. To create an -// instance of this class, use one of the factory functions +// To create an instance of this class, use one of the factory functions // (AssertionSuccess() and AssertionFailure()). // -// For example, in order to be able to write: +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: // // // Verifies that Foo() returns an even number. // EXPECT_PRED_FORMAT1(IsEven, Foo()); // -// you just need to define: +// you need to define: // // testing::AssertionResult IsEven(const char* expr, int n) { -// if ((n % 2) == 0) return testing::AssertionSuccess(); -// -// Message msg; -// msg << "Expected: " << expr << " is even\n" -// << " Actual: it's " << n; -// return testing::AssertionFailure(msg); +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; // } // // If Foo() returns 5, you will see the following message: // // Expected: Foo() is even // Actual: it's 5 -class AssertionResult { +// +class GTEST_API_ AssertionResult { public: - // Declares factory functions for making successful and failed - // assertion results as friends. - friend AssertionResult AssertionSuccess(); - friend AssertionResult AssertionFailure(const Message&); + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} // Returns true iff the assertion succeeded. - operator bool() const { return failure_message_.c_str() == NULL; } // NOLINT + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL && message_->c_str() != NULL ? + message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } - // Returns the assertion's failure message. - const char* failure_message() const { return failure_message_.c_str(); } + // Streams a custom failure message into this object. + template <typename T> AssertionResult& operator<<(const T& value); private: - // The default constructor. It is used when the assertion succeeded. - AssertionResult() {} - - // The constructor used when the assertion failed. - explicit AssertionResult(const internal::String& failure_message); - - // Stores the assertion's failure message. - internal::String failure_message_; -}; + // No implementation - we want AssertionResult to be + // copy-constructible but not assignable. + void operator=(const AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr<internal::String> message_; +}; // class AssertionResult + +// Streams a custom failure message into this object. +template <typename T> +AssertionResult& AssertionResult::operator<<(const T& value) { + Message msg; + if (message_.get() != NULL) + msg << *message_; + msg << value; + message_.reset(new internal::String(msg.GetString())); + return *this; +} // Makes a successful assertion result. -AssertionResult AssertionSuccess(); +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); // Makes a failed assertion result with the given failure message. -AssertionResult AssertionFailure(const Message& msg); +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // The abstract class that all tests inherit from. // @@ -206,7 +338,7 @@ AssertionResult AssertionFailure(const Message& msg); // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. -class Test { +class GTEST_API_ Test { public: friend class internal::TestInfoImpl; @@ -237,6 +369,13 @@ class Test { // Returns true iff the current test has a fatal failure. static bool HasFatalFailure(); + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + // Logs a property for the current test. Only the last value for a given // key is remembered. // These are public static so they can be called from utility functions @@ -304,6 +443,155 @@ class Test { GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + internal::String key_; + // The value supplied by the user. + internal::String value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestInfoImpl; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector<TestPartResult>& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector<TestProperty>& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector<TestPartResult> test_part_results_; + // The vector of TestProperties + std::vector<TestProperty> test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult // A TestInfo object stores the following information about a test: // @@ -316,7 +604,7 @@ class Test { // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. -class TestInfo { +class GTEST_API_ TestInfo { public: // Destructs a TestInfo object. This function is not virtual, so // don't inherit from TestInfo. @@ -334,7 +622,9 @@ class TestInfo { // Returns the test comment. const char* comment() const; - // Returns true if this test should run. + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. // // Google Test allows the user to filter the tests by their full names. // The full name of a test Bar in test case Foo is defined as @@ -351,15 +641,16 @@ class TestInfo { bool should_run() const; // Returns the result of the test. - const internal::TestResult* result() const; + const TestResult* result() const; + private: -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST - friend class internal::TestInfoImpl; - friend class internal::UnitTestImpl; friend class Test; friend class TestCase; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* test_case_comment, const char* comment, @@ -368,6 +659,9 @@ class TestInfo { Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); + // Returns true if this test matches the user-specified filter. + bool matches_filter() const; + // Increments the number of death tests encountered in this test so // far. int increment_death_test_count(); @@ -389,6 +683,141 @@ class TestInfo { GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* comment() const { return comment_.c_str(); } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector<TestInfo*>& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector<TestInfo*>& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Returns true iff test passed. + static bool TestPassed(const TestInfo * test_info); + + // Returns true iff test failed. + static bool TestFailed(const TestInfo * test_info); + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo * test_info); + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo *test_info); + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + internal::String name_; + // Comment on the test case. + internal::String comment_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector<TestInfo*> test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector<int> test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + // An Environment object is capable of setting up and tearing down an // environment. The user should subclass this to define his own // environment(s). @@ -420,7 +849,159 @@ class Environment { virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; -// A UnitTest consists of a list of TestCases. +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is // created when UnitTest::GetInstance() is first called. This @@ -430,40 +1011,13 @@ class Environment { // // This class is thread-safe as long as the methods are called // according to their specification. -class UnitTest { +class GTEST_API_ UnitTest { public: // Gets the singleton UnitTest object. The first time this method // is called, a UnitTest object is constructed and returned. // Consecutive calls will return the same object. static UnitTest* GetInstance(); - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); - - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - void AddTestPartResult(TestPartResultType result_type, - const char* file_name, - int line_number, - const internal::String& message, - const internal::String& os_stack_trace); - - // Adds a TestProperty to the current TestResult object. If the result already - // contains a property with the same key, the value will be updated. - void RecordPropertyForCurrentTest(const char* key, const char* value); - // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // @@ -484,19 +1038,107 @@ class UnitTest { // or NULL if no test is running. const TestInfo* current_test_info() const; -#ifdef GTEST_HAS_PARAM_TEST + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); #endif // GTEST_HAS_PARAM_TEST + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } - private: - // ScopedTrace is a friend as it needs to modify the per-thread - // trace stack, which is a private member of UnitTest. + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const internal::String& message); // Creates an empty UnitTest. UnitTest(); @@ -556,36 +1198,34 @@ inline Environment* AddGlobalTestEnvironment(Environment* env) { // updated. // // Calling the function for the second time has no user-visible effect. -void InitGoogleTest(int* argc, char** argv); +GTEST_API_ void InitGoogleTest(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. -void InitGoogleTest(int* argc, wchar_t** argv); +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { // These overloaded versions handle ::std::string and ::std::wstring. -#if GTEST_HAS_STD_STRING -inline String FormatForFailureMessage(const ::std::string& str) { +GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) { return (Message() << '"' << str << '"').GetString(); } -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_STD_WSTRING -inline String FormatForFailureMessage(const ::std::wstring& wstr) { +GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) { return (Message() << "L\"" << wstr << '"').GetString(); } #endif // GTEST_HAS_STD_WSTRING // These overloaded versions handle ::string and ::wstring. #if GTEST_HAS_GLOBAL_STRING -inline String FormatForFailureMessage(const ::string& str) { +GTEST_API_ inline String FormatForFailureMessage(const ::string& str) { return (Message() << '"' << str << '"').GetString(); } #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING -inline String FormatForFailureMessage(const ::wstring& wstr) { +GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { return (Message() << "L\"" << wstr << '"').GetString(); } #endif // GTEST_HAS_GLOBAL_WSTRING @@ -614,10 +1254,20 @@ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + if (expected == actual) { return AssertionSuccess(); } +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), @@ -628,10 +1278,10 @@ AssertionResult CmpHelperEQ(const char* expected_expression, // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual); +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() @@ -688,7 +1338,7 @@ class EqHelper<true> { template <typename T1, typename T2> static AssertionResult Compare(const char* expected_expression, const char* actual_expression, - const T1& expected, + const T1& /* expected */, T2* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, @@ -720,72 +1370,72 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ return AssertionFailure(msg);\ }\ }\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - BiggestInt val1, BiggestInt val2); +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // Implements the helper function for {ASSERT|EXPECT}_NE -GTEST_IMPL_CMP_HELPER_(NE, !=) +GTEST_IMPL_CMP_HELPER_(NE, !=); // Implements the helper function for {ASSERT|EXPECT}_LE -GTEST_IMPL_CMP_HELPER_(LE, <=) +GTEST_IMPL_CMP_HELPER_(LE, <=); // Implements the helper function for {ASSERT|EXPECT}_LT -GTEST_IMPL_CMP_HELPER_(LT, < ) +GTEST_IMPL_CMP_HELPER_(LT, < ); // Implements the helper function for {ASSERT|EXPECT}_GE -GTEST_IMPL_CMP_HELPER_(GE, >=) +GTEST_IMPL_CMP_HELPER_(GE, >=); // Implements the helper function for {ASSERT|EXPECT}_GT -GTEST_IMPL_CMP_HELPER_(GT, > ) +GTEST_IMPL_CMP_HELPER_(GT, > ); #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual); +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); } // namespace internal @@ -797,32 +1447,30 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. -AssertionResult IsSubstring( +GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); -AssertionResult IsSubstring( +GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); -AssertionResult IsNotSubstring( +GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); -AssertionResult IsNotSubstring( +GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); -#if GTEST_HAS_STD_STRING -AssertionResult IsSubstring( +GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); -AssertionResult IsNotSubstring( +GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring( +GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); -AssertionResult IsNotSubstring( +GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING @@ -865,35 +1513,57 @@ AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error); +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros -class AssertHelper { +class GTEST_API_ AssertHelper { public: // Constructor. - AssertHelper(TestPartResultType type, const char* file, int line, + AssertHelper(TestPartResult::Type type, + const char* file, + int line, const char* message); + ~AssertHelper(); + // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; + private: - TestPartResultType const type_; - const char* const file_; - int const line_; - String const message_; + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // The abstract base class that all value-parameterized tests inherit from. // // This class adds support for accessing the test parameter value via @@ -981,10 +1651,22 @@ const T* TestWithParam<T>::parameter_ = NULL; #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") // Generates a fatal failure with a generic message. -#define FAIL() GTEST_FATAL_FAILURE_("Failed") +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +#define FAIL() GTEST_FAIL() +#endif // Generates a success with a generic message. -#define SUCCEED() GTEST_SUCCESS_("Succeeded") +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +#define SUCCEED() GTEST_SUCCEED() +#endif // Macros for testing exceptions. // @@ -1008,7 +1690,9 @@ const T* TestWithParam<T>::parameter_ = NULL; #define ASSERT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) -// Boolean assertions. +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. #define EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) @@ -1181,13 +1865,13 @@ const T* TestWithParam<T>::parameter_ = NULL; // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2); -AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2); +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. @@ -1242,6 +1926,52 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) +namespace internal { + +// This template is declared, but intentionally undefined. +template <typename T1, typename T2> +struct StaticAssertTypeEqHelper; + +template <typename T> +struct StaticAssertTypeEqHelper<T, T> {}; + +} // namespace internal + +// Compile-time assertion for type equality. +// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq<T1, T2> by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template <typename T> class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq<int, T>(); } +// }; +// +// the code: +// +// void Test1() { Foo<bool> foo; } +// +// will NOT generate a compiler error, as Foo<bool>::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo<bool> foo; foo.Bar(); } +// +// to cause a compiler error. +template <typename T1, typename T2> +bool StaticAssertTypeEq() { + internal::StaticAssertTypeEqHelper<T1, T2>(); + return true; +} // Defines a test. // @@ -1268,10 +1998,15 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. -#define TEST(test_case_name, test_name)\ - GTEST_TEST_(test_case_name, test_name,\ +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif // Defines a test that uses a test fixture. // @@ -1300,7 +2035,7 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, // } #define TEST_F(test_fixture, test_name)\ - GTEST_TEST_(test_fixture, test_name, test_fixture,\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId<test_fixture>()) // Use this macro in main() to run all tests. It returns 0 if all diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h index 0769fca..e433084 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -46,9 +46,10 @@ GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method @@ -63,7 +64,7 @@ const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() -class DeathTest { +class GTEST_API_ DeathTest { public: // Create returns false if there was an error determining the // appropriate action to take for the current death test; for example, @@ -120,7 +121,12 @@ class DeathTest { // the last death test. static const char* LastMessage(); + static void set_last_death_test_message(const String& message); + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; @@ -141,13 +147,13 @@ class DefaultDeathTestFactory : public DeathTestFactory { // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status); +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. #define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (true) { \ + if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ @@ -166,7 +172,7 @@ bool ExitedUnsuccessfully(int exit_status); case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ - { statement; } \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ @@ -178,14 +184,35 @@ bool ExitedUnsuccessfully(int exit_status); // The symbol "fail" here expands to something into which a message // can be streamed. -// A struct representing the parsed contents of the +// A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. -struct InternalRunDeathTestFlag { - String file; - int line; - int index; - int status_fd; +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + String file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields @@ -193,6 +220,53 @@ struct InternalRunDeathTestFlag { // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + #endif // GTEST_HAS_DEATH_TEST } // namespace internal diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h index 9a0682a..4b76d79 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h @@ -34,7 +34,7 @@ // This header file declares classes and functions used internally by // Google Test. They are subject to change without notice. // -// This file is #included in testing/base/internal/gtest-internal.h +// This file is #included in <gtest/internal/gtest-internal.h>. // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ @@ -56,7 +56,7 @@ namespace internal { // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. -class FilePath { +class GTEST_API_ FilePath { public: FilePath() : pathname_("") { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } @@ -93,6 +93,12 @@ class FilePath { int number, const char* extension); + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_<number>.extension if directory/base_name.extension @@ -164,6 +170,9 @@ class FilePath { // root directory per disk drive.) bool IsRootDirectory() const; + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other @@ -180,9 +189,18 @@ class FilePath { // particular, RemoveTrailingPathSeparator() only removes one separator, and // it is called in CreateDirectoriesRecursively() assuming that it will change // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". void Normalize(); + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + String pathname_; }; // class FilePath diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h index b8f67c1..855b215 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h @@ -37,50 +37,51 @@ #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ -// GTEST_IMPLEMENTATION is defined iff the current translation unit is -// part of Google Test's implementation. -#ifndef GTEST_IMPLEMENTATION +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. #error "gtest-internal-inl.h is part of Google Test's internal implementation." #error "It must not be included except by Google Test itself." -#endif // GTEST_IMPLEMENTATION +#endif // GTEST_IMPLEMENTATION_ +#ifndef _WIN32_WCE +#include <errno.h> +#endif // !_WIN32_WCE #include <stddef.h> +#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. +#include <string.h> // For memmove. + +#include <algorithm> +#include <string> +#include <vector> #include <gtest/internal/gtest-port.h> -#ifdef GTEST_OS_WINDOWS -#include <windows.h> // NOLINT +#if GTEST_OS_WINDOWS +#include <windows.h> // For DWORD. #endif // GTEST_OS_WINDOWS -#include <gtest/gtest.h> +#include <gtest/gtest.h> // NOLINT #include <gtest/gtest-spi.h> namespace testing { // Declares the flags. // -// 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); +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). -extern const TypeId kTestTypeIdInGoogleTest; +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; @@ -88,7 +89,60 @@ const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast<unsigned int>(GetTimeInMillis()) : + static_cast<unsigned int>(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast<int>((raw_seed - 1U) % + static_cast<unsigned int>(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. @@ -96,44 +150,62 @@ class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. + bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; String color_; String death_test_style_; + bool death_test_use_fork_; String filter_; String internal_run_death_test_; bool list_tests_; String output_; bool print_time_; bool pretty_; + internal::Int32 random_seed_; internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. @@ -144,7 +216,7 @@ class GTestFlagSaver { // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output // as '(Invalid Unicode 0xXXXXXXXX)'. -char* CodePointToUtf8(UInt32 code_point, char* str); +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: @@ -159,300 +231,95 @@ char* CodePointToUtf8(UInt32 code_point, char* str); // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. -String WideStringToUtf8(const wchar_t* str, int num_chars); - -// Returns the number of active threads, or 0 when there is an error. -size_t GetThreadCount(); - -// List is a simple singly-linked list container. -// -// We cannot use std::list as Microsoft's implementation of STL has -// problems when exception is disabled. There is a hack to work -// around this, but we've seen cases where the hack fails to work. -// -// TODO(wan): switch to std::list when we have a reliable fix for the -// STL problem, e.g. when we upgrade to the next version of Visual -// C++, or (more likely) switch to STLport. -// -// The element type must support copy constructor. - -// Forward declare List -template <typename E> // E is the element type. -class List; - -// ListNode is a node in a singly-linked list. It consists of an -// element and a pointer to the next node. The last node in the list -// has a NULL value for its next pointer. -template <typename E> // E is the element type. -class ListNode { - friend class List<E>; - - private: - - E element_; - ListNode * next_; - - // The c'tor is private s.t. only in the ListNode class and in its - // friend class List we can create a ListNode object. - // - // Creates a node with a given element value. The next pointer is - // set to NULL. - // - // ListNode does NOT have a default constructor. Always use this - // constructor (with parameter) to create a ListNode object. - explicit ListNode(const E & element) : element_(element), next_(NULL) {} - - // We disallow copying ListNode - GTEST_DISALLOW_COPY_AND_ASSIGN_(ListNode); - - public: - - // Gets the element in this node. - E & element() { return element_; } - const E & element() const { return element_; } - - // Gets the next node in the list. - ListNode * next() { return next_; } - const ListNode * next() const { return next_; } -}; - - -// List is a simple singly-linked list container. -template <typename E> // E is the element type. -class List { - public: - - // Creates an empty list. - List() : head_(NULL), last_(NULL), size_(0) {} - - // D'tor. - virtual ~List(); - - // Clears the list. - void Clear() { - if ( size_ > 0 ) { - // 1. Deletes every node. - ListNode<E> * node = head_; - ListNode<E> * next = node->next(); - for ( ; ; ) { - delete node; - node = next; - if ( node == NULL ) break; - next = node->next(); - } - - // 2. Resets the member variables. - head_ = last_ = NULL; - size_ = 0; - } - } - - // Gets the number of elements. - int size() const { return size_; } - - // Returns true if the list is empty. - bool IsEmpty() const { return size() == 0; } - - // Gets the first element of the list, or NULL if the list is empty. - ListNode<E> * Head() { return head_; } - const ListNode<E> * Head() const { return head_; } - - // Gets the last element of the list, or NULL if the list is empty. - ListNode<E> * Last() { return last_; } - const ListNode<E> * Last() const { return last_; } - - // Adds an element to the end of the list. A copy of the element is - // created using the copy constructor, and then stored in the list. - // Changes made to the element in the list doesn't affect the source - // object, and vice versa. - void PushBack(const E & element) { - ListNode<E> * new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - last_->next_ = new_node; - last_ = new_node; - size_++; - } - } - - // Adds an element to the beginning of this list. - void PushFront(const E& element) { - ListNode<E>* const new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - new_node->next_ = head_; - head_ = new_node; - size_++; - } - } - - // Removes an element from the beginning of this list. If the - // result argument is not NULL, the removed element is stored in the - // memory it points to. Otherwise the element is thrown away. - // Returns true iff the list wasn't empty before the operation. - bool PopFront(E* result) { - if (size_ == 0) return false; - - if (result != NULL) { - *result = head_->element_; - } - - ListNode<E>* const old_head = head_; - size_--; - if (size_ == 0) { - head_ = last_ = NULL; - } else { - head_ = head_->next_; - } - delete old_head; - - return true; - } - - // Inserts an element after a given node in the list. It's the - // caller's responsibility to ensure that the given node is in the - // list. If the given node is NULL, inserts the element at the - // front of the list. - ListNode<E>* InsertAfter(ListNode<E>* node, const E& element) { - if (node == NULL) { - PushFront(element); - return Head(); - } - - ListNode<E>* const new_node = new ListNode<E>(element); - new_node->next_ = node->next_; - node->next_ = new_node; - size_++; - if (node == last_) { - last_ = new_node; - } - - return new_node; - } - - // Returns the number of elements that satisfy a given predicate. - // The parameter 'predicate' is a Boolean function or functor that - // accepts a 'const E &', where E is the element type. - template <typename P> // P is the type of the predicate function/functor - int CountIf(P predicate) const { - int count = 0; - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { - count++; - } - } - - return count; - } - - // Applies a function/functor to each element in the list. The - // parameter 'functor' is a function/functor that accepts a 'const - // E &', where E is the element type. This method does not change - // the elements. - template <typename F> // F is the type of the function/functor - void ForEach(F functor) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - functor(node->element()); - } - } - - // Returns the first node whose element satisfies a given predicate, - // or NULL if none is found. The parameter 'predicate' is a - // function/functor that accepts a 'const E &', where E is the - // element type. This method does not change the elements. - template <typename P> // P is the type of the predicate function/functor. - const ListNode<E> * FindIf(P predicate) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { - return node; - } - } +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template <class Container, typename Predicate> +inline int CountIf(const Container& c, Predicate predicate) { + return static_cast<int>(std::count_if(c.begin(), c.end(), predicate)); +} - return NULL; - } +// Applies a function/functor to each element in the container. +template <class Container, typename Functor> +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} - template <typename P> - ListNode<E> * FindIf(P predicate) { - for ( ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element() ) ) { - return node; - } - } +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template <typename E> +inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { + return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i]; +} - return NULL; +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template <typename E> +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector<E>* v) { + const int size = static_cast<int>(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); } +} - private: - ListNode<E>* head_; // The first node of the list. - ListNode<E>* last_; // The last node of the list. - int size_; // The number of elements in the list. - - // We disallow copying List. - GTEST_DISALLOW_COPY_AND_ASSIGN_(List); -}; - -// The virtual destructor of List. +// Performs an in-place shuffle of the vector's elements. template <typename E> -List<E>::~List() { - Clear(); +inline void Shuffle(internal::Random* random, std::vector<E>* v) { + ShuffleRange(random, 0, static_cast<int>(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template <typename T> -static void Delete(T * x) { +static void Delete(T* x) { delete x; } -// A copyable object representing a user specified test property which can be -// output as a key/value string pair. -// -// Don't inherit from TestProperty as its destructor is not virtual. -class TestProperty { - public: - // C'tor. TestProperty does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestProperty object. - TestProperty(const char* key, const char* value) : - key_(key), value_(value) { - } - - // Gets the user supplied key. - const char* key() const { - return key_.c_str(); - } - - // Gets the user supplied value. - const char* value() const { - return value_.c_str(); - } - - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const char* new_value) { - value_ = new_value; - } - - private: - // The key supplied by the user. - String key_; - // The value supplied by the user. - String value_; -}; - // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. @@ -473,96 +340,6 @@ class TestPropertyKeyIs { String key_; }; -// The result of a single Test. This includes a list of -// TestPartResults, a list of TestProperties, a count of how many -// death tests there are in the Test, and how much time it took to run -// the Test. -// -// TestResult is not copyable. -class TestResult { - public: - // Creates an empty TestResult. - TestResult(); - - // D'tor. Do not inherit from TestResult. - ~TestResult(); - - // Gets the list of TestPartResults. - const internal::List<TestPartResult> & test_part_results() const { - return test_part_results_; - } - - // Gets the list of TestProperties. - const internal::List<internal::TestProperty> & test_properties() const { - return test_properties_; - } - - // Gets the number of successful test parts. - int successful_part_count() const; - - // Gets the number of failed test parts. - int failed_part_count() const; - - // Gets the number of all test parts. This is the sum of the number - // of successful test parts and the number of failed test parts. - int total_part_count() const; - - // Returns true iff the test passed (i.e. no test part failed). - bool Passed() const { return !Failed(); } - - // Returns true iff the test failed. - bool Failed() const { return failed_part_count() > 0; } - - // Returns true iff the test fatally failed. - bool HasFatalFailure() const; - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); - - // Adds a test property to the list. The property is validated and may add - // a non-fatal failure if invalid (e.g., if it conflicts with reserved - // key names). If a property is already recorded for the same key, the - // value will be updated, rather than storing multiple values for the same - // key. - void RecordProperty(const internal::TestProperty& test_property); - - // Adds a failure if the key is a reserved attribute of Google Test - // testcase tags. Returns true if the property is valid. - // TODO(russr): Validate attribute names are legal and human readable. - static bool ValidateTestProperty(const internal::TestProperty& test_property); - - // Returns the death test count. - int death_test_count() const { return death_test_count_; } - - // Increments the death test count, returning the new count. - int increment_death_test_count() { return ++death_test_count_; } - - // Clears the object. - void Clear(); - private: - // Protects mutable state of the property list and of owned properties, whose - // values may be updated. - internal::Mutex test_properites_mutex_; - - // The list of TestPartResults - internal::List<TestPartResult> test_part_results_; - // The list of TestProperties - internal::List<internal::TestProperty> test_properties_; - // Running count of death tests. - int death_test_count_; - // The elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - - // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); -}; // class TestResult - class TestInfoImpl { public: TestInfoImpl(TestInfo* parent, const char* test_case_name, @@ -583,6 +360,12 @@ class TestInfoImpl { // Sets the is_disabled member. void set_is_disabled(bool is) { is_disabled_ = is; } + // Returns true if this test matches the filter specified by the user. + bool matches_filter() const { return matches_filter_; } + + // Sets the matches_filter member. + void set_matches_filter(bool matches) { matches_filter_ = matches; } + // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } @@ -599,18 +382,13 @@ class TestInfoImpl { TypeId fixture_class_id() const { return fixture_class_id_; } // Returns the test result. - internal::TestResult* result() { return &result_; } - const internal::TestResult* result() const { return &result_; } + TestResult* result() { return &result_; } + const TestResult* result() const { return &result_; } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); - // Calls the given TestInfo object's Run() method. - static void RunTest(TestInfo * test_info) { - test_info->impl()->Run(); - } - // Clears the test result. void ClearResult() { result_.Clear(); } @@ -629,150 +407,18 @@ class TestInfoImpl { const TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. - internal::TestResult result_; + TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); }; -} // namespace internal - -// A test case, which consists of a list of TestInfos. -// -// TestCase is not copyable. -class TestCase { - public: - // Creates a TestCase with the given name. - // - // TestCase does NOT have a default constructor. Always use this - // constructor to create a TestCase object. - // - // Arguments: - // - // name: name of the test case - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase(const char* name, const char* comment, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); - - // Destructor of TestCase. - virtual ~TestCase(); - - // Gets the name of the TestCase. - const char* name() const { return name_.c_str(); } - - // Returns the test case comment. - const char* comment() const { return comment_.c_str(); } - - // Returns true if any test in this test case should run. - bool should_run() const { return should_run_; } - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Gets the (mutable) list of TestInfos in this TestCase. - internal::List<TestInfo*>& test_info_list() { return *test_info_list_; } - - // Gets the (immutable) list of TestInfos in this TestCase. - const internal::List<TestInfo *> & test_info_list() const { - return *test_info_list_; - } - - // Gets the number of successful tests in this test case. - int successful_test_count() const; - - // Gets the number of failed tests in this test case. - int failed_test_count() const; - - // Gets the number of disabled tests in this test case. - int disabled_test_count() const; - - // Get the number of tests in this test case that should run. - int test_to_run_count() const; - - // Gets the number of all tests in this test case. - int total_test_count() const; - - // Returns true iff the test case passed. - bool Passed() const { return !Failed(); } - - // Returns true iff the test case failed. - bool Failed() const { return failed_test_count() > 0; } - - // Returns the elapsed time, in milliseconds. - internal::TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Adds a TestInfo to this test case. Will delete the TestInfo upon - // destruction of the TestCase object. - void AddTestInfo(TestInfo * test_info); - - // Finds and returns a TestInfo with the given name. If one doesn't - // exist, returns NULL. - TestInfo* GetTestInfo(const char* test_name); - - // Clears the results of all tests in this test case. - void ClearResult(); - - // Clears the results of all tests in the given test case. - static void ClearTestCaseResult(TestCase* test_case) { - test_case->ClearResult(); - } - - // Runs every test in this TestCase. - void Run(); - - // Runs every test in the given TestCase. - static void RunTestCase(TestCase * test_case) { test_case->Run(); } - - // Returns true iff test passed. - static bool TestPassed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Passed(); - } - - // Returns true iff test failed. - static bool TestFailed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Failed(); - } - - // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo * test_info) { - return test_info->impl()->is_disabled(); - } - - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo *test_info) { - return test_info->impl()->should_run(); - } - - private: - // Name of the test case. - internal::String name_; - // Comment on the test case. - internal::String comment_; - // List of TestInfos. - internal::List<TestInfo*>* test_info_list_; - // Pointer to the function that sets up the test case. - Test::SetUpTestCaseFunc set_up_tc_; - // Pointer to the function that tears down the test case. - Test::TearDownTestCaseFunc tear_down_tc_; - // True iff any test in this test case should run. - bool should_run_; - // Elapsed time, in milliseconds. - internal::TimeInMillis elapsed_time_; - - // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); -}; - -namespace internal { - // Class UnitTestOptions. // // This class contains functions for processing options the user @@ -783,16 +429,17 @@ namespace internal { // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. -class UnitTestOptions { +class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. static String GetOutputFormat(); - // Returns the name of the requested output file, or the default if none - // was explicitly specified. - static String GetOutputFile(); + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. @@ -808,7 +455,7 @@ class UnitTestOptions { static bool FilterMatchesTest(const String &test_case_name, const String &test_name); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the @@ -824,7 +471,7 @@ class UnitTestOptions { // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. -FilePath GetCurrentExecutableName(); +GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { @@ -852,7 +499,7 @@ class OsStackTraceGetterInterface { // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: - OsStackTraceGetter() {} + OsStackTraceGetter() : caller_frame_(NULL) {} virtual String CurrentStackTrace(int max_depth, int skip_count); virtual void UponLeavingGTest(); @@ -891,6 +538,8 @@ class DefaultGlobalTestPartResultReporter private: UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in @@ -905,13 +554,15 @@ class DefaultPerThreadTestPartResultReporter private: UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // 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 { +class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); @@ -977,26 +628,29 @@ class UnitTestImpl { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - internal::TestResult* current_test_result(); + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } - // Returns the TestResult for the ad hoc test. - const internal::TestResult* ad_hoc_test_result() const { - return &ad_hoc_test_result_; + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; } - // Sets the unit test result printer. - // - // Does nothing if the input and the current printer object are the - // same; otherwise, deletes the old printer object and makes the - // input the current printer. - void set_result_printer(UnitTestEventListenerInterface * result_printer); + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); - // Returns the current unit test result printer if it is not NULL; - // otherwise, creates an appropriate result printer, makes it the - // current printer, and returns it. - UnitTestEventListenerInterface* result_printer(); + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // @@ -1054,10 +708,8 @@ class UnitTestImpl { // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); - if (original_working_dir_.IsEmpty()) { - printf("%s\n", "Failed to get the current working directory."); - abort(); - } + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), @@ -1066,7 +718,7 @@ class UnitTestImpl { tear_down_tc)->AddTestInfo(test_info); } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { @@ -1075,15 +727,15 @@ class UnitTestImpl { #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* current_test_case) { - current_test_case_ = current_test_case; + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. - void set_current_test_info(TestInfo* current_test_info) { - current_test_info_ = current_test_info; + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and @@ -1104,45 +756,50 @@ class UnitTestImpl { // Clears the results of all tests, including the ad hoc test. void ClearResult() { - test_cases_.ForEach(TestCase::ClearTestCaseResult); + ForEach(test_cases_, TestCase::ClearTestCaseResult); ad_hoc_test_result_.Clear(); } + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. // Returns the number of tests that should run. - int FilterTests(); + int FilterTests(ReactionToSharding shard_tests); - // Lists all the tests by name. - void ListAllTests(); + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } - // Returns the list of environments that need to be set-up/torn-down + // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. - internal::List<Environment*>* environments() { return &environments_; } - internal::List<Environment*>* environments_in_reverse_order() { - return &environments_in_reverse_order_; - } - - internal::List<TestCase*>* test_cases() { return &test_cases_; } - const internal::List<TestCase*>* test_cases() const { return &test_cases_; } + std::vector<Environment*>& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. - internal::List<TraceInfo>* gtest_trace_stack() { - return gtest_trace_stack_.pointer(); + std::vector<TraceInfo>& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); } - const internal::List<TraceInfo>* gtest_trace_stack() const { - return gtest_trace_stack_.pointer(); + const std::vector<TraceInfo>& gtest_trace_stack() const { + return gtest_trace_stack_.get(); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } @@ -1152,9 +809,35 @@ class UnitTestImpl { return death_test_factory_.get(); } + void SuppressTestEventsIfInSubprocess(); + friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + private: friend class ::testing::UnitTest; @@ -1180,15 +863,21 @@ class UnitTestImpl { 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_ - // simply mirrors environments_ in reverse order. - internal::List<Environment*> environments_; - internal::List<Environment*> environments_in_reverse_order_; + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector<Environment*> environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector<TestCase*> test_cases_; - internal::List<TestCase*> test_cases_; // The list of TestCases. + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector<int> test_case_indices_; -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; @@ -1197,13 +886,13 @@ class UnitTestImpl { bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST - // Points to the last death test case registered. Initially NULL. - internal::ListNode<TestCase*>* last_death_test_case_; + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initally NULL. + // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It @@ -1220,13 +909,11 @@ class UnitTestImpl { // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. - internal::TestResult ad_hoc_test_result_; + TestResult ad_hoc_test_result_; - // The unit test result printer. Will be deleted when the UnitTest - // object is destructed. By default, a plain text printer is used, - // but the user can set this field to use a custom printer if that - // is desired. - UnitTestEventListenerInterface* result_printer_; + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, @@ -1234,10 +921,19 @@ class UnitTestImpl { // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; @@ -1245,7 +941,7 @@ class UnitTestImpl { #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal<internal::List<TraceInfo> > gtest_trace_stack_; + internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl @@ -1256,10 +952,121 @@ inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsDigit(char ch); +GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsWhiteSpace(char ch); +GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + // Parses the command line for Google Test flags, without initializing // other parts of Google Test. -void ParseGoogleTestFlagsOnly(int* argc, char** argv); -void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastErrnoDescription(); + +#if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +#endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template <typename Integer> +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !isdigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); +#else + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast<Integer>(parsed); + if (parse_success && static_cast<BiggestConvertible>(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector<testing::TestPartResult>& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; } // namespace internal } // namespace testing diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h index 242ffea..0b90132 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h @@ -39,7 +39,7 @@ #include <gtest/internal/gtest-port.h> -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> @@ -121,32 +121,26 @@ namespace testing { // Forward declaration of classes. +class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. class Test; // Represents a test. -class TestCase; // A collection of related tests. -class TestPartResult; // Result of a test part. class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. -class UnitTestEventListenerInterface; // Listens to Google Test events. -class AssertionResult; // Result of an assertion. namespace internal { struct TraceInfo; // Information about a trace point. class ScopedTrace; // Implements scoped trace. class TestInfoImpl; // Opaque implementation of TestInfo -class TestResult; // Result of a single Test. class UnitTestImpl; // Opaque implementation of UnitTest -template <typename E> class List; // A generic list. -template <typename E> class ListNode; // A node in a generic list. - // How many times InitGoogleTest() has been called. extern int g_init_gtest_count; // The text used in failure messages to indicate the start of the // stack trace. -extern const char kStackTraceMarker[]; +GTEST_API_ extern const char kStackTraceMarker[]; // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a @@ -173,24 +167,21 @@ char (&IsNullLiteralHelper(...))[2]; // NOLINT // A compile-time bool constant that is true if and only if x is a // null pointer literal (i.e. NULL or any 0-valued compile-time // integral constant). -#ifdef GTEST_ELLIPSIS_NEEDS_COPY_ -// Passing non-POD classes through ellipsis (...) crashes the ARM -// compiler. The Nokia Symbian and the IBM XL C/C++ compiler try to -// instantiate a copy constructor for objects passed through ellipsis -// (...), failing for uncopyable objects. Hence we define this to -// false (and lose support for NULL detection). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). #define GTEST_IS_NULL_LITERAL_(x) false #else #define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) -#endif // GTEST_ELLIPSIS_NEEDS_COPY_ +#endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. -String AppendUserMessage(const String& gtest_msg, - const Message& user_msg); +GTEST_API_ String AppendUserMessage(const String& gtest_msg, + const Message& user_msg); // A helper class for creating scoped traces in user programs. -class ScopedTrace { +class GTEST_API_ ScopedTrace { public: // The c'tor pushes the given source file location and message onto // a trace stack maintained by Google Test. @@ -231,13 +222,13 @@ String StreamableToString(const T& streamable); // This overload makes sure that all pointers (including // those to char or wchar_t) are printed as raw pointers. template <typename T> -inline String FormatValueForFailureMessage(internal::true_type dummy, +inline String FormatValueForFailureMessage(internal::true_type /*dummy*/, T* pointer) { return StreamableToString(static_cast<const void*>(pointer)); } template <typename T> -inline String FormatValueForFailureMessage(internal::false_type dummy, +inline String FormatValueForFailureMessage(internal::false_type /*dummy*/, const T& value) { return StreamableToString(value); } @@ -269,8 +260,8 @@ inline String FormatForFailureMessage(T* pointer) { #endif // GTEST_NEEDS_IS_POINTER_ // These overloaded versions handle narrow and wide characters. -String FormatForFailureMessage(char ch); -String FormatForFailureMessage(wchar_t wchar); +GTEST_API_ String FormatForFailureMessage(char ch); +GTEST_API_ String FormatForFailureMessage(wchar_t wchar); // When this operand is a const char* or char*, and the other operand // is a ::std::string or ::string, we print this operand as a C string @@ -287,9 +278,7 @@ inline String FormatForComparisonFailureMessage(\ return operand1_printer(str);\ } -#if GTEST_HAS_STD_STRING GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_STD_WSTRING GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) #endif // GTEST_HAS_STD_WSTRING @@ -318,12 +307,18 @@ GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. -AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const String& expected_value, - const String& actual_value, - bool ignoring_case); - +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ String GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the @@ -403,7 +398,7 @@ class FloatingPoint { // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) : value_(x) {} + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods @@ -412,8 +407,8 @@ class FloatingPoint { // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); - fp.bits_ = bits; - return fp.value_; + fp.u_.bits_ = bits; + return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. @@ -424,16 +419,16 @@ class FloatingPoint { // Non-static methods // Returns the bits that represents this number. - const Bits &bits() const { return bits_; } + const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & bits_; } + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & bits_; } + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & bits_; } + Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { @@ -453,10 +448,17 @@ class FloatingPoint { // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; - return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps; + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; } private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the @@ -491,10 +493,7 @@ class FloatingPoint { return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } - union { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; + FloatingPointUnion u_; }; // Typedefs the instances of the FloatingPoint template class that we @@ -539,7 +538,7 @@ TypeId GetTypeId() { // ::testing::Test, as the latter may give the wrong result due to a // suspected linker bug when compiling Google Test as a Mac OS X // framework. -TypeId GetTestTypeId(); +GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. @@ -566,14 +565,16 @@ class TestFactoryImpl : public TestFactoryBase { virtual Test* CreateTest() { return new TestClass; } }; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. -AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT -AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT #endif // GTEST_OS_WINDOWS @@ -612,7 +613,7 @@ typedef void (*TearDownTestCaseFunc)(); // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. -TestInfo* MakeAndRegisterTestInfo( +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* test_case_comment, const char* comment, TypeId fixture_class_id, @@ -620,10 +621,15 @@ TestInfo* MakeAndRegisterTestInfo( TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); -#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. -class TypedTestCasePState { +class GTEST_API_ TypedTestCasePState { public: TypedTestCasePState() : registered_(false) {} @@ -636,7 +642,8 @@ class TypedTestCasePState { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); - abort(); + fflush(stderr); + posix::Abort(); } defined_test_names_.insert(test_name); return true; @@ -745,8 +752,8 @@ class TypeParameterizedTestCase { template <GTEST_TEMPLATE_ Fixture, typename Types> class TypeParameterizedTestCase<Fixture, Templates0, Types> { public: - static bool Register(const char* prefix, const char* case_name, - const char* test_names) { + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { return true; } }; @@ -763,10 +770,39 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count); +GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} -// Returns the number of failed test parts in the given test result object. -int GetFailedPartCount(const TestResult* result); + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; } // namespace internal } // namespace testing @@ -776,20 +812,26 @@ int GetFailedPartCount(const TestResult* result); = ::testing::Message() #define GTEST_FATAL_FAILURE_(message) \ - return GTEST_MESSAGE_(message, ::testing::TPRT_FATAL_FAILURE) + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ - GTEST_MESSAGE_(message, ::testing::TPRT_NONFATAL_FAILURE) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ - GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ - statement; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ @@ -813,7 +855,7 @@ int GetFailedPartCount(const TestResult* result); GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ try { \ - statement; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ @@ -829,7 +871,7 @@ int GetFailedPartCount(const TestResult* result); if (const char* gtest_msg = "") { \ bool gtest_caught_any = false; \ try { \ - statement; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ @@ -844,18 +886,23 @@ int GetFailedPartCount(const TestResult* result); fail(gtest_msg) -#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \ +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (boolexpr) \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ ; \ else \ - fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected) + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - { statement; } \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h b/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h index d4c7a39..2404ea8 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h @@ -77,7 +77,7 @@ namespace testing { namespace internal { // Protects copying of all linked_ptr objects. -extern Mutex g_linked_ptr_mutex; +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // This is used internally by all instances of linked_ptr<>. It needs to be // a non-template class because different types of linked_ptr<> can refer to diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h index 17f3f7b..ab4ab56 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h @@ -44,13 +44,30 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include <gtest/internal/gtest-param-util.h> #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST - -#include <gtest/internal/gtest-param-util.h> +#if GTEST_HAS_PARAM_TEST namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn( + ForwardIterator begin, ForwardIterator end); + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]); + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container); + namespace internal { // Used in the Values() function to provide polymorphic capabilities. @@ -63,6 +80,9 @@ class ValueArray1 { operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + const T1 v1_; }; @@ -78,6 +98,9 @@ class ValueArray2 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + const T1 v1_; const T2 v2_; }; @@ -94,6 +117,9 @@ class ValueArray3 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -112,6 +138,9 @@ class ValueArray4 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -131,6 +160,9 @@ class ValueArray5 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -152,6 +184,9 @@ class ValueArray6 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -174,6 +209,9 @@ class ValueArray7 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -198,6 +236,9 @@ class ValueArray8 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -223,6 +264,9 @@ class ValueArray9 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -249,6 +293,9 @@ class ValueArray10 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -277,6 +324,9 @@ class ValueArray11 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -307,6 +357,9 @@ class ValueArray12 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -339,6 +392,9 @@ class ValueArray13 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -372,6 +428,9 @@ class ValueArray14 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -406,6 +465,9 @@ class ValueArray15 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -443,6 +505,9 @@ class ValueArray16 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -481,6 +546,9 @@ class ValueArray17 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -520,6 +588,9 @@ class ValueArray18 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -560,6 +631,9 @@ class ValueArray19 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -602,6 +676,9 @@ class ValueArray20 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -646,6 +723,9 @@ class ValueArray21 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -691,6 +771,9 @@ class ValueArray22 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -739,6 +822,9 @@ class ValueArray23 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -788,6 +874,9 @@ class ValueArray24 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -838,6 +927,9 @@ class ValueArray25 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -890,6 +982,9 @@ class ValueArray26 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -944,6 +1039,9 @@ class ValueArray27 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -999,6 +1097,9 @@ class ValueArray28 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1055,6 +1156,9 @@ class ValueArray29 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1113,6 +1217,9 @@ class ValueArray30 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1173,6 +1280,9 @@ class ValueArray31 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1234,6 +1344,9 @@ class ValueArray32 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1297,6 +1410,9 @@ class ValueArray33 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1361,6 +1477,9 @@ class ValueArray34 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1427,6 +1546,9 @@ class ValueArray35 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1495,6 +1617,9 @@ class ValueArray36 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1565,6 +1690,9 @@ class ValueArray37 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1636,6 +1764,9 @@ class ValueArray38 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1708,6 +1839,9 @@ class ValueArray39 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1782,6 +1916,9 @@ class ValueArray40 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1858,6 +1995,9 @@ class ValueArray41 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1935,6 +2075,9 @@ class ValueArray42 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2013,6 +2156,9 @@ class ValueArray43 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2093,6 +2239,9 @@ class ValueArray44 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2174,6 +2323,9 @@ class ValueArray45 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2257,6 +2409,9 @@ class ValueArray46 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2343,6 +2498,9 @@ class ValueArray47 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2430,6 +2588,9 @@ class ValueArray48 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2518,6 +2679,9 @@ class ValueArray49 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2607,6 +2771,9 @@ class ValueArray50 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2659,7 +2826,7 @@ class ValueArray50 { const T50 v50_; }; -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced @@ -2757,6 +2924,9 @@ class CartesianProductGenerator2 current2_ == end2_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -2767,11 +2937,14 @@ class CartesianProductGenerator2 const typename ParamGenerator<T2>::iterator end2_; typename ParamGenerator<T2>::iterator current2_; ParamType current_value_; - }; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; -}; +}; // class CartesianProductGenerator2 template <typename T1, typename T2, typename T3> @@ -2879,6 +3052,9 @@ class CartesianProductGenerator3 current3_ == end3_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -2892,12 +3068,15 @@ class CartesianProductGenerator3 const typename ParamGenerator<T3>::iterator end3_; typename ParamGenerator<T3>::iterator current3_; ParamType current_value_; - }; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; -}; +}; // class CartesianProductGenerator3 template <typename T1, typename T2, typename T3, typename T4> @@ -3020,6 +3199,9 @@ class CartesianProductGenerator4 current4_ == end4_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3036,13 +3218,16 @@ class CartesianProductGenerator4 const typename ParamGenerator<T4>::iterator end4_; typename ParamGenerator<T4>::iterator current4_; ParamType current_value_; - }; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; const ParamGenerator<T4> g4_; -}; +}; // class CartesianProductGenerator4 template <typename T1, typename T2, typename T3, typename T4, typename T5> @@ -3177,6 +3362,9 @@ class CartesianProductGenerator5 current5_ == end5_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3196,14 +3384,17 @@ class CartesianProductGenerator5 const typename ParamGenerator<T5>::iterator end5_; typename ParamGenerator<T5>::iterator current5_; ParamType current_value_; - }; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; const ParamGenerator<T4> g4_; const ParamGenerator<T5> g5_; -}; +}; // class CartesianProductGenerator5 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3353,6 +3544,9 @@ class CartesianProductGenerator6 current6_ == end6_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3375,7 +3569,10 @@ class CartesianProductGenerator6 const typename ParamGenerator<T6>::iterator end6_; typename ParamGenerator<T6>::iterator current6_; ParamType current_value_; - }; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3383,7 +3580,7 @@ class CartesianProductGenerator6 const ParamGenerator<T4> g4_; const ParamGenerator<T5> g5_; const ParamGenerator<T6> g6_; -}; +}; // class CartesianProductGenerator6 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3546,6 +3743,9 @@ class CartesianProductGenerator7 current7_ == end7_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3571,7 +3771,10 @@ class CartesianProductGenerator7 const typename ParamGenerator<T7>::iterator end7_; typename ParamGenerator<T7>::iterator current7_; ParamType current_value_; - }; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3580,7 +3783,7 @@ class CartesianProductGenerator7 const ParamGenerator<T5> g5_; const ParamGenerator<T6> g6_; const ParamGenerator<T7> g7_; -}; +}; // class CartesianProductGenerator7 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3758,6 +3961,9 @@ class CartesianProductGenerator8 current8_ == end8_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3786,7 +3992,10 @@ class CartesianProductGenerator8 const typename ParamGenerator<T8>::iterator end8_; typename ParamGenerator<T8>::iterator current8_; ParamType current_value_; - }; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3796,7 +4005,7 @@ class CartesianProductGenerator8 const ParamGenerator<T6> g6_; const ParamGenerator<T7> g7_; const ParamGenerator<T8> g8_; -}; +}; // class CartesianProductGenerator8 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3987,6 +4196,9 @@ class CartesianProductGenerator9 current9_ == end9_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -4018,7 +4230,10 @@ class CartesianProductGenerator9 const typename ParamGenerator<T9>::iterator end9_; typename ParamGenerator<T9>::iterator current9_; ParamType current_value_; - }; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -4029,7 +4244,7 @@ class CartesianProductGenerator9 const ParamGenerator<T7> g7_; const ParamGenerator<T8> g8_; const ParamGenerator<T9> g9_; -}; +}; // class CartesianProductGenerator9 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -4233,6 +4448,9 @@ class CartesianProductGenerator10 current10_ == end10_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -4267,7 +4485,10 @@ class CartesianProductGenerator10 const typename ParamGenerator<T10>::iterator end10_; typename ParamGenerator<T10>::iterator current10_; ParamType current_value_; - }; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -4279,7 +4500,7 @@ class CartesianProductGenerator10 const ParamGenerator<T8> g8_; const ParamGenerator<T9> g9_; const ParamGenerator<T10> g10_; -}; +}; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -4302,9 +4523,12 @@ CartesianProductHolder2(const Generator1& g1, const Generator2& g2) } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + const Generator1 g1_; const Generator2 g2_; -}; +}; // class CartesianProductHolder2 template <class Generator1, class Generator2, class Generator3> class CartesianProductHolder3 { @@ -4322,10 +4546,13 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; -}; +}; // class CartesianProductHolder3 template <class Generator1, class Generator2, class Generator3, class Generator4> @@ -4345,11 +4572,14 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; -}; +}; // class CartesianProductHolder4 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5> @@ -4370,12 +4600,15 @@ CartesianProductHolder5(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; -}; +}; // class CartesianProductHolder5 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6> @@ -4399,13 +4632,16 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; -}; +}; // class CartesianProductHolder6 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7> @@ -4431,6 +4667,9 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4438,7 +4677,7 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; -}; +}; // class CartesianProductHolder7 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4467,6 +4706,9 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4475,7 +4717,7 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; -}; +}; // class CartesianProductHolder8 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4507,6 +4749,9 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4516,7 +4761,7 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; -}; +}; // class CartesianProductHolder9 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4550,6 +4795,9 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4560,7 +4808,7 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; -}; +}; // class CartesianProductHolder10 #endif // GTEST_HAS_COMBINE diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h index 3bb07ec..0cbb58c 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h @@ -38,16 +38,14 @@ #include <utility> #include <vector> +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include <gtest/internal/gtest-internal.h> +#include <gtest/internal/gtest-linked_ptr.h> #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST - -#if GTEST_HAS_RTTI -#include <typeinfo> -#endif // GTEST_HAS_RTTI - -#include <gtest/internal/gtest-linked_ptr.h> -#include <gtest/internal/gtest-internal.h> +#if GTEST_HAS_PARAM_TEST namespace testing { namespace internal { @@ -58,26 +56,8 @@ namespace internal { // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name // but in different namespaces. -void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Downcasts the pointer of type Base to Derived. -// Derived must be a subclass of Base. The parameter MUST -// point to a class of type Derived, not any subclass of it. -// When RTTI is available, the function performs a runtime -// check to enforce this. -template <class Derived, class Base> -Derived* CheckedDowncastToActualType(Base* base) { -#if GTEST_HAS_RTTI - GTEST_CHECK_(typeid(*base) == typeid(Derived)); - Derived* derived = dynamic_cast<Derived*>(base); // NOLINT -#else - Derived* derived = static_cast<Derived*>(base); // Poor man's downcast. -#endif // GTEST_HAS_RTTI - return derived; -} +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); template <typename> class ParamGeneratorInterface; template <typename> class ParamGenerator; @@ -169,7 +149,7 @@ class ParamGeneratorInterface { virtual ParamIteratorInterface<T>* End() const = 0; }; -// Wraps ParamGeneratorInetrface<T> and provides general generator syntax +// Wraps ParamGeneratorInterface<T> and provides general generator syntax // compatible with the STL Container concept. // This class implements copy initialization semantics and the contained // ParamGeneratorInterface<T> instance is shared among all copies @@ -245,9 +225,13 @@ class RangeGenerator : public ParamGeneratorInterface<T> { private: Iterator(const Iterator& other) - : base_(other.base_), value_(other.value_), index_(other.index_), + : ParamIteratorInterface<T>(), + base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<T>* const base_; T value_; int index_; @@ -263,6 +247,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> { return end_index; } + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + const T begin_; const T end_; const IncrementT step_; @@ -349,7 +336,10 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr<const T> value_; - }; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator @@ -483,8 +473,8 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // about a generator. int AddTestCaseInstantiation(const char* instantiation_name, GeneratorCreationFunc* func, - const char* file, - int line) { + const char* /* file */, + int /* line */) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } @@ -533,12 +523,12 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { - TestInfo(const char* test_case_base_name, - const char* test_base_name, - TestMetaFactoryBase<ParamType>* test_meta_factory) : - test_case_base_name(test_case_base_name), - test_base_name(test_base_name), - test_meta_factory(test_meta_factory) {} + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase<ParamType>* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} const String test_case_base_name; const String test_base_name; diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/utils/unittest/googletest/include/gtest/internal/gtest-port.h index 20a95c9..9683271 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-port.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-port.h @@ -42,6 +42,8 @@ // // GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) // is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::string, which is different to std::string). @@ -52,32 +54,42 @@ // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. -// GTEST_HAS_STD_STRING - Define it to 1/0 to indicate that -// std::string does/doesn't work (Google Test can -// be used where std::string is unavailable). // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). -// GTEST_HAS_TR1_TUPLE 1 - Define it to 1/0 to indicate tr1::tuple +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple // is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. // This header defines the following utilities: // -// Macros indicating the name of the Google C++ Testing Framework project: -// GTEST_NAME - a string literal of the project name. -// GTEST_FLAG_PREFIX - a string literal of the prefix all Google -// Test flag names share. -// GTEST_FLAG_PREFIX_UPPER - a string literal of the prefix all Google -// Test flag names share, in upper case. -// -// Macros indicating the current platform: -// GTEST_OS_CYGWIN - defined iff compiled on Cygwin. -// GTEST_OS_LINUX - defined iff compiled on Linux. -// GTEST_OS_MAC - defined iff compiled on Mac OS X. -// GTEST_OS_SOLARIS - defined iff compiled on Sun Solaris. -// GTEST_OS_SYMBIAN - defined iff compiled for Symbian. -// GTEST_OS_WINDOWS - defined iff compiled on Windows. -// GTEST_OS_ZOS - defined iff compiled on IBM z/OS. +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HAIKU - Haiku +// GTEST_OS_LINUX - Linux +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project @@ -86,22 +98,26 @@ // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // -// Note that it is possible that none of the GTEST_OS_ macros are defined. +// Note that it is possible that none of the GTEST_OS_* macros are defined. // -// Macros indicating available Google Test features: -// GTEST_HAS_COMBINE - defined iff Combine construct is supported -// in value-parameterized tests. -// GTEST_HAS_DEATH_TEST - defined iff death tests are supported. -// GTEST_HAS_PARAM_TEST - defined iff value-parameterized tests are -// supported. -// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported. -// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are -// supported. +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. -// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances don't have to -// be used. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // @@ -128,7 +144,10 @@ // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. // -// Stderr capturing: +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. // CaptureStderr() - starts capturing stderr. // GetCapturedStderr() - stops capturing stderr and returns the captured // string. @@ -151,13 +170,24 @@ // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. +#include <stddef.h> // For ptrdiff_t #include <stdlib.h> #include <stdio.h> -#include <iostream> // Used for GTEST_CHECK_ +#include <string.h> +#ifndef _WIN32_WCE +#include <sys/stat.h> +#endif // !_WIN32_WCE + +#include <iostream> // NOLINT +#include <sstream> // NOLINT +#include <string> // NOLINT -#define GTEST_NAME "Google Test" -#define GTEST_FLAG_PREFIX "gtest_" -#define GTEST_FLAG_PREFIX_UPPER "GTEST_" +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ @@ -168,50 +198,104 @@ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ -#define GTEST_OS_CYGWIN -#elif __SYMBIAN32__ -#define GTEST_OS_SYMBIAN -#elif defined _MSC_VER -// TODO(kenton@google.com): GTEST_OS_WINDOWS is currently used to mean -// both "The OS is Windows" and "The compiler is MSVC". These -// meanings really should be separated in order to better support -// Windows compilers other than MSVC. -#define GTEST_OS_WINDOWS +#define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +#define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE #elif defined __APPLE__ -#define GTEST_OS_MAC +#define GTEST_OS_MAC 1 #elif defined __linux__ -#define GTEST_OS_LINUX +#define GTEST_OS_LINUX 1 #elif defined __MVS__ -#define GTEST_OS_ZOS +#define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) -#define GTEST_OS_SOLARIS +#define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +#define GTEST_OS_AIX 1 #elif defined(__HAIKU__) -#define GTEST_OS_HAIKU -#endif // _MSC_VER +#define GTEST_OS_HAIKU 1 +#endif // __CYGWIN__ + +#if GTEST_OS_CYGWIN || GTEST_OS_HAIKU || GTEST_OS_LINUX || GTEST_OS_MAC || \ + GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX + +// On some platforms, <regex.h> needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included <stdlib.h>, which is guaranteed to define size_t through +// <stddef.h>. +#include <regex.h> // NOLINT +#include <strings.h> // NOLINT +#include <sys/types.h> // NOLINT +#include <time.h> // NOLINT +#include <unistd.h> // NOLINT -// Determines whether ::std::string and ::string are available. +#define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +#include <direct.h> // NOLINT +#include <io.h> // NOLINT +#endif -#ifndef GTEST_HAS_STD_STRING -// The user didn't tell us whether ::std::string is available, so we -// need to figure it out. +// <regex.h> is not available on Windows. Use our own simple regex +// implementation instead. +#define GTEST_USES_SIMPLE_RE 1 -#ifdef GTEST_OS_WINDOWS +#else + +// <regex.h> may not be available on this platform. Use our own +// simple regex implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || + // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. #ifndef _HAS_EXCEPTIONS #define _HAS_EXCEPTIONS 1 #endif // _HAS_EXCEPTIONS -// GTEST_HAS_EXCEPTIONS is non-zero iff exceptions are enabled. It is -// always defined, while _HAS_EXCEPTIONS is defined only on Windows. #define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -// On Windows, we can use ::std::string if the compiler version is VS -// 2005 or above, or if exceptions are enabled. -#define GTEST_HAS_STD_STRING ((_MSC_VER >= 1400) || GTEST_HAS_EXCEPTIONS) -#else // We are on Linux or Mac OS. +#elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#else +// For other compilers, we assume exceptions are disabled to be +// conservative. #define GTEST_HAS_EXCEPTIONS 0 -#define GTEST_HAS_STD_STRING 1 -#endif // GTEST_OS_WINDOWS +#endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS -#endif // GTEST_HAS_STD_STRING +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +#define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +#error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need @@ -227,35 +311,21 @@ // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. -#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) || defined(_MINIX) -// At least some versions of cygwin don't support ::std::wstring. +// Cygwin 1.5 and below doesn't support ::std::wstring. +// Cygwin 1.7 might add wstring support; this should be updated when clear. // Solaris' libc++ doesn't support it either. // Minix currently doesn't support it either. -#define GTEST_HAS_STD_WSTRING 0 -#else -#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_STRING -#endif // defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) +#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || defined(_MINIX))) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. -#define GTEST_HAS_GLOBAL_WSTRING GTEST_HAS_GLOBAL_STRING +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING -#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || \ - GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING -#include <string> // NOLINT -#endif // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || - // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING - -#if GTEST_HAS_STD_STRING -#include <sstream> // NOLINT -#else -#include <strstream> // NOLINT -#endif // GTEST_HAS_STD_STRING - // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to @@ -267,72 +337,128 @@ #define GTEST_HAS_RTTI 1 #else #define GTEST_HAS_RTTI 0 -#endif // _CPPRTTI - -#elif defined(__GNUC__) +#endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. -#if GTEST_GCC_VER_ >= 40302 +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + #ifdef __GXX_RTTI #define GTEST_HAS_RTTI 1 #else #define GTEST_HAS_RTTI 0 #endif // __GXX_RTTI -#else -// For gcc versions smaller than 4.3.2, we assume RTTI is enabled. + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +#ifdef __RTTI_ALL__ #define GTEST_HAS_RTTI 1 -#endif // GTEST_GCC_VER >= 40302 +#else +#define GTEST_HAS_RTTI 0 +#endif #else -// Unknown compiler - assume RTTI is enabled. +// For all other compilers, we assume RTTI is enabled. #define GTEST_HAS_RTTI 1 #endif // _MSC_VER #endif // GTEST_HAS_RTTI -// Determines whether <pthread.h> is available. -#ifndef GTEST_HAS_PTHREAD -// The user didn't tell us, so we need to figure it out. - -#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) -#define GTEST_HAS_PTHREAD 1 -#else -#define GTEST_HAS_PTHREAD 0 -#endif // GTEST_OS_LINUX || GTEST_OS_MAC +// It's this header's responsibility to #include <typeinfo> when RTTI +// is enabled. +#if GTEST_HAS_RTTI +#include <typeinfo> +#endif +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) #endif // GTEST_HAS_PTHREAD -// Determines whether tr1/tuple is available. If you have tr1/tuple -// on your platform, define GTEST_HAS_TR1_TUPLE=1 for both the Google -// Test project and your tests. If you would like Google Test to detect -// tr1/tuple on your platform automatically, please open an issue -// ticket at http://code.google.com/p/googletest. +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us not to do it, so we assume it's OK. +#define GTEST_HAS_TR1_TUPLE 1 +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE // The user didn't tell us, so we need to figure it out. -// GCC provides <tr1/tuple> since 4.0.0. -#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) -#define GTEST_HAS_TR1_TUPLE 1 +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, GCC 4.0.0+ and MSVC +// 2010 are the only mainstream compilers that come with a TR1 tuple +// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by +// defining __GNUC__ and friends, but cannot compile GCC's tuple +// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB +// Feature Pack download, which we cannot assume the user has. +#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ + || _MSC_VER >= 1600 +#define GTEST_USE_OWN_TR1_TUPLE 0 #else -#define GTEST_HAS_TR1_TUPLE 0 -#endif // __GNUC__ -#endif // GTEST_HAS_TR1_TUPLE +#define GTEST_USE_OWN_TR1_TUPLE 1 +#endif + +#endif // GTEST_USE_OWN_TR1_TUPLE // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing // tr1/tuple. #if GTEST_HAS_TR1_TUPLE -#if defined(__GNUC__) -// GCC implements tr1/tuple in the <tr1/tuple> header. This does not -// conform to the TR1 spec, which requires the header to be <tuple>. + +#if GTEST_USE_OWN_TR1_TUPLE +#include <gtest/internal/gtest-tuple.h> +#elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +#ifdef BOOST_HAS_TR1_TUPLE +#undef BOOST_HAS_TR1_TUPLE +#endif // BOOST_HAS_TR1_TUPLE + +// This prevents <boost/tr1/detail/config.hpp>, which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>. +#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +#include <tuple> + +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does +// not conform to the TR1 spec, which requires the header to be <tuple>. + +#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes <tr1/functional>, +// which is #included by <tr1/tuple>, to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// <tr1/functional>. Hence the following #define is a hack to prevent +// <tr1/functional> from being included. +#define _TR1_FUNCTIONAL 1 #include <tr1/tuple> +#undef _TR1_FUNCTIONAL // Allows the user to #include + // <tr1/functional> if he chooses to. #else -// If the compiler is not GCC, we assume the user is using a +#include <tr1/tuple> // NOLINT +#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +#else +// If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. -#include <tuple> -#endif // __GNUC__ +#include <tuple> // NOLINT +#endif // GTEST_USE_OWN_TR1_TUPLE + #endif // GTEST_HAS_TR1_TUPLE // Determines whether clone(2) is supported. @@ -342,55 +468,57 @@ #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. -#if defined(GTEST_OS_LINUX) && !defined(__ia64__) +#if GTEST_OS_LINUX && !defined(__ia64__) #define GTEST_HAS_CLONE 1 #else #define GTEST_HAS_CLONE 0 -#endif // defined(GTEST_OS_LINUX) && !defined(__ia64__) +#endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE -// Determines whether to support death tests. -#if GTEST_HAS_STD_STRING && GTEST_HAS_CLONE -#define GTEST_HAS_DEATH_TEST -// On some platforms, <regex.h> needs someone to define size_t, and -// won't compile otherwise. We can #include it here as we already -// included <stdlib.h>, which is guaranteed to define size_t through -// <stddef.h>. -#include <regex.h> -#include <vector> -#include <fcntl.h> -#include <sys/mman.h> -#endif // GTEST_HAS_STD_STRING && GTEST_HAS_CLONE +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#define GTEST_HAS_STREAM_REDIRECTION_ 1 +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN -// Determines whether to support value-parameterized tests. +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX) +#define GTEST_HAS_DEATH_TEST 1 +#include <vector> // NOLINT +#endif -#if defined(__GNUC__) || (_MSC_VER >= 1400) -// TODO(vladl@google.com): get the implementation rid of vector and list -// to compile on MSVC 7.1. -#define GTEST_HAS_PARAM_TEST -#endif // defined(__GNUC__) || (_MSC_VER >= 1400) +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 // Determines whether to support type-driven tests. -// Typed tests need <typeinfo> and variadic macros, which gcc and VC -// 8.0+ support. -#if defined(__GNUC__) || (_MSC_VER >= 1400) -#define GTEST_HAS_TYPED_TEST -#define GTEST_HAS_TYPED_TEST_P -#endif // defined(__GNUC__) || (_MSC_VER >= 1400) +// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, and IBM Visual Age support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 +#endif // Determines whether to support Combine(). This only makes sense when -// value-parameterized tests are enabled. -#if defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE -#define GTEST_HAS_COMBINE -#endif // defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +#define GTEST_HAS_COMBINE 1 +#endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. -#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \ - defined(GTEST_OS_SYMBIAN) -#define GTEST_WIDE_STRING_USES_UTF16_ 1 -#endif +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Defines some utility macros. @@ -408,7 +536,7 @@ #define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT #endif -// Use this annotation at the end of a struct / class definition to +// Use this annotation at the end of a struct/class definition to // prevent the compiler from optimizing away instances that are never // used. This is useful when all interesting logic happens inside the // c'tor and / or d'tor. Example: @@ -416,17 +544,25 @@ // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) #define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #else #define GTEST_ATTRIBUTE_UNUSED_ #endif -// A macro to disallow the evil copy constructor and operator= functions +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ - type(const type &);\ - void operator=(const type &) + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations @@ -439,6 +575,36 @@ #define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +#define GTEST_HAS_SEH 1 +#else +// Assume no SEH. +#define GTEST_HAS_SEH 0 +#endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +#define GTEST_API_ +#endif + namespace testing { class Message; @@ -447,15 +613,11 @@ namespace internal { class String; -// std::strstream is deprecated. However, we have to use it on -// Windows as std::stringstream won't compile on Windows when -// exceptions are disabled. We use std::stringstream on other -// platforms to avoid compiler warnings there. -#if GTEST_HAS_STD_STRING typedef ::std::stringstream StrStream; -#else -typedef ::std::strstream StrStream; -#endif // GTEST_HAS_STD_STRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); // Defines scoped_ptr. @@ -464,6 +626,8 @@ typedef ::std::strstream StrStream; template <typename T> class scoped_ptr { public: + typedef T element_type; + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} ~scoped_ptr() { reset(); } @@ -479,7 +643,7 @@ class scoped_ptr { void reset(T* p = NULL) { if (p != ptr_) { - if (sizeof(T) > 0) { // Makes sure T is a complete type. + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; @@ -491,18 +655,18 @@ class scoped_ptr { GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; -#ifdef GTEST_HAS_DEATH_TEST - // Defines RE. -// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended +// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended // Regular Expression syntax. -class RE { +class GTEST_API_ RE { public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + // Constructs an RE from a string. -#if GTEST_HAS_STD_STRING RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT @@ -521,14 +685,12 @@ class RE { // // TODO(wan@google.com): make FullMatch() and PartialMatch() work // when str contains NUL characters. -#if GTEST_HAS_STD_STRING static bool FullMatch(const ::std::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::std::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { @@ -550,15 +712,20 @@ class RE { // String type here, in order to simplify dependencies between the // files. const char* pattern_; + bool is_valid_; +#if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). - bool is_valid_; -}; +#else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); +#endif -#endif // GTEST_HAS_DEATH_TEST + GTEST_DISALLOW_ASSIGN_(RE); +}; // Defines logging utilities: -// GTEST_LOG_() - logs messages at the specified severity level. +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. @@ -569,35 +736,439 @@ enum GTestLogSeverity { GTEST_FATAL }; -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg); +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); -#define GTEST_LOG_(severity, msg)\ - ::testing::internal::GTestLog(\ - ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \ - (::testing::Message() << (msg)).GetString().c_str()) + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template <class Derived, class Base> +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast<Derived*>(base); // NOLINT +#else + return static_cast<Derived*>(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION_ + // Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ String GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ String GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). extern ::std::vector<String> g_argvs; -void CaptureStderr(); // GTEST_HAS_DEATH_TEST implies we have ::std::string. -::std::string GetCapturedStderr(); const ::std::vector<String>& GetArgvs(); #endif // GTEST_HAS_DEATH_TEST // Defines synchronization primitives. +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) {} + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { notified_ = true; } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + while(!notified_) { + SleepMilliseconds(10); + } + } + + private: + volatile bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast<ThreadWithParamBase*>(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template <typename T> +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is +// true. +#include <pthread.h> + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + } + + // Releases this mutex. + void Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_ = 0; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. +}; + +// Forward-declares a static mutex. +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + owner_ = 0; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal<T>. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast<ThreadLocalValueHolderBase*>(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal<int> tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template <typename T> +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType<ValueHolder>(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +#define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where // mutex is not supported - using Google Test in multiple threads is not @@ -606,14 +1177,14 @@ const ::std::vector<String>& GetArgvs(); class Mutex { public: Mutex() {} - explicit Mutex(int /*unused*/) {} void AssertHeld() const {} - enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 }; }; -// We cannot call it MutexLock directly as the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. Hence the typedef trick below. +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT @@ -634,30 +1205,37 @@ class ThreadLocal { T value_; }; -// There's no portable way to detect the number of threads, so we just -// return 0 to indicate that we cannot detect it. -inline size_t GetThreadCount() { return 0; } - // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. #define GTEST_IS_THREADSAFE 0 -#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM -// compiler. The Nokia Symbian and the IBM XL C/C++ compiler try to -// instantiate a copy constructor for objects passed through ellipsis -// (...), failing for uncopyable objects. We define this to indicate -// the fact. -#define GTEST_ELLIPSIS_NEEDS_COPY_ 1 +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +#define GTEST_CAN_COMPARE_NULL 1 +#endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between // const T& and const T* in a function template. These compilers // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) #define GTEST_NEEDS_IS_POINTER_ 1 - -#endif // defined(__SYMBIAN32__) || defined(__IBMCPP__) +#endif template <bool bool_value> struct bool_constant { @@ -675,15 +1253,146 @@ struct is_pointer : public false_type {}; template <typename T> struct is_pointer<T*> : public true_type {}; -// Defines BiggestInt as the biggest signed integer type the compiler -// supports. - -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +#ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +#else +inline int IsATTY(int fd) { return _isatty(fd); } +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +#else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +#endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast<int>(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast<int>(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + // The maximum number a BiggestInt can represent. This definition // works no matter BiggestInt is represented in one's complement or // two's complement. @@ -736,7 +1445,7 @@ class TypeWithSize<4> { template <> class TypeWithSize<8> { public: -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else @@ -754,96 +1463,23 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Utilities for command line flags and environment variables. -// A wrapper for getenv() that works on Linux, Windows, and Mac OS. -inline const char* GetEnv(const char* name) { -#ifdef _WIN32_WCE // We are on Windows CE. - // CE has no environment variables. - return NULL; -#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. - // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 - // (deprecated function) there. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - return getenv(name); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - return getenv(name); -#endif -} - -#ifdef _WIN32_WCE -// Windows CE has no C library. The abort() function is used in -// several places in Google Test. This implementation provides a reasonable -// imitation of standard behaviour. -void abort(); -#else -inline void abort() { ::abort(); } -#endif // _WIN32_WCE - -// INTERNAL IMPLEMENTATION - DO NOT USE. -// -// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition -// is not satisfied. -// Synopsys: -// GTEST_CHECK_(boolean_condition); -// or -// GTEST_CHECK_(boolean_condition) << "Additional message"; -// -// This checks the condition and if the condition is not satisfied -// it prints message about the condition violation, including the -// condition itself, plus additional message streamed into it, if any, -// and then it aborts the program. It aborts the program irrespective of -// whether it is built in the debug mode or not. -class GTestCheckProvider { - public: - GTestCheckProvider(const char* condition, const char* file, int line) { - FormatFileLocation(file, line); - ::std::cerr << " ERROR: Condition " << condition << " failed. "; - } - ~GTestCheckProvider() { - ::std::cerr << ::std::endl; - abort(); - } - void FormatFileLocation(const char* file, int line) { - if (file == NULL) - file = "unknown file"; - if (line < 0) { - ::std::cerr << file << ":"; - } else { -#if _MSC_VER - ::std::cerr << file << "(" << line << "):"; -#else - ::std::cerr << file << ":" << line << ":"; -#endif - } - } - ::std::ostream& GetStream() { return ::std::cerr; } -}; -#define GTEST_CHECK_(condition) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (condition) \ - ; \ - else \ - ::testing::internal::GTestCheckProvider(\ - #condition, __FILE__, __LINE__).GetStream() - // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name // Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ - extern ::testing::internal::Int32 GTEST_FLAG(name) + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ - extern ::testing::internal::String GTEST_FLAG(name) + GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ - bool GTEST_FLAG(name) = (default_val) + GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ - ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ - ::testing::internal::String GTEST_FLAG(name) = (default_val) + GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns @@ -856,7 +1492,7 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value); // Parses a bool/Int32/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); -Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/utils/unittest/googletest/include/gtest/internal/gtest-string.h index 178f14e..aff093d 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-string.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-string.h @@ -35,32 +35,34 @@ // Google Test. They are subject to change without notice. They should not used // by code external to Google Test. // -// This header file is #included by testing/base/internal/gtest-internal.h. +// This header file is #included by <gtest/internal/gtest-internal.h>. // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +#include <mem.h> +#endif + #include <string.h> #include <gtest/internal/gtest-port.h> -#if GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING #include <string> -#endif // GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING namespace testing { namespace internal { // String - a UTF-8 string class. // -// We cannot use std::string as Microsoft's STL implementation in -// Visual C++ 7.1 has problems when exception is disabled. There is a -// hack to work around this, but we've seen cases where the hack fails -// to work. +// For historic reasons, we don't use std::string. +// +// TODO(wan@google.com): replace this class with std::string or +// implement it in terms of the latter. // -// Also, String is different from std::string in that it can represent -// both NULL and the empty string, while std::string cannot represent -// NULL. +// Note that String can represent both NULL and the empty string, +// while std::string cannot represent NULL. // // NULL and the empty string are considered different. NULL is less // than anything (including the empty string) except itself. @@ -76,23 +78,10 @@ namespace internal { // // In order to make the representation efficient, the d'tor of String // is not virtual. Therefore DO NOT INHERIT FROM String. -class String { +class GTEST_API_ String { public: // Static utility methods - // Returns the input if it's not NULL, otherwise returns "(null)". - // This function serves two purposes: - // - // 1. ShowCString(NULL) has type 'const char *', instead of the - // type of NULL (which is int). - // - // 2. In MSVC, streaming a null char pointer to StrStream generates - // an access violation, so we need to convert NULL to "(null)" - // before streaming it. - static inline const char* ShowCString(const char* c_str) { - return c_str ? c_str : "(null)"; - } - // Returns the input enclosed in double quotes if it's not NULL; // otherwise returns "(null)". For example, "\"Hello\"" is returned // for input "Hello". @@ -111,7 +100,7 @@ class String { // memory using malloc(). static const char* CloneCString(const char* c_str); -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. @@ -200,22 +189,29 @@ class String { // C'tors // The default c'tor constructs a NULL string. - String() : c_str_(NULL) {} + String() : c_str_(NULL), length_(0) {} // Constructs a String by cloning a 0-terminated C string. - String(const char* c_str) : c_str_(NULL) { // NOLINT - *this = c_str; + String(const char* a_c_str) { // NOLINT + if (a_c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(a_c_str, strlen(a_c_str)); + } } // Constructs a String by copying a given number of chars from a - // buffer. E.g. String("hello", 3) will create the string "hel". - String(const char* buffer, size_t len); + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t a_length) { + ConstructNonNull(buffer, a_length); + } // The copy c'tor creates a new copy of the string. The two // String objects do not share content. - String(const String& str) : c_str_(NULL) { - *this = str; - } + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } // D'tor. String is intended to be a final class, so the d'tor // doesn't need to be virtual. @@ -227,22 +223,22 @@ class String { // Converting a ::std::string or ::string containing an embedded NUL // character to a String will result in the prefix up to the first // NUL character. -#if GTEST_HAS_STD_STRING - String(const ::std::string& str) : c_str_(NULL) { *this = str.c_str(); } + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } - operator ::std::string() const { return ::std::string(c_str_); } -#endif // GTEST_HAS_STD_STRING + operator ::std::string() const { return ::std::string(c_str(), length()); } #if GTEST_HAS_GLOBAL_STRING - String(const ::string& str) : c_str_(NULL) { *this = str.c_str(); } + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } - operator ::string() const { return ::string(c_str_); } + operator ::string() const { return ::string(c_str(), length()); } #endif // GTEST_HAS_GLOBAL_STRING // Returns true iff this is an empty string (i.e. ""). - bool empty() const { - return (c_str_ != NULL) && (*c_str_ == '\0'); - } + bool empty() const { return (c_str() != NULL) && (length() == 0); } // Compares this with another String. // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 @@ -251,19 +247,15 @@ class String { // Returns true iff this String equals the given C string. A NULL // string and a non-NULL string are considered not equal. - bool operator==(const char* c_str) const { - return CStringEquals(c_str_, c_str); - } + bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; } - // Returns true iff this String is less than the given C string. A NULL - // string is considered less than "". + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". bool operator<(const String& rhs) const { return Compare(rhs) < 0; } // Returns true iff this String doesn't equal the given C string. A NULL // string and a non-NULL string are considered not equal. - bool operator!=(const char* c_str) const { - return !CStringEquals(c_str_, c_str); - } + bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); } // Returns true iff this String ends with the given suffix. *Any* // String is considered to end with a NULL or empty suffix. @@ -273,50 +265,73 @@ class String { // case. Any String is considered to end with a NULL or empty suffix. bool EndsWithCaseInsensitive(const char* suffix) const; - // Returns the length of the encapsulated string, or -1 if the + // Returns the length of the encapsulated string, or 0 if the // string is NULL. - int GetLength() const { - return c_str_ ? static_cast<int>(strlen(c_str_)) : -1; - } + size_t length() const { return length_; } // Gets the 0-terminated C string this String object represents. // The String object still owns the string. Therefore the caller // should NOT delete the return value. const char* c_str() const { return c_str_; } - // Sets the 0-terminated C string this String object represents. - // The old string in this object is deleted, and this object will - // own a clone of the input string. This function copies only up to - // length bytes (plus a terminating null byte), or until the first - // null byte, whichever comes first. - // - // This function works even when the c_str parameter has the same - // value as that of the c_str_ field. - void Set(const char* c_str, size_t length); - // Assigns a C string to this object. Self-assignment works. - const String& operator=(const char* c_str); + const String& operator=(const char* a_c_str) { + return *this = String(a_c_str); + } // Assigns a String object to this object. Self-assignment works. - const String& operator=(const String &rhs) { - *this = rhs.c_str_; + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + return *this; } private: - const char* c_str_; -}; + // Constructs a non-NULL String from the given content. This + // function can only be called when data_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t a_length) { + char* const str = new char[a_length + 1]; + memcpy(str, buffer, a_length); + str[a_length] = '\0'; + c_str_ = str; + length_ = a_length; + } -// Streams a String to an ostream. -inline ::std::ostream& operator <<(::std::ostream& os, const String& str) { - // We call String::ShowCString() to convert NULL to "(null)". - // Otherwise we'll get an access violation on Windows. - return os << String::ShowCString(str.c_str()); + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; } // Gets the content of the StrStream's buffer as a String. Each '\0' // character in the buffer is replaced with "\\0". -String StrStreamToString(StrStream* stream); +GTEST_API_ String StrStreamToString(StrStream* stream); // Converts a streamable value to a String. A NULL pointer is // converted to "(null)". When the input value is a ::string, diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h new file mode 100644 index 0000000..16178fc --- /dev/null +++ b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h @@ -0,0 +1,968 @@ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// 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: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include <utility> // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template <GTEST_10_TYPENAMES_(U)> friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \ + void, void, void> +#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \ + void, void, void> +#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \ + void, void, void> +#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \ + void, void, void> +#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \ + void, void, void> +#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \ + void, void, void> +#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + void, void, void> +#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, void, void> +#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, void> +#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, T##9> + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <typename T0 = void, typename T1 = void, typename T2 = void, + typename T3 = void, typename T4 = void, typename T5 = void, + typename T6 = void, typename T7 = void, typename T8 = void, + typename T9 = void> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef<T>::type is T if T is a reference; otherwise it's const T&. +template <typename T> +struct ByRef { typedef const T& type; }; // NOLINT +template <typename T> +struct ByRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type + +// AddRef<T>::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference<T>::type. +template <typename T> +struct AddRef { typedef T& type; }; // NOLINT +template <typename T> +struct AddRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type + +// A helper for implementing get<k>(). +template <int k> class Get; + +// A helper for implementing tuple_element<k, T>. kIndexValid is true +// iff k < the number of fields in tuple type T. +template <bool kIndexValid, int kIndex, class Tuple> +struct TupleElement; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; }; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template <GTEST_1_TYPENAMES_(T)> +class GTEST_1_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template <GTEST_1_TYPENAMES_(U)> + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_1_TYPENAMES_(U)> + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_1_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template <GTEST_2_TYPENAMES_(T)> +class GTEST_2_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template <GTEST_2_TYPENAMES_(U)> + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template <typename U0, typename U1> + tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_2_TYPENAMES_(U)> + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template <typename U0, typename U1> + tuple& operator=(const ::std::pair<U0, U1>& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_2_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template <GTEST_3_TYPENAMES_(T)> +class GTEST_3_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template <GTEST_3_TYPENAMES_(U)> + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_3_TYPENAMES_(U)> + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_3_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template <GTEST_4_TYPENAMES_(T)> +class GTEST_4_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template <GTEST_4_TYPENAMES_(U)> + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_4_TYPENAMES_(U)> + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_4_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template <GTEST_5_TYPENAMES_(T)> +class GTEST_5_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template <GTEST_5_TYPENAMES_(U)> + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_5_TYPENAMES_(U)> + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_5_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template <GTEST_6_TYPENAMES_(T)> +class GTEST_6_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template <GTEST_6_TYPENAMES_(U)> + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_6_TYPENAMES_(U)> + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_6_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template <GTEST_7_TYPENAMES_(T)> +class GTEST_7_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template <GTEST_7_TYPENAMES_(U)> + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_7_TYPENAMES_(U)> + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_7_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template <GTEST_8_TYPENAMES_(T)> +class GTEST_8_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template <GTEST_8_TYPENAMES_(U)> + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_8_TYPENAMES_(U)> + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_8_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template <GTEST_9_TYPENAMES_(T)> +class GTEST_9_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template <GTEST_9_TYPENAMES_(U)> + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_9_TYPENAMES_(U)> + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_9_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template <GTEST_10_TYPENAMES_(T)> +class tuple { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template <GTEST_10_TYPENAMES_(U)> + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_10_TYPENAMES_(U)> + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_10_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper<T> to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template <GTEST_1_TYPENAMES_(T)> +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template <GTEST_2_TYPENAMES_(T)> +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template <GTEST_3_TYPENAMES_(T)> +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template <GTEST_4_TYPENAMES_(T)> +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template <GTEST_5_TYPENAMES_(T)> +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template <GTEST_6_TYPENAMES_(T)> +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template <GTEST_7_TYPENAMES_(T)> +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template <GTEST_8_TYPENAMES_(T)> +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template <GTEST_9_TYPENAMES_(T)> +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template <GTEST_10_TYPENAMES_(T)> +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template <typename Tuple> struct tuple_size; + +template <GTEST_0_TYPENAMES_(T)> +struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; }; + +template <GTEST_1_TYPENAMES_(T)> +struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; }; + +template <GTEST_2_TYPENAMES_(T)> +struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; }; + +template <GTEST_3_TYPENAMES_(T)> +struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; }; + +template <GTEST_4_TYPENAMES_(T)> +struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; }; + +template <GTEST_5_TYPENAMES_(T)> +struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; }; + +template <GTEST_6_TYPENAMES_(T)> +struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; }; + +template <GTEST_7_TYPENAMES_(T)> +struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; }; + +template <GTEST_8_TYPENAMES_(T)> +struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; }; + +template <GTEST_9_TYPENAMES_(T)> +struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; }; + +template <GTEST_10_TYPENAMES_(T)> +struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; }; + +template <int k, class Tuple> +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size<Tuple>::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::Field(t); +} + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template <int kSize1, int kSize2> +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template <int k> +struct SameSizeTuplePrefixComparator<k, k> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && + ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); + } +}; + +} // namespace gtest_internal + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size<GTEST_10_TUPLE_(T)>::value, + tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u); +} + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h index 815da4b..093eee6 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. @@ -45,13 +47,13 @@ #include <gtest/internal/gtest-port.h> #include <gtest/internal/gtest-string.h> -#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P -#ifdef __GNUC__ +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +#ifdef __GLIBCXX__ #include <cxxabi.h> -#endif // __GNUC__ - -#include <typeinfo> +#endif // __GLIBCXX__ namespace testing { namespace internal { @@ -74,7 +76,7 @@ String GetTypeName() { #if GTEST_HAS_RTTI const char* const name = typeid(T).name(); -#ifdef __GNUC__ +#ifdef __GLIBCXX__ int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. @@ -84,7 +86,7 @@ String GetTypeName() { return name_str; #else return name; -#endif // __GNUC__ +#endif // __GLIBCXX__ #else return "<type>"; |