Simplifies the implementation by using std::vector instead of Vector.

This commit is contained in:
zhanyong.wan
2010-02-25 01:09:07 +00:00
parent 3bef459eac
commit 0d27868d0f
10 changed files with 340 additions and 821 deletions

View File

@@ -52,7 +52,9 @@
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
#include <string.h> // For memmove.
#include <algorithm>
#include <string>
#include <vector>
#include <gtest/internal/gtest-port.h>
@@ -243,255 +245,62 @@ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
// method. Assumes that 0 <= shard_index < total_shards.
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
// Vector is an ordered container that supports random access to the
// elements.
//
// We cannot use std::vector, as Visual C++ 7.1's implementation of
// STL has problems compiling when exceptions are disabled. There is
// a hack to work around the problems, but we've seen cases where the
// hack fails to work.
//
// The element type must support copy constructor and operator=.
template <typename E> // E is the element type.
class Vector {
public:
// Creates an empty Vector.
Vector() : elements_(NULL), capacity_(0), size_(0) {}
// STL container utilities.
// D'tor.
virtual ~Vector() { Clear(); }
// 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 std::count_if(c.begin(), c.end(), predicate);
}
// Clears the Vector.
void Clear() {
if (elements_ != NULL) {
for (int i = 0; i < size_; i++) {
delete elements_[i];
}
// 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);
}
free(elements_);
elements_ = NULL;
capacity_ = size_ = 0;
}
// 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];
}
// 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]);
}
}
// Gets the number of elements.
int size() const { return size_; }
// Adds an element to the end of the Vector. A copy of the element
// is created using the copy constructor, and then stored in the
// Vector. Changes made to the element in the Vector doesn't affect
// the source object, and vice versa.
void PushBack(const E& element) { Insert(element, size_); }
// Adds an element to the beginning of this Vector.
void PushFront(const E& element) { Insert(element, 0); }
// Removes an element from the beginning of this Vector. If the
// result argument is not NULL, the removed element is stored in the
// memory it points to. Otherwise the element is thrown away.
// Returns true iff the vector wasn't empty before the operation.
bool PopFront(E* result) {
if (size_ == 0)
return false;
if (result != NULL)
*result = GetElement(0);
Erase(0);
return true;
}
// Inserts an element at the given index. It's the caller's
// responsibility to ensure that the given index is in the range [0,
// size()].
void Insert(const E& element, int index) {
GrowIfNeeded();
MoveElements(index, size_ - index, index + 1);
elements_[index] = new E(element);
size_++;
}
// Erases the element at the specified index, or aborts the program if the
// index is not in range [0, size()).
void Erase(int index) {
GTEST_CHECK_(0 <= index && index < size_)
<< "Invalid Vector index " << index << ": must be in range [0, "
<< (size_ - 1) << "].";
delete elements_[index];
MoveElements(index + 1, size_ - index - 1, index);
size_--;
}
// Returns the number of elements that satisfy a given predicate.
// The parameter 'predicate' is a Boolean function or functor that
// accepts a 'const E &', where E is the element type.
template <typename P> // P is the type of the predicate function/functor
int CountIf(P predicate) const {
int count = 0;
for (int i = 0; i < size_; i++) {
if (predicate(*(elements_[i]))) {
count++;
}
}
return count;
}
// Applies a function/functor to each element in the Vector. The
// parameter 'functor' is a function/functor that accepts a 'const
// E &', where E is the element type. This method does not change
// the elements.
template <typename F> // F is the type of the function/functor
void ForEach(F functor) const {
for (int i = 0; i < size_; i++) {
functor(*(elements_[i]));
}
}
// Returns the first node whose element satisfies a given predicate,
// or NULL if none is found. The parameter 'predicate' is a
// function/functor that accepts a 'const E &', where E is the
// element type. This method does not change the elements.
template <typename P> // P is the type of the predicate function/functor.
const E* FindIf(P predicate) const {
for (int i = 0; i < size_; i++) {
if (predicate(*elements_[i])) {
return elements_[i];
}
}
return NULL;
}
template <typename P>
E* FindIf(P predicate) {
for (int i = 0; i < size_; i++) {
if (predicate(*elements_[i])) {
return elements_[i];
}
}
return NULL;
}
// Returns the i-th element of the Vector, or aborts the program if i
// is not in range [0, size()).
const E& GetElement(int i) const {
GTEST_CHECK_(0 <= i && i < size_)
<< "Invalid Vector index " << i << ": must be in range [0, "
<< (size_ - 1) << "].";
return *(elements_[i]);
}
// Returns a mutable reference to the i-th element of the Vector, or
// aborts the program if i is not in range [0, size()).
E& GetMutableElement(int i) {
GTEST_CHECK_(0 <= i && i < size_)
<< "Invalid Vector index " << i << ": must be in range [0, "
<< (size_ - 1) << "].";
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
// 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, v->size(), v);
}
// A function for deleting an object. Handy for being used as a
// functor.
template <typename T>
static void Delete(T * x) {
static void Delete(T* x) {
delete x;
}
@@ -806,15 +615,15 @@ class UnitTestImpl {
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const {
const int index = test_case_indices_.GetElementOr(i, -1);
return index < 0 ? NULL : test_cases_.GetElement(i);
const int index = GetElementOr(test_case_indices_, i, -1);
return index < 0 ? NULL : test_cases_[i];
}
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
TestCase* GetMutableTestCase(int i) {
const int index = test_case_indices_.GetElementOr(i, -1);
return index < 0 ? NULL : test_cases_.GetElement(index);
const int index = GetElementOr(test_case_indices_, i, -1);
return index < 0 ? NULL : test_cases_[index];
}
// Provides access to the event listener list.
@@ -931,7 +740,7 @@ class UnitTestImpl {
// Clears the results of all tests, including the ad hoc test.
void ClearResult() {
test_cases_.ForEach(TestCase::ClearTestCaseResult);
ForEach(test_cases_, TestCase::ClearTestCaseResult);
ad_hoc_test_result_.Clear();
}
@@ -957,17 +766,14 @@ class UnitTestImpl {
// Returns the vector of environments that need to be set-up/torn-down
// before/after the tests are run.
internal::Vector<Environment*>* environments() { return &environments_; }
internal::Vector<Environment*>* environments_in_reverse_order() {
return &environments_in_reverse_order_;
}
std::vector<Environment*>& environments() { return environments_; }
// Getters for the per-thread Google Test trace stack.
internal::Vector<TraceInfo>* gtest_trace_stack() {
return gtest_trace_stack_.pointer();
std::vector<TraceInfo>& gtest_trace_stack() {
return *(gtest_trace_stack_.pointer());
}
const internal::Vector<TraceInfo>* gtest_trace_stack() const {
return gtest_trace_stack_.pointer();
const std::vector<TraceInfo>& gtest_trace_stack() const {
return gtest_trace_stack_.get();
}
#if GTEST_HAS_DEATH_TEST
@@ -1042,20 +848,18 @@ class UnitTestImpl {
per_thread_test_part_result_reporter_;
// The vector of environments that need to be set-up/torn-down
// before/after the tests are run. environments_in_reverse_order_
// simply mirrors environments_ in reverse order.
internal::Vector<Environment*> environments_;
internal::Vector<Environment*> environments_in_reverse_order_;
// before/after the tests are run.
std::vector<Environment*> environments_;
// The vector of TestCases in their original order. It owns the
// elements in the vector.
internal::Vector<TestCase*> test_cases_;
std::vector<TestCase*> test_cases_;
// Provides a level of indirection for the test case list to allow
// easy shuffling and restoring the test case order. The i-th
// element of this vector is the index of the i-th test case in the
// shuffled order.
internal::Vector<int> test_case_indices_;
std::vector<int> test_case_indices_;
#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
@@ -1121,7 +925,7 @@ class UnitTestImpl {
#endif // GTEST_HAS_DEATH_TEST
// A per-thread stack of traces created by the SCOPED_TRACE() macro.
internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_;
internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
}; // class UnitTestImpl
@@ -1242,7 +1046,7 @@ class TestResultAccessor {
test_result->ClearTestPartResults();
}
static const Vector<testing::TestPartResult>& test_part_results(
static const std::vector<testing::TestPartResult>& test_part_results(
const TestResult& test_result) {
return test_result.test_part_results();
}

View File

@@ -64,19 +64,9 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
<< result.message() << std::endl;
}
// Constructs an empty TestPartResultArray.
TestPartResultArray::TestPartResultArray()
: array_(new internal::Vector<TestPartResult>) {
}
// Destructs a TestPartResultArray.
TestPartResultArray::~TestPartResultArray() {
delete array_;
}
// Appends a TestPartResult to the array.
void TestPartResultArray::Append(const TestPartResult& result) {
array_->PushBack(result);
array_.push_back(result);
}
// Returns the TestPartResult at the given index (0-based).
@@ -86,12 +76,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
internal::posix::Abort();
}
return array_->GetElement(index);
return array_[index];
}
// Returns the number of TestPartResult objects in the array.
int TestPartResultArray::size() const {
return array_->size();
return array_.size();
}
namespace internal {

View File

@@ -42,8 +42,10 @@
#include <wchar.h>
#include <wctype.h>
#include <algorithm>
#include <ostream>
#include <sstream>
#include <vector>
#if GTEST_OS_LINUX
@@ -132,6 +134,11 @@
namespace testing {
using internal::CountIf;
using internal::ForEach;
using internal::GetElementOr;
using internal::Shuffle;
// Constants.
// A test whose test case name or test name matches this filter is
@@ -293,11 +300,11 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
// Iterates over a vector of TestCases, keeping a running sum of the
// results of calling a given int-returning method on each.
// Returns the sum.
static int SumOverTestCaseList(const internal::Vector<TestCase*>& case_list,
static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
int (TestCase::*method)() const) {
int sum = 0;
for (int i = 0; i < case_list.size(); i++) {
sum += (case_list.GetElement(i)->*method)();
for (size_t i = 0; i < case_list.size(); i++) {
sum += (case_list[i]->*method)();
}
return sum;
}
@@ -673,12 +680,12 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
// Gets the number of successful test cases.
int UnitTestImpl::successful_test_case_count() const {
return test_cases_.CountIf(TestCasePassed);
return CountIf(test_cases_, TestCasePassed);
}
// Gets the number of failed test cases.
int UnitTestImpl::failed_test_case_count() const {
return test_cases_.CountIf(TestCaseFailed);
return CountIf(test_cases_, TestCaseFailed);
}
// Gets the number of all test cases.
@@ -689,7 +696,7 @@ int UnitTestImpl::total_test_case_count() const {
// Gets the number of all test cases that contain at least one test
// that should run.
int UnitTestImpl::test_case_to_run_count() const {
return test_cases_.CountIf(ShouldRunTestCase);
return CountIf(test_cases_, ShouldRunTestCase);
}
// Gets the number of successful tests.
@@ -1786,9 +1793,7 @@ String AppendUserMessage(const String& gtest_msg,
// Creates an empty TestResult.
TestResult::TestResult()
: test_part_results_(new internal::Vector<TestPartResult>),
test_properties_(new internal::Vector<TestProperty>),
death_test_count_(0),
: death_test_count_(0),
elapsed_time_(0) {
}
@@ -1800,24 +1805,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 {
return test_part_results_->GetElement(i);
return test_part_results_.at(i);
}
// Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, aborts the
// program.
const TestProperty& TestResult::GetTestProperty(int i) const {
return test_properties_->GetElement(i);
return test_properties_.at(i);
}
// Clears the test part results.
void TestResult::ClearTestPartResults() {
test_part_results_->Clear();
test_part_results_.clear();
}
// Adds a test part result to the list.
void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
test_part_results_->PushBack(test_part_result);
test_part_results_.push_back(test_part_result);
}
// Adds a test property to the list. If a property with the same key as the
@@ -1828,11 +1833,11 @@ void TestResult::RecordProperty(const TestProperty& test_property) {
return;
}
internal::MutexLock lock(&test_properites_mutex_);
TestProperty* const property_with_matching_key =
test_properties_->FindIf(
internal::TestPropertyKeyIs(test_property.key()));
if (property_with_matching_key == NULL) {
test_properties_->PushBack(test_property);
const std::vector<TestProperty>::iterator property_with_matching_key =
std::find_if(test_properties_.begin(), test_properties_.end(),
internal::TestPropertyKeyIs(test_property.key()));
if (property_with_matching_key == test_properties_.end()) {
test_properties_.push_back(test_property);
return;
}
property_with_matching_key->SetValue(test_property.value());
@@ -1855,8 +1860,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;
}
@@ -1877,7 +1882,7 @@ static bool TestPartFatallyFailed(const TestPartResult& result) {
// Returns true iff the test fatally failed.
bool TestResult::HasFatalFailure() const {
return test_part_results_->CountIf(TestPartFatallyFailed) > 0;
return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
}
// Returns true iff the test part non-fatally failed.
@@ -1887,18 +1892,18 @@ static bool TestPartNonfatallyFailed(const TestPartResult& result) {
// Returns true iff the test has a non-fatal failure.
bool TestResult::HasNonfatalFailure() const {
return test_part_results_->CountIf(TestPartNonfatallyFailed) > 0;
return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
}
// Gets the number of all test parts. This is the sum of the number
// of successful test parts and the number of failed test parts.
int TestResult::total_part_count() const {
return test_part_results_->size();
return test_part_results_.size();
}
// Returns the number of the test properties.
int TestResult::test_property_count() const {
return test_properties_->size();
return test_properties_.size();
}
// class Test
@@ -1982,7 +1987,7 @@ bool Test::HasSameFixtureClass() {
// Info about the first test in the current test case.
const internal::TestInfoImpl* const first_test_info =
test_case->test_info_list().GetElement(0)->impl();
test_case->test_info_list()[0]->impl();
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
const char* const first_test_name = first_test_info->name();
@@ -2326,26 +2331,26 @@ void TestInfoImpl::Run() {
// Gets the number of successful tests in this test case.
int TestCase::successful_test_count() const {
return test_info_list_->CountIf(TestPassed);
return CountIf(test_info_list_, TestPassed);
}
// Gets the number of failed tests in this test case.
int TestCase::failed_test_count() const {
return test_info_list_->CountIf(TestFailed);
return CountIf(test_info_list_, TestFailed);
}
int TestCase::disabled_test_count() const {
return test_info_list_->CountIf(TestDisabled);
return CountIf(test_info_list_, TestDisabled);
}
// Get the number of tests in this test case that should run.
int TestCase::test_to_run_count() const {
return test_info_list_->CountIf(ShouldRunTest);
return CountIf(test_info_list_, ShouldRunTest);
}
// Gets the number of all tests.
int TestCase::total_test_count() const {
return test_info_list_->size();
return test_info_list_.size();
}
// Creates a TestCase with the given name.
@@ -2360,8 +2365,6 @@ TestCase::TestCase(const char* a_name, const char* a_comment,
Test::TearDownTestCaseFunc tear_down_tc)
: name_(a_name),
comment_(a_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),
@@ -2371,28 +2374,28 @@ TestCase::TestCase(const char* a_name, const char* a_comment,
// Destructor of TestCase.
TestCase::~TestCase() {
// Deletes every Test in the collection.
test_info_list_->ForEach(internal::Delete<TestInfo>);
ForEach(test_info_list_, internal::Delete<TestInfo>);
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* TestCase::GetTestInfo(int i) const {
const int index = test_indices_->GetElementOr(i, -1);
return index < 0 ? NULL : test_info_list_->GetElement(index);
const int index = GetElementOr(test_indices_, i, -1);
return index < 0 ? NULL : test_info_list_[index];
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
TestInfo* TestCase::GetMutableTestInfo(int i) {
const int index = test_indices_->GetElementOr(i, -1);
return index < 0 ? NULL : test_info_list_->GetElement(index);
const int index = GetElementOr(test_indices_, i, -1);
return index < 0 ? NULL : test_info_list_[index];
}
// Adds a test to this test case. Will delete the test upon
// destruction of the TestCase object.
void TestCase::AddTestInfo(TestInfo * test_info) {
test_info_list_->PushBack(test_info);
test_indices_->PushBack(test_indices_->size());
test_info_list_.push_back(test_info);
test_indices_.push_back(test_indices_.size());
}
// Runs every test in this TestCase.
@@ -2422,7 +2425,7 @@ void TestCase::Run() {
// Clears the results of all tests in this test case.
void TestCase::ClearResult() {
test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult);
ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
}
// Returns true iff test passed.
@@ -2449,13 +2452,13 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
// Shuffles the tests in this test case.
void TestCase::ShuffleTests(internal::Random* random) {
test_indices_->Shuffle(random);
Shuffle(random, &test_indices_);
}
// Restores the test order to before the first shuffle.
void TestCase::UnshuffleTests() {
for (int i = 0; i < test_indices_->size(); i++) {
test_indices_->GetMutableElement(i) = i;
for (size_t i = 0; i < test_indices_.size(); i++) {
test_indices_[i] = i;
}
}
@@ -2902,26 +2905,24 @@ class TestEventRepeater : public TestEventListener {
// in death test child processes.
bool forwarding_enabled_;
// The list of listeners that receive events.
Vector<TestEventListener*> listeners_;
std::vector<TestEventListener*> listeners_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
};
TestEventRepeater::~TestEventRepeater() {
for (int i = 0; i < listeners_.size(); i++) {
delete listeners_.GetElement(i);
}
ForEach(listeners_, Delete<TestEventListener>);
}
void TestEventRepeater::Append(TestEventListener *listener) {
listeners_.PushBack(listener);
listeners_.push_back(listener);
}
// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
for (int i = 0; i < listeners_.size(); ++i) {
if (listeners_.GetElement(i) == listener) {
listeners_.Erase(i);
for (size_t i = 0; i < listeners_.size(); ++i) {
if (listeners_[i] == listener) {
listeners_.erase(listeners_.begin() + i);
return listener;
}
}
@@ -2934,8 +2935,8 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
#define GTEST_REPEATER_METHOD_(Name, Type) \
void TestEventRepeater::Name(const Type& parameter) { \
if (forwarding_enabled_) { \
for (int i = 0; i < listeners_.size(); i++) { \
listeners_.GetElement(i)->Name(parameter); \
for (size_t i = 0; i < listeners_.size(); i++) { \
listeners_[i]->Name(parameter); \
} \
} \
}
@@ -2945,7 +2946,7 @@ void TestEventRepeater::Name(const Type& parameter) { \
void TestEventRepeater::Name(const Type& parameter) { \
if (forwarding_enabled_) { \
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
listeners_.GetElement(i)->Name(parameter); \
listeners_[i]->Name(parameter); \
} \
} \
}
@@ -2968,8 +2969,8 @@ GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
int iteration) {
if (forwarding_enabled_) {
for (int i = 0; i < listeners_.size(); i++) {
listeners_.GetElement(i)->OnTestIterationStart(unit_test, iteration);
for (size_t i = 0; i < listeners_.size(); i++) {
listeners_[i]->OnTestIterationStart(unit_test, iteration);
}
}
}
@@ -2978,7 +2979,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
int iteration) {
if (forwarding_enabled_) {
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
listeners_.GetElement(i)->OnTestIterationEnd(unit_test, iteration);
listeners_[i]->OnTestIterationEnd(unit_test, iteration);
}
}
}
@@ -3532,8 +3533,7 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
return NULL;
}
impl_->environments()->PushBack(env);
impl_->environments_in_reverse_order()->PushFront(env);
impl_->environments().push_back(env);
return env;
}
@@ -3564,12 +3564,11 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
msg << message;
internal::MutexLock lock(&mutex_);
if (impl_->gtest_trace_stack()->size() > 0) {
if (impl_->gtest_trace_stack().size() > 0) {
msg << "\n" << GTEST_NAME_ << " trace:";
for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
const internal::TraceInfo& trace =
impl_->gtest_trace_stack()->GetElement(i);
for (int i = impl_->gtest_trace_stack().size(); i > 0; --i) {
const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
<< " " << trace.message;
}
@@ -3734,14 +3733,14 @@ UnitTest::~UnitTest() {
// L < mutex_
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
internal::MutexLock lock(&mutex_);
impl_->gtest_trace_stack()->PushFront(trace);
impl_->gtest_trace_stack().push_back(trace);
}
// Pops a trace from the per-thread Google Test trace stack.
// L < mutex_
void UnitTest::PopGTestTrace() {
internal::MutexLock lock(&mutex_);
impl_->gtest_trace_stack()->PopFront(NULL);
impl_->gtest_trace_stack().pop_back();
}
namespace internal {
@@ -3787,10 +3786,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
UnitTestImpl::~UnitTestImpl() {
// Deletes every TestCase.
test_cases_.ForEach(internal::Delete<TestCase>);
ForEach(test_cases_, internal::Delete<TestCase>);
// Deletes every Environment.
environments_.ForEach(internal::Delete<Environment>);
ForEach(environments_, internal::Delete<Environment>);
delete os_stack_trace_getter_;
}
@@ -3882,9 +3881,11 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name?
TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name));
const std::vector<TestCase*>::const_iterator test_case =
std::find_if(test_cases_.begin(), test_cases_.end(),
TestCaseNameIs(test_case_name));
if (test_case != NULL)
if (test_case != test_cases_.end())
return *test_case;
// No. Let's create one.
@@ -3898,18 +3899,20 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
// defined so far. This only works when the test cases haven't
// been shuffled. Otherwise we may end up running a death test
// after a non-death test.
test_cases_.Insert(new_test_case, ++last_death_test_case_);
++last_death_test_case_;
test_cases_.insert(test_cases_.begin() + last_death_test_case_,
new_test_case);
} else {
// No. Appends to the end of the list.
test_cases_.PushBack(new_test_case);
test_cases_.push_back(new_test_case);
}
test_case_indices_.PushBack(test_case_indices_.size());
test_case_indices_.push_back(test_case_indices_.size());
return new_test_case;
}
// Helpers for setting up / tearing down the given environment. They
// are for use in the Vector::ForEach() method.
// are for use in the ForEach() function.
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
@@ -4005,7 +4008,7 @@ int UnitTestImpl::RunAllTests() {
if (has_tests_to_run) {
// Sets up all environments beforehand.
repeater->OnEnvironmentsSetUpStart(*parent_);
environments_.ForEach(SetUpEnvironment);
ForEach(environments_, SetUpEnvironment);
repeater->OnEnvironmentsSetUpEnd(*parent_);
// Runs the tests only if there was no fatal failure during global
@@ -4019,7 +4022,8 @@ int UnitTestImpl::RunAllTests() {
// Tears down all environments in reverse order afterwards.
repeater->OnEnvironmentsTearDownStart(*parent_);
environments_in_reverse_order_.ForEach(TearDownEnvironment);
std::for_each(environments_.rbegin(), environments_.rend(),
TearDownEnvironment);
repeater->OnEnvironmentsTearDownEnd(*parent_);
}
@@ -4165,13 +4169,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// this shard.
int num_runnable_tests = 0;
int num_selected_tests = 0;
for (int i = 0; i < test_cases_.size(); i++) {
TestCase* const test_case = test_cases_.GetElement(i);
for (size_t i = 0; i < test_cases_.size(); i++) {
TestCase* const test_case = test_cases_[i];
const String &test_case_name = test_case->name();
test_case->set_should_run(false);
for (int j = 0; j < test_case->test_info_list().size(); j++) {
TestInfo* const test_info = test_case->test_info_list().GetElement(j);
for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
TestInfo* const test_info = test_case->test_info_list()[j];
const String test_name(test_info->name());
// A test is disabled if test case name or test name matches
// kDisableTestFilter.
@@ -4208,13 +4212,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// Prints the names of the tests matching the user-specified filter flag.
void UnitTestImpl::ListTestsMatchingFilter() {
for (int i = 0; i < test_cases_.size(); i++) {
const TestCase* const test_case = test_cases_.GetElement(i);
for (size_t i = 0; i < test_cases_.size(); i++) {
const TestCase* const test_case = test_cases_[i];
bool printed_test_case_name = false;
for (int j = 0; j < test_case->test_info_list().size(); j++) {
for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
const TestInfo* const test_info =
test_case->test_info_list().GetElement(j);
test_case->test_info_list()[j];
if (test_info->matches_filter()) {
if (!printed_test_case_name) {
printed_test_case_name = true;
@@ -4262,25 +4266,25 @@ TestResult* UnitTestImpl::current_test_result() {
// making sure that death tests are still run first.
void UnitTestImpl::ShuffleTests() {
// Shuffles the death test cases.
test_case_indices_.ShuffleRange(random(), 0, last_death_test_case_ + 1);
ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
// Shuffles the non-death test cases.
test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1,
test_cases_.size());
ShuffleRange(random(), last_death_test_case_ + 1,
test_cases_.size(), &test_case_indices_);
// Shuffles the tests inside each test case.
for (int i = 0; i < test_cases_.size(); i++) {
test_cases_.GetElement(i)->ShuffleTests(random());
for (size_t i = 0; i < test_cases_.size(); i++) {
test_cases_[i]->ShuffleTests(random());
}
}
// Restores the test cases and tests to their order before the first shuffle.
void UnitTestImpl::UnshuffleTests() {
for (int i = 0; i < test_cases_.size(); i++) {
for (size_t i = 0; i < test_cases_.size(); i++) {
// Unshuffles the tests in each test case.
test_cases_.GetElement(i)->UnshuffleTests();
test_cases_[i]->UnshuffleTests();
// Resets the index of each test case.
test_case_indices_.GetMutableElement(i) = i;
test_case_indices_[i] = i;
}
}