summaryrefslogtreecommitdiffstats
path: root/gtest/src
diff options
context:
space:
mode:
Diffstat (limited to 'gtest/src')
-rw-r--r--gtest/src/gtest-all.cc6
-rw-r--r--gtest/src/gtest-death-test.cc34
-rw-r--r--gtest/src/gtest-filepath.cc64
-rw-r--r--gtest/src/gtest-internal-inl.h413
-rw-r--r--gtest/src/gtest-port.cc151
-rw-r--r--gtest/src/gtest-test-part.cc16
-rw-r--r--gtest/src/gtest-typed-test.cc12
-rw-r--r--gtest/src/gtest.cc362
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 << "]]>]]&gt;<![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, &GTEST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
- ParseInt32Flag(arg, kStackTraceDepthFlag,
- &GTEST_FLAG(stack_trace_depth)) ||
ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_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;
}
}