aboutsummaryrefslogtreecommitdiffstats
path: root/gtest/src
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2010-05-29 13:00:38 -0700
committerWink Saville <wink@google.com>2010-05-29 13:00:38 -0700
commitd0332953cda33fb4f8e24ebff9c49159b69c43d6 (patch)
tree81612e8b12f590310aeb0ebf1da37b304eb7baa6 /gtest/src
parentede38fe9b9f93888e6e41afc7abb09525f44da95 (diff)
downloadexternal_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.zip
external_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.tar.gz
external_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.tar.bz2
Add protobuf 2.3.0 sources
This is the contents of protobuf-2.3.0.tar.bz2 from http://code.google.com/p/protobuf/downloads/list. Change-Id: Idfde09ce7ef5ac027b07ee83f2674fbbed5c30b2
Diffstat (limited to 'gtest/src')
-rw-r--r--gtest/src/gtest-death-test.cc57
-rw-r--r--gtest/src/gtest-filepath.cc47
-rw-r--r--gtest/src/gtest-internal-inl.h176
-rw-r--r--gtest/src/gtest-port.cc51
-rw-r--r--gtest/src/gtest-test-part.cc12
-rw-r--r--gtest/src/gtest.cc1023
6 files changed, 821 insertions, 545 deletions
diff --git a/gtest/src/gtest-death-test.cc b/gtest/src/gtest-death-test.cc
index 02ce48d..106b01c 100644
--- a/gtest/src/gtest-death-test.cc
+++ b/gtest/src/gtest-death-test.cc
@@ -220,12 +220,12 @@ void DeathTestAbort(const String& message) {
// 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
@@ -241,11 +241,11 @@ void DeathTestAbort(const String& message) {
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 in errno.
String GetLastErrnoDescription() {
@@ -269,13 +269,11 @@ static void FailFromInternalError(int fd) {
} while (num_read == -1 && errno == EINTR);
if (num_read == 0) {
- GTEST_LOG_(FATAL, error);
+ GTEST_LOG_(FATAL) << error.GetString();
} else {
const int last_error = errno;
- const String message = GetLastErrnoDescription();
- GTEST_LOG_(FATAL,
- Message() << "Error while reading death test internal: "
- << message << " [" << last_error << "]");
+ GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+ << GetLastErrnoDescription() << " [" << last_error << "]";
}
}
@@ -397,15 +395,13 @@ void DeathTestImpl::ReadAndInterpretStatusByte() {
FailFromInternalError(read_fd()); // Does not return.
break;
default:
- GTEST_LOG_(FATAL,
- Message() << "Death test child process reported "
- << "unexpected status byte ("
- << static_cast<unsigned int>(flag) << ")");
+ GTEST_LOG_(FATAL) << "Death test child process reported "
+ << "unexpected status byte ("
+ << static_cast<unsigned int>(flag) << ")";
}
} else {
- GTEST_LOG_(FATAL,
- Message() << "Read from death test child process failed: "
- << GetLastErrnoDescription());
+ GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+ << GetLastErrnoDescription();
}
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
set_read_fd(-1);
@@ -469,7 +465,8 @@ bool DeathTestImpl::Passed(bool status_ok) {
break;
case DIED:
if (status_ok) {
- if (RE::PartialMatch(error_message.c_str(), *regex())) {
+ const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+ if (matched) {
success = true;
} else {
buffer << " Result: died but not with expected error.\n"
@@ -483,8 +480,8 @@ bool DeathTestImpl::Passed(bool status_ok) {
break;
case IN_PROGRESS:
default:
- GTEST_LOG_(FATAL,
- "DeathTest::Passed somehow called before conclusion of test");
+ GTEST_LOG_(FATAL)
+ << "DeathTest::Passed somehow called before conclusion of test";
}
DeathTest::set_last_death_test_message(buffer.GetString());
@@ -584,8 +581,8 @@ int WindowsDeathTest::Wait() {
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();
@@ -615,9 +612,10 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
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.
+ 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);
@@ -680,7 +678,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
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);
@@ -740,7 +738,7 @@ class NoExecDeathTest : public ForkingDeathTest {
DeathTest::TestRole NoExecDeathTest::AssumeRole() {
const size_t thread_count = GetThreadCount();
if (thread_count != 1) {
- GTEST_LOG_(WARNING, DeathTestThreadWarning(thread_count));
+ GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
}
int pipe_fd[2];
@@ -767,6 +765,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// concurrent writes to the log files. We capture stderr in the parent
// process and append the child process' output to a log.
LogToStderr();
+ // Event forwarding to the listeners of event listener API mush be shut
+ // down in death test subprocesses.
+ GetUnitTestImpl()->listeners()->SuppressEventForwarding();
return EXECUTE_TEST;
} else {
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
@@ -1042,7 +1043,7 @@ static void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest) {
::std::vector< ::std::string> parsed;
::std::string::size_type pos = 0;
- while (true) {
+ while (::testing::internal::AlwaysTrue()) {
const ::std::string::size_type colon = str.find(delimiter, pos);
if (colon == ::std::string::npos) {
parsed.push_back(str.substr(pos));
diff --git a/gtest/src/gtest-filepath.cc b/gtest/src/gtest-filepath.cc
index f966352..515d61c 100644
--- a/gtest/src/gtest-filepath.cc
+++ b/gtest/src/gtest-filepath.cc
@@ -34,7 +34,7 @@
#include <stdlib.h>
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
#include <windows.h>
#elif GTEST_OS_WINDOWS
#include <direct.h>
@@ -45,7 +45,7 @@
#else
#include <limits.h>
#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
@@ -65,7 +65,7 @@ namespace internal {
#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.
@@ -74,7 +74,7 @@ const char kCurrentDirectoryString[] = "\\";
const DWORD kInvalidFileAttributes = 0xffffffff;
#else
const char kCurrentDirectoryString[] = ".\\";
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
#else
const char kPathSeparator = '/';
const char kPathSeparatorString[] = "/";
@@ -83,9 +83,9 @@ const char kCurrentDirectoryString[] = "./";
// 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] = { '\0' };
@@ -93,7 +93,7 @@ FilePath FilePath::GetCurrentDir() {
#else
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.
@@ -103,7 +103,7 @@ FilePath FilePath::GetCurrentDir() {
FilePath FilePath::RemoveExtension(const char* extension) const {
String dot_extension(String::Format(".%s", extension));
if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
- return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4));
+ return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
}
return *this;
}
@@ -169,7 +169,7 @@ FilePath FilePath::ConcatPaths(const FilePath& directory,
// Returns true if pathname describes something findable in the file-system,
// either a file, directory, or whatever.
bool FilePath::FileOrDirectoryExists() const {
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
@@ -177,7 +177,7 @@ bool FilePath::FileOrDirectoryExists() const {
#else
posix::StatStruct file_stat;
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
}
// Returns true if pathname describes a directory in the file-system
@@ -193,7 +193,7 @@ bool FilePath::DirectoryExists() const {
const FilePath& path(*this);
#endif
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
@@ -205,7 +205,7 @@ bool FilePath::DirectoryExists() const {
posix::StatStruct file_stat;
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat);
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
return result;
}
@@ -217,7 +217,7 @@ bool FilePath::IsRootDirectory() const {
// TODO(wan@google.com): on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
- return pathname_.GetLength() == 3 && IsAbsolutePath();
+ return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_ == kPathSeparatorString;
#endif
@@ -227,7 +227,7 @@ bool FilePath::IsRootDirectory() const {
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] == ':' &&
@@ -271,7 +271,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
return false;
}
- if (pathname_.GetLength() == 0 || this->DirectoryExists()) {
+ if (pathname_.length() == 0 || this->DirectoryExists()) {
return true;
}
@@ -284,18 +284,17 @@ bool FilePath::CreateDirectoriesRecursively() const {
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool FilePath::CreateFolder() const {
-#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.
}
@@ -307,7 +306,7 @@ bool FilePath::CreateFolder() const {
// 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;
}
@@ -320,9 +319,9 @@ void FilePath::Normalize() {
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;
diff --git a/gtest/src/gtest-internal-inl.h b/gtest/src/gtest-internal-inl.h
index 189852e..47aec22 100644
--- a/gtest/src/gtest-internal-inl.h
+++ b/gtest/src/gtest-internal-inl.h
@@ -277,7 +277,7 @@ class Vector {
// 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_); }
+ void PushBack(const E& element) { Insert(element, size_); }
// Adds an element to the beginning of this Vector.
void PushFront(const E& element) { Insert(element, 0); }
@@ -369,7 +369,7 @@ class Vector {
return NULL;
}
- // Returns the i-th element of the list, or aborts the program if i
+ // 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_)
@@ -379,13 +379,84 @@ class Vector {
return *(elements_[i]);
}
- // Returns the i-th element of the list, or default_value if i is not
+ // 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);
+ }
+ }
+
+ // Performs an in-place shuffle of this Vector's nodes.
+ void Shuffle(internal::Random* random) {
+ ShuffleRange(random, 0, size());
+ }
+
+ // 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_)
@@ -397,9 +468,7 @@ class Vector {
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.";
- capacity_ = new_capacity;
- elements_ = static_cast<E**>(
- realloc(elements_, capacity_*sizeof(elements_[0])));
+ Reserve(new_capacity);
}
// Moves the give consecutive elements to a new index in the Vector.
@@ -491,11 +560,6 @@ class TestInfoImpl {
// 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(); }
@@ -606,7 +670,7 @@ class OsStackTraceGetterInterface {
// A working implementation of the OsStackTraceGetterInterface interface.
class OsStackTraceGetter : public OsStackTraceGetterInterface {
public:
- OsStackTraceGetter() {}
+ OsStackTraceGetter() : caller_frame_(NULL) {}
virtual String CurrentStackTrace(int max_depth, int skip_count);
virtual void UponLeavingGTest();
@@ -738,9 +802,20 @@ class UnitTestImpl {
// 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 {
- return test_cases_.GetElementOr(i, NULL);
+ 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.
TestResult* current_test_result();
@@ -748,18 +823,6 @@ class UnitTestImpl {
// Returns the TestResult for the ad hoc test.
const 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();
-
// Sets the OS stack trace getter.
//
// Does nothing if the input and the current OS stack trace getter
@@ -895,9 +958,6 @@ class UnitTestImpl {
return &environments_in_reverse_order_;
}
- internal::Vector<TestCase*>* test_cases() { return &test_cases_; }
- const internal::Vector<TestCase*>* test_cases() const { return &test_cases_; }
-
// Getters for the per-thread Google Test trace stack.
internal::Vector<TraceInfo>* gtest_trace_stack() {
return gtest_trace_stack_.pointer();
@@ -907,9 +967,13 @@ class UnitTestImpl {
}
#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();
}
@@ -919,12 +983,35 @@ class UnitTestImpl {
return death_test_factory_.get();
}
+ void SuppressTestEventsIfInSubprocess();
+
friend class ReplaceDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST
- // Gets the random seed used at the start of the current test run.
+ // 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;
@@ -956,7 +1043,15 @@ class UnitTestImpl {
internal::Vector<Environment*> environments_;
internal::Vector<Environment*> environments_in_reverse_order_;
- internal::Vector<TestCase*> test_cases_; // The vector 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
@@ -992,11 +1087,9 @@ class UnitTestImpl {
// test, and records the result in 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,
@@ -1004,9 +1097,15 @@ class UnitTestImpl {
// desired.
OsStackTraceGetterInterface* os_stack_trace_getter_;
+ // True iff PostFlagParsingInit() has been called.
+ bool post_flag_parse_init_performed_;
+
// The random number seed used at the beginning of the test run.
int random_seed_;
+ // Our random number generator.
+ internal::Random random_;
+
// How long the test took to run, in milliseconds.
TimeInMillis elapsed_time_;
@@ -1099,13 +1198,14 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
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@google.com): Convert this to compile time assertion when it is
@@ -1131,8 +1231,6 @@ class TestResultAccessor {
test_result->RecordProperty(property);
}
- static bool Passed(const TestResult& result) { return result.Passed(); }
-
static void ClearTestPartResults(TestResult* test_result) {
test_result->ClearTestPartResults();
}
diff --git a/gtest/src/gtest-port.cc b/gtest/src/gtest-port.cc
index 09d1a8e..de169e2 100644
--- a/gtest/src/gtest-port.cc
+++ b/gtest/src/gtest-port.cc
@@ -35,14 +35,14 @@
#include <stdlib.h>
#include <stdio.h>
-#if GTEST_OS_WINDOWS
-#ifndef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h> // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
#include <io.h>
#include <sys/stat.h>
-#endif // _WIN32_WCE
#else
#include <unistd.h>
-#endif // GTEST_OS_WINDOWS
+#endif // GTEST_OS_WINDOWS_MOBILE
#if GTEST_OS_MAC
#include <mach/mach_init.h>
@@ -50,10 +50,6 @@
#include <mach/vm_map.h>
#endif // GTEST_OS_MAC
-#ifdef _WIN32_WCE
-#include <windows.h> // For TerminateProcess()
-#endif // _WIN32_WCE
-
#include <gtest/gtest-spi.h>
#include <gtest/gtest-message.h>
#include <gtest/internal/gtest-string.h>
@@ -417,20 +413,25 @@ void RE::Init(const char* regex) {
#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.
+ GetStream() << ::std::endl << marker << " "
+ << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// 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
@@ -444,7 +445,7 @@ class CapturedStderr {
public:
// The ctor redirects stderr to a temporary file.
CapturedStderr() {
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
// Not supported on Windows CE.
posix::Abort();
#else
@@ -469,24 +470,24 @@ class CapturedStderr {
fflush(NULL);
dup2(captured_fd, kStdErrFileno);
close(captured_fd);
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
}
~CapturedStderr() {
-#ifndef _WIN32_WCE
+#if !GTEST_OS_WINDOWS_MOBILE
remove(filename_.c_str());
-#endif // _WIN32_WCE
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
// Stops redirecting stderr.
void StopCapture() {
-#ifndef _WIN32_WCE
+#if !GTEST_OS_WINDOWS_MOBILE
// Restores the original stream.
fflush(NULL);
dup2(uncaptured_fd_, kStdErrFileno);
close(uncaptured_fd_);
uncaptured_fd_ = -1;
-#endif // !_WIN32_WCE
+#endif // !GTEST_OS_WINDOWS_MOBILE
}
// Returns the name of the temporary file holding the stderr output.
@@ -537,7 +538,7 @@ static String ReadEntireFile(FILE * file) {
// Starts capturing stderr.
void CaptureStderr() {
if (g_captured_stderr != NULL) {
- GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time.");
+ GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
}
g_captured_stderr = new CapturedStderr;
}
@@ -568,14 +569,14 @@ const ::std::vector<String>& GetArgvs() { return g_argvs; }
#endif // GTEST_HAS_DEATH_TEST
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
namespace posix {
void Abort() {
DebugBreak();
TerminateProcess(GetCurrentProcess(), 1);
}
} // namespace posix
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
// Returns the name of the environment variable corresponding to the
// given flag. For example, FlagToEnvVar("foo") will return
@@ -585,7 +586,7 @@ static String FlagToEnvVar(const char* flag) {
(Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
Message env_var;
- for (int i = 0; i != full_flag.GetLength(); i++) {
+ for (size_t i = 0; i != full_flag.length(); i++) {
env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
}
diff --git a/gtest/src/gtest-test-part.cc b/gtest/src/gtest-test-part.cc
index f053773..4f36df6 100644
--- a/gtest/src/gtest-test-part.cc
+++ b/gtest/src/gtest-test-part.cc
@@ -56,12 +56,12 @@ internal::String TestPartResult::ExtractSummary(const char* message) {
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
- return os << result.file_name() << ":"
- << result.line_number() << ": "
- << (result.type() == TPRT_SUCCESS ? "Success" :
- result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" :
- "Non-fatal failure") << ":\n"
- << result.message() << std::endl;
+ 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.
diff --git a/gtest/src/gtest.cc b/gtest/src/gtest.cc
index a767d19..9340724 100644
--- a/gtest/src/gtest.cc
+++ b/gtest/src/gtest.cc
@@ -42,6 +42,8 @@
#include <wchar.h>
#include <wctype.h>
+#include <ostream>
+
#if GTEST_OS_LINUX
// TODO(kenton@google.com): Use autoconf to detect availability of
@@ -70,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
@@ -81,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@google.com): Use autoconf to detect availability of
// gettimeofday().
@@ -90,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.
@@ -129,10 +131,6 @@
namespace testing {
-using internal::TestCase;
-using internal::TestProperty;
-using internal::TestResult;
-
// Constants.
// A test whose test case name or test name matches this filter is
@@ -257,6 +255,25 @@ GTEST_DEFINE_bool_(
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;
@@ -301,16 +318,22 @@ static bool ShouldRunTestCase(const TestCase* test_case) {
}
// AssertHelper constructor.
-AssertHelper::AssertHelper(TestPartResultType type, const char* file,
- int line, const char* message)
- : type_(type), file_(file), line_(line), message_(message) {
+AssertHelper::AssertHelper(TestPartResult::Type type,
+ const char* file,
+ int line,
+ const char* message)
+ : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+ delete data_;
}
// Message assignment, for assertion streaming support.
void AssertHelper::operator=(const Message& message) const {
UnitTest::GetInstance()->
- AddTestPartResult(type_, file_, line_,
- AppendUserMessage(message_, message),
+ AddTestPartResult(data_->type, data_->file, data_->line,
+ AppendUserMessage(data_->message, message),
UnitTest::GetInstance()->impl()
->CurrentOsStackTraceExceptTop(1)
// Skips the stack frame for this function itself.
@@ -328,11 +351,11 @@ String g_executable_path;
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();
}
@@ -445,7 +468,7 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name,
positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter
negative = String("");
} else {
- positive.Set(p, dash - p); // Everything up to the dash
+ positive = String(p, dash - p); // Everything up to the dash
negative = String(dash+1); // Everything after the dash
if (positive.empty()) {
// Treat '-test1' as the same as '*-test1'
@@ -476,86 +499,6 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
} // namespace internal
-// The interface for printing the result of a UnitTest
-class UnitTestEventListenerInterface {
- public:
- // The d'tor is pure virtual as this is an abstract class.
- virtual ~UnitTestEventListenerInterface() {}
-
- // Called before the unit test starts.
- virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
-
- // Called after the unit test ends.
- virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0;
-
- // Called before the test case starts.
- virtual void OnTestCaseStart(const TestCase& test_case) = 0;
-
- // Called after the test case ends.
- virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
-
- // Called before the global set-up starts.
- virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0;
-
- // Called after the global set-up ends.
- virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0;
-
- // Called before the global tear-down starts.
- virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0;
-
- // Called after the global tear-down ends.
- virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0;
-
- // Called before the test starts.
- virtual void OnTestStart(const TestInfo& test_info) = 0;
-
- // Called after the test ends.
- virtual void OnTestEnd(const TestInfo& test_info) = 0;
-
- // Called after an assertion.
- virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 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.
-class EmptyTestEventListener : public UnitTestEventListenerInterface {
- public:
- // Called before the unit test starts.
- virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the unit test ends.
- virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the test case starts.
- virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
-
- // Called after the test case ends.
- virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {}
-
- // Called before the global set-up starts.
- virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the global set-up ends.
- virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the global tear-down starts.
- virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the global tear-down ends.
- virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the test starts.
- virtual void OnTestStart(const TestInfo& /*test_info*/) {}
-
- // Called after the test ends.
- virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
-
- // Called after an assertion.
- virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
- }
-};
-
// 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.
@@ -631,11 +574,11 @@ AssertionResult HasOneFailure(const char* /* results_expr */,
const char* /* type_expr */,
const char* /* substr_expr */,
const TestPartResultArray& results,
- TestPartResultType type,
+ TestPartResult::Type type,
const char* substr) {
- const String expected(
- type == TPRT_FATAL_FAILURE ? "1 fatal failure" :
- "1 non-fatal failure");
+ const String expected(type == TestPartResult::kFatalFailure ?
+ "1 fatal failure" :
+ "1 non-fatal failure");
Message msg;
if (results.size() != 1) {
msg << "Expected: " << expected << "\n"
@@ -670,7 +613,7 @@ AssertionResult HasOneFailure(const char* /* results_expr */,
// substring the failure message should contain.
SingleFailureChecker:: SingleFailureChecker(
const TestPartResultArray* results,
- TestPartResultType type,
+ TestPartResult::Type type,
const char* substr)
: results_(results),
type_(type),
@@ -690,7 +633,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
const TestPartResult& result) {
unit_test_->current_test_result()->AddTestPartResult(result);
- unit_test_->result_printer()->OnNewTestPartResult(result);
+ unit_test_->listeners()->repeater()->OnTestPartResult(result);
}
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
@@ -790,7 +733,7 @@ String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
// Returns the current time in milliseconds.
TimeInMillis GetTimeInMillis() {
-#if defined(_WIN32_WCE) || defined(__BORLANDC__)
+#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 =
@@ -873,7 +816,7 @@ const char * String::CloneCString(const char* c_str) {
NULL : CloneString(c_str, strlen(c_str));
}
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
@@ -907,7 +850,7 @@ const char* String::Utf16ToAnsi(LPCWSTR utf16_str) {
return ansi;
}
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
// Compares two C strings. Returns true iff they have the same content.
//
@@ -926,17 +869,17 @@ bool String::CStringEquals(const char * lhs, const char * rhs) {
// Converts an array of wide chars to a narrow string using the UTF-8
// encoding, and streams the result to the given Message object.
-static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len,
+static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
Message* msg) {
// TODO(wan): consider allowing a testing::String object to
// contain '\0'. This will make it behave more like std::string,
// and will allow ToUtf8String() to return the correct encoding
// for '\0' s.t. we can get rid of the conditional here (and in
// several other places).
- for (size_t i = 0; i != len; ) { // NOLINT
+ for (size_t i = 0; i != length; ) { // NOLINT
if (wstr[i] != L'\0') {
- *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i));
- while (i != len && wstr[i] != L'\0')
+ *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+ while (i != length && wstr[i] != L'\0')
i++;
} else {
*msg << '\0';
@@ -1381,7 +1324,7 @@ namespace {
AssertionResult HRESULTFailureHelper(const char* expr,
const char* expected,
long hr) { // NOLINT
-#ifdef _WIN32_WCE
+#if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't support FormatMessage.
const char error_text[] = "";
#else
@@ -1405,7 +1348,7 @@ AssertionResult HRESULTFailureHelper(const char* expr,
--message_length) {
error_text[message_length - 1] = '\0';
}
-#endif // _WIN32_WCE
+#endif // GTEST_OS_WINDOWS_MOBILE
const String error_hex(String::Format("0x%08X ", hr));
Message msg;
@@ -1679,24 +1622,30 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
#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*
@@ -1704,12 +1653,12 @@ int String::Compare(const String & rhs) const {
bool String::EndsWith(const char* suffix) const {
if (suffix == NULL || CStringEquals(suffix, "")) return true;
- if (c_str_ == NULL) return false;
+ if (c_str() == NULL) return false;
- const size_t this_len = strlen(c_str_);
+ const size_t this_len = strlen(c_str());
const size_t suffix_len = strlen(suffix);
return (this_len >= suffix_len) &&
- CStringEquals(c_str_ + this_len - suffix_len, suffix);
+ CStringEquals(c_str() + this_len - suffix_len, suffix);
}
// Returns true iff this String ends with the given suffix, ignoring case.
@@ -1717,37 +1666,12 @@ bool String::EndsWith(const char* suffix) const {
bool String::EndsWithCaseInsensitive(const char* suffix) const {
if (suffix == NULL || CStringEquals(suffix, "")) return true;
- if (c_str_ == NULL) return false;
+ if (c_str() == NULL) return false;
- const size_t this_len = strlen(c_str_);
+ const size_t this_len = strlen(c_str());
const size_t suffix_len = strlen(suffix);
return (this_len >= suffix_len) &&
- CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix);
-}
-
-// Sets the 0-terminated C string this String object represents. The
-// old string in this object is deleted, and this object will own a
-// clone of the input string. This function copies only up to length
-// bytes (plus a terminating null byte), or until the first null byte,
-// whichever comes first.
-//
-// This function works even when the c_str parameter has the same
-// value as that of the c_str_ field.
-void String::Set(const char * c_str, size_t length) {
- // Makes sure this works when c_str == c_str_
- const char* const temp = CloneString(c_str, length);
- delete[] c_str_;
- c_str_ = temp;
-}
-
-// Assigns a C string to this object. Self-assignment works.
-const String& String::operator=(const char* c_str) {
- // Makes sure this works when c_str == c_str_
- if (c_str != c_str_) {
- delete[] c_str_;
- c_str_ = CloneCString(c_str);
- }
- return *this;
+ CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix);
}
// Formats a list of arguments to a String, using the same format
@@ -1757,28 +1681,38 @@ const String& String::operator=(const char* c_str) {
// available.
//
// The result is limited to 4096 characters (including the tailing 0).
-// If 4096 characters are not enough to format the input,
-// "<buffer exceeded>" is returned.
+// If 4096 characters are not enough to format the input, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
String String::Format(const char * format, ...) {
va_list args;
va_start(args, format);
char buffer[4096];
+ const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
// MSVC 8 deprecates vsnprintf(), so we want to suppress warning
// 4996 (deprecated function) there.
#ifdef _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 not using MSVC.
- const int size =
- vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
+ 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
@@ -1829,6 +1763,8 @@ String AppendUserMessage(const String& gtest_msg,
return msg.GetString();
}
+} // namespace internal
+
// class TestResult
// Creates an empty TestResult.
@@ -1948,8 +1884,6 @@ int TestResult::test_property_count() const {
return test_properties_->size();
}
-} // namespace internal
-
// class Test
// Creates a Test object.
@@ -1990,7 +1924,7 @@ void Test::RecordProperty(const char* key, int value) {
namespace internal {
-void ReportFailureInUnknownLocation(TestPartResultType result_type,
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
const String& message) {
// This function is a friend of UnitTest and as such has access to
// AddTestPartResult.
@@ -2014,7 +1948,7 @@ static void AddExceptionThrownFailure(DWORD exception_code,
message << "Exception thrown with code 0x" << std::setbase(16) <<
exception_code << std::setbase(10) << " in " << location << ".";
- internal::ReportFailureInUnknownLocation(TPRT_FATAL_FAILURE,
+ internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
message.GetString());
}
@@ -2316,11 +2250,10 @@ void TestInfoImpl::Run() {
UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(parent_);
- // Notifies the unit test event listener that a test is about to
- // start.
- UnitTestEventListenerInterface* const result_printer =
- impl->result_printer();
- result_printer->OnTestStart(*parent_);
+ TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+ // Notifies the unit test event listeners that a test is about to start.
+ repeater->OnTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis();
@@ -2363,13 +2296,15 @@ void TestInfoImpl::Run() {
result_.set_elapsed_time(GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
- result_printer->OnTestEnd(*parent_);
+ repeater->OnTestEnd(*parent_);
// Tells UnitTest to stop associating assertion results to this
// test.
impl->set_current_test_info(NULL);
}
+} // namespace internal
+
// class TestCase
// Gets the number of successful tests in this test case.
@@ -2408,33 +2343,39 @@ TestCase::TestCase(const char* name, const char* comment,
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::Vector<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 {
- return test_info_list_->GetElementOr(i, NULL);
+ 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.
@@ -2444,20 +2385,21 @@ void TestCase::Run() {
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_case(this);
- UnitTestEventListenerInterface * const result_printer =
- impl->result_printer();
+ TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
- result_printer->OnTestCaseStart(*this);
+ repeater->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest();
set_up_tc_();
const internal::TimeInMillis start = internal::GetTimeInMillis();
- test_info_list_->ForEach(internal::TestInfoImpl::RunTest);
+ for (int i = 0; i < total_test_count(); i++) {
+ GetMutableTestInfo(i)->impl()->Run();
+ }
elapsed_time_ = internal::GetTimeInMillis() - start;
impl->os_stack_trace_getter()->UponLeavingGTest();
tear_down_tc_();
- result_printer->OnTestCaseEnd(*this);
+ repeater->OnTestCaseEnd(*this);
impl->set_current_test_case(NULL);
}
@@ -2488,11 +2430,17 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
return test_info->impl()->should_run();
}
-} // namespace internal
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+ test_indices_->Shuffle(random);
+}
-// 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 EmptyTestEventListener {};
+// 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.
@@ -2516,17 +2464,17 @@ static internal::String FormatTestCaseCount(int test_case_count) {
return FormatCountableNoun(test_case_count, "test case", "test cases");
}
-// Converts a TestPartResultType enum to human-friendly string
-// representation. Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE
-// are translated to "Failure", as the user usually doesn't care about
-// the difference between the two when viewing the test result.
-static const char * TestPartResultTypeToString(TestPartResultType type) {
+// Converts a TestPartResult::Type enum to human-friendly string
+// representation. Both kNonFatalFailure and kFatalFailure are translated
+// to "Failure", as the user usually doesn't care about the difference
+// between the two when viewing the test result.
+static const char * TestPartResultTypeToString(TestPartResult::Type type) {
switch (type) {
- case TPRT_SUCCESS:
+ case TestPartResult::kSuccess:
return "Success";
- case TPRT_NONFATAL_FAILURE:
- case TPRT_FATAL_FAILURE:
+ case TestPartResult::kNonFatalFailure:
+ case TestPartResult::kFatalFailure:
#ifdef _MSC_VER
return "error: ";
#else
@@ -2557,12 +2505,10 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) {
// 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.
-#ifdef _WIN32_WCE
- // Windows Mobile doesn't support the ANSI version of OutputDebugString,
- // it works only with UTF16 strings.
- ::OutputDebugString(internal::String::AnsiToUtf16(result.c_str()));
- ::OutputDebugString(L"\n");
-#elif GTEST_OS_WINDOWS
+#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
@@ -2579,7 +2525,7 @@ enum GTestColor {
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) {
@@ -2604,7 +2550,7 @@ const char* GetAnsiColorCode(GTestColor color) {
};
}
-#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) {
@@ -2645,13 +2591,13 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
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(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) {
@@ -2660,7 +2606,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
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.
@@ -2678,41 +2624,34 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
printf("\033[0;3%sm", GetAnsiColorCode(color));
vprintf(fmt, args);
printf("\033[m"); // Resets the terminal to default.
-#endif // 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& unit_test);
- virtual void OnGlobalSetUpEnd(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 OnTestCaseEnd(const TestCase& test_case);
virtual void OnTestStart(const TestInfo& test_info);
- virtual void OnNewTestPartResult(const TestPartResult& result);
+ virtual void OnTestPartResult(const TestPartResult& result);
virtual void OnTestEnd(const TestInfo& test_info);
- virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
- virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
- virtual void OnUnitTestEnd(const UnitTest& unit_test);
+ 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);
@@ -2720,8 +2659,12 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface {
internal::String test_case_name_;
};
-// Called before the unit test starts.
-void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) {
+ // 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
@@ -2751,7 +2694,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) {
fflush(stdout);
}
-void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment set-up.\n");
@@ -2772,19 +2715,6 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
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) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_case_name_.c_str(), test_info.name());
@@ -2796,6 +2726,18 @@ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
fflush(stdout);
}
+// 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 ] ");
@@ -2812,19 +2754,20 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
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(
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
const UnitTest& /*unit_test*/) {
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment tear-down\n");
@@ -2863,7 +2806,8 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
}
}
-void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
+ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("%s from %s ran.",
FormatTestCount(unit_test.test_to_run_count()).c_str(),
@@ -2902,76 +2846,129 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
// 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::Vector<UnitTestEventListenerInterface *> Listeners;
- 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);
+ 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 OnTestCaseEnd(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 OnNewTestPartResult(const TestPartResult& result);
+ 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() {
+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@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 (int i = 0; i < listeners_.size(); i++) { \
- listeners_.GetElement(i)->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 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
@@ -2989,23 +2986,26 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// 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);
@@ -3017,11 +3017,10 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// 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 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);
};
@@ -3037,13 +3036,14 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
}
// Called after the unit test ends.
-void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
+void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
FILE* xmlout = NULL;
- internal::FilePath output_file(output_file_);
- internal::FilePath output_dir(output_file.RemoveFileName());
+ FilePath output_file(output_file_);
+ FilePath output_dir(output_file.RemoveFileName());
if (output_dir.CreateDirectoriesRecursively()) {
- xmlout = internal::posix::FOpen(output_file_.c_str(), "w");
+ xmlout = posix::FOpen(output_file_.c_str(), "w");
}
if (xmlout == NULL) {
// TODO(wan): report the reason of the failure.
@@ -3078,8 +3078,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
// most invalid characters can be retained using character references.
// TODO(wan): It might be nice to have a minimally invasive, human-readable
// escaping scheme for invalid characters, rather than dropping them.
-internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
- bool is_attribute) {
+String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
Message m;
if (str != NULL) {
@@ -3109,7 +3108,7 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
default:
if (IsValidXmlCharacter(*src)) {
if (is_attribute && IsNormalizableWhitespace(*src))
- m << internal::String::Format("&#x%02X;", unsigned(*src));
+ m << String::Format("&#x%02X;", unsigned(*src));
else
m << *src;
}
@@ -3121,6 +3120,21 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
return m.GetString();
}
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+ char* const output = new char[strlen(str) + 1];
+ char* appender = output;
+ for (char ch = *str; ch != '\0'; ch = *++str)
+ if (IsValidXmlCharacter(ch))
+ *appender++ = ch;
+ *appender = '\0';
+
+ String ret_value(output);
+ delete[] output;
+ return ret_value;
+}
// The following routines generate an XML representation of a UnitTest
// object.
@@ -3138,8 +3152,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
// </testsuite>
// </testsuites>
-namespace internal {
-
// Formats the given time in milliseconds as seconds. The returned
// C-string is owned by this function and cannot be released by the
// caller. Calling the function again invalidates the previous
@@ -3150,43 +3162,62 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) {
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 << "]]>]]&gt;<![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) {
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info) {
const TestResult& result = *test_info.result();
- 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());
+ *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 (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
@@ -3201,9 +3232,12 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
test_case.disabled_test_count());
fprintf(out,
"errors=\"0\" time=\"%s\">\n",
- internal::FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
- for (int i = 0; i < test_case.total_test_count(); ++i)
- PrintXmlTestInfo(out, test_case.name(), *test_case.GetTestInfo(i));
+ 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");
}
@@ -3217,7 +3251,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
unit_test.total_test_count(),
unit_test.failed_test_count(),
unit_test.disabled_test_count(),
- internal::FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
if (GTEST_FLAG(shuffle)) {
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
}
@@ -3229,7 +3263,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
// 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(
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
const TestResult& result) {
Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) {
@@ -3242,8 +3276,6 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
// End XmlUnitTestResultPrinter
-namespace internal {
-
// Class ScopedTrace
// Pushes the given source file location and message onto a per-thread
@@ -3290,6 +3322,81 @@ OsStackTraceGetter::kElidedFramesMarker =
} // 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
@@ -3378,6 +3485,18 @@ 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
// program is run, all global test environments will be set-up in the
// order they were registered. After all tests in the program have
@@ -3416,7 +3535,7 @@ class GoogleTestFailureException : public ::std::runtime_error {
// 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,
@@ -3446,7 +3565,7 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type,
impl_->GetTestPartResultReporterForCurrentThread()->
ReportTestPartResult(result);
- if (result_type != TPRT_SUCCESS) {
+ 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
@@ -3491,27 +3610,27 @@ int UnitTest::Run() {
// 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) {
-#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) || defined(__MINGW32__)) && !defined(_WIN32_WCE)
+#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 && !defined(_WIN32_WCE)
+#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
@@ -3624,7 +3743,6 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
&default_global_test_part_result_reporter_),
per_thread_test_part_result_reporter_(
&default_per_thread_test_part_result_reporter_),
- test_cases_(),
#if GTEST_HAS_PARAM_TEST
parameterized_test_registry_(),
parameterized_tests_registered_(false),
@@ -3633,9 +3751,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
current_test_case_(NULL),
current_test_info_(NULL),
ad_hoc_test_result_(),
- result_printer_(NULL),
os_stack_trace_getter_(NULL),
- random_seed_(0),
+ 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),
@@ -3643,6 +3762,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
#else
elapsed_time_(0) {
#endif // GTEST_HAS_DEATH_TEST
+ listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
}
UnitTestImpl::~UnitTestImpl() {
@@ -3652,12 +3772,58 @@ UnitTestImpl::~UnitTestImpl() {
// 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.
//
@@ -3682,7 +3848,9 @@ class TestCaseNameIs {
};
// Finds and returns a TestCase with the given name. If one doesn't
-// exist, creates one and returns it.
+// exist, creates one and returns it. It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
//
// Arguments:
//
@@ -3707,13 +3875,16 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
kDeathTestCaseFilter)) {
// Yes. Inserts the test case after the last death test case
- // defined so far.
+ // 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);
}
+ test_case_indices_.PushBack(test_case_indices_.size());
return new_test_case;
}
@@ -3728,7 +3899,7 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// considered to be failed, but the rest of the tests will still be
// run. (We disable exceptions on Linux and Mac OS X, so the issue
// doesn't apply there.)
-// When parameterized tests are enabled, it explands and registers
+// When parameterized tests are enabled, it expands and registers
// parameterized tests first in RegisterParameterizedTests().
// All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run.
@@ -3745,7 +3916,9 @@ int UnitTestImpl::RunAllTests() {
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
@@ -3757,12 +3930,9 @@ int UnitTestImpl::RunAllTests() {
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);
@@ -3785,59 +3955,79 @@ int UnitTestImpl::RunAllTests() {
// 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 run.
+ // 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;
}
@@ -4016,49 +4206,6 @@ void UnitTestImpl::ListTestsMatchingFilter() {
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
@@ -4090,6 +4237,32 @@ TestResult* UnitTestImpl::current_test_result() {
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,
@@ -4126,7 +4299,8 @@ TestInfoImpl::~TestInfoImpl() {
// For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
-String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) {
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+ int skip_count) {
// We pass skip_count + 1 to skip this wrapper function in addition
// to what the user really wants to skip.
return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
@@ -4138,11 +4312,13 @@ namespace {
class ClassUniqueToAlwaysTrue {};
}
+bool IsTrue(bool condition) { return condition; }
+
bool AlwaysTrue() {
#if GTEST_HAS_EXCEPTIONS
// This condition is always false so AlwaysTrue() never actually throws,
// but it makes the compiler think that it may throw.
- if (atoi("42") == 36) // NOLINT
+ if (IsTrue(false))
throw ClassUniqueToAlwaysTrue();
#endif // GTEST_HAS_EXCEPTIONS
return true;
@@ -4161,7 +4337,7 @@ const char* ParseFlagValue(const char* str,
// 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.
@@ -4301,8 +4477,8 @@ static const char kColorEncodedHelpMessage[] =
"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\n"
-" Randomize tests' orders on every run. To be implemented.\n"
+" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+" Randomize tests' orders on every iteration.\n"
" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
" Random number seed to use for shuffling test orders (between 1 and\n"
" 99999, or 0 to use a seed based on the current time).\n"
@@ -4439,6 +4615,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
#endif // GTEST_HAS_DEATH_TEST
ParseGoogleTestFlagsOnly(argc, argv);
+ GetUnitTestImpl()->PostFlagParsingInit();
}
} // namespace internal