diff options
author | Jeff Davidson <jpd@google.com> | 2015-01-20 10:18:05 -0800 |
---|---|---|
committer | Jeff Davidson <jpd@google.com> | 2015-01-20 10:18:05 -0800 |
commit | 0ddac1f3791efefb2cffdb425f0c600feb7a47e6 (patch) | |
tree | efeab8fb69198186f1dabfe43d341c7b70c9c5f1 /gtest/src | |
parent | 77a6b2f4cdd580d57630f079db1d908d7fd90a54 (diff) | |
download | external_protobuf-0ddac1f3791efefb2cffdb425f0c600feb7a47e6.zip external_protobuf-0ddac1f3791efefb2cffdb425f0c600feb7a47e6.tar.gz external_protobuf-0ddac1f3791efefb2cffdb425f0c600feb7a47e6.tar.bz2 |
Update protobuf's gtest to expected version.
Generated by running:
rm -rf gtest
./autogen.sh
./configure
Change-Id: I5d9c0bea09dd9d3e4d7d4442dd8222011f5c522a
Diffstat (limited to 'gtest/src')
-rw-r--r-- | gtest/src/gtest-all.cc | 6 | ||||
-rw-r--r-- | gtest/src/gtest-death-test.cc | 34 | ||||
-rw-r--r-- | gtest/src/gtest-filepath.cc | 64 | ||||
-rw-r--r-- | gtest/src/gtest-internal-inl.h | 413 | ||||
-rw-r--r-- | gtest/src/gtest-port.cc | 151 | ||||
-rw-r--r-- | gtest/src/gtest-test-part.cc | 16 | ||||
-rw-r--r-- | gtest/src/gtest-typed-test.cc | 12 | ||||
-rw-r--r-- | gtest/src/gtest.cc | 362 |
8 files changed, 512 insertions, 546 deletions
diff --git a/gtest/src/gtest-all.cc b/gtest/src/gtest-all.cc index a67ea0f..fe34765 100644 --- a/gtest/src/gtest-all.cc +++ b/gtest/src/gtest-all.cc @@ -33,6 +33,12 @@ // // Sometimes it's desirable to build Google Test by compiling a single file. // This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include <gtest/gtest.h> + +// The following lines pull in the real gtest *.cc files. #include "src/gtest.cc" #include "src/gtest-death-test.cc" #include "src/gtest-filepath.cc" diff --git a/gtest/src/gtest-death-test.cc b/gtest/src/gtest-death-test.cc index 106b01c..3b73b01 100644 --- a/gtest/src/gtest-death-test.cc +++ b/gtest/src/gtest-death-test.cc @@ -308,9 +308,9 @@ String DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: - DeathTestImpl(const char* statement, const RE* regex) - : statement_(statement), - regex_(regex), + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), @@ -326,11 +326,11 @@ class DeathTestImpl : public DeathTest { const char* statement() const { return statement_; } const RE* regex() const { return regex_; } bool spawned() const { return spawned_; } - void set_spawned(bool spawned) { spawned_ = spawned; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } - void set_status(int status) { status_ = status; } + void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } - void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } @@ -705,8 +705,8 @@ class ForkingDeathTest : public DeathTestImpl { }; // Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) - : DeathTestImpl(statement, regex), +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit @@ -718,18 +718,18 @@ int ForkingDeathTest::Wait() { ReadAndInterpretStatusByte(); - int status; - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0)); - set_status(status); - return status; + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: - NoExecDeathTest(const char* statement, const RE* regex) : - ForkingDeathTest(statement, regex) { } + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; @@ -782,9 +782,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: - ExecDeathTest(const char* statement, const RE* regex, + ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : - ForkingDeathTest(statement, regex), file_(file), line_(line) { } + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. @@ -1037,8 +1037,6 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. -// TODO(vladl@google.com): Get rid of std::vector to be able to build on -// Visual C++ 7.1 with exceptions disabled. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; diff --git a/gtest/src/gtest-filepath.cc b/gtest/src/gtest-filepath.cc index 515d61c..c1ef918 100644 --- a/gtest/src/gtest-filepath.cc +++ b/gtest/src/gtest-filepath.cc @@ -63,8 +63,14 @@ namespace testing { namespace internal { #if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; #if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least @@ -81,6 +87,15 @@ const char kPathSeparatorString[] = "/"; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE @@ -108,6 +123,22 @@ FilePath FilePath::RemoveExtension(const char* extension) const { return *this; } +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns @@ -115,7 +146,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const { // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); + const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(String(last_sep + 1)) : *this; } @@ -126,7 +157,7 @@ FilePath FilePath::RemoveDirectoryName() const { // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); + const char* const last_sep = FindLastPathSeparator(); String dir; if (last_sep) { dir = String(c_str(), last_sep + 1 - c_str()); @@ -219,7 +250,7 @@ bool FilePath::IsRootDirectory() const { // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else - return pathname_ == kPathSeparatorString; + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } @@ -231,9 +262,9 @@ bool FilePath::IsAbsolutePath() const { ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && - name[2] == kPathSeparator; + IsPathSeparator(name[2]); #else - return name[0] == kPathSeparator; + return IsPathSeparator(name[0]); #endif } @@ -260,7 +291,8 @@ FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { - return pathname_.EndsWith(kPathSeparatorString); + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if @@ -305,14 +337,15 @@ bool FilePath::CreateFolder() const { // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { - return pathname_.EndsWith(kPathSeparatorString) + return IsDirectory() ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) : *this; } -// Normalize removes any redundant separators that might be in the pathname. +// Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; @@ -324,12 +357,19 @@ void FilePath::Normalize() { memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { - *dest_ptr++ = *src; - if (*src != kPathSeparator) + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { src++; - else - while (*src == kPathSeparator) + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) src++; + } + dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; diff --git a/gtest/src/gtest-internal-inl.h b/gtest/src/gtest-internal-inl.h index 47aec22..855b215 100644 --- a/gtest/src/gtest-internal-inl.h +++ b/gtest/src/gtest-internal-inl.h @@ -52,7 +52,9 @@ #include <stdlib.h> // For strtoll/_strtoul64/malloc/free. #include <string.h> // For memmove. +#include <algorithm> #include <string> +#include <vector> #include <gtest/internal/gtest-port.h> @@ -60,7 +62,7 @@ #include <windows.h> // For DWORD. #endif // GTEST_OS_WINDOWS -#include <gtest/gtest.h> +#include <gtest/gtest.h> // NOLINT #include <gtest/gtest-spi.h> namespace testing { @@ -76,7 +78,7 @@ namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). -extern const TypeId kTestTypeIdInGoogleTest; +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; @@ -90,13 +92,31 @@ const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + // Returns the current time in milliseconds. -TimeInMillis GetTimeInMillis(); +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. @@ -144,6 +164,7 @@ class GTestFlagSaver { random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } @@ -163,6 +184,7 @@ class GTestFlagSaver { GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: @@ -182,6 +204,7 @@ class GTestFlagSaver { internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; + internal::Int32 stack_trace_depth_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; @@ -193,7 +216,7 @@ class GTestFlagSaver { // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output // as '(Invalid Unicode 0xXXXXXXXX)'. -char* CodePointToUtf8(UInt32 code_point, char* str); +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: @@ -208,10 +231,7 @@ char* CodePointToUtf8(UInt32 code_point, char* str); // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. -String WideStringToUtf8(const wchar_t* str, int num_chars); - -// Returns the number of active threads, or 0 when there is an error. -size_t GetThreadCount(); +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this @@ -225,269 +245,78 @@ void WriteToShardStatusFileIfNeeded(); // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. -bool ShouldShard(const char* total_shards_str, const char* shard_index_str, - bool in_subprocess_for_death_test); +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. -Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. -bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id); - -// Vector is an ordered container that supports random access to the -// elements. -// -// We cannot use std::vector, as Visual C++ 7.1's implementation of -// STL has problems compiling when exceptions are disabled. There is -// a hack to work around the problems, but we've seen cases where the -// hack fails to work. -// -// The element type must support copy constructor and operator=. -template <typename E> // E is the element type. -class Vector { - public: - // Creates an empty Vector. - Vector() : elements_(NULL), capacity_(0), size_(0) {} - - // D'tor. - virtual ~Vector() { Clear(); } - - // Clears the Vector. - void Clear() { - if (elements_ != NULL) { - for (int i = 0; i < size_; i++) { - delete elements_[i]; - } - - free(elements_); - elements_ = NULL; - capacity_ = size_ = 0; - } - } - - // Gets the number of elements. - int size() const { return size_; } - - // Adds an element to the end of the Vector. A copy of the element - // is created using the copy constructor, and then stored in the - // Vector. Changes made to the element in the Vector doesn't affect - // the source object, and vice versa. - void PushBack(const E& element) { Insert(element, size_); } - - // Adds an element to the beginning of this Vector. - void PushFront(const E& element) { Insert(element, 0); } - - // Removes an element from the beginning of this Vector. If the - // result argument is not NULL, the removed element is stored in the - // memory it points to. Otherwise the element is thrown away. - // Returns true iff the vector wasn't empty before the operation. - bool PopFront(E* result) { - if (size_ == 0) - return false; - - if (result != NULL) - *result = GetElement(0); - - Erase(0); - return true; - } - - // Inserts an element at the given index. It's the caller's - // responsibility to ensure that the given index is in the range [0, - // size()]. - void Insert(const E& element, int index) { - GrowIfNeeded(); - MoveElements(index, size_ - index, index + 1); - elements_[index] = new E(element); - size_++; - } - - // Erases the element at the specified index, or aborts the program if the - // index is not in range [0, size()). - void Erase(int index) { - GTEST_CHECK_(0 <= index && index < size_) - << "Invalid Vector index " << index << ": must be in range [0, " - << (size_ - 1) << "]."; - - delete elements_[index]; - MoveElements(index + 1, size_ - index - 1, index); - size_--; - } - - // Returns the number of elements that satisfy a given predicate. - // The parameter 'predicate' is a Boolean function or functor that - // accepts a 'const E &', where E is the element type. - template <typename P> // P is the type of the predicate function/functor - int CountIf(P predicate) const { - int count = 0; - for (int i = 0; i < size_; i++) { - if (predicate(*(elements_[i]))) { - count++; - } - } - - return count; - } - - // Applies a function/functor to each element in the Vector. The - // parameter 'functor' is a function/functor that accepts a 'const - // E &', where E is the element type. This method does not change - // the elements. - template <typename F> // F is the type of the function/functor - void ForEach(F functor) const { - for (int i = 0; i < size_; i++) { - functor(*(elements_[i])); - } - } - - // Returns the first node whose element satisfies a given predicate, - // or NULL if none is found. The parameter 'predicate' is a - // function/functor that accepts a 'const E &', where E is the - // element type. This method does not change the elements. - template <typename P> // P is the type of the predicate function/functor. - const E* FindIf(P predicate) const { - for (int i = 0; i < size_; i++) { - if (predicate(*elements_[i])) { - return elements_[i]; - } - } - return NULL; - } - - template <typename P> - E* FindIf(P predicate) { - for (int i = 0; i < size_; i++) { - if (predicate(*elements_[i])) { - return elements_[i]; - } - } - return NULL; - } - - // Returns the i-th element of the Vector, or aborts the program if i - // is not in range [0, size()). - const E& GetElement(int i) const { - GTEST_CHECK_(0 <= i && i < size_) - << "Invalid Vector index " << i << ": must be in range [0, " - << (size_ - 1) << "]."; - - return *(elements_[i]); - } - - // Returns a mutable reference to the i-th element of the Vector, or - // aborts the program if i is not in range [0, size()). - E& GetMutableElement(int i) { - GTEST_CHECK_(0 <= i && i < size_) - << "Invalid Vector index " << i << ": must be in range [0, " - << (size_ - 1) << "]."; +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); - 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); - } - } +// STL container utilities. - // 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; - } +// Returns the number of elements in the given container that satisfy +// the given predicate. +template <class Container, typename Predicate> +inline int CountIf(const Container& c, Predicate predicate) { + return static_cast<int>(std::count_if(c.begin(), c.end(), predicate)); +} - 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]))); - } +// Applies a function/functor to each element in the container. +template <class Container, typename Functor> +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} - // Grows the buffer if it is not big enough to hold one more element. - void GrowIfNeeded() { - if (size_ < capacity_) - return; - - // Exponential bump-up is necessary to ensure that inserting N - // elements is O(N) instead of O(N^2). The factor 3/2 means that - // no more than 1/3 of the slots are wasted. - const int new_capacity = 3*(capacity_/2 + 1); - GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow? - << "Cannot grow a Vector with " << capacity_ << " elements already."; - Reserve(new_capacity); - } +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template <typename E> +inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { + return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i]; +} - // Moves the give consecutive elements to a new index in the Vector. - void MoveElements(int source, int count, int dest) { - memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0])); +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template <typename E> +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector<E>* v) { + const int size = static_cast<int>(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); } +} - E** elements_; - int capacity_; // The number of elements allocated for elements_. - int size_; // The number of elements; in the range [0, capacity_]. - - // We disallow copying Vector. - GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector); -}; // class Vector +// Performs an in-place shuffle of the vector's elements. +template <typename E> +inline void Shuffle(internal::Random* random, std::vector<E>* v) { + ShuffleRange(random, 0, static_cast<int>(v->size()), v); +} // A function for deleting an object. Handy for being used as a // functor. template <typename T> -static void Delete(T * x) { +static void Delete(T* x) { delete x; } @@ -600,7 +429,7 @@ class TestInfoImpl { // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. -class UnitTestOptions { +class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. @@ -642,7 +471,7 @@ class UnitTestOptions { // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. -FilePath GetCurrentExecutableName(); +GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { @@ -733,7 +562,7 @@ class DefaultPerThreadTestPartResultReporter // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. -class UnitTestImpl { +class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); @@ -802,15 +631,15 @@ 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 { - const int index = test_case_indices_.GetElementOr(i, -1); - return index < 0 ? NULL : test_cases_.GetElement(i); + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[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); + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; } // Provides access to the event listener list. @@ -898,15 +727,15 @@ class UnitTestImpl { #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* current_test_case) { - current_test_case_ = current_test_case; + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. - void set_current_test_info(TestInfo* current_test_info) { - current_test_info_ = current_test_info; + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and @@ -927,7 +756,7 @@ class UnitTestImpl { // Clears the results of all tests, including the ad hoc test. void ClearResult() { - test_cases_.ForEach(TestCase::ClearTestCaseResult); + ForEach(test_cases_, TestCase::ClearTestCaseResult); ad_hoc_test_result_.Clear(); } @@ -953,17 +782,14 @@ class UnitTestImpl { // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. - internal::Vector<Environment*>* environments() { return &environments_; } - internal::Vector<Environment*>* environments_in_reverse_order() { - return &environments_in_reverse_order_; - } + std::vector<Environment*>& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. - internal::Vector<TraceInfo>* gtest_trace_stack() { - return gtest_trace_stack_.pointer(); + std::vector<TraceInfo>& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); } - const internal::Vector<TraceInfo>* gtest_trace_stack() const { - return gtest_trace_stack_.pointer(); + const std::vector<TraceInfo>& gtest_trace_stack() const { + return gtest_trace_stack_.get(); } #if GTEST_HAS_DEATH_TEST @@ -1038,20 +864,18 @@ class UnitTestImpl { per_thread_test_part_result_reporter_; // The vector of environments that need to be set-up/torn-down - // before/after the tests are run. environments_in_reverse_order_ - // simply mirrors environments_ in reverse order. - internal::Vector<Environment*> environments_; - internal::Vector<Environment*> environments_in_reverse_order_; + // before/after the tests are run. + std::vector<Environment*> environments_; // The vector of TestCases in their original order. It owns the // elements in the vector. - internal::Vector<TestCase*> test_cases_; + std::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_; + std::vector<int> test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized @@ -1117,7 +941,7 @@ class UnitTestImpl { #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_; + internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl @@ -1130,24 +954,24 @@ inline UnitTestImpl* GetUnitTestImpl() { // Internal helper functions for implementing the simple regular // expression matcher. -bool IsInSet(char ch, const char* str); -bool IsDigit(char ch); -bool IsPunct(char ch); -bool IsRepeat(char ch); -bool IsWhiteSpace(char ch); -bool IsWordChar(char ch); -bool IsValidEscape(char ch); -bool AtomMatchesChar(bool escaped, char pattern, char ch); -bool ValidateRegex(const char* regex); -bool MatchRegexAtHead(const char* regex, const char* str); -bool MatchRepetitionAndRegexAtHead( +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsDigit(char ch); +GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsWhiteSpace(char ch); +GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); -bool MatchRegexAnywhere(const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); // Parses the command line for Google Test flags, without initializing // other parts of Google Test. -void ParseGoogleTestFlagsOnly(int* argc, char** argv); -void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST @@ -1224,6 +1048,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, @@ -1235,7 +1062,7 @@ class TestResultAccessor { test_result->ClearTestPartResults(); } - static const Vector<testing::TestPartResult>& test_part_results( + static const std::vector<testing::TestPartResult>& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } diff --git a/gtest/src/gtest-port.cc b/gtest/src/gtest-port.cc index de169e2..b9504f5 100644 --- a/gtest/src/gtest-port.cc +++ b/gtest/src/gtest-port.cc @@ -68,8 +68,10 @@ namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else +const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER @@ -109,8 +111,14 @@ size_t GetThreadCount() { // Implements RE. Currently only needed for death tests. RE::~RE() { - regfree(&partial_regex_); - regfree(&full_regex_); + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } free(const_cast<char*>(pattern_)); } @@ -150,9 +158,10 @@ void RE::Init(const char* regex) { // Some implementation of POSIX regex (e.g. on at least some // versions of Cygwin) doesn't accept the empty string as a valid // regex. We change it to an equivalent form "()" to be safe. - const char* const partial_regex = (*regex == '\0') ? "()" : regex; - is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0) - && is_valid_; + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; @@ -439,81 +448,83 @@ GTestLog::~GTestLog() { #pragma warning(disable: 4996) #endif // _MSC_VER -// Defines the stderr capturer. +#if GTEST_HAS_STREAM_REDIRECTION_ -class CapturedStderr { +// Object that captures an output stream (stdout/stderr). +class CapturedStream { public: - // The ctor redirects stderr to a temporary file. - CapturedStderr() { -#if GTEST_OS_WINDOWS_MOBILE - // Not supported on Windows CE. - posix::Abort(); -#else - uncaptured_fd_ = dup(kStdErrFileno); - + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { #if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; filename_ = temp_file_path; #else // There's no guarantee that a test has write access to the // current directory, so we create the temporary file in the /tmp // directory instead. - char name_template[] = "/tmp/captured_stderr.XXXXXX"; + char name_template[] = "/tmp/captured_stream.XXXXXX"; const int captured_fd = mkstemp(name_template); filename_ = name_template; #endif // GTEST_OS_WINDOWS fflush(NULL); - dup2(captured_fd, kStdErrFileno); + dup2(captured_fd, fd_); close(captured_fd); -#endif // GTEST_OS_WINDOWS_MOBILE } - ~CapturedStderr() { -#if !GTEST_OS_WINDOWS_MOBILE + ~CapturedStream() { remove(filename_.c_str()); -#endif // !GTEST_OS_WINDOWS_MOBILE } - // Stops redirecting stderr. - void StopCapture() { -#if !GTEST_OS_WINDOWS_MOBILE - // Restores the original stream. - fflush(NULL); - dup2(uncaptured_fd_, kStdErrFileno); - close(uncaptured_fd_); - uncaptured_fd_ = -1; -#endif // !GTEST_OS_WINDOWS_MOBILE - } + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } - // Returns the name of the temporary file holding the stderr output. - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - ::std::string filename() const { return filename_; } + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; + } private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. int uncaptured_fd_; + // Name of the temporary file holding the stderr output. ::std::string filename_; -}; -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - -static CapturedStderr* g_captured_stderr = NULL; + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; // Returns the size (in bytes) of a file. -static size_t GetFileSize(FILE * file) { +size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast<size_t>(ftell(file)); } // Reads the entire content of a file as a string. -static String ReadEntireFile(FILE * file) { +String CapturedStream::ReadEntireFile(FILE* file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; @@ -535,30 +546,50 @@ static String ReadEntireFile(FILE * file) { return content; } -// Starts capturing stderr. -void CaptureStderr() { - if (g_captured_stderr != NULL) { - GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time."; +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; } - g_captured_stderr = new CapturedStderr; + *stream = new CapturedStream(fd); } -// Stops capturing stderr and returns the captured string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. -String GetCapturedStderr() { - g_captured_stderr->StopCapture(); +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); - FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r"); - const String content = ReadEntireFile(file); - posix::FClose(file); - - delete g_captured_stderr; - g_captured_stderr = NULL; + delete *captured_stream; + *captured_stream = NULL; return content; } +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). diff --git a/gtest/src/gtest-test-part.cc b/gtest/src/gtest-test-part.cc index 4f36df6..5d183a4 100644 --- a/gtest/src/gtest-test-part.cc +++ b/gtest/src/gtest-test-part.cc @@ -64,19 +64,9 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { << result.message() << std::endl; } -// Constructs an empty TestPartResultArray. -TestPartResultArray::TestPartResultArray() - : array_(new internal::Vector<TestPartResult>) { -} - -// Destructs a TestPartResultArray. -TestPartResultArray::~TestPartResultArray() { - delete array_; -} - // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { - array_->PushBack(result); + array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). @@ -86,12 +76,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { internal::posix::Abort(); } - return array_->GetElement(index); + return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { - return array_->size(); + return static_cast<int>(array_.size()); } namespace internal { diff --git a/gtest/src/gtest-typed-test.cc b/gtest/src/gtest-typed-test.cc index 4a0f657..3cc4b5d 100644 --- a/gtest/src/gtest-typed-test.cc +++ b/gtest/src/gtest-typed-test.cc @@ -37,6 +37,14 @@ namespace internal { #if GTEST_HAS_TYPED_TEST_P +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (isspace(*str)) + str++; + return str; +} + // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. @@ -45,6 +53,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( typedef ::std::set<const char*>::const_iterator DefinedTestIter; registered_ = true; + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + Message errors; ::std::set<String> tests; for (const char* names = registered_tests; names != NULL; diff --git a/gtest/src/gtest.cc b/gtest/src/gtest.cc index 9340724..342d458 100644 --- a/gtest/src/gtest.cc +++ b/gtest/src/gtest.cc @@ -42,7 +42,10 @@ #include <wchar.h> #include <wctype.h> +#include <algorithm> #include <ostream> +#include <sstream> +#include <vector> #if GTEST_OS_LINUX @@ -131,6 +134,11 @@ namespace testing { +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + // Constants. // A test whose test case name or test name matches this filter is @@ -161,6 +169,10 @@ namespace internal { // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + } // namespace internal GTEST_DEFINE_bool_( @@ -242,7 +254,7 @@ GTEST_DEFINE_bool_( GTEST_DEFINE_int32_( stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); @@ -274,10 +286,6 @@ UInt32 Random::Generate(UInt32 range) { 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; - // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). @@ -292,11 +300,11 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. -static int SumOverTestCaseList(const internal::Vector<TestCase*>& case_list, +static int SumOverTestCaseList(const std::vector<TestCase*>& case_list, int (TestCase::*method)() const) { int sum = 0; - for (int i = 0; i < case_list.size(); i++) { - sum += (case_list.GetElement(i)->*method)(); + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); } return sum; } @@ -341,7 +349,7 @@ void AssertHelper::operator=(const Message& message) const { } // Mutex for linked pointers. -Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. String g_executable_path; @@ -672,23 +680,23 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread( // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { - return test_cases_.CountIf(TestCasePassed); + return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { - return test_cases_.CountIf(TestCaseFailed); + return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { - return test_cases_.size(); + return static_cast<int>(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { - return test_cases_.CountIf(ShouldRunTestCase); + return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. @@ -952,21 +960,37 @@ String FormatForFailureMessage(wchar_t wchar) { } // namespace internal -// AssertionResult constructor. -AssertionResult::AssertionResult(const internal::String& failure_message) - : failure_message_(failure_message) { +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new internal::String(*other.message_) : + static_cast<internal::String*>(NULL)) { } +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} // Makes a successful assertion result. AssertionResult AssertionSuccess() { - return AssertionResult(); + return AssertionResult(true); } +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} // Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { - return AssertionResult(message.GetString()); + return AssertionFailure() << message; } namespace internal { @@ -1008,6 +1032,20 @@ AssertionResult EqFailure(const char* expected_expression, return AssertionFailure(msg); } +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, @@ -1286,7 +1324,6 @@ AssertionResult IsNotSubstring( return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -#if GTEST_HAS_STD_STRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { @@ -1298,7 +1335,6 @@ AssertionResult IsNotSubstring( const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -#endif // GTEST_HAS_STD_STRING #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( @@ -1718,14 +1754,9 @@ String String::Format(const char * format, ...) { // Converts the buffer in a StrStream to a String, converting NUL // bytes to "\\0" along the way. String StrStreamToString(StrStream* ss) { -#if GTEST_HAS_STD_STRING const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); -#else - const char* const start = ss->str(); - const char* const end = start + ss->pcount(); -#endif // GTEST_HAS_STD_STRING // We need to use a helper StrStream to do this transformation // because String doesn't support push_back(). @@ -1738,14 +1769,7 @@ String StrStreamToString(StrStream* ss) { } } -#if GTEST_HAS_STD_STRING return String(helper.str().c_str()); -#else - const String str(helper.str(), helper.pcount()); - helper.freeze(false); - ss->freeze(false); - return str; -#endif // GTEST_HAS_STD_STRING } // Appends the user-supplied message to the Google-Test-generated message. @@ -1769,9 +1793,7 @@ String AppendUserMessage(const String& gtest_msg, // Creates an empty TestResult. TestResult::TestResult() - : test_part_results_(new internal::Vector<TestPartResult>), - test_properties_(new internal::Vector<TestProperty>), - death_test_count_(0), + : death_test_count_(0), elapsed_time_(0) { } @@ -1783,24 +1805,28 @@ TestResult::~TestResult() { // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { - return test_part_results_->GetElement(i); + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { - return test_properties_->GetElement(i); + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); } // Clears the test part results. void TestResult::ClearTestPartResults() { - test_part_results_->Clear(); + test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_->PushBack(test_part_result); + test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the @@ -1811,11 +1837,11 @@ void TestResult::RecordProperty(const TestProperty& test_property) { return; } internal::MutexLock lock(&test_properites_mutex_); - TestProperty* const property_with_matching_key = - test_properties_->FindIf( - internal::TestPropertyKeyIs(test_property.key())); - if (property_with_matching_key == NULL) { - test_properties_->PushBack(test_property); + const std::vector<TestProperty>::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); return; } property_with_matching_key->SetValue(test_property.value()); @@ -1838,8 +1864,8 @@ bool TestResult::ValidateTestProperty(const TestProperty& test_property) { // Clears the object. void TestResult::Clear() { - test_part_results_->Clear(); - test_properties_->Clear(); + test_part_results_.clear(); + test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } @@ -1860,7 +1886,7 @@ static bool TestPartFatallyFailed(const TestPartResult& result) { // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { - return test_part_results_->CountIf(TestPartFatallyFailed) > 0; + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. @@ -1870,18 +1896,18 @@ static bool TestPartNonfatallyFailed(const TestPartResult& result) { // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { - return test_part_results_->CountIf(TestPartNonfatallyFailed) > 0; + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { - return test_part_results_->size(); + return static_cast<int>(test_part_results_.size()); } // Returns the number of the test properties. int TestResult::test_property_count() const { - return test_properties_->size(); + return static_cast<int>(test_properties_.size()); } // class Test @@ -1965,7 +1991,7 @@ bool Test::HasSameFixtureClass() { // Info about the first test in the current test case. const internal::TestInfoImpl* const first_test_info = - test_case->test_info_list().GetElement(0)->impl(); + test_case->test_info_list()[0]->impl(); const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); const char* const first_test_name = first_test_info->name(); @@ -2093,14 +2119,14 @@ bool Test::HasNonfatalFailure() { // Constructs a TestInfo object. It assumes ownership of the test factory // object via impl_. -TestInfo::TestInfo(const char* test_case_name, - const char* name, - const char* test_case_comment, - const char* comment, +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) { - impl_ = new internal::TestInfoImpl(this, test_case_name, name, - test_case_comment, comment, + impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, + a_test_case_comment, a_comment, fixture_class_id, factory); } @@ -2309,26 +2335,26 @@ void TestInfoImpl::Run() { // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { - return test_info_list_->CountIf(TestPassed); + return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { - return test_info_list_->CountIf(TestFailed); + return CountIf(test_info_list_, TestFailed); } int TestCase::disabled_test_count() const { - return test_info_list_->CountIf(TestDisabled); + return CountIf(test_info_list_, TestDisabled); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { - return test_info_list_->CountIf(ShouldRunTest); + return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { - return test_info_list_->size(); + return static_cast<int>(test_info_list_.size()); } // Creates a TestCase with the given name. @@ -2338,13 +2364,11 @@ int TestCase::total_test_count() const { // name: name of the test case // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case -TestCase::TestCase(const char* name, const char* comment, +TestCase::TestCase(const char* a_name, const char* a_comment, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) - : name_(name), - comment_(comment), - test_info_list_(new internal::Vector<TestInfo*>), - test_indices_(new internal::Vector<int>), + : name_(a_name), + comment_(a_comment), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), @@ -2354,28 +2378,28 @@ TestCase::TestCase(const char* name, const char* comment, // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. - test_info_list_->ForEach(internal::Delete<TestInfo>); + ForEach(test_info_list_, internal::Delete<TestInfo>); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { - const int index = test_indices_->GetElementOr(i, -1); - return index < 0 ? NULL : test_info_list_->GetElement(index); + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[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); + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { - test_info_list_->PushBack(test_info); - test_indices_->PushBack(test_indices_->size()); + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast<int>(test_indices_.size())); } // Runs every test in this TestCase. @@ -2405,7 +2429,7 @@ void TestCase::Run() { // Clears the results of all tests in this test case. void TestCase::ClearResult() { - test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult); + ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); } // Returns true iff test passed. @@ -2432,13 +2456,13 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) { // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { - test_indices_->Shuffle(random); + Shuffle(random, &test_indices_); } // 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; + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast<int>(i); } } @@ -2614,10 +2638,15 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); + fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else @@ -2880,26 +2909,24 @@ class TestEventRepeater : public TestEventListener { // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. - Vector<TestEventListener*> listeners_; + std::vector<TestEventListener*> listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { - for (int i = 0; i < listeners_.size(); i++) { - delete listeners_.GetElement(i); - } + ForEach(listeners_, Delete<TestEventListener>); } void TestEventRepeater::Append(TestEventListener *listener) { - listeners_.PushBack(listener); + listeners_.push_back(listener); } // 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); + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); return listener; } } @@ -2912,8 +2939,8 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ - for (int i = 0; i < listeners_.size(); i++) { \ - listeners_.GetElement(i)->Name(parameter); \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ } \ } \ } @@ -2923,7 +2950,7 @@ void TestEventRepeater::Name(const Type& parameter) { \ 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); \ + listeners_[i]->Name(parameter); \ } \ } \ } @@ -2946,8 +2973,8 @@ GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) 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); + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); } } } @@ -2956,7 +2983,7 @@ 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); + listeners_[i]->OnTestIterationEnd(unit_test, iteration); } } } @@ -3152,14 +3179,11 @@ String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { // </testsuite> // </testsuites> -// Formats the given time in milliseconds as seconds. The returned -// C-string is owned by this function and cannot be released by the -// caller. Calling the function again invalidates the previous -// result. -const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) { - static String str; - str = (Message() << (ms/1000.0)).GetString(); - return str.c_str(); +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. @@ -3170,7 +3194,8 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, for (;;) { const char* const next_segment = strstr(segment, "]]>"); if (next_segment != NULL) { - stream->write(segment, next_segment - segment); + stream->write( + segment, static_cast<std::streamsize>(next_segment - segment)); *stream << "]]>]]><![CDATA["; segment = next_segment + strlen("]]>"); } else { @@ -3232,7 +3257,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, test_case.disabled_test_count()); fprintf(out, "errors=\"0\" time=\"%s\">\n", - FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); for (int i = 0; i < test_case.total_test_count(); ++i) { StrStream stream; OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); @@ -3251,7 +3276,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, unit_test.total_test_count(), unit_test.failed_test_count(), unit_test.disabled_test_count(), - FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str()); if (GTEST_FLAG(shuffle)) { fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); } @@ -3512,8 +3537,7 @@ Environment* UnitTest::AddEnvironment(Environment* env) { return NULL; } - impl_->environments()->PushBack(env); - impl_->environments_in_reverse_order()->PushFront(env); + impl_->environments().push_back(env); return env; } @@ -3544,12 +3568,12 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type, msg << message; internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack()->size() > 0) { + if (impl_->gtest_trace_stack().size() > 0) { msg << "\n" << GTEST_NAME_ << " trace:"; - for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) { - const internal::TraceInfo& trace = - impl_->gtest_trace_stack()->GetElement(i); + for (int i = static_cast<int>(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } @@ -3714,14 +3738,14 @@ UnitTest::~UnitTest() { // L < mutex_ void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PushFront(trace); + impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. // L < mutex_ void UnitTest::PopGTestTrace() { internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PopFront(NULL); + impl_->gtest_trace_stack().pop_back(); } namespace internal { @@ -3767,10 +3791,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. - test_cases_.ForEach(internal::Delete<TestCase>); + ForEach(test_cases_, internal::Delete<TestCase>); // Deletes every Environment. - environments_.ForEach(internal::Delete<Environment>); + ForEach(environments_, internal::Delete<Environment>); delete os_stack_trace_getter_; } @@ -3862,9 +3886,11 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? - TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name)); + const std::vector<TestCase*>::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); - if (test_case != NULL) + if (test_case != test_cases_.end()) return *test_case; // No. Let's create one. @@ -3878,18 +3904,20 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, // 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_); + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); } else { // No. Appends to the end of the list. - test_cases_.PushBack(new_test_case); + test_cases_.push_back(new_test_case); } - test_case_indices_.PushBack(test_case_indices_.size()); + test_case_indices_.push_back(static_cast<int>(test_case_indices_.size())); return new_test_case; } // Helpers for setting up / tearing down the given environment. They -// are for use in the Vector::ForEach() method. +// are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } @@ -3985,20 +4013,22 @@ int UnitTestImpl::RunAllTests() { if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); - environments_.ForEach(SetUpEnvironment); + ForEach(environments_, SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { - for (int i = 0; i < total_test_case_count(); i++) { - GetMutableTestCase(i)->Run(); + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); - environments_in_reverse_order_.ForEach(TearDownEnvironment); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } @@ -4144,13 +4174,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; - for (int i = 0; i < test_cases_.size(); i++) { - TestCase* const test_case = test_cases_.GetElement(i); + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; const String &test_case_name = test_case->name(); test_case->set_should_run(false); - for (int j = 0; j < test_case->test_info_list().size(); j++) { - TestInfo* const test_info = test_case->test_info_list().GetElement(j); + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; const String test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. @@ -4187,13 +4217,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { - for (int i = 0; i < test_cases_.size(); i++) { - const TestCase* const test_case = test_cases_.GetElement(i); + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; bool printed_test_case_name = false; - for (int j = 0; j < test_case->test_info_list().size(); j++) { + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = - test_case->test_info_list().GetElement(j); + test_case->test_info_list()[j]; if (test_info->matches_filter()) { if (!printed_test_case_name) { printed_test_case_name = true; @@ -4241,43 +4271,43 @@ TestResult* UnitTestImpl::current_test_result() { // 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); + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); // Shuffles the non-death test cases. - test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1, - test_cases_.size()); + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast<int>(test_cases_.size()), &test_case_indices_); // Shuffles the tests inside each test case. - for (int i = 0; i < test_cases_.size(); i++) { - test_cases_.GetElement(i)->ShuffleTests(random()); + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); } } // Restores the test cases and tests to their order before the first shuffle. void UnitTestImpl::UnshuffleTests() { - for (int i = 0; i < test_cases_.size(); i++) { + for (size_t i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. - test_cases_.GetElement(i)->UnshuffleTests(); + test_cases_[i]->UnshuffleTests(); // Resets the index of each test case. - test_case_indices_.GetMutableElement(i) = i; + test_case_indices_[i] = static_cast<int>(i); } } // TestInfoImpl constructor. The new instance assumes ownership of the test // factory object. TestInfoImpl::TestInfoImpl(TestInfo* parent, - const char* test_case_name, - const char* name, - const char* test_case_comment, - const char* comment, - TypeId fixture_class_id, + const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + TypeId a_fixture_class_id, internal::TestFactoryBase* factory) : parent_(parent), - test_case_name_(String(test_case_name)), - name_(String(name)), - test_case_comment_(String(test_case_comment)), - comment_(String(comment)), - fixture_class_id_(fixture_class_id), + test_case_name_(String(a_test_case_name)), + name_(String(a_name)), + test_case_comment_(String(a_test_case_comment)), + comment_(String(a_comment)), + fixture_class_id_(a_fixture_class_id), should_run_(false), is_disabled_(false), matches_filter_(false), @@ -4324,6 +4354,18 @@ bool AlwaysTrue() { return true; } +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. @@ -4413,6 +4455,21 @@ bool ParseStringFlag(const char* str, const char* flag, String* value) { return true; } +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + // Prints a string containing code-encoded text. The following escape // sequences can be used in the string to control the text color: // @@ -4553,6 +4610,8 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note @@ -4570,7 +4629,10 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?") { + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. g_help_flag = true; } } |