diff options
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, 546 insertions, 512 deletions
diff --git a/gtest/src/gtest-all.cc b/gtest/src/gtest-all.cc index fe34765..a67ea0f 100644 --- a/gtest/src/gtest-all.cc +++ b/gtest/src/gtest-all.cc @@ -33,12 +33,6 @@ // // 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 3b73b01..106b01c 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* a_statement, const RE* a_regex) - : statement_(a_statement), - regex_(a_regex), + DeathTestImpl(const char* statement, const RE* regex) + : statement_(statement), + regex_(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 is_spawned) { spawned_ = is_spawned; } + void set_spawned(bool spawned) { spawned_ = spawned; } int status() const { return status_; } - void set_status(int a_status) { status_ = a_status; } + void set_status(int status) { status_ = status; } DeathTestOutcome outcome() const { return outcome_; } - void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } @@ -705,8 +705,8 @@ class ForkingDeathTest : public DeathTestImpl { }; // Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) - : DeathTestImpl(a_statement, a_regex), +ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) + : DeathTestImpl(statement, 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_value; - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); - set_status(status_value); - return status_value; + int status; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0)); + set_status(status); + return status; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: - NoExecDeathTest(const char* a_statement, const RE* a_regex) : - ForkingDeathTest(a_statement, a_regex) { } + NoExecDeathTest(const char* statement, const RE* regex) : + ForkingDeathTest(statement, 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* a_statement, const RE* a_regex, + ExecDeathTest(const char* statement, const RE* regex, const char* file, int line) : - ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + ForkingDeathTest(statement, regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. @@ -1037,6 +1037,8 @@ 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 c1ef918..515d61c 100644 --- a/gtest/src/gtest-filepath.cc +++ b/gtest/src/gtest-filepath.cc @@ -63,14 +63,8 @@ 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 @@ -87,15 +81,6 @@ 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 @@ -123,22 +108,6 @@ 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 @@ -146,7 +115,7 @@ const char* FilePath::FindLastPathSeparator() const { // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = FindLastPathSeparator(); + const char* const last_sep = strrchr(c_str(), kPathSeparator); return last_sep ? FilePath(String(last_sep + 1)) : *this; } @@ -157,7 +126,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 = FindLastPathSeparator(); + const char* const last_sep = strrchr(c_str(), kPathSeparator); String dir; if (last_sep) { dir = String(c_str(), last_sep + 1 - c_str()); @@ -250,7 +219,7 @@ bool FilePath::IsRootDirectory() const { // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else - return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); + return pathname_ == kPathSeparatorString; #endif } @@ -262,9 +231,9 @@ bool FilePath::IsAbsolutePath() const { ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && - IsPathSeparator(name[2]); + name[2] == kPathSeparator; #else - return IsPathSeparator(name[0]); + return name[0] == kPathSeparator; #endif } @@ -291,8 +260,7 @@ 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_.empty() && - IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); + return pathname_.EndsWith(kPathSeparatorString); } // Create directories so that path exists. Returns true if successful or if @@ -337,15 +305,14 @@ 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 IsDirectory() + return pathname_.EndsWith(kPathSeparatorString) ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) : *this; } -// Removes any redundant separators that might be in the pathname. +// Normalize 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_ = ""; @@ -357,19 +324,12 @@ void FilePath::Normalize() { memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { - *dest_ptr = *src; - if (!IsPathSeparator(*src)) { + *dest_ptr++ = *src; + if (*src != kPathSeparator) src++; - } else { -#if GTEST_HAS_ALT_PATH_SEP_ - if (*dest_ptr == kAlternatePathSeparator) { - *dest_ptr = kPathSeparator; - } -#endif - while (IsPathSeparator(*src)) + else + while (*src == kPathSeparator) 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 855b215..47aec22 100644 --- a/gtest/src/gtest-internal-inl.h +++ b/gtest/src/gtest-internal-inl.h @@ -52,9 +52,7 @@ #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> @@ -62,7 +60,7 @@ #include <windows.h> // For DWORD. #endif // GTEST_OS_WINDOWS -#include <gtest/gtest.h> // NOLINT +#include <gtest/gtest.h> #include <gtest/gtest-spi.h> namespace testing { @@ -78,7 +76,7 @@ namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). -GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; +extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; @@ -92,31 +90,13 @@ const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; -const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; -// g_help_flag is true iff the --help flag or an equivalent form is -// specified on the command line. -GTEST_API_ extern bool g_help_flag; - // Returns the current time in milliseconds. -GTEST_API_ TimeInMillis GetTimeInMillis(); - -// Returns true iff Google Test should use colors in the output. -GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); - -// Formats the given time in milliseconds as seconds. -GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); - -// Parses a string for an Int32 flag, in the form of "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -GTEST_API_ bool ParseInt32Flag( - const char* str, const char* flag, Int32* value); +TimeInMillis GetTimeInMillis(); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. @@ -164,7 +144,6 @@ 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); } @@ -184,7 +163,6 @@ 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: @@ -204,7 +182,6 @@ class GTestFlagSaver { internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; - internal::Int32 stack_trace_depth_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; @@ -216,7 +193,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)'. -GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); +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: @@ -231,7 +208,10 @@ GTEST_API_ 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. -GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); +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(); // 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 @@ -245,78 +225,269 @@ 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. -GTEST_API_ bool ShouldShard(const char* total_shards_str, - const char* shard_index_str, - bool in_subprocess_for_death_test); +bool ShouldShard(const char* total_shards_str, const char* shard_index_str, + bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. -GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); +Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. -GTEST_API_ bool ShouldRunTestOnShard( - int total_shards, int shard_index, int test_id); +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id); -// STL container utilities. +// 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; + } + } -// 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)); -} + // Gets the number of elements. + int size() const { return size_; } -// 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); -} + // 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_); } -// 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]; -} + // 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; -// 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]); + if (result != NULL) + *result = GetElement(0); + + Erase(0); + return true; } -} -// 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); -} + // 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) << "]."; + + 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_) + return; + + // Exponential bump-up is necessary to ensure that inserting N + // elements is O(N) instead of O(N^2). The factor 3/2 means that + // no more than 1/3 of the slots are wasted. + const int new_capacity = 3*(capacity_/2 + 1); + GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow? + << "Cannot grow a Vector with " << capacity_ << " elements already."; + Reserve(new_capacity); + } + + // Moves the give consecutive elements to a new index in the Vector. + void MoveElements(int source, int count, int dest) { + memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0])); + } + + E** elements_; + int capacity_; // The number of elements allocated for elements_. + int size_; // The number of elements; in the range [0, capacity_]. + + // We disallow copying Vector. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector); +}; // class Vector // A function for deleting an object. Handy for being used as a // functor. template <typename T> -static void Delete(T* x) { +static void Delete(T * x) { delete x; } @@ -429,7 +600,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 GTEST_API_ UnitTestOptions { +class UnitTestOptions { public: // Functions for processing the gtest_output flag. @@ -471,7 +642,7 @@ class GTEST_API_ UnitTestOptions { // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. -GTEST_API_ FilePath GetCurrentExecutableName(); +FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { @@ -562,7 +733,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 GTEST_API_ UnitTestImpl { +class UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); @@ -631,15 +802,15 @@ class GTEST_API_ 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 = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[i]; + 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 = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[index]; + const int index = test_case_indices_.GetElementOr(i, -1); + return index < 0 ? NULL : test_cases_.GetElement(index); } // Provides access to the event listener list. @@ -727,15 +898,15 @@ class GTEST_API_ UnitTestImpl { #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* a_current_test_case) { - current_test_case_ = a_current_test_case; + void set_current_test_case(TestCase* current_test_case) { + current_test_case_ = 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* a_current_test_info) { - current_test_info_ = a_current_test_info; + void set_current_test_info(TestInfo* current_test_info) { + current_test_info_ = current_test_info; } // Registers all parameterized tests defined using TEST_P and @@ -756,7 +927,7 @@ class GTEST_API_ UnitTestImpl { // Clears the results of all tests, including the ad hoc test. void ClearResult() { - ForEach(test_cases_, TestCase::ClearTestCaseResult); + test_cases_.ForEach(TestCase::ClearTestCaseResult); ad_hoc_test_result_.Clear(); } @@ -782,14 +953,17 @@ class GTEST_API_ UnitTestImpl { // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. - std::vector<Environment*>& environments() { return environments_; } + internal::Vector<Environment*>* environments() { return &environments_; } + internal::Vector<Environment*>* environments_in_reverse_order() { + return &environments_in_reverse_order_; + } // Getters for the per-thread Google Test trace stack. - std::vector<TraceInfo>& gtest_trace_stack() { - return *(gtest_trace_stack_.pointer()); + internal::Vector<TraceInfo>* gtest_trace_stack() { + return gtest_trace_stack_.pointer(); } - const std::vector<TraceInfo>& gtest_trace_stack() const { - return gtest_trace_stack_.get(); + const internal::Vector<TraceInfo>* gtest_trace_stack() const { + return gtest_trace_stack_.pointer(); } #if GTEST_HAS_DEATH_TEST @@ -864,18 +1038,20 @@ class GTEST_API_ 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. - std::vector<Environment*> environments_; + // 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_; // The vector of TestCases in their original order. It owns the // elements in the vector. - std::vector<TestCase*> test_cases_; + 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. - std::vector<int> test_case_indices_; + internal::Vector<int> test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized @@ -941,7 +1117,7 @@ class GTEST_API_ UnitTestImpl { #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; + internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl @@ -954,24 +1130,24 @@ inline UnitTestImpl* GetUnitTestImpl() { // Internal helper functions for implementing the simple regular // expression matcher. -GTEST_API_ bool IsInSet(char ch, const char* str); -GTEST_API_ bool IsDigit(char ch); -GTEST_API_ bool IsPunct(char ch); -GTEST_API_ bool IsRepeat(char ch); -GTEST_API_ bool IsWhiteSpace(char ch); -GTEST_API_ bool IsWordChar(char ch); -GTEST_API_ bool IsValidEscape(char ch); -GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); -GTEST_API_ bool ValidateRegex(const char* regex); -GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); -GTEST_API_ bool MatchRepetitionAndRegexAtHead( +bool 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( bool escaped, char ch, char repeat, const char* regex, const char* str); -GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); +bool MatchRegexAnywhere(const char* regex, const char* str); // Parses the command line for Google Test flags, without initializing // other parts of Google Test. -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); +void ParseGoogleTestFlagsOnly(int* argc, char** argv); +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST @@ -1048,9 +1224,6 @@ 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, @@ -1062,7 +1235,7 @@ class TestResultAccessor { test_result->ClearTestPartResults(); } - static const std::vector<testing::TestPartResult>& test_part_results( + static const 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 b9504f5..de169e2 100644 --- a/gtest/src/gtest-port.cc +++ b/gtest/src/gtest-port.cc @@ -68,10 +68,8 @@ 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 @@ -111,14 +109,8 @@ size_t GetThreadCount() { // Implements RE. Currently only needed for death tests. RE::~RE() { - 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_); - } + regfree(&partial_regex_); + regfree(&full_regex_); free(const_cast<char*>(pattern_)); } @@ -158,10 +150,9 @@ 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. - if (is_valid_) { - const char* const partial_regex = (*regex == '\0') ? "()" : regex; - is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; - } + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0) + && is_valid_; EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; @@ -448,83 +439,81 @@ GTestLog::~GTestLog() { #pragma warning(disable: 4996) #endif // _MSC_VER -#if GTEST_HAS_STREAM_REDIRECTION_ +// Defines the stderr capturer. -// Object that captures an output stream (stdout/stderr). -class CapturedStream { +class CapturedStderr { public: - // The ctor redirects the stream to a temporary file. - CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { + // The ctor redirects stderr to a temporary file. + CapturedStderr() { +#if GTEST_OS_WINDOWS_MOBILE + // Not supported on Windows CE. + posix::Abort(); +#else + uncaptured_fd_ = dup(kStdErrFileno); + #if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - const UINT success = ::GetTempFileNameA(temp_dir_path, - "gtest_redir", - 0, // Generate unique file name. - temp_file_path); - GTEST_CHECK_(success != 0) - << "Unable to create a temporary file in " << temp_dir_path; + ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_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_stream.XXXXXX"; + char name_template[] = "/tmp/captured_stderr.XXXXXX"; const int captured_fd = mkstemp(name_template); filename_ = name_template; #endif // GTEST_OS_WINDOWS fflush(NULL); - dup2(captured_fd, fd_); + dup2(captured_fd, kStdErrFileno); close(captured_fd); +#endif // GTEST_OS_WINDOWS_MOBILE } - ~CapturedStream() { + ~CapturedStderr() { +#if !GTEST_OS_WINDOWS_MOBILE remove(filename_.c_str()); +#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; - } - - FILE* const file = posix::FOpen(filename_.c_str(), "r"); - const String content = ReadEntireFile(file); - posix::FClose(file); - return content; + // 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 } - 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); + // 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_; } - const int fd_; // A stream to capture. + private: int uncaptured_fd_; - // Name of the temporary file holding the stderr output. ::std::string filename_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStderr* g_captured_stderr = NULL; + // Returns the size (in bytes) of a file. -size_t CapturedStream::GetFileSize(FILE* file) { +static size_t 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. -String CapturedStream::ReadEntireFile(FILE* file) { +static String ReadEntireFile(FILE * file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; @@ -546,50 +535,30 @@ String CapturedStream::ReadEntireFile(FILE* file) { return content; } -#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."; +// Starts capturing stderr. +void CaptureStderr() { + if (g_captured_stderr != NULL) { + GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time."; } - *stream = new CapturedStream(fd); + g_captured_stderr = new CapturedStderr; } -// Stops capturing the output stream and returns the captured string. -String GetCapturedStream(CapturedStream** captured_stream) { - const String content = (*captured_stream)->GetCapturedString(); +// 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(); - delete *captured_stream; - *captured_stream = NULL; + FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); - return content; -} + delete g_captured_stderr; + g_captured_stderr = NULL; -// Starts capturing stdout. -void CaptureStdout() { - CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); -} - -// Starts capturing stderr. -void CaptureStderr() { - CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); + return content; } -// 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 5d183a4..4f36df6 100644 --- a/gtest/src/gtest-test-part.cc +++ b/gtest/src/gtest-test-part.cc @@ -64,9 +64,19 @@ 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_.push_back(result); + array_->PushBack(result); } // Returns the TestPartResult at the given index (0-based). @@ -76,12 +86,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { internal::posix::Abort(); } - return array_[index]; + return array_->GetElement(index); } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { - return static_cast<int>(array_.size()); + return array_->size(); } namespace internal { diff --git a/gtest/src/gtest-typed-test.cc b/gtest/src/gtest-typed-test.cc index 3cc4b5d..4a0f657 100644 --- a/gtest/src/gtest-typed-test.cc +++ b/gtest/src/gtest-typed-test.cc @@ -37,14 +37,6 @@ 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. @@ -53,10 +45,6 @@ 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 342d458..9340724 100644 --- a/gtest/src/gtest.cc +++ b/gtest/src/gtest.cc @@ -42,10 +42,7 @@ #include <wchar.h> #include <wctype.h> -#include <algorithm> #include <ostream> -#include <sstream> -#include <vector> #if GTEST_OS_LINUX @@ -134,11 +131,6 @@ 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 @@ -169,10 +161,6 @@ 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_( @@ -254,7 +242,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."); @@ -286,6 +274,10 @@ 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(). @@ -300,11 +292,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 std::vector<TestCase*>& case_list, +static int SumOverTestCaseList(const internal::Vector<TestCase*>& case_list, int (TestCase::*method)() const) { int sum = 0; - for (size_t i = 0; i < case_list.size(); i++) { - sum += (case_list[i]->*method)(); + for (int i = 0; i < case_list.size(); i++) { + sum += (case_list.GetElement(i)->*method)(); } return sum; } @@ -349,7 +341,7 @@ void AssertHelper::operator=(const Message& message) const { } // Mutex for linked pointers. -GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); +Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); // Application pathname gotten in InitGoogleTest. String g_executable_path; @@ -680,23 +672,23 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread( // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { - return CountIf(test_cases_, TestCasePassed); + return test_cases_.CountIf(TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { - return CountIf(test_cases_, TestCaseFailed); + return test_cases_.CountIf(TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { - return static_cast<int>(test_cases_.size()); + return 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 CountIf(test_cases_, ShouldRunTestCase); + return test_cases_.CountIf(ShouldRunTestCase); } // Gets the number of successful tests. @@ -960,37 +952,21 @@ String FormatForFailureMessage(wchar_t wchar) { } // namespace internal -// 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)) { +// AssertionResult constructor. +AssertionResult::AssertionResult(const internal::String& failure_message) + : failure_message_(failure_message) { } -// 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(true); + return AssertionResult(); } -// 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 AssertionFailure() << message; + return AssertionResult(message.GetString()); } namespace internal { @@ -1032,20 +1008,6 @@ 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, @@ -1324,6 +1286,7 @@ 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) { @@ -1335,6 +1298,7 @@ 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( @@ -1754,9 +1718,14 @@ 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(). @@ -1769,7 +1738,14 @@ 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. @@ -1793,7 +1769,9 @@ String AppendUserMessage(const String& gtest_msg, // Creates an empty TestResult. TestResult::TestResult() - : death_test_count_(0), + : test_part_results_(new internal::Vector<TestPartResult>), + test_properties_(new internal::Vector<TestProperty>), + death_test_count_(0), elapsed_time_(0) { } @@ -1805,28 +1783,24 @@ 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 { - if (i < 0 || i >= total_part_count()) - internal::posix::Abort(); - return test_part_results_.at(i); + return test_part_results_->GetElement(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { - if (i < 0 || i >= test_property_count()) - internal::posix::Abort(); - return test_properties_.at(i); + return test_properties_->GetElement(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_.push_back(test_part_result); + test_part_results_->PushBack(test_part_result); } // Adds a test property to the list. If a property with the same key as the @@ -1837,11 +1811,11 @@ void TestResult::RecordProperty(const TestProperty& test_property) { return; } internal::MutexLock lock(&test_properites_mutex_); - const std::vector<TestProperty>::iterator property_with_matching_key = - std::find_if(test_properties_.begin(), test_properties_.end(), - internal::TestPropertyKeyIs(test_property.key())); - if (property_with_matching_key == test_properties_.end()) { - test_properties_.push_back(test_property); + TestProperty* const property_with_matching_key = + test_properties_->FindIf( + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == NULL) { + test_properties_->PushBack(test_property); return; } property_with_matching_key->SetValue(test_property.value()); @@ -1864,8 +1838,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; } @@ -1886,7 +1860,7 @@ static bool TestPartFatallyFailed(const TestPartResult& result) { // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { - return CountIf(test_part_results_, TestPartFatallyFailed) > 0; + return test_part_results_->CountIf(TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. @@ -1896,18 +1870,18 @@ static bool TestPartNonfatallyFailed(const TestPartResult& result) { // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { - return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; + return test_part_results_->CountIf(TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { - return static_cast<int>(test_part_results_.size()); + return test_part_results_->size(); } // Returns the number of the test properties. int TestResult::test_property_count() const { - return static_cast<int>(test_properties_.size()); + return test_properties_->size(); } // class Test @@ -1991,7 +1965,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()[0]->impl(); + test_case->test_info_list().GetElement(0)->impl(); const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); const char* const first_test_name = first_test_info->name(); @@ -2119,14 +2093,14 @@ bool Test::HasNonfatalFailure() { // Constructs a TestInfo object. It assumes ownership of the test factory // object via impl_. -TestInfo::TestInfo(const char* a_test_case_name, - const char* a_name, - const char* a_test_case_comment, - const char* a_comment, +TestInfo::TestInfo(const char* test_case_name, + const char* name, + const char* test_case_comment, + const char* comment, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) { - impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, - a_test_case_comment, a_comment, + impl_ = new internal::TestInfoImpl(this, test_case_name, name, + test_case_comment, comment, fixture_class_id, factory); } @@ -2335,26 +2309,26 @@ void TestInfoImpl::Run() { // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { - return CountIf(test_info_list_, TestPassed); + return test_info_list_->CountIf(TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { - return CountIf(test_info_list_, TestFailed); + return test_info_list_->CountIf(TestFailed); } int TestCase::disabled_test_count() const { - return CountIf(test_info_list_, TestDisabled); + return test_info_list_->CountIf(TestDisabled); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { - return CountIf(test_info_list_, ShouldRunTest); + return test_info_list_->CountIf(ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { - return static_cast<int>(test_info_list_.size()); + return test_info_list_->size(); } // Creates a TestCase with the given name. @@ -2364,11 +2338,13 @@ 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* a_name, const char* a_comment, +TestCase::TestCase(const char* name, const char* comment, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) - : name_(a_name), - comment_(a_comment), + : 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), @@ -2378,28 +2354,28 @@ TestCase::TestCase(const char* a_name, const char* a_comment, // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. - ForEach(test_info_list_, internal::Delete<TestInfo>); + test_info_list_->ForEach(internal::Delete<TestInfo>); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; + 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 = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; + 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_.push_back(test_info); - test_indices_.push_back(static_cast<int>(test_indices_.size())); + test_info_list_->PushBack(test_info); + test_indices_->PushBack(test_indices_->size()); } // Runs every test in this TestCase. @@ -2429,7 +2405,7 @@ void TestCase::Run() { // Clears the results of all tests in this test case. void TestCase::ClearResult() { - ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); + test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult); } // Returns true iff test passed. @@ -2456,13 +2432,13 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) { // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { - Shuffle(random, &test_indices_); + test_indices_->Shuffle(random); } // Restores the test order to before the first shuffle. void TestCase::UnshuffleTests() { - for (size_t i = 0; i < test_indices_.size(); i++) { - test_indices_[i] = static_cast<int>(i); + for (int i = 0; i < test_indices_->size(); i++) { + test_indices_->GetMutableElement(i) = i; } } @@ -2638,15 +2614,10 @@ 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 @@ -2909,24 +2880,26 @@ class TestEventRepeater : public TestEventListener { // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. - std::vector<TestEventListener*> listeners_; + Vector<TestEventListener*> listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { - ForEach(listeners_, Delete<TestEventListener>); + for (int i = 0; i < listeners_.size(); i++) { + delete listeners_.GetElement(i); + } } void TestEventRepeater::Append(TestEventListener *listener) { - listeners_.push_back(listener); + listeners_.PushBack(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { - for (size_t i = 0; i < listeners_.size(); ++i) { - if (listeners_[i] == listener) { - listeners_.erase(listeners_.begin() + i); + for (int i = 0; i < listeners_.size(); ++i) { + if (listeners_.GetElement(i) == listener) { + listeners_.Erase(i); return listener; } } @@ -2939,8 +2912,8 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ - for (size_t i = 0; i < listeners_.size(); i++) { \ - listeners_[i]->Name(parameter); \ + for (int i = 0; i < listeners_.size(); i++) { \ + listeners_.GetElement(i)->Name(parameter); \ } \ } \ } @@ -2950,7 +2923,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_[i]->Name(parameter); \ + listeners_.GetElement(i)->Name(parameter); \ } \ } \ } @@ -2973,8 +2946,8 @@ GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { - for (size_t i = 0; i < listeners_.size(); i++) { - listeners_[i]->OnTestIterationStart(unit_test, iteration); + for (int i = 0; i < listeners_.size(); i++) { + listeners_.GetElement(i)->OnTestIterationStart(unit_test, iteration); } } } @@ -2983,7 +2956,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_[i]->OnTestIterationEnd(unit_test, iteration); + listeners_.GetElement(i)->OnTestIterationEnd(unit_test, iteration); } } } @@ -3179,11 +3152,14 @@ String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { // </testsuite> // </testsuites> -// Formats the given time in milliseconds as seconds. -std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { - ::std::stringstream ss; - ss << ms/1000.0; - return ss.str(); +// 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(); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. @@ -3194,8 +3170,7 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, for (;;) { const char* const next_segment = strstr(segment, "]]>"); if (next_segment != NULL) { - stream->write( - segment, static_cast<std::streamsize>(next_segment - segment)); + stream->write(segment, next_segment - segment); *stream << "]]>]]><![CDATA["; segment = next_segment + strlen("]]>"); } else { @@ -3257,7 +3232,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, test_case.disabled_test_count()); fprintf(out, "errors=\"0\" time=\"%s\">\n", - FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + 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)); @@ -3276,7 +3251,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()).c_str()); + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); } @@ -3537,7 +3512,8 @@ Environment* UnitTest::AddEnvironment(Environment* env) { return NULL; } - impl_->environments().push_back(env); + impl_->environments()->PushBack(env); + impl_->environments_in_reverse_order()->PushFront(env); return env; } @@ -3568,12 +3544,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 = static_cast<int>(impl_->gtest_trace_stack().size()); - i > 0; --i) { - const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) { + const internal::TraceInfo& trace = + impl_->gtest_trace_stack()->GetElement(i); msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } @@ -3738,14 +3714,14 @@ UnitTest::~UnitTest() { // L < mutex_ void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().push_back(trace); + impl_->gtest_trace_stack()->PushFront(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().pop_back(); + impl_->gtest_trace_stack()->PopFront(NULL); } namespace internal { @@ -3791,10 +3767,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. - ForEach(test_cases_, internal::Delete<TestCase>); + test_cases_.ForEach(internal::Delete<TestCase>); // Deletes every Environment. - ForEach(environments_, internal::Delete<Environment>); + environments_.ForEach(internal::Delete<Environment>); delete os_stack_trace_getter_; } @@ -3886,11 +3862,9 @@ 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? - const std::vector<TestCase*>::const_iterator test_case = - std::find_if(test_cases_.begin(), test_cases_.end(), - TestCaseNameIs(test_case_name)); + TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name)); - if (test_case != test_cases_.end()) + if (test_case != NULL) return *test_case; // No. Let's create one. @@ -3904,20 +3878,18 @@ 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. - ++last_death_test_case_; - test_cases_.insert(test_cases_.begin() + last_death_test_case_, - new_test_case); + test_cases_.Insert(new_test_case, ++last_death_test_case_); } else { // No. Appends to the end of the list. - test_cases_.push_back(new_test_case); + test_cases_.PushBack(new_test_case); } - test_case_indices_.push_back(static_cast<int>(test_case_indices_.size())); + test_case_indices_.PushBack(test_case_indices_.size()); return new_test_case; } // Helpers for setting up / tearing down the given environment. They -// are for use in the ForEach() function. +// are for use in the Vector::ForEach() method. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } @@ -4013,22 +3985,20 @@ int UnitTestImpl::RunAllTests() { if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); - ForEach(environments_, SetUpEnvironment); + environments_.ForEach(SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { - for (int test_index = 0; test_index < total_test_case_count(); - test_index++) { - GetMutableTestCase(test_index)->Run(); + for (int i = 0; i < total_test_case_count(); i++) { + GetMutableTestCase(i)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); - std::for_each(environments_.rbegin(), environments_.rend(), - TearDownEnvironment); + environments_in_reverse_order_.ForEach(TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } @@ -4174,13 +4144,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; - for (size_t i = 0; i < test_cases_.size(); i++) { - TestCase* const test_case = test_cases_[i]; + for (int i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_.GetElement(i); const String &test_case_name = test_case->name(); test_case->set_should_run(false); - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { - TestInfo* const test_info = test_case->test_info_list()[j]; + for (int j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list().GetElement(j); const String test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. @@ -4217,13 +4187,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { - for (size_t i = 0; i < test_cases_.size(); i++) { - const TestCase* const test_case = test_cases_[i]; + for (int i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_.GetElement(i); bool printed_test_case_name = false; - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + for (int j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = - test_case->test_info_list()[j]; + test_case->test_info_list().GetElement(j); if (test_info->matches_filter()) { if (!printed_test_case_name) { printed_test_case_name = true; @@ -4271,43 +4241,43 @@ TestResult* UnitTestImpl::current_test_result() { // making sure that death tests are still run first. void UnitTestImpl::ShuffleTests() { // Shuffles the death test cases. - ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + test_case_indices_.ShuffleRange(random(), 0, last_death_test_case_ + 1); // Shuffles the non-death test cases. - ShuffleRange(random(), last_death_test_case_ + 1, - static_cast<int>(test_cases_.size()), &test_case_indices_); + test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1, + test_cases_.size()); // Shuffles the tests inside each test case. - for (size_t i = 0; i < test_cases_.size(); i++) { - test_cases_[i]->ShuffleTests(random()); + 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 (size_t i = 0; i < test_cases_.size(); i++) { + for (int i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. - test_cases_[i]->UnshuffleTests(); + test_cases_.GetElement(i)->UnshuffleTests(); // Resets the index of each test case. - test_case_indices_[i] = static_cast<int>(i); + test_case_indices_.GetMutableElement(i) = i; } } // TestInfoImpl constructor. The new instance assumes ownership of the test // factory object. TestInfoImpl::TestInfoImpl(TestInfo* parent, - 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, + const char* test_case_name, + const char* name, + const char* test_case_comment, + const char* comment, + TypeId fixture_class_id, internal::TestFactoryBase* factory) : parent_(parent), - 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), + 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), should_run_(false), is_disabled_(false), matches_filter_(false), @@ -4354,18 +4324,6 @@ 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. @@ -4455,21 +4413,6 @@ 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: // @@ -4610,8 +4553,6 @@ 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 @@ -4629,10 +4570,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?" || - HasGoogleTestFlagPrefix(arg)) { - // Both help flag and unrecognized Google Test flags (excluding - // internal ones) trigger help display. + arg_string == "-?" || arg_string == "/?") { g_help_flag = true; } } |