[llvm-commits] [llvm] r105353 - in /llvm/trunk/utils/unittest/googletest: ./ include/gtest/ include/gtest/internal/
Benjamin Kramer
benny.kra at googlemail.com
Wed Jun 2 15:02:11 PDT 2010
Author: d0k
Date: Wed Jun 2 17:02:11 2010
New Revision: 105353
URL: http://llvm.org/viewvc/llvm-project?rev=105353&view=rev
Log:
Merge gtest-1.4.0.
Added:
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
Modified:
llvm/trunk/utils/unittest/googletest/gtest-death-test.cc
llvm/trunk/utils/unittest/googletest/gtest-filepath.cc
llvm/trunk/utils/unittest/googletest/gtest-port.cc
llvm/trunk/utils/unittest/googletest/gtest-test-part.cc
llvm/trunk/utils/unittest/googletest/gtest-typed-test.cc
llvm/trunk/utils/unittest/googletest/gtest.cc
llvm/trunk/utils/unittest/googletest/include/gtest/gtest-death-test.h
llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h
llvm/trunk/utils/unittest/googletest/include/gtest/gtest-param-test.h
llvm/trunk/utils/unittest/googletest/include/gtest/gtest-spi.h
llvm/trunk/utils/unittest/googletest/include/gtest/gtest-test-part.h
llvm/trunk/utils/unittest/googletest/include/gtest/gtest.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-port.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-string.h
llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
Modified: llvm/trunk/utils/unittest/googletest/gtest-death-test.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest-death-test.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest-death-test.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest-death-test.cc Wed Jun 2 17:02:11 2010
@@ -204,15 +204,7 @@
const InternalRunDeathTestFlag* const flag =
GetUnitTestImpl()->internal_run_death_test_flag();
if (flag != NULL) {
-// Suppress MSVC complaints about POSIX functions.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable: 4996)
-#endif // _MSC_VER
- FILE* parent = fdopen(flag->status_fd(), "w");
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
+ FILE* parent = posix::FDOpen(flag->write_fd(), "w");
fputc(kDeathTestInternalError, parent);
fprintf(parent, "%s", message.c_str());
fflush(parent);
@@ -228,12 +220,12 @@
// fails.
#define GTEST_DEATH_TEST_CHECK_(expression) \
do { \
- if (!(expression)) { \
- DeathTestAbort(::testing::internal::String::Format(\
+ 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
@@ -249,54 +241,42 @@
gtest_retval = (expression); \
} while (gtest_retval == -1 && errno == EINTR); \
if (gtest_retval == -1) { \
- DeathTestAbort(::testing::internal::String::Format(\
+ 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, regardless of the
-// platform.
-String GetLastSystemErrorMessage() {
-#if GTEST_OS_WINDOWS
- const DWORD error_num = ::GetLastError();
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+ return String(errno == 0 ? "" : posix::StrError(errno));
+}
- if (error_num == NULL)
- return String("");
+// 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;
- char* message_ptr;
+ do {
+ while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+ buffer[num_read] = '\0';
+ error << buffer;
+ }
+ } while (num_read == -1 && errno == EINTR);
- ::FormatMessageA(
- // The caller does not provide a buffer. The function will allocate one.
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- // The function must look up an error message in its system error
- // message table.
- FORMAT_MESSAGE_FROM_SYSTEM |
- // Do not expand insert sequences in the message definition.
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, // Message source. Ignored in this call.
- error_num,
- 0x0, // Use system-default language.
- reinterpret_cast<LPSTR>(&message_ptr),
- 0, // Buffer size. Ignored in this call.
- NULL); // Message arguments. Ignored in this call.
-
- const String message = message_ptr;
- ::LocalFree(message_ptr);
- return message;
-#else
- return errno == 0 ? String("") : String(strerror(errno));
-#endif // GTEST_OS_WINDOWS
+ 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 << "]";
+ }
}
-// TODO(vladl at google.com): Move the definition of FailFromInternalError
-// here.
-#if GTEST_OS_WINDOWS
-static void FailFromInternalError(HANDLE handle);
-#else
-static void FailFromInternalError(int fd);
-#endif // GTEST_OS_WINDOWS
-
// Death test constructor. Increments the running death test count
// for the current test.
DeathTest::DeathTest() {
@@ -326,8 +306,6 @@
String DeathTest::last_death_test_message_;
// Provides cross platform implementation for some death functionality.
-// TODO(vladl at google.com): Merge this class with DeathTest in
-// gtest-death-test-internal.h.
class DeathTestImpl : public DeathTest {
protected:
DeathTestImpl(const char* statement, const RE* regex)
@@ -335,8 +313,14 @@
regex_(regex),
spawned_(false),
status_(-1),
- outcome_(IN_PROGRESS) {}
+ 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_; }
@@ -347,6 +331,16 @@
void set_status(int status) { status_ = status; }
DeathTestOutcome outcome() const { return outcome_; }
void set_outcome(DeathTestOutcome outcome) { outcome_ = 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. This class
@@ -361,9 +355,138 @@
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_;
};
-// TODO(vladl at google.com): Move definition of DeathTestImpl::Passed() here.
+// 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.
+ do {
+ bytes_read = posix::Read(read_fd(), &flag, 1);
+ } while (bytes_read == -1 && errno == EINTR);
+
+ if (bytes_read == 0) {
+ set_outcome(DIED);
+ } else if (bytes_read == 1) {
+ switch (flag) {
+ case kDeathTestReturned:
+ set_outcome(RETURNED);
+ break;
+ case kDeathTestLived:
+ set_outcome(LIVED);
+ break;
+ case kDeathTestInternalError:
+ FailFromInternalError(read_fd()); // Does not return.
+ break;
+ default:
+ GTEST_LOG_(FATAL) << "Death test child process reported "
+ << "unexpected status byte ("
+ << static_cast<unsigned int>(flag) << ")";
+ }
+ } else {
+ GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+ << GetLastErrnoDescription();
+ }
+ GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+ set_read_fd(-1);
+}
+
+// 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
+// concluded: DIED, LIVED, or RETURNED. The death test fails
+// 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.
+//
+// Argument:
+// status_ok: true if exit_status is acceptable in the context of
+// this particular death test, which fails if it is false
+//
+// 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 last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+ if (!spawned())
+ return false;
+
+ const String error_message = GetCapturedStderr();
+
+ bool success = false;
+ Message buffer;
+
+ buffer << "Death test: " << statement() << "\n";
+ switch (outcome()) {
+ case LIVED:
+ buffer << " Result: failed to die.\n"
+ << " Error msg: " << error_message;
+ break;
+ case RETURNED:
+ buffer << " Result: illegal return in test statement.\n"
+ << " Error msg: " << error_message;
+ break;
+ case DIED:
+ if (status_ok) {
+ 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"
+ << "Actual msg: " << error_message;
+ }
+ } else {
+ buffer << " Result: died but not with expected exit code:\n"
+ << " " << ExitSummary(status()) << "\n";
+ }
+ break;
+ case IN_PROGRESS:
+ default:
+ GTEST_LOG_(FATAL)
+ << "DeathTest::Passed somehow called before conclusion of test";
+ }
+
+ DeathTest::set_last_death_test_message(buffer.GetString());
+ return success;
+}
#if GTEST_OS_WINDOWS
// WindowsDeathTest implements death tests on Windows. Due to the
@@ -404,7 +527,6 @@
// All of these virtual functions are inherited from DeathTest.
virtual int Wait();
- virtual void Abort(AbortReason reason);
virtual TestRole AssumeRole();
private:
@@ -412,10 +534,6 @@
const char* const file_;
// The line number on which the death test is located.
const int line_;
- // Handle to the read end of the pipe to the child process.
- // The child keeps its write end of the pipe in the status_handle_
- // field of its InternalRunDeathTestFlag class.
- AutoHandle read_handle_;
// Handle to the write end of the pipe to the child process.
AutoHandle write_handle_;
// Child process handle.
@@ -430,9 +548,6 @@
// 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.
-// TODO(vladl at google.com): Outcome classification logic is common with
-// ForkingDeathTes::Wait(). Refactor it into a
-// common function.
int WindowsDeathTest::Wait() {
if (!spawned())
return 0;
@@ -456,44 +571,7 @@
write_handle_.Reset();
event_handle_.Reset();
- // ReadFile() 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 or
- // after the child process has exited.
- char flag;
- DWORD bytes_read;
- GTEST_DEATH_TEST_CHECK_(::ReadFile(read_handle_.Get(),
- &flag,
- 1,
- &bytes_read,
- NULL) ||
- ::GetLastError() == ERROR_BROKEN_PIPE);
-
- if (bytes_read == 0) {
- set_outcome(DIED);
- } else if (bytes_read == 1) {
- switch (flag) {
- case kDeathTestReturned:
- set_outcome(RETURNED);
- break;
- case kDeathTestLived:
- set_outcome(LIVED);
- break;
- case kDeathTestInternalError:
- FailFromInternalError(read_handle_.Get()); // Does not return.
- break;
- default:
- GTEST_LOG_(FATAL,
- Message() << "Death test child process reported "
- << " unexpected status byte ("
- << static_cast<unsigned int>(flag) << ")");
- }
- } else {
- GTEST_LOG_(FATAL,
- Message() << "Read from death test child process failed: "
- << GetLastSystemErrorMessage());
- }
- read_handle_.Reset(); // Done with reading.
+ ReadAndInterpretStatusByte();
// Waits for the child process to exit if it haven't already. This
// returns immediately if the child has already exited, regardless of
@@ -503,41 +581,13 @@
WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
INFINITE));
DWORD status;
- GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(),
- &status));
+ GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+ != FALSE);
child_handle_.Reset();
set_status(static_cast<int>(status));
return this->status();
}
-// TODO(vladl at google.com): define a cross-platform way to write to
-// status_fd to be used both here and in ForkingDeathTest::Abort().
-//
-// Signals that the death test did not die as expected. This is called
-// from the child process only.
-void WindowsDeathTest::Abort(AbortReason reason) {
- const InternalRunDeathTestFlag* const internal_flag =
- GetUnitTestImpl()->internal_run_death_test_flag();
- // 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;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable: 4996)
-#endif // _MSC_VER
- GTEST_DEATH_TEST_CHECK_SYSCALL_(write(internal_flag->status_fd(),
- &status_ch, 1));
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
-
- // The write handle will be closed when the child terminates in _exit().
- _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
-}
-
// 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
@@ -553,6 +603,7 @@
if (flag != NULL) {
// ParseInternalRunDeathTestFlag() has performed all the necessary
// processing.
+ set_write_fd(flag->write_fd());
return EXECUTE_TEST;
}
@@ -561,10 +612,12 @@
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.
- read_handle_.Reset(read_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,
@@ -625,7 +678,7 @@
NULL, // Inherit the parent's environment.
UnitTest::GetInstance()->original_working_dir(),
&startup_info,
- &process_info));
+ &process_info) != FALSE);
child_handle_.Reset(process_info.hProcess);
::CloseHandle(process_info.hThread);
set_spawned(true);
@@ -642,92 +695,20 @@
// All of these virtual functions are inherited from DeathTest.
virtual int Wait();
- virtual void Abort(AbortReason reason);
protected:
void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
- void set_read_fd(int fd) { read_fd_ = fd; }
- void set_write_fd(int fd) { write_fd_ = fd; }
private:
// 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.
};
// Constructs a ForkingDeathTest.
ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex)
: DeathTestImpl(statement, regex),
- child_pid_(-1),
- read_fd_(-1),
- write_fd_(-1) {
-}
-#endif // GTEST_OS_WINDOWS
-
-// 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.
-// TODO(vladl at google.com): Re-factor the code to merge common parts after
-// the reading code is abstracted.
-#if GTEST_OS_WINDOWS
-static void FailFromInternalError(HANDLE handle) {
- Message error;
- char buffer[256];
-
- bool read_succeeded = true;
- DWORD bytes_read;
- do {
- // ERROR_BROKEN_PIPE arises when the other end of the pipe has been
- // closed. This is a normal condition for us.
- bytes_read = 0;
- read_succeeded = ::ReadFile(handle,
- buffer,
- sizeof(buffer) - 1,
- &bytes_read,
- NULL) || ::GetLastError() == ERROR_BROKEN_PIPE;
- buffer[bytes_read] = 0;
- error << buffer;
- } while (read_succeeded && bytes_read > 0);
-
- if (read_succeeded) {
- GTEST_LOG_(FATAL, error);
- } else {
- const DWORD last_error = ::GetLastError();
- const String message = GetLastSystemErrorMessage();
- GTEST_LOG_(FATAL,
- Message() << "Error while reading death test internal: "
- << message << " [" << last_error << "]");
- }
-}
-#else
-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);
-
- if (num_read == 0) {
- GTEST_LOG_(FATAL, error);
- } else {
- const int last_error = errno;
- const String message = GetLastSystemErrorMessage();
- GTEST_LOG_(FATAL,
- Message() << "Error while reading death test internal: "
- << message << " [" << last_error << "]");
- }
-}
-#endif // GTEST_OS_WINDOWS
+ child_pid_(-1) {}
-#if !GTEST_OS_WINDOWS
// 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.
@@ -735,135 +716,13 @@
if (!spawned())
return 0;
- // 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;
+ ReadAndInterpretStatusByte();
- do {
- bytes_read = read(read_fd_, &flag, 1);
- } while (bytes_read == -1 && errno == EINTR);
-
- if (bytes_read == 0) {
- set_outcome(DIED);
- } else if (bytes_read == 1) {
- switch (flag) {
- case kDeathTestReturned:
- set_outcome(RETURNED);
- break;
- case kDeathTestLived:
- set_outcome(LIVED);
- break;
- case kDeathTestInternalError:
- 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)
- << ")");
- }
- } else {
- const String error_message = GetLastSystemErrorMessage();
- GTEST_LOG_(FATAL,
- Message() << "Read from death test child process failed: "
- << error_message);
- }
-
- GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_));
int status;
GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0));
set_status(status);
return status;
}
-#endif // !GTEST_OS_WINDOWS
-
-// 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
-// concluded: DIED, LIVED, or RETURNED. The death test fails
-// 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.
-//
-// Argument:
-// status_ok: true if exit_status is acceptable in the context of
-// this particular death test, which fails if it is false
-//
-// 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 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
-
- bool success = false;
- Message buffer;
-
- buffer << "Death test: " << statement() << "\n";
- switch (outcome()) {
- case LIVED:
- buffer << " Result: failed to die.\n"
- << " Error msg: " << error_message;
- break;
- case RETURNED:
- buffer << " Result: illegal return in test statement.\n"
- << " Error msg: " << error_message;
- break;
- case DIED:
- if (status_ok) {
- if (RE::PartialMatch(error_message, *regex())) {
- success = true;
- } else {
- buffer << " Result: died but not with expected error.\n"
- << " Expected: " << regex()->pattern() << "\n"
- << "Actual msg: " << error_message;
- }
- } else {
- buffer << " Result: died but not with expected exit code:\n"
- << " " << ExitSummary(status()) << "\n";
- }
- break;
- case IN_PROGRESS:
- default:
- GTEST_LOG_(FATAL,
- "DeathTest::Passed somehow called before conclusion of test");
- }
-
- DeathTest::set_last_death_test_message(buffer.GetString());
- return success;
-}
-
-#if !GTEST_OS_WINDOWS
-// 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 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)
-}
// A concrete death test class that forks, then immediately runs the test
// in the child process.
@@ -879,7 +738,7 @@
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];
@@ -906,6 +765,9 @@
// 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]));
@@ -945,7 +807,7 @@
}
}
void AddArgument(const char* argument) {
- args_.insert(args_.end() - 1, strdup(argument));
+ args_.insert(args_.end() - 1, posix::StrDup(argument));
}
template <typename Str>
@@ -953,7 +815,7 @@
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() {
@@ -978,12 +840,10 @@
return *_NSGetEnviron();
}
#else
-extern "C" char** environ; // Some POSIX platforms expect you
- // to declare environ. extern "C" makes
- // it reside in the global namespace.
-inline char** GetEnviron() {
- return environ;
-}
+// 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.
@@ -1002,7 +862,7 @@
if (chdir(original_dir) != 0) {
DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
original_dir,
- GetLastSystemErrorMessage().c_str()));
+ GetLastErrnoDescription().c_str()));
return EXIT_FAILURE;
}
@@ -1015,7 +875,7 @@
DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
args->argv[0],
original_dir,
- GetLastSystemErrorMessage().c_str()));
+ GetLastErrnoDescription().c_str()));
return EXIT_FAILURE;
}
@@ -1039,7 +899,7 @@
// wrong.
static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
ExecDeathTestArgs args = { argv, close_fd };
- pid_t child_pid;
+ pid_t child_pid = -1;
#if GTEST_HAS_CLONE
const bool use_fork = GTEST_FLAG(death_test_use_fork);
@@ -1083,7 +943,7 @@
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;
}
@@ -1183,7 +1043,7 @@
::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));
@@ -1201,7 +1061,7 @@
// 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 status_handle_as_size_t,
+ 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.
@@ -1215,22 +1075,22 @@
// compile-time assertion when available.
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
- const HANDLE status_handle =
- reinterpret_cast<HANDLE>(status_handle_as_size_t);
- HANDLE dup_status_handle;
+ 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(), status_handle,
- ::GetCurrentProcess(), &dup_status_handle,
+ 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",
- status_handle_as_size_t, parent_process_id));
+ write_handle_as_size_t, parent_process_id));
}
const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
@@ -1246,20 +1106,19 @@
event_handle_as_size_t, parent_process_id));
}
- const int status_fd =
- ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_status_handle),
- O_APPEND | O_TEXT);
- if (status_fd == -1) {
+ 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",
- status_handle_as_size_t));
+ 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 status_fd;
+ return write_fd;
}
#endif // GTEST_OS_WINDOWS
@@ -1275,37 +1134,37 @@
int index = -1;
::std::vector< ::std::string> fields;
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
- int status_fd = -1;
+ int write_fd = -1;
#if GTEST_OS_WINDOWS
unsigned int parent_process_id = 0;
- size_t status_handle_as_size_t = 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], &status_handle_as_size_t)
+ || !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()));
}
- status_fd = GetStatusFileDescriptor(parent_process_id,
- status_handle_as_size_t,
- event_handle_as_size_t);
+ write_fd = GetStatusFileDescriptor(parent_process_id,
+ write_handle_as_size_t,
+ event_handle_as_size_t);
#else
if (fields.size() != 4
|| !ParseNaturalNumber(fields[1], &line)
|| !ParseNaturalNumber(fields[2], &index)
- || !ParseNaturalNumber(fields[3], &status_fd)) {
+ || !ParseNaturalNumber(fields[3], &write_fd)) {
DeathTestAbort(String::Format(
"Bad --gtest_internal_run_death_test flag: %s",
GTEST_FLAG(internal_run_death_test).c_str()));
}
#endif // GTEST_OS_WINDOWS
- return new InternalRunDeathTestFlag(fields[0], line, index, status_fd);
+ return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
}
} // namespace internal
Modified: llvm/trunk/utils/unittest/googletest/gtest-filepath.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest-filepath.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest-filepath.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest-filepath.cc Wed Jun 2 17:02:11 2010
@@ -34,22 +34,18 @@
#include <stdlib.h>
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
#include <windows.h>
#elif GTEST_OS_WINDOWS
#include <direct.h>
#include <io.h>
-#include <sys/stat.h>
#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> // NOLINT
-#include <unistd.h> // NOLINT
#include <climits> // Some Linux distributions define PATH_MAX here.
-#endif // _WIN32_WCE or _WIN32
+#endif // GTEST_OS_WINDOWS_MOBILE
#if GTEST_OS_WINDOWS
#define GTEST_PATH_MAX_ _MAX_PATH
@@ -69,7 +65,7 @@
#if GTEST_OS_WINDOWS
const char kPathSeparator = '\\';
const char kPathSeparatorString[] = "\\";
-#ifdef _WIN32_WCE
+#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.
@@ -78,7 +74,7 @@
const DWORD kInvalidFileAttributes = 0xffffffff;
#else
const char kCurrentDirectoryString[] = ".\\";
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
#else
const char kPathSeparator = '/';
const char kPathSeparatorString[] = "/";
@@ -87,17 +83,17 @@
// 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 GTEST_OS_WINDOWS
- char cwd[GTEST_PATH_MAX_ + 1] = {};
+ 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.
@@ -107,7 +103,7 @@
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;
}
@@ -131,8 +127,13 @@
// 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));
+ 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.
@@ -145,11 +146,13 @@
const FilePath& base_name,
int number,
const char* extension) {
- const FilePath file_name(
- (number == 0) ?
- String::Format("%s.%s", base_name.c_str(), extension) :
- String::Format("%s_%d.%s", base_name.c_str(), number, extension));
- return ConcatPaths(directory, file_name);
+ String file;
+ if (number == 0) {
+ file = String::Format("%s.%s", base_name.c_str(), extension);
+ } else {
+ file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+ }
+ return ConcatPaths(directory, FilePath(file));
}
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
@@ -166,20 +169,15 @@
// Returns true if pathname describes something findable in the file-system,
// either a file, directory, or whatever.
bool FilePath::FileOrDirectoryExists() const {
-#if 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
@@ -191,7 +189,11 @@
// 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;
@@ -200,15 +202,11 @@
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;
}
@@ -219,7 +217,7 @@
// TODO(wan at 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_.GetLength() == 3 && IsAbsolutePath();
+ return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_ == kPathSeparatorString;
#endif
@@ -229,7 +227,7 @@
bool FilePath::IsAbsolutePath() const {
const char* const name = pathname_.c_str();
#if GTEST_OS_WINDOWS
- return pathname_.GetLength() >= 3 &&
+ return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' &&
@@ -273,7 +271,7 @@
return false;
}
- if (pathname_.GetLength() == 0 || this->DirectoryExists()) {
+ if (pathname_.length() == 0 || this->DirectoryExists()) {
return true;
}
@@ -286,18 +284,17 @@
// 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 {
-#if 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.
}
@@ -309,7 +306,7 @@
// 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))
+ ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
: *this;
}
@@ -322,9 +319,9 @@
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;
Modified: llvm/trunk/utils/unittest/googletest/gtest-port.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest-port.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest-port.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest-port.cc Wed Jun 2 17:02:11 2010
@@ -35,20 +35,20 @@
#include <stdlib.h>
#include <stdio.h>
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h> // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
#include <io.h>
#include <sys/stat.h>
#else
#include <unistd.h>
-#endif // GTEST_OS_WINDOWS
+#endif // GTEST_OS_WINDOWS_MOBILE
-#if GTEST_USES_SIMPLE_RE
-#include <string.h>
-#endif
-
-#ifdef _WIN32_WCE
-#include <windows.h> // For TerminateProcess()
-#endif // _WIN32_WCE
+#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>
@@ -66,12 +66,43 @@
namespace testing {
namespace internal {
-#if GTEST_OS_WINDOWS
-// Microsoft does not provide a definition of STDERR_FILENO.
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
const int kStdErrFileno = 2;
#else
const int kStdErrFileno = STDERR_FILENO;
-#endif // GTEST_OS_WINDOWS
+#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
@@ -102,7 +133,7 @@
// 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.
@@ -350,11 +381,7 @@
void RE::Init(const char* regex) {
pattern_ = full_pattern_ = NULL;
if (regex != NULL) {
-#if GTEST_OS_WINDOWS
- pattern_ = _strdup(regex);
-#else
- pattern_ = strdup(regex);
-#endif
+ pattern_ = posix::StrDup(regex);
}
is_valid_ = ValidateRegex(regex);
@@ -386,22 +413,25 @@
#endif // GTEST_USES_POSIX_RE
-// Logs a message at the given severity level.
-void GTestLog(GTestLogSeverity severity, const char* file,
- int line, const char* msg) {
+
+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) {
- fflush(NULL); // abort() is not guaranteed to flush open file streams.
- abort();
- }
+ GetStream() << ::std::endl << marker << " "
+ << FormatFileLocation(file, line).c_str() << ": ";
}
-#if GTEST_HAS_STD_STRING
-
+// 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
@@ -415,6 +445,10 @@
public:
// The ctor redirects stderr to a temporary file.
CapturedStderr() {
+#if GTEST_OS_WINDOWS_MOBILE
+ // Not supported on Windows CE.
+ posix::Abort();
+#else
uncaptured_fd_ = dup(kStdErrFileno);
#if GTEST_OS_WINDOWS
@@ -436,19 +470,24 @@
fflush(NULL);
dup2(captured_fd, kStdErrFileno);
close(captured_fd);
+#endif // GTEST_OS_WINDOWS_MOBILE
}
~CapturedStderr() {
+#if !GTEST_OS_WINDOWS_MOBILE
remove(filename_.c_str());
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
// Stops redirecting stderr.
void StopCapture() {
+#if !GTEST_OS_WINDOWS_MOBILE
// Restores the original stream.
fflush(NULL);
dup2(uncaptured_fd_, kStdErrFileno);
close(uncaptured_fd_);
uncaptured_fd_ = -1;
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
// Returns the name of the temporary file holding the stderr output.
@@ -474,7 +513,7 @@
}
// Reads the entire content of a file as a string.
-static ::std::string ReadEntireFile(FILE * file) {
+static String ReadEntireFile(FILE * file) {
const size_t file_size = GetFileSize(file);
char* const buffer = new char[file_size];
@@ -490,7 +529,7 @@
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;
@@ -499,7 +538,7 @@
// Starts capturing stderr.
void CaptureStderr() {
if (g_captured_stderr != NULL) {
- GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time.");
+ GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
}
g_captured_stderr = new CapturedStderr;
}
@@ -507,20 +546,12 @@
// 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() {
+String GetCapturedStderr() {
g_captured_stderr->StopCapture();
-// Disables Microsoft deprecation warning for fopen and fclose.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable: 4996)
-#endif // _MSC_VER
- FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r");
- const ::std::string content = ReadEntireFile(file);
- fclose(file);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
+ FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r");
+ const String content = ReadEntireFile(file);
+ posix::FClose(file);
delete g_captured_stderr;
g_captured_stderr = NULL;
@@ -528,8 +559,6 @@
return content;
}
-#endif // GTEST_HAS_STD_STRING
-
#if GTEST_HAS_DEATH_TEST
// A copy of all command line arguments. Set by InitGoogleTest().
@@ -540,12 +569,14 @@
#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
@@ -555,7 +586,7 @@
(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]));
}
@@ -609,7 +640,7 @@
// 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());
+ const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == NULL ?
default_value : strcmp(string_value, "0") != 0;
}
@@ -619,7 +650,7 @@
// 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;
@@ -641,7 +672,7 @@
// 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;
}
Modified: llvm/trunk/utils/unittest/googletest/gtest-test-part.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest-test-part.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest-test-part.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest-test-part.cc Wed Jun 2 17:02:11 2010
@@ -44,6 +44,8 @@
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,55 @@
// 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;
+ 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;
}
// Constructs an empty TestPartResultArray.
TestPartResultArray::TestPartResultArray()
- : list_(new internal::List<TestPartResult>) {
+ : array_(new internal::Vector<TestPartResult>) {
}
// Destructs a TestPartResultArray.
TestPartResultArray::~TestPartResultArray() {
- delete list_;
+ delete array_;
}
// Appends a TestPartResult to the array.
void TestPartResultArray::Append(const TestPartResult& result) {
- list_->PushBack(result);
+ array_->PushBack(result);
}
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
if (index < 0 || index >= size()) {
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
- internal::abort();
- }
-
- const internal::ListNode<TestPartResult>* p = list_->Head();
- for (int i = 0; i < index; i++) {
- p = p->next();
+ internal::posix::Abort();
}
- return p->element();
+ return array_->GetElement(index);
}
// Returns the number of TestPartResult objects in the array.
int TestPartResultArray::size() const {
- return list_->size();
+ return 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_);
}
Modified: llvm/trunk/utils/unittest/googletest/gtest-typed-test.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest-typed-test.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest-typed-test.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest-typed-test.cc Wed Jun 2 17:02:11 2010
@@ -86,7 +86,7 @@
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors_str.c_str());
fflush(stderr);
- abort();
+ posix::Abort();
}
return registered_tests;
Modified: llvm/trunk/utils/unittest/googletest/gtest.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/gtest.cc?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/gtest.cc (original)
+++ llvm/trunk/utils/unittest/googletest/gtest.cc Wed Jun 2 17:02:11 2010
@@ -39,10 +39,11 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <wchar.h>
#include <wctype.h>
+#include <ostream>
+
#if GTEST_OS_LINUX
// TODO(kenton at google.com): Use autoconf to detect availability of
@@ -71,7 +72,7 @@
// On z/OS we additionally need strings.h for strcasecmp.
#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
@@ -82,7 +83,7 @@
#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 at google.com): Use autoconf to detect availability of
// gettimeofday().
@@ -91,7 +92,7 @@
// supports these. consider using them instead.
#define GTEST_HAS_GETTIMEOFDAY_ 1
#include <sys/time.h> // NOLINT
-#endif // defined(__MINGW__) || defined(__MINGW32__)
+#endif // GTEST_OS_WINDOWS_MINGW
// cpplint thinks that the header is already included, so we want to
// silence it.
@@ -125,8 +126,6 @@
#undef GTEST_IMPLEMENTATION_
#if GTEST_OS_WINDOWS
-#define fileno _fileno
-#define isatty _isatty
#define vsnprintf _vsnprintf
#endif // GTEST_OS_WINDOWS
@@ -186,7 +185,7 @@
"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,
@@ -214,16 +213,33 @@
GTEST_DEFINE_bool_(
print_time,
- internal::BoolFromGTestEnv("print_time", false),
+ 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),
@@ -231,11 +247,6 @@
"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.");
-
-GTEST_DEFINE_bool_(
throw_on_failure,
internal::BoolFromGTestEnv("throw_on_failure", false),
"When this flag is specified, a failed assertion will throw an exception "
@@ -244,6 +255,25 @@
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;
+}
+
// g_help_flag is true iff the --help flag or an equivalent form is
// specified on the command line.
static bool g_help_flag = false;
@@ -259,16 +289,14 @@
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 internal::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 (int i = 0; i < case_list.size(); i++) {
+ sum += (case_list.GetElement(i)->*method)();
}
return sum;
}
@@ -290,16 +318,22 @@
}
// 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.
@@ -317,11 +351,11 @@
FilePath GetCurrentExecutableName() {
FilePath result;
-#if defined(_WIN32_WCE) || 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();
}
@@ -434,7 +468,7 @@
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'
@@ -465,46 +499,6 @@
} // 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.
@@ -526,7 +520,7 @@
}
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);
@@ -539,7 +533,7 @@
// 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 {
@@ -580,11 +574,11 @@
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"
@@ -619,7 +613,7 @@
// substring the failure message should contain.
SingleFailureChecker:: SingleFailureChecker(
const TestPartResultArray* results,
- TestPartResultType type,
+ TestPartResult::Type type,
const char* substr)
: results_(results),
type_(type),
@@ -639,7 +633,7 @@
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(
@@ -737,11 +731,13 @@
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;
@@ -806,16 +802,7 @@
return NULL;
} else {
char* const clone = new char[length + 1];
- // MSVC 8 deprecates strncpy(), so we want to suppress warning
- // 4996 (deprecated function) there.
-#if 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;
}
@@ -829,7 +816,7 @@
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
@@ -863,7 +850,7 @@
return ansi;
}
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
// Compares two C strings. Returns true iff they have the same content.
//
@@ -882,17 +869,17 @@
// 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';
@@ -1337,7 +1324,7 @@
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
@@ -1361,7 +1348,7 @@
--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;
@@ -1455,17 +1442,8 @@
// 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.
-#if 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);
-#if 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.
}
@@ -1603,15 +1581,11 @@
// 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;
-
-#if 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
@@ -1648,24 +1622,30 @@
#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;
-}
-
// 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*
@@ -1673,12 +1653,12 @@
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.
@@ -1686,37 +1666,12 @@
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
@@ -1726,28 +1681,38 @@
// 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.
-#if 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
@@ -1798,11 +1763,15 @@
return msg.GetString();
}
+} // namespace internal
+
// class TestResult
// Creates an empty TestResult.
TestResult::TestResult()
- : death_test_count_(0),
+ : test_part_results_(new internal::Vector<TestPartResult>),
+ test_properties_(new internal::Vector<TestProperty>),
+ death_test_count_(0),
elapsed_time_(0) {
}
@@ -1810,9 +1779,28 @@
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 {
+ return test_part_results_->GetElement(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 {
+ return test_properties_->GetElement(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_->PushBack(test_part_result);
}
// Adds a test property to the list. If a property with the same key as the
@@ -1822,21 +1810,21 @@
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_);
+ TestProperty* const property_with_matching_key =
+ test_properties_->FindIf(
+ internal::TestPropertyKeyIs(test_property.key()));
+ if (property_with_matching_key == NULL) {
+ test_properties_->PushBack(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(): "
@@ -1850,49 +1838,51 @@
// 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 test_part_results_->CountIf(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 test_part_results_->CountIf(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 test_part_results_->size();
}
-} // namespace internal
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+ return test_properties_->size();
+}
// class Test
@@ -1932,6 +1922,22 @@
RecordProperty(key, value_message.GetString().c_str());
}
+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.
@@ -1942,15 +1948,8 @@
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
@@ -1966,7 +1965,7 @@
// 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().GetElement(0)->impl();
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
const char* const first_test_name = first_test_info->name();
@@ -2028,8 +2027,8 @@
if (!HasSameFixtureClass()) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
-#if 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();
@@ -2060,7 +2059,7 @@
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();
@@ -2075,7 +2074,7 @@
// failed.
impl->os_stack_trace_getter()->UponLeavingGTest();
TearDown();
-#endif // GTEST_OS_WINDOWS
+#endif // GTEST_HAS_SEH
}
@@ -2084,6 +2083,12 @@
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
@@ -2181,8 +2186,11 @@
// 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.
@@ -2219,17 +2227,6 @@
} // 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
@@ -2253,17 +2250,16 @@
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 GTEST_OS_WINDOWS && !defined(__MINGW32__)
- // We are on Windows.
+#if GTEST_HAS_SEH
+ // Catch SEH-style exceptions.
Test* test = NULL;
__try {
@@ -2275,7 +2271,7 @@
"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
@@ -2284,7 +2280,7 @@
// 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.
@@ -2300,7 +2296,7 @@
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.
@@ -2347,27 +2343,39 @@
Test::TearDownTestCaseFunc tear_down_tc)
: name_(name),
comment_(comment),
+ test_info_list_(new internal::Vector<TestInfo*>),
+ test_indices_(new internal::Vector<int>),
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>);
+}
- // 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.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+ const int index = test_indices_->GetElementOr(i, -1);
+ return index < 0 ? NULL : test_info_list_->GetElement(index);
+}
+
+// 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 = test_indices_->GetElementOr(i, -1);
+ return index < 0 ? NULL : test_info_list_->GetElement(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_indices_->PushBack(test_indices_->size());
}
// Runs every test in this TestCase.
@@ -2377,20 +2385,21 @@
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);
}
@@ -2399,16 +2408,39 @@
test_info_list_->ForEach(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) {
+ test_indices_->Shuffle(random);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+ for (int i = 0; i < test_indices_->size(); i++) {
+ test_indices_->GetMutableElement(i) = i;
+ }
+}
// Formats a countable noun. Depending on its quantity, either the
// singular form or the plural form is used. e.g.
@@ -2432,17 +2464,17 @@
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
@@ -2464,10 +2496,22 @@
}
// Prints a TestPartResult.
-static void PrintTestPartResult(
- const TestPartResult& test_part_result) {
- printf("%s\n", PrintTestPartResultToString(test_part_result).c_str());
+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
@@ -2481,7 +2525,7 @@
COLOR_YELLOW
};
-#if 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) {
@@ -2506,7 +2550,7 @@
};
}
-#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) {
@@ -2519,10 +2563,12 @@
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
@@ -2545,13 +2591,13 @@
va_list args;
va_start(args, fmt);
-#if defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
const bool use_color = false;
#else
static const bool in_color_mode =
- ShouldUseColor(isatty(fileno(stdout)) != 0);
+ ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
-#endif // defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
// The '!= 0' comparison is necessary to satisfy MSVC 7.1.
if (!use_color) {
@@ -2560,7 +2606,7 @@
return;
}
-#if 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.
@@ -2578,48 +2624,48 @@
printf("\033[0;3%sm", GetAnsiColorCode(color));
vprintf(fmt, args);
printf("\033[m"); // Resets the terminal to default.
-#endif // GTEST_OS_WINDOWS && !defined(_WIN32_WCE)
+#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
va_end(args);
}
-} // namespace internal
-
-using internal::ColoredPrintf;
-using internal::COLOR_DEFAULT;
-using internal::COLOR_RED;
-using internal::COLOR_GREEN;
-using internal::COLOR_YELLOW;
-
-// This class implements the UnitTestEventListenerInterface interface.
+// 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.
@@ -2631,164 +2677,160 @@
if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
ColoredPrintf(COLOR_YELLOW,
"Note: This is test shard %s of %s.\n",
- internal::GetEnv(kTestShardIndex),
- internal::GetEnv(kTestTotalShards));
+ 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();
+ 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.
@@ -2804,81 +2846,129 @@
// 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.
+ 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() {
+ for (int i = 0; i < listeners_.size(); i++) {
+ delete listeners_.GetElement(i);
}
}
-void UnitTestEventsRepeater::AddListener(
- UnitTestEventListenerInterface *listener) {
+void TestEventRepeater::Append(TestEventListener *listener) {
listeners_.PushBack(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 at google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+ for (int i = 0; i < listeners_.size(); ++i) {
+ if (listeners_.GetElement(i) == listener) {
+ listeners_.Erase(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 (int i = 0; i < listeners_.size(); i++) { \
+ listeners_.GetElement(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_.GetElement(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 (int i = 0; i < listeners_.size(); i++) {
+ listeners_.GetElement(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_.GetElement(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
@@ -2896,39 +2986,41 @@
// 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); }
- // 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 CDATA section, escaping invalid CDATA sequences as needed.
+ static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+ // 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);
};
@@ -2944,23 +3036,14 @@
}
// 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.
-#if 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.
@@ -2995,8 +3078,7 @@
// 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) {
@@ -3026,7 +3108,7 @@
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;
}
@@ -3038,13 +3120,28 @@
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>
@@ -3053,9 +3150,7 @@
// <-- individual assertion failures
// </testcase>
// </testsuite>
-// </testsuite>
-
-namespace internal {
+// </testsuites>
// Formats the given time in milliseconds as seconds. The returned
// C-string is owned by this function and cannot be released by the
@@ -3067,104 +3162,112 @@
return str.c_str();
}
-} // namespace internal
+// 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, next_segment - segment);
+ *stream << "]]>]]><![CDATA[";
+ segment = next_segment + strlen("]]>");
+ } else {
+ *stream << segment;
+ break;
+ }
+ }
+ *stream << "]]>";
+}
// 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()));
+ 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()));
+ 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()) << "\"";
}
@@ -3173,8 +3276,6 @@
// End XmlUnitTestResultPrinter
-namespace internal {
-
// Class ScopedTrace
// Pushes the given source file location and message onto a per-thread
@@ -3221,6 +3322,81 @@
} // 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
@@ -3237,13 +3413,88 @@
// 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
@@ -3275,7 +3526,7 @@
class GoogleTestFailureException : public ::std::runtime_error {
public:
explicit GoogleTestFailureException(const TestPartResult& failure)
- : runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+ : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
};
#endif
@@ -3284,7 +3535,7 @@
// 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,
@@ -3296,12 +3547,11 @@
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;
+ for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
+ const internal::TraceInfo& trace =
+ impl_->gtest_trace_stack()->GetElement(i);
+ msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+ << " " << trace.message;
}
}
@@ -3315,14 +3565,21 @@
impl_->GetTestPartResultReporterForCurrentThread()->
ReportTestPartResult(result);
- if (result_type != TPRT_SUCCESS) {
- // gunit_break_on_failure takes precedence over
- // gunit_throw_on_failure. This allows a user to set the latter
+ 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
*static_cast<int*>(NULL) = 1;
+#endif // GTEST_OS_WINDOWS
} else if (GTEST_FLAG(throw_on_failure)) {
#if GTEST_HAS_EXCEPTIONS
throw GoogleTestFailureException(result);
@@ -3339,7 +3596,7 @@
// 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);
}
@@ -3349,36 +3606,37 @@
// We don't protect this under mutex_, as we only support calling it
// from the main thread.
int UnitTest::Run() {
-#if GTEST_OS_WINDOWS && !defined(__MINGW32__)
+#if GTEST_HAS_SEH
+ // Catch SEH-style exceptions.
const bool in_death_test_child_process =
- internal::GTEST_FLAG(internal_run_death_test).GetLength() > 0;
+ 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) {
- // 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 !defined(_WIN32_WCE)
+#if !GTEST_OS_WINDOWS_MOBILE
// SetErrorMode doesn't exist on CE.
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
-#endif // _WIN32_WCE
+#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.
-#if _MSC_VER >= 1400
+ //
// 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.
@@ -3388,7 +3646,7 @@
_set_abort_behavior(
0x0, // Clear the following flags:
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
-#endif // _MSC_VER >= 1400
+#endif
}
__try {
@@ -3400,11 +3658,10 @@
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
@@ -3429,6 +3686,9 @@
return impl_->current_test_info();
}
+// 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.
@@ -3483,17 +3743,18 @@
&default_global_test_part_result_reporter_),
per_thread_test_part_result_reporter_(
&default_per_thread_test_part_result_reporter_),
- test_cases_(),
#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),
+ 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),
@@ -3501,6 +3762,7 @@
#else
elapsed_time_(0) {
#endif // GTEST_HAS_DEATH_TEST
+ listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
}
UnitTestImpl::~UnitTestImpl() {
@@ -3510,12 +3772,58 @@
// Deletes every Environment.
environments_.ForEach(internal::Delete<Environment>);
- // Deletes the current test result printer.
- delete result_printer_;
-
delete os_stack_trace_getter_;
}
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+ if (internal_run_death_test_flag_.get() != NULL)
+ listeners()->SuppressEventForwarding();
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+ const String& output_format = UnitTestOptions::GetOutputFormat();
+ if (output_format == "xml") {
+ listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+ } else if (output_format != "") {
+ printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+ output_format.c_str());
+ fflush(stdout);
+ }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests. Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+ // Ensures that this function does not execute more than once.
+ if (!post_flag_parse_init_performed_) {
+ post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+ InitDeathTestSubprocessControlInfo();
+ SuppressTestEventsIfInSubprocess();
+#endif // GTEST_HAS_DEATH_TEST
+
+ // Registers parameterized tests. This makes parameterized tests
+ // available to the UnitTest reflection API without running
+ // RUN_ALL_TESTS.
+ RegisterParameterizedTests();
+
+ // Configures listeners for XML output. This makes it possible for users
+ // to shut down the default XML output before invoking RUN_ALL_TESTS.
+ ConfigureXmlOutput();
+ }
+}
+
// A predicate that checks the name of a TestCase against a known
// value.
//
@@ -3540,7 +3848,9 @@
};
// 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:
//
@@ -3552,34 +3862,34 @@
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));
+ TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name));
+
+ if (test_case != NULL)
+ 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.
+ test_cases_.Insert(new_test_case, ++last_death_test_case_);
+ } else {
+ // No. Appends to the end of the list.
+ test_cases_.PushBack(new_test_case);
}
- // Returns the TestCase found.
- return node->element();
+ test_case_indices_.PushBack(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 Vector::ForEach() method.
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
@@ -3589,7 +3899,7 @@
// 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.
@@ -3606,31 +3916,23 @@
if (g_help_flag)
return 0;
- RegisterParameterizedTests();
+ // 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();
- // Lists all the tests and exits if the --gtest_list_tests
- // flag was specified.
- if (GTEST_FLAG(list_tests)) {
- ListAllTests();
- return 0;
- }
-
// True iff we are in a subprocess for running a thread-safe-style
// death test.
bool in_subprocess_for_death_test = false;
#if GTEST_HAS_DEATH_TEST
- internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
#endif // GTEST_HAS_DEATH_TEST
- UnitTestEventListenerInterface * const printer = result_printer();
-
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
in_subprocess_for_death_test);
@@ -3640,57 +3942,92 @@
? 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_);
+ repeater->OnEnvironmentsSetUpStart(*parent_);
environments_.ForEach(SetUpEnvironment);
- printer->OnGlobalSetUpEnd(parent_);
+ 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 i = 0; i < total_test_case_count(); i++) {
+ GetMutableTestCase(i)->Run();
+ }
}
// Tears down all environments in reverse order afterwards.
- printer->OnGlobalTearDownStart(parent_);
+ repeater->OnEnvironmentsTearDownStart(*parent_);
environments_in_reverse_order_.ForEach(TearDownEnvironment);
- printer->OnGlobalTearDownEnd(parent_);
+ 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;
}
@@ -3700,17 +4037,9 @@
// 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 = GetEnv(kTestShardStatusFile);
+ const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
if (test_shard_file != NULL) {
-#ifdef _MSC_VER // MSVC 8 deprecates fopen().
-#pragma warning(push) // Saves the current warning state.
-#pragma warning(disable:4996) // Temporarily disables warning on
- // deprecated functions.
-#endif
- FILE* const file = fopen(test_shard_file, "w");
-#ifdef _MSC_VER
-#pragma warning(pop) // Restores the warning state.
-#endif
+ 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\" "
@@ -3775,7 +4104,7 @@
// 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 = GetEnv(var);
+ const char* str_val = posix::GetEnv(var);
if (str_val == NULL) {
return default_val;
}
@@ -3815,19 +4144,13 @@
// this shard.
int num_runnable_tests = 0;
int num_selected_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();
+ for (int i = 0; i < test_cases_.size(); i++) {
+ TestCase* const test_case = test_cases_.GetElement(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 (int j = 0; j < test_case->test_info_list().size(); j++) {
+ TestInfo* const test_info = test_case->test_info_list().GetElement(j);
const String test_name(test_info->name());
// A test is disabled if test case name or test name matches
// kDisableTestFilter.
@@ -3838,10 +4161,14 @@
kDisableTestFilter);
test_info->impl()->set_is_disabled(is_disabled);
- const bool is_runnable =
- (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+ const bool matches_filter =
internal::UnitTestOptions::FilterMatchesTest(test_case_name,
test_name);
+ test_info->impl()->set_matches_filter(matches_filter);
+
+ const bool is_runnable =
+ (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+ matches_filter;
const bool is_selected = is_runnable &&
(shard_tests == IGNORE_SHARDING_PROTOCOL ||
@@ -3858,71 +4185,27 @@
return num_selected_tests;
}
-// 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();
-
- // Prints the test case name following by an indented list of test nodes.
- printf("%s.\n", test_case->name());
-
- 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();
-
- printf(" %s\n", test_info->name());
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+ for (int i = 0; i < test_cases_.size(); i++) {
+ const TestCase* const test_case = test_cases_.GetElement(i);
+ bool printed_test_case_name = false;
+
+ for (int j = 0; j < test_case->test_info_list().size(); j++) {
+ const TestInfo* const test_info =
+ test_case->test_info_list().GetElement(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());
+ }
}
}
fflush(stdout);
}
-// Sets the unit test result printer.
-//
-// Does nothing if the input and the current printer object are the
-// same; otherwise, deletes the old printer object and makes the
-// input the current printer.
-void UnitTestImpl::set_result_printer(
- UnitTestEventListenerInterface* result_printer) {
- if (result_printer_ != result_printer) {
- delete result_printer_;
- result_printer_ = result_printer;
- }
-}
-
-// Returns the current unit test result printer if it is not NULL;
-// otherwise, creates an appropriate result printer, makes it the
-// current printer, and returns it.
-UnitTestEventListenerInterface* UnitTestImpl::result_printer() {
- if (result_printer_ != NULL) {
- return result_printer_;
- }
-
-#if GTEST_HAS_DEATH_TEST
- if (internal_run_death_test_flag_.get() != NULL) {
- result_printer_ = new NullUnitTestResultPrinter;
- return result_printer_;
- }
-#endif // GTEST_HAS_DEATH_TEST
-
- UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater;
- const String& output_format = internal::UnitTestOptions::GetOutputFormat();
- if (output_format == "xml") {
- repeater->AddListener(new XmlUnitTestResultPrinter(
- internal::UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
- } else if (output_format != "") {
- printf("WARNING: unrecognized output format \"%s\" ignored.\n",
- output_format.c_str());
- fflush(stdout);
- }
- repeater->AddListener(new PrettyUnitTestResultPrinter);
- result_printer_ = repeater;
- return result_printer_;
-}
-
// Sets the OS stack trace getter.
//
// Does nothing if the input and the current OS stack trace getter are
@@ -3949,11 +4232,37 @@
// 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.
+ test_case_indices_.ShuffleRange(random(), 0, last_death_test_case_ + 1);
+
+ // Shuffles the non-death test cases.
+ test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1,
+ test_cases_.size());
+
+ // Shuffles the tests inside each test case.
+ for (int i = 0; i < test_cases_.size(); i++) {
+ test_cases_.GetElement(i)->ShuffleTests(random());
+ }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+ for (int i = 0; i < test_cases_.size(); i++) {
+ // Unshuffles the tests in each test case.
+ test_cases_.GetElement(i)->UnshuffleTests();
+ // Resets the index of each test case.
+ test_case_indices_.GetMutableElement(i) = i;
+ }
+}
+
// TestInfoImpl constructor. The new instance assumes ownership of the test
// factory object.
TestInfoImpl::TestInfoImpl(TestInfo* parent,
@@ -3971,6 +4280,7 @@
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),
+ matches_filter_(false),
factory_(factory) {
}
@@ -3989,15 +4299,11 @@
// 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);
-}
-
-// Returns the number of failed test parts in the given test result object.
-int GetFailedPartCount(const TestResult* result) {
- return result->failed_part_count();
+ return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
}
// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable
@@ -4006,11 +4312,13 @@
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 (atoi("42") == 36) // NOLINT
+ if (IsTrue(false))
throw ClassUniqueToAlwaysTrue();
#endif // GTEST_HAS_EXCEPTIONS
return true;
@@ -4029,7 +4337,7 @@
// 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();
+ const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
// Skips the flag name.
@@ -4165,20 +4473,31 @@
" matches any substring; ':' separates two patterns.\n"
" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests at 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 at 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 at Y|@Gno at Y|@Gauto at Y)@D\n"
" Enable/disable colored output. The default is @Gauto at D.\n"
-" - at G-" GTEST_FLAG_PREFIX_ "print_time at D\n"
-" Print the elapsed time of each test.\n"
+" - at G-" GTEST_FLAG_PREFIX_ "print_time=0 at D\n"
+" Don't print the elapsed time of each test.\n"
" @G--" GTEST_FLAG_PREFIX_ "output=xml at Y[@G:@YDIRECTORY_PATH at 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 at D defaults to @Gtest_details.xml at D.\n"
"\n"
-"Failure Behavior:\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast at Y|@Gthreadsafe at 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 at D\n"
" Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure at D\n"
@@ -4191,10 +4510,9 @@
"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests at D, you can alternatively set "
"the corresponding\n"
"environment variable of a flag (all letters in upper-case). For example, to\n"
-"print the elapsed time, you can either specify @G--" GTEST_FLAG_PREFIX_
- "print_time at D or set the\n"
-"@G" GTEST_FLAG_PREFIX_UPPER_ "PRINT_TIME at D environment variable to a "
- "non-zero value.\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+ "color=no at D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR at D environment variable to @Gno at 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"
@@ -4232,7 +4550,9 @@
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
+ ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
+ ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure))
) {
// Yes. Shift the remainder of the argv list left by one. Note
@@ -4295,6 +4615,7 @@
#endif // GTEST_HAS_DEATH_TEST
ParseGoogleTestFlagsOnly(argc, argv);
+ GetUnitTestImpl()->PostFlagParsingInit();
}
} // namespace internal
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest-death-test.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest-death-test.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-death-test.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-death-test.h Wed Jun 2 17:02:11 2010
@@ -181,6 +181,9 @@
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_;
};
@@ -242,10 +245,10 @@
#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
@@ -257,6 +260,24 @@
#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_
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h Wed Jun 2 17:02:11 2010
@@ -193,7 +193,7 @@
// 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 +201,7 @@
}
}
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
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest-param-test.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest-param-test.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-param-test.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-param-test.h Wed Jun 2 17:02:11 2010
@@ -146,10 +146,11 @@
#endif // 0
+#include <gtest/internal/gtest-port.h>
+#if !GTEST_OS_SYMBIAN
#include <utility>
-
-#include <gtest/internal/gtest-port.h>
+#endif
#if GTEST_HAS_PARAM_TEST
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest-spi.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest-spi.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-spi.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-spi.h Wed Jun 2 17:02:11 2010
@@ -97,12 +97,12 @@
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 @@
};\
::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 @@
};\
::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 @@
// 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_
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest-test-part.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest-test-part.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-test-part.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-test-part.h Wed Jun 2 17:02:11 2010
@@ -39,24 +39,24 @@
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 {
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,
+ TestPartResult(Type type,
const char* file_name,
int line_number,
const char* message)
@@ -68,7 +68,7 @@
}
// 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 +85,18 @@
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.
@@ -136,9 +136,8 @@
// 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_;
+ // Internally we use a Vector to implement the array.
+ internal::Vector<TestPartResult>* const array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
};
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/gtest.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/gtest.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/gtest.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest.h Wed Jun 2 17:02:11 2010
@@ -51,16 +51,6 @@
#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 <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-string.h>
@@ -126,6 +116,9 @@
// 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);
@@ -134,6 +127,9 @@
// 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);
@@ -148,7 +144,22 @@
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,
@@ -279,6 +290,13 @@
// 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
@@ -346,6 +364,155 @@
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* 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.
+ 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 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 internal::Vector<TestPartResult>& test_part_results() const {
+ return *test_part_results_;
+ }
+
+ // Gets the vector of TestProperties.
+ const internal::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
+ internal::scoped_ptr<internal::Vector<TestPartResult> > test_part_results_;
+ // The vector of TestProperties
+ internal::scoped_ptr<internal::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:
//
@@ -376,7 +543,9 @@
// 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
@@ -393,15 +562,16 @@
bool should_run() const;
// Returns the result of the test.
- const internal::TestResult* result() const;
+ const TestResult* result() const;
+
private:
#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,
@@ -410,6 +580,9 @@
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();
@@ -431,6 +604,141 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
};
+// A test case, which consists of a vector 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_; }
+
+ // 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.
+ internal::Vector<TestInfo*>& test_info_list() { return *test_info_list_; }
+
+ // Gets the (immutable) vector of TestInfos in this TestCase.
+ const internal::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.
+ const internal::scoped_ptr<internal::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.
+ const internal::scoped_ptr<internal::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).
@@ -462,7 +770,159 @@
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 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
@@ -479,33 +939,6 @@
// 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.
//
@@ -526,19 +959,107 @@
// or NULL if no test is running.
const TestInfo* current_test_info() const;
+ // 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();
@@ -929,16 +1450,38 @@
class 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);
};
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h Wed Jun 2 17:02:11 2010
@@ -39,10 +39,6 @@
#include <gtest/internal/gtest-internal.h>
-#if GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS
-#include <io.h>
-#endif // GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS
-
namespace testing {
namespace internal {
@@ -157,7 +153,7 @@
// 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, \
@@ -176,7 +172,7 @@
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
- GTEST_HIDE_UNREACHABLE_CODE_(statement); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
@@ -196,32 +192,24 @@
InternalRunDeathTestFlag(const String& file,
int line,
int index,
- int status_fd)
- : file_(file), line_(line), index_(index), status_fd_(status_fd) {}
+ int write_fd)
+ : file_(file), line_(line), index_(index), write_fd_(write_fd) {}
~InternalRunDeathTestFlag() {
- if (status_fd_ >= 0)
-// Suppress MSVC complaints about POSIX functions.
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable: 4996)
-#endif // _MSC_VER
- close(status_fd_);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
+ if (write_fd_ >= 0)
+ posix::Close(write_fd_);
}
String file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
- int status_fd() const { return status_fd_; }
+ int write_fd() const { return write_fd_; }
private:
String file_;
int line_;
int index_;
- int status_fd_;
+ int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
};
@@ -231,6 +219,53 @@
// 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
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h Wed Jun 2 17:02:11 2010
@@ -45,9 +45,12 @@
#error "It must not be included except by Google Test itself."
#endif // GTEST_IMPLEMENTATION_
+#ifndef _WIN32_WCE
#include <errno.h>
+#endif // !_WIN32_WCE
#include <stddef.h>
-#include <stdlib.h> // For strtoll/_strtoul64.
+#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
+#include <string.h> // For memmove.
#include <string>
@@ -84,9 +87,43 @@
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 kThrowOnFailureFlag[] = "throw_on_failure";
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis();
+
+// 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.
class GTestFlagSaver {
@@ -104,7 +141,9 @@
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);
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
}
@@ -121,7 +160,9 @@
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(throw_on_failure) = throw_on_failure_;
}
private:
@@ -138,7 +179,9 @@
String output_;
bool print_time_;
bool pretty_;
+ internal::Int32 random_seed_;
internal::Int32 repeat_;
+ bool shuffle_;
bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_;
@@ -196,176 +239,84 @@
// method. Assumes that 0 <= shard_index < total_shards.
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
-// List is a simple singly-linked list container.
+// Vector is an ordered container that supports random access to the
+// elements.
//
-// 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.
+// We cannot use std::vector, as Visual C++ 7.1's implementation of
+// STL has problems compiling when exceptions are disabled. There is
+// a hack to work around the problems, 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.
+// The element type must support copy constructor and operator=.
template <typename E> // E is the element type.
-class List {
+class Vector {
public:
-
- // Creates an empty list.
- List() : head_(NULL), last_(NULL), size_(0) {}
+ // Creates an empty Vector.
+ Vector() : elements_(NULL), capacity_(0), size_(0) {}
// D'tor.
- virtual ~List();
+ virtual ~Vector() { Clear(); }
- // Clears the list.
+ // Clears the Vector.
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();
+ if (elements_ != NULL) {
+ for (int i = 0; i < size_; i++) {
+ delete elements_[i];
}
- // 2. Resets the member variables.
- head_ = last_ = NULL;
- size_ = 0;
+ free(elements_);
+ elements_ = NULL;
+ capacity_ = 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 end of the Vector. A copy of the element
+ // is created using the copy constructor, and then stored in the
+ // Vector. Changes made to the element in the Vector doesn't affect
+ // the source object, and vice versa.
+ void PushBack(const E& element) { Insert(element, 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_++;
- }
- }
+ // Adds an element to the beginning of this Vector.
+ void PushFront(const E& element) { Insert(element, 0); }
- // Removes an element from the beginning of this list. If the
+ // Removes an element from the beginning of this Vector. 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.
+ // Returns true iff the vector wasn't empty before the operation.
bool PopFront(E* result) {
- if (size_ == 0) return false;
-
- if (result != NULL) {
- *result = head_->element_;
- }
+ if (size_ == 0)
+ return false;
- ListNode<E>* const old_head = head_;
- size_--;
- if (size_ == 0) {
- head_ = last_ = NULL;
- } else {
- head_ = head_->next_;
- }
- delete old_head;
+ if (result != NULL)
+ *result = GetElement(0);
+ Erase(0);
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;
+ // Inserts an element at the given index. It's the caller's
+ // responsibility to ensure that the given index is in the range [0,
+ // size()].
+ void Insert(const E& element, int index) {
+ GrowIfNeeded();
+ MoveElements(index, size_ - index, index + 1);
+ elements_[index] = new E(element);
size_++;
- if (node == last_) {
- last_ = new_node;
- }
+ }
- return new_node;
+ // Erases the element at the specified index, or aborts the program if the
+ // index is not in range [0, size()).
+ void Erase(int index) {
+ GTEST_CHECK_(0 <= index && index < size_)
+ << "Invalid Vector index " << index << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ delete elements_[index];
+ MoveElements(index + 1, size_ - index - 1, index);
+ size_--;
}
// Returns the number of elements that satisfy a given predicate.
@@ -374,10 +325,8 @@
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()) ) {
+ for (int i = 0; i < size_; i++) {
+ if (predicate(*(elements_[i]))) {
count++;
}
}
@@ -385,16 +334,14 @@
return count;
}
- // Applies a function/functor to each element in the list. The
+ // Applies a function/functor to each element in the Vector. 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());
+ for (int i = 0; i < size_; i++) {
+ functor(*(elements_[i]));
}
}
@@ -403,45 +350,139 @@
// 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;
+ const E* FindIf(P predicate) const {
+ for (int i = 0; i < size_; i++) {
+ if (predicate(*elements_[i])) {
+ return elements_[i];
}
}
-
return NULL;
}
template <typename P>
- ListNode<E> * FindIf(P predicate) {
- for ( ListNode<E> * node = Head();
- node != NULL;
- node = node->next() ) {
- if ( predicate(node->element() ) ) {
- return node;
+ E* FindIf(P predicate) {
+ for (int i = 0; i < size_; i++) {
+ if (predicate(*elements_[i])) {
+ return elements_[i];
}
}
-
return NULL;
}
- 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.
+ // Returns the i-th element of the Vector, or aborts the program if i
+ // is not in range [0, size()).
+ const E& GetElement(int i) const {
+ GTEST_CHECK_(0 <= i && i < size_)
+ << "Invalid Vector index " << i << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ return *(elements_[i]);
+ }
+
+ // Returns a mutable reference to the i-th element of the Vector, or
+ // aborts the program if i is not in range [0, size()).
+ E& GetMutableElement(int i) {
+ GTEST_CHECK_(0 <= i && i < size_)
+ << "Invalid Vector index " << i << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ return *(elements_[i]);
+ }
+
+ // Returns the i-th element of the Vector, or default_value if i is not
+ // in range [0, size()).
+ E GetElementOr(int i, E default_value) const {
+ return (i < 0 || i >= size_) ? default_value : *(elements_[i]);
+ }
+
+ // Swaps the i-th and j-th elements of the Vector. Crashes if i or
+ // j is invalid.
+ void Swap(int i, int j) {
+ GTEST_CHECK_(0 <= i && i < size_)
+ << "Invalid first swap element " << i << ": must be in range [0, "
+ << (size_ - 1) << "].";
+ GTEST_CHECK_(0 <= j && j < size_)
+ << "Invalid second swap element " << j << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ E* const temp = elements_[i];
+ elements_[i] = elements_[j];
+ elements_[j] = temp;
+ }
+
+ // Performs an in-place shuffle of a range of this Vector's nodes.
+ // '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.
+ void ShuffleRange(internal::Random* random, int begin, int end) {
+ 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);
+ Swap(selected, last_in_range);
+ }
+ }
- // We disallow copying List.
- GTEST_DISALLOW_COPY_AND_ASSIGN_(List);
-};
+ // Performs an in-place shuffle of this Vector's nodes.
+ void Shuffle(internal::Random* random) {
+ ShuffleRange(random, 0, size());
+ }
-// The virtual destructor of List.
-template <typename E>
-List<E>::~List() {
- Clear();
-}
+ // Returns a copy of this Vector.
+ Vector* Clone() const {
+ Vector* const clone = new Vector;
+ clone->Reserve(size_);
+ for (int i = 0; i < size_; i++) {
+ clone->PushBack(GetElement(i));
+ }
+ return clone;
+ }
+
+ private:
+ // Makes sure this Vector's capacity is at least the given value.
+ void Reserve(int new_capacity) {
+ if (new_capacity <= capacity_)
+ return;
+
+ capacity_ = new_capacity;
+ elements_ = static_cast<E**>(
+ realloc(elements_, capacity_*sizeof(elements_[0])));
+ }
+
+ // Grows the buffer if it is not big enough to hold one more element.
+ void GrowIfNeeded() {
+ if (size_ < capacity_)
+ return;
+
+ // Exponential bump-up is necessary to ensure that inserting N
+ // elements is O(N) instead of O(N^2). The factor 3/2 means that
+ // no more than 1/3 of the slots are wasted.
+ const int new_capacity = 3*(capacity_/2 + 1);
+ GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow?
+ << "Cannot grow a Vector with " << capacity_ << " elements already.";
+ Reserve(new_capacity);
+ }
+
+ // Moves the give consecutive elements to a new index in the Vector.
+ void MoveElements(int source, int count, int dest) {
+ memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0]));
+ }
+
+ E** elements_;
+ int capacity_; // The number of elements allocated for elements_.
+ int size_; // The number of elements; in the range [0, capacity_].
+
+ // We disallow copying Vector.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector);
+}; // class Vector
// A function for deleting an object. Handy for being used as a
// functor.
@@ -450,41 +491,6 @@
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.
@@ -505,96 +511,6 @@
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,
@@ -615,6 +531,12 @@
// 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(); }
@@ -631,18 +553,13 @@
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(); }
@@ -661,150 +578,18 @@
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
@@ -885,7 +670,7 @@
// 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();
@@ -1014,26 +799,29 @@
return failed_test_case_count() > 0 || ad_hoc_test_result()->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* GetTestCase(int i) const {
+ const int index = test_case_indices_.GetElementOr(i, -1);
+ return index < 0 ? NULL : test_cases_.GetElement(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* GetMutableTestCase(int i) {
+ const int index = test_case_indices_.GetElementOr(i, -1);
+ return index < 0 ? NULL : test_cases_.GetElement(index);
+ }
+
+ // 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.
- internal::TestResult* current_test_result();
+ TestResult* current_test_result();
// Returns the TestResult for the ad hoc test.
- const internal::TestResult* ad_hoc_test_result() const {
- return &ad_hoc_test_result_;
- }
-
- // Sets the unit test result printer.
- //
- // Does nothing if the input and the current printer object are the
- // same; otherwise, deletes the old printer object and makes the
- // input the current printer.
- void set_result_printer(UnitTestEventListenerInterface * result_printer);
-
- // Returns the current unit test result printer if it is not NULL;
- // otherwise, creates an appropriate result printer, makes it the
- // current printer, and returns it.
- UnitTestEventListenerInterface* result_printer();
+ const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
// Sets the OS stack trace getter.
//
@@ -1091,10 +879,8 @@
// 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(),
@@ -1158,35 +944,36 @@
// Returns the number of tests that should run.
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() {
+ internal::Vector<Environment*>* environments() { return &environments_; }
+ internal::Vector<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_; }
-
// Getters for the per-thread Google Test trace stack.
- internal::List<TraceInfo>* gtest_trace_stack() {
+ internal::Vector<TraceInfo>* gtest_trace_stack() {
return gtest_trace_stack_.pointer();
}
- const internal::List<TraceInfo>* gtest_trace_stack() const {
+ const internal::Vector<TraceInfo>* gtest_trace_stack() const {
return gtest_trace_stack_.pointer();
}
#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();
}
@@ -1196,9 +983,35 @@
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;
@@ -1224,13 +1037,21 @@
internal::ThreadLocal<TestPartResultReporterInterface*>
per_thread_test_part_result_reporter_;
- // The list of environments that need to be set-up/torn-down
+ // The vector 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_;
+ internal::Vector<Environment*> environments_;
+ internal::Vector<Environment*> environments_in_reverse_order_;
- internal::List<TestCase*> test_cases_; // The list of TestCases.
+ // The vector of TestCases in their original order. It owns the
+ // elements in the vector.
+ internal::Vector<TestCase*> test_cases_;
+
+ // 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.
+ internal::Vector<int> test_case_indices_;
#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
@@ -1241,13 +1062,13 @@
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
@@ -1264,13 +1085,11 @@
// 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,
@@ -1278,6 +1097,15 @@
// 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_;
@@ -1289,7 +1117,7 @@
#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<internal::Vector<TraceInfo> > gtest_trace_stack_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
}; // class UnitTestImpl
@@ -1325,7 +1153,7 @@
// Returns the message describing the last system error, regardless of the
// platform.
-String GetLastSystemErrorMessage();
+String GetLastErrnoDescription();
#if GTEST_OS_WINDOWS
// Provides leak-safe Windows kernel handle ownership.
@@ -1370,13 +1198,14 @@
char* end;
// BiggestConvertible is the largest integer type that system-provided
// string-to-number conversion routines can return.
-#if GTEST_OS_WINDOWS
+#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
+#endif // GTEST_OS_WINDOWS && !defined(__GNUC__)
const bool parse_success = *end == '\0' && errno == 0;
// TODO(vladl at google.com): Convert this to compile time assertion when it is
@@ -1392,6 +1221,26 @@
}
#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.
+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 Vector<testing::TestPartResult>& test_part_results(
+ const TestResult& test_result) {
+ return test_result.test_part_results();
+ }
+};
+
} // namespace internal
} // namespace testing
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-internal.h Wed Jun 2 17:02:11 2010
@@ -121,25 +121,20 @@
// 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.
+template <typename E> class Vector; // A generic vector.
// How many times InitGoogleTest() has been called.
extern int g_init_gtest_count;
@@ -231,13 +226,13 @@
// 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);
}
@@ -403,7 +398,7 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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
@@ -637,7 +636,7 @@
"REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
FormatFileLocation(file, line).c_str(), test_name, case_name);
fflush(stderr);
- abort();
+ posix::Abort();
}
defined_test_names_.insert(test_name);
return true;
@@ -746,8 +745,8 @@
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;
}
};
@@ -766,12 +765,37 @@
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
-// Returns the number of failed test parts in the given test result object.
-int GetFailedPartCount(const TestResult* result);
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
-// A helper for suppressing warnings on unreachable code in some macros.
+// Always returns true.
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 Random {
+ public:
+ static const UInt32 kMaxRange = 1u << 31;
+
+ explicit Random(UInt32 seed) : state_(seed) {}
+
+ 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
@@ -780,18 +804,18 @@
= ::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_HIDE_UNREACHABLE_CODE_(statement) \
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
if (::testing::internal::AlwaysTrue()) { statement; }
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
@@ -799,7 +823,7 @@
if (const char* gtest_msg = "") { \
bool gtest_caught_expected = false; \
try { \
- GTEST_HIDE_UNREACHABLE_CODE_(statement); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (expected_exception const&) { \
gtest_caught_expected = true; \
@@ -823,7 +847,7 @@
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const char* gtest_msg = "") { \
try { \
- GTEST_HIDE_UNREACHABLE_CODE_(statement); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (...) { \
gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
@@ -839,7 +863,7 @@
if (const char* gtest_msg = "") { \
bool gtest_caught_any = false; \
try { \
- GTEST_HIDE_UNREACHABLE_CODE_(statement); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (...) { \
gtest_caught_any = true; \
@@ -856,7 +880,7 @@
#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (boolexpr) \
+ if (::testing::internal::IsTrue(boolexpr)) \
; \
else \
fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected)
@@ -865,7 +889,7 @@
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const char* gtest_msg = "") { \
::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
- GTEST_HIDE_UNREACHABLE_CODE_(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" \
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h Wed Jun 2 17:02:11 2010
@@ -63,6 +63,9 @@
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 +81,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray2& other);
+
const T1 v1_;
const T2 v2_;
};
@@ -94,6 +100,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray3& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -112,6 +121,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray4& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -131,6 +143,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray5& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -152,6 +167,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray6& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -174,6 +192,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray7& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -198,6 +219,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray8& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -223,6 +247,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray9& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -249,6 +276,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray10& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -277,6 +307,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray11& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -307,6 +340,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray12& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -339,6 +375,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray13& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -372,6 +411,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray14& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -406,6 +448,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray15& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -443,6 +488,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray16& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -481,6 +529,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray17& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -520,6 +571,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray18& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -560,6 +614,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray19& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -602,6 +659,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray20& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -646,6 +706,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray21& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -691,6 +754,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray22& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -739,6 +805,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray23& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -788,6 +857,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray24& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -838,6 +910,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray25& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -890,6 +965,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray26& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -944,6 +1022,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray27& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -999,6 +1080,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray28& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1055,6 +1139,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray29& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1113,6 +1200,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray30& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1173,6 +1263,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray31& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1234,6 +1327,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray32& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1297,6 +1393,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray33& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1361,6 +1460,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray34& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1427,6 +1529,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray35& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1495,6 +1600,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray36& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1565,6 +1673,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray37& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1636,6 +1747,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray38& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1708,6 +1822,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray39& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1782,6 +1899,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray40& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1858,6 +1978,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray41& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -1935,6 +2058,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray42& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2013,6 +2139,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray43& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2093,6 +2222,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray44& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2174,6 +2306,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray45& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2257,6 +2392,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray46& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2343,6 +2481,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray47& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2430,6 +2571,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray48& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2518,6 +2662,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray49& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2607,6 +2754,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const ValueArray50& other);
+
const T1 v1_;
const T2 v2_;
const T3 v3_;
@@ -2757,6 +2907,9 @@
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 +2920,14 @@
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 +3035,9 @@
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 +3051,15 @@
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 +3182,9 @@
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 +3201,16 @@
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 +3345,9 @@
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 +3367,17 @@
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 +3527,9 @@
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 +3552,10 @@
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 +3563,7 @@
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 +3726,9 @@
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 +3754,10 @@
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 +3766,7 @@
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 +3944,9 @@
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 +3975,10 @@
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 +3988,7 @@
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 +4179,9 @@
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 +4213,10 @@
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 +4227,7 @@
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 +4431,9 @@
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 +4468,10 @@
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 +4483,7 @@
const ParamGenerator<T8> g8_;
const ParamGenerator<T9> g9_;
const ParamGenerator<T10> g10_;
-};
+}; // class CartesianProductGenerator10
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@@ -4302,9 +4506,12 @@
}
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 +4529,13 @@
}
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 +4555,14 @@
}
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 +4583,15 @@
}
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 +4615,16 @@
}
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 +4650,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder7& other);
+
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
@@ -4438,7 +4660,7 @@
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 +4689,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder8& other);
+
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
@@ -4475,7 +4700,7 @@
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 +4732,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder9& other);
+
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
@@ -4516,7 +4744,7 @@
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 +4778,9 @@
}
private:
+ // No implementation - assignment is unsupported.
+ void operator=(const CartesianProductHolder10& other);
+
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
@@ -4560,7 +4791,7 @@
const Generator8 g8_;
const Generator9 g9_;
const Generator10 g10_;
-};
+}; // class CartesianProductHolder10
#endif // GTEST_HAS_COMBINE
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h Wed Jun 2 17:02:11 2010
@@ -248,6 +248,9 @@
: 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 +266,9 @@
return end_index;
}
+ // No implementation - assignment is unsupported.
+ void operator=(const RangeGenerator& other);
+
const T begin_;
const T end_;
const IncrementT step_;
@@ -349,7 +355,10 @@
// 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 +492,8 @@
// 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.
}
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-port.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-port.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-port.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-port.h Wed Jun 2 17:02:11 2010
@@ -58,8 +58,15 @@
// 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.
// This header defines the following utilities:
//
@@ -70,7 +77,10 @@
// GTEST_OS_MAC - Mac OS X
// GTEST_OS_SOLARIS - Sun Solaris
// GTEST_OS_SYMBIAN - Symbian
-// GTEST_OS_WINDOWS - Windows
+// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
+// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
+// GTEST_OS_WINDOWS_MINGW - MinGW
+// GTEST_OS_WINODWS_MOBILE - Windows Mobile
// GTEST_OS_ZOS - z/OS
//
// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
@@ -96,8 +106,8 @@
//
// 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_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
//
@@ -147,9 +157,15 @@
// 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
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
#define GTEST_FLAG_PREFIX_ "gtest_"
@@ -167,14 +183,17 @@
// Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__
#define GTEST_OS_CYGWIN 1
-#elif __SYMBIAN32__
+#elif defined __SYMBIAN32__
#define GTEST_OS_SYMBIAN 1
-#elif defined _MSC_VER
-// TODO(kenton at 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.
+#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 1
#elif defined __linux__
@@ -185,35 +204,54 @@
#define GTEST_OS_SOLARIS 1
#elif defined(__HAIKU__)
#define GTEST_OS_HAIKU
-#endif // _MSC_VER
+#endif // __CYGWIN__
-#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
+#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
+ GTEST_OS_SOLARIS
// 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 <unistd.h> // NOLINT
+
#define GTEST_USES_POSIX_RE 1
+#elif GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+#include <direct.h> // NOLINT
+#include <io.h> // NOLINT
+#endif
+
+// <regex.h> is not available on Windows. Use our own simple regex
+// implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
#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
+#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
+ // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS
// Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0
// otherwise.
-#ifdef _MSC_VER // Compiled by MSVC?
+#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 // MSVC uses this macro to enable exceptions.
+#ifndef _HAS_EXCEPTIONS
#define _HAS_EXCEPTIONS 1
#endif // _HAS_EXCEPTIONS
#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
-#else // The compiler is not MSVC.
+#else // The compiler is not MSVC or C++Builder.
// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For
// other compilers, we assume exceptions are disabled to be
// conservative.
@@ -222,7 +260,7 @@
#else
#define GTEST_HAS_EXCEPTIONS 0
#endif // defined(__GNUC__) && __EXCEPTIONS
-#endif // _MSC_VER
+#endif // defined(_MSC_VER) || defined(__BORLANDC__)
// Determines whether ::std::string and ::string are available.
@@ -325,35 +363,80 @@
#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.
+// 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+ is the only
+// mainstream compiler that comes with a TR1 tuple implementation.
+// MSVC 2008 (9.0) provides TR1 tuple in a 323 MB Feature Pack
+// download, which we cannot assume the user has. MSVC 2010 isn't
+// released yet.
#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
-#define GTEST_HAS_TR1_TUPLE 1
+#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 // defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+
+#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>
+#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__
+#endif // GTEST_USE_OWN_TR1_TUPLE
+
#endif // GTEST_HAS_TR1_TUPLE
// Determines whether clone(2) is supported.
@@ -379,12 +462,11 @@
// (this is covered by GTEST_HAS_STD_STRING guard).
// 3. 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_HAS_STD_STRING && (GTEST_OS_LINUX || \
- GTEST_OS_MAC || \
- GTEST_OS_CYGWIN || \
- (GTEST_OS_WINDOWS && _MSC_VER >= 1400))
+#if GTEST_HAS_STD_STRING && \
+ (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
+ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW)
#define GTEST_HAS_DEATH_TEST 1
-#include <vector>
+#include <vector> // NOLINT
#endif
// Determines whether to support value-parameterized tests.
@@ -430,7 +512,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:
@@ -438,6 +520,9 @@
// 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
@@ -461,6 +546,22 @@
#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
+
namespace testing {
class Message;
@@ -479,6 +580,10 @@
typedef ::std::strstream StrStream;
#endif // GTEST_HAS_STD_STRING
+// A helper for suppressing warnings on constant condition. It just
+// returns 'condition'.
+bool IsTrue(bool condition);
+
// Defines scoped_ptr.
// This implementation of scoped_ptr is PARTIAL - it only contains
@@ -501,7 +606,7 @@
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;
@@ -582,7 +687,8 @@
};
// 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.
@@ -593,13 +699,27 @@
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 GTestLog {
+ public:
+ GTestLog(GTestLogSeverity severity, const char* file, int line);
-#define GTEST_LOG_(severity, msg)\
- ::testing::internal::GTestLog(\
- ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \
- (::testing::Message() << (msg)).GetString().c_str())
+ // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+ ~GTestLog();
+
+ ::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); }
@@ -608,10 +728,8 @@
// CaptureStderr - starts capturing stderr.
// GetCapturedStderr - stops capturing stderr and returns the captured string.
-#if GTEST_HAS_STD_STRING
void CaptureStderr();
-::std::string GetCapturedStderr();
-#endif // GTEST_HAS_STD_STRING
+String GetCapturedStderr();
#if GTEST_HAS_DEATH_TEST
@@ -661,9 +779,9 @@
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; }
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount();
// The above synchronization primitives have dummy implementations.
// Therefore Google Test is not thread-safe.
@@ -704,18 +822,142 @@
#if GTEST_OS_WINDOWS
#define GTEST_PATH_SEP_ "\\"
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
#else
#define GTEST_PATH_SEP_ "/"
+typedef long long BiggestInt; // NOLINT
#endif // GTEST_OS_WINDOWS
-// Defines BiggestInt as the biggest signed integer type the compiler
-// supports.
+// 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 __int64 BiggestInt;
+
+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 long long BiggestInt; // NOLINT
+
+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__)
+ // 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.
@@ -786,32 +1028,6 @@
// 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 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
@@ -826,38 +1042,12 @@
// 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) \
+ if (::testing::internal::IsTrue(condition)) \
; \
else \
- ::testing::internal::GTestCheckProvider(\
- #condition, __FILE__, __LINE__).GetStream()
+ GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
// Macro for referencing flags.
#define GTEST_FLAG(name) FLAGS_gtest_##name
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-string.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-string.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-string.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-string.h Wed Jun 2 17:02:11 2010
@@ -80,19 +80,6 @@
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 +98,7 @@
// 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 +187,29 @@
// 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* c_str) { // NOLINT
+ if (c_str == NULL) {
+ c_str_ = NULL;
+ length_ = 0;
+ } else {
+ ConstructNonNull(c_str, strlen(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 length) {
+ ConstructNonNull(buffer, 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.
@@ -228,21 +222,23 @@
// 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_); }
+ operator ::std::string() const { return ::std::string(c_str(), length()); }
#endif // GTEST_HAS_STD_STRING
#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 @@
// 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* c_str) const { return Compare(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* c_str) const { return !(*this == 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,45 +265,66 @@
// 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* c_str) { return *this = String(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:
+ // 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 length) {
+ char* const str = new char[length + 1];
+ memcpy(str, buffer, length);
+ str[length] = '\0';
+ c_str_ = str;
+ length_ = length;
+ }
+
const char* c_str_;
-};
+ size_t length_;
+}; // class String
-// 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());
+// 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'
Added: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h?rev=105353&view=auto
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h (added)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h Wed Jun 2 17:02:11 2010
@@ -0,0 +1,966 @@
+// 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 at 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.
+#if defined(__SYMBIAN32__)
+#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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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() {}
+
+ 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_
Modified: llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h?rev=105353&r1=105352&r2=105353&view=diff
==============================================================================
--- llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h (original)
+++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h Wed Jun 2 17:02:11 2010
@@ -47,9 +47,11 @@
#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__
+#endif // __GLIBCXX__
#include <typeinfo>
@@ -74,7 +76,7 @@
#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 @@
return name_str;
#else
return name;
-#endif // __GNUC__
+#endif // __GLIBCXX__
#else
return "<type>";
More information about the llvm-commits
mailing list