Simplifies the implementation by using std::vector instead of Vector.
This commit is contained in:
parent
3bef459eac
commit
0d27868d0f
@ -34,6 +34,7 @@
|
|||||||
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <vector>
|
||||||
#include <gtest/internal/gtest-internal.h>
|
#include <gtest/internal/gtest-internal.h>
|
||||||
#include <gtest/internal/gtest-string.h>
|
#include <gtest/internal/gtest-string.h>
|
||||||
|
|
||||||
@ -117,15 +118,11 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
|||||||
|
|
||||||
// An array of TestPartResult objects.
|
// An array of TestPartResult objects.
|
||||||
//
|
//
|
||||||
// We define this class as we cannot use STL containers when compiling
|
|
||||||
// Google Test with MSVC 7.1 and exceptions disabled.
|
|
||||||
//
|
|
||||||
// Don't inherit from TestPartResultArray as its destructor is not
|
// Don't inherit from TestPartResultArray as its destructor is not
|
||||||
// virtual.
|
// virtual.
|
||||||
class TestPartResultArray {
|
class TestPartResultArray {
|
||||||
public:
|
public:
|
||||||
TestPartResultArray();
|
TestPartResultArray() {}
|
||||||
~TestPartResultArray();
|
|
||||||
|
|
||||||
// Appends the given TestPartResult to the array.
|
// Appends the given TestPartResult to the array.
|
||||||
void Append(const TestPartResult& result);
|
void Append(const TestPartResult& result);
|
||||||
@ -135,9 +132,9 @@ class TestPartResultArray {
|
|||||||
|
|
||||||
// Returns the number of TestPartResult objects in the array.
|
// Returns the number of TestPartResult objects in the array.
|
||||||
int size() const;
|
int size() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internally we use a Vector to implement the array.
|
std::vector<TestPartResult> array_;
|
||||||
internal::Vector<TestPartResult>* const array_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,8 @@
|
|||||||
#define GTEST_INCLUDE_GTEST_GTEST_H_
|
#define GTEST_INCLUDE_GTEST_GTEST_H_
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <gtest/internal/gtest-internal.h>
|
#include <gtest/internal/gtest-internal.h>
|
||||||
#include <gtest/internal/gtest-string.h>
|
#include <gtest/internal/gtest-string.h>
|
||||||
#include <gtest/gtest-death-test.h>
|
#include <gtest/gtest-death-test.h>
|
||||||
@ -535,13 +537,13 @@ class TestResult {
|
|||||||
friend class internal::WindowsDeathTest;
|
friend class internal::WindowsDeathTest;
|
||||||
|
|
||||||
// Gets the vector of TestPartResults.
|
// Gets the vector of TestPartResults.
|
||||||
const internal::Vector<TestPartResult>& test_part_results() const {
|
const std::vector<TestPartResult>& test_part_results() const {
|
||||||
return *test_part_results_;
|
return test_part_results_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the vector of TestProperties.
|
// Gets the vector of TestProperties.
|
||||||
const internal::Vector<TestProperty>& test_properties() const {
|
const std::vector<TestProperty>& test_properties() const {
|
||||||
return *test_properties_;
|
return test_properties_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the elapsed time.
|
// Sets the elapsed time.
|
||||||
@ -579,9 +581,9 @@ class TestResult {
|
|||||||
internal::Mutex test_properites_mutex_;
|
internal::Mutex test_properites_mutex_;
|
||||||
|
|
||||||
// The vector of TestPartResults
|
// The vector of TestPartResults
|
||||||
internal::scoped_ptr<internal::Vector<TestPartResult> > test_part_results_;
|
std::vector<TestPartResult> test_part_results_;
|
||||||
// The vector of TestProperties
|
// The vector of TestProperties
|
||||||
internal::scoped_ptr<internal::Vector<TestProperty> > test_properties_;
|
std::vector<TestProperty> test_properties_;
|
||||||
// Running count of death tests.
|
// Running count of death tests.
|
||||||
int death_test_count_;
|
int death_test_count_;
|
||||||
// The elapsed time, in milliseconds.
|
// The elapsed time, in milliseconds.
|
||||||
@ -745,11 +747,11 @@ class TestCase {
|
|||||||
friend class internal::UnitTestImpl;
|
friend class internal::UnitTestImpl;
|
||||||
|
|
||||||
// Gets the (mutable) vector of TestInfos in this TestCase.
|
// Gets the (mutable) vector of TestInfos in this TestCase.
|
||||||
internal::Vector<TestInfo*>& test_info_list() { return *test_info_list_; }
|
std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
|
||||||
|
|
||||||
// Gets the (immutable) vector of TestInfos in this TestCase.
|
// Gets the (immutable) vector of TestInfos in this TestCase.
|
||||||
const internal::Vector<TestInfo *> & test_info_list() const {
|
const std::vector<TestInfo*>& test_info_list() const {
|
||||||
return *test_info_list_;
|
return test_info_list_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the i-th test among all the tests. i can range from 0 to
|
// Returns the i-th test among all the tests. i can range from 0 to
|
||||||
@ -798,11 +800,11 @@ class TestCase {
|
|||||||
internal::String comment_;
|
internal::String comment_;
|
||||||
// The vector of TestInfos in their original order. It owns the
|
// The vector of TestInfos in their original order. It owns the
|
||||||
// elements in the vector.
|
// elements in the vector.
|
||||||
const internal::scoped_ptr<internal::Vector<TestInfo*> > test_info_list_;
|
std::vector<TestInfo*> test_info_list_;
|
||||||
// Provides a level of indirection for the test list to allow easy
|
// Provides a level of indirection for the test list to allow easy
|
||||||
// shuffling and restoring the test order. The i-th element in this
|
// shuffling and restoring the test order. The i-th element in this
|
||||||
// vector is the index of the i-th test in the shuffled test list.
|
// vector is the index of the i-th test in the shuffled test list.
|
||||||
const internal::scoped_ptr<internal::Vector<int> > test_indices_;
|
std::vector<int> test_indices_;
|
||||||
// Pointer to the function that sets up the test case.
|
// Pointer to the function that sets up the test case.
|
||||||
Test::SetUpTestCaseFunc set_up_tc_;
|
Test::SetUpTestCaseFunc set_up_tc_;
|
||||||
// Pointer to the function that tears down the test case.
|
// Pointer to the function that tears down the test case.
|
||||||
|
@ -114,7 +114,6 @@ struct TraceInfo; // Information about a trace point.
|
|||||||
class ScopedTrace; // Implements scoped trace.
|
class ScopedTrace; // Implements scoped trace.
|
||||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||||
template <typename E> class Vector; // A generic vector.
|
|
||||||
|
|
||||||
// How many times InitGoogleTest() has been called.
|
// How many times InitGoogleTest() has been called.
|
||||||
extern int g_init_gtest_count;
|
extern int g_init_gtest_count;
|
||||||
|
@ -13,7 +13,6 @@ EXPORTS
|
|||||||
??0ScopedTrace@internal@testing@@QAE@PBDHABVMessage@2@@Z
|
??0ScopedTrace@internal@testing@@QAE@PBDHABVMessage@2@@Z
|
||||||
??0SingleFailureChecker@internal@testing@@QAE@PBVTestPartResultArray@2@W4Type@TestPartResult@2@PBD@Z
|
??0SingleFailureChecker@internal@testing@@QAE@PBVTestPartResultArray@2@W4Type@TestPartResult@2@PBD@Z
|
||||||
??0Test@testing@@IAE@XZ
|
??0Test@testing@@IAE@XZ
|
||||||
??0TestPartResultArray@testing@@QAE@XZ
|
|
||||||
??1AssertHelper@internal@testing@@QAE@XZ
|
??1AssertHelper@internal@testing@@QAE@XZ
|
||||||
??1GTestLog@internal@testing@@QAE@XZ
|
??1GTestLog@internal@testing@@QAE@XZ
|
||||||
??1HasNewFatalFailureHelper@internal@testing@@UAE@XZ
|
??1HasNewFatalFailureHelper@internal@testing@@UAE@XZ
|
||||||
@ -22,7 +21,6 @@ EXPORTS
|
|||||||
??1ScopedTrace@internal@testing@@QAE@XZ
|
??1ScopedTrace@internal@testing@@QAE@XZ
|
||||||
??1SingleFailureChecker@internal@testing@@QAE@XZ
|
??1SingleFailureChecker@internal@testing@@QAE@XZ
|
||||||
??1Test@testing@@UAE@XZ
|
??1Test@testing@@UAE@XZ
|
||||||
??1TestPartResultArray@testing@@QAE@XZ
|
|
||||||
??4AssertHelper@internal@testing@@QBEXABVMessage@2@@Z
|
??4AssertHelper@internal@testing@@QBEXABVMessage@2@@Z
|
||||||
??6Message@testing@@QAEAAV01@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z
|
??6Message@testing@@QAEAAV01@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z
|
||||||
??7AssertionResult@testing@@QBE?AV01@XZ
|
??7AssertionResult@testing@@QBE?AV01@XZ
|
||||||
|
@ -52,7 +52,9 @@
|
|||||||
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
|
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
|
||||||
#include <string.h> // For memmove.
|
#include <string.h> // For memmove.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <gtest/internal/gtest-port.h>
|
#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.
|
// method. Assumes that 0 <= shard_index < total_shards.
|
||||||
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
|
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
|
||||||
|
|
||||||
// Vector is an ordered container that supports random access to the
|
// STL container utilities.
|
||||||
// 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.
|
// Returns the number of elements in the given container that satisfy
|
||||||
virtual ~Vector() { Clear(); }
|
// 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.
|
// Applies a function/functor to each element in the container.
|
||||||
void Clear() {
|
template <class Container, typename Functor>
|
||||||
if (elements_ != NULL) {
|
void ForEach(const Container& c, Functor functor) {
|
||||||
for (int i = 0; i < size_; i++) {
|
std::for_each(c.begin(), c.end(), functor);
|
||||||
delete elements_[i];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(elements_);
|
// Returns the i-th element of the vector, or default_value if i is not
|
||||||
elements_ = NULL;
|
// in range [0, v.size()).
|
||||||
capacity_ = size_ = 0;
|
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.
|
// Performs an in-place shuffle of the vector's elements.
|
||||||
int size() const { return size_; }
|
template <typename E>
|
||||||
|
inline void Shuffle(internal::Random* random, std::vector<E>* v) {
|
||||||
// Adds an element to the end of the Vector. A copy of the element
|
ShuffleRange(random, 0, v->size(), v);
|
||||||
// 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
|
|
||||||
|
|
||||||
// A function for deleting an object. Handy for being used as a
|
// A function for deleting an object. Handy for being used as a
|
||||||
// functor.
|
// functor.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void Delete(T * x) {
|
static void Delete(T* x) {
|
||||||
delete 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
|
// 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.
|
// total_test_case_count() - 1. If i is not in that range, returns NULL.
|
||||||
const TestCase* GetTestCase(int i) const {
|
const TestCase* GetTestCase(int i) const {
|
||||||
const int index = test_case_indices_.GetElementOr(i, -1);
|
const int index = GetElementOr(test_case_indices_, i, -1);
|
||||||
return index < 0 ? NULL : test_cases_.GetElement(i);
|
return index < 0 ? NULL : test_cases_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the i-th test case among all the test cases. i can range from 0 to
|
// 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.
|
// total_test_case_count() - 1. If i is not in that range, returns NULL.
|
||||||
TestCase* GetMutableTestCase(int i) {
|
TestCase* GetMutableTestCase(int i) {
|
||||||
const int index = test_case_indices_.GetElementOr(i, -1);
|
const int index = GetElementOr(test_case_indices_, i, -1);
|
||||||
return index < 0 ? NULL : test_cases_.GetElement(index);
|
return index < 0 ? NULL : test_cases_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provides access to the event listener list.
|
// Provides access to the event listener list.
|
||||||
@ -931,7 +740,7 @@ class UnitTestImpl {
|
|||||||
|
|
||||||
// Clears the results of all tests, including the ad hoc test.
|
// Clears the results of all tests, including the ad hoc test.
|
||||||
void ClearResult() {
|
void ClearResult() {
|
||||||
test_cases_.ForEach(TestCase::ClearTestCaseResult);
|
ForEach(test_cases_, TestCase::ClearTestCaseResult);
|
||||||
ad_hoc_test_result_.Clear();
|
ad_hoc_test_result_.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,17 +766,14 @@ class UnitTestImpl {
|
|||||||
|
|
||||||
// Returns the vector of environments that need to be set-up/torn-down
|
// Returns the vector of environments that need to be set-up/torn-down
|
||||||
// before/after the tests are run.
|
// before/after the tests are run.
|
||||||
internal::Vector<Environment*>* environments() { return &environments_; }
|
std::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.
|
// Getters for the per-thread Google Test trace stack.
|
||||||
internal::Vector<TraceInfo>* gtest_trace_stack() {
|
std::vector<TraceInfo>& gtest_trace_stack() {
|
||||||
return gtest_trace_stack_.pointer();
|
return *(gtest_trace_stack_.pointer());
|
||||||
}
|
}
|
||||||
const internal::Vector<TraceInfo>* gtest_trace_stack() const {
|
const std::vector<TraceInfo>& gtest_trace_stack() const {
|
||||||
return gtest_trace_stack_.pointer();
|
return gtest_trace_stack_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
@ -1042,20 +848,18 @@ class UnitTestImpl {
|
|||||||
per_thread_test_part_result_reporter_;
|
per_thread_test_part_result_reporter_;
|
||||||
|
|
||||||
// The vector of environments that need to be set-up/torn-down
|
// The vector of environments that need to be set-up/torn-down
|
||||||
// before/after the tests are run. environments_in_reverse_order_
|
// before/after the tests are run.
|
||||||
// simply mirrors environments_ in reverse order.
|
std::vector<Environment*> environments_;
|
||||||
internal::Vector<Environment*> environments_;
|
|
||||||
internal::Vector<Environment*> environments_in_reverse_order_;
|
|
||||||
|
|
||||||
// The vector of TestCases in their original order. It owns the
|
// The vector of TestCases in their original order. It owns the
|
||||||
// elements in the vector.
|
// 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
|
// Provides a level of indirection for the test case list to allow
|
||||||
// easy shuffling and restoring the test case order. The i-th
|
// 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
|
// element of this vector is the index of the i-th test case in the
|
||||||
// shuffled order.
|
// shuffled order.
|
||||||
internal::Vector<int> test_case_indices_;
|
std::vector<int> test_case_indices_;
|
||||||
|
|
||||||
#if GTEST_HAS_PARAM_TEST
|
#if GTEST_HAS_PARAM_TEST
|
||||||
// ParameterizedTestRegistry object used to register value-parameterized
|
// ParameterizedTestRegistry object used to register value-parameterized
|
||||||
@ -1121,7 +925,7 @@ class UnitTestImpl {
|
|||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
// A per-thread stack of traces created by the SCOPED_TRACE() macro.
|
// 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);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
|
||||||
}; // class UnitTestImpl
|
}; // class UnitTestImpl
|
||||||
@ -1242,7 +1046,7 @@ class TestResultAccessor {
|
|||||||
test_result->ClearTestPartResults();
|
test_result->ClearTestPartResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Vector<testing::TestPartResult>& test_part_results(
|
static const std::vector<testing::TestPartResult>& test_part_results(
|
||||||
const TestResult& test_result) {
|
const TestResult& test_result) {
|
||||||
return test_result.test_part_results();
|
return test_result.test_part_results();
|
||||||
}
|
}
|
||||||
|
@ -64,19 +64,9 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
|||||||
<< result.message() << std::endl;
|
<< 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.
|
// Appends a TestPartResult to the array.
|
||||||
void TestPartResultArray::Append(const TestPartResult& result) {
|
void TestPartResultArray::Append(const TestPartResult& result) {
|
||||||
array_->PushBack(result);
|
array_.push_back(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the TestPartResult at the given index (0-based).
|
// Returns the TestPartResult at the given index (0-based).
|
||||||
@ -86,12 +76,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
|||||||
internal::posix::Abort();
|
internal::posix::Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_->GetElement(index);
|
return array_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of TestPartResult objects in the array.
|
// Returns the number of TestPartResult objects in the array.
|
||||||
int TestPartResultArray::size() const {
|
int TestPartResultArray::size() const {
|
||||||
return array_->size();
|
return array_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
186
src/gtest.cc
186
src/gtest.cc
@ -42,8 +42,10 @@
|
|||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if GTEST_OS_LINUX
|
#if GTEST_OS_LINUX
|
||||||
|
|
||||||
@ -132,6 +134,11 @@
|
|||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
|
using internal::CountIf;
|
||||||
|
using internal::ForEach;
|
||||||
|
using internal::GetElementOr;
|
||||||
|
using internal::Shuffle;
|
||||||
|
|
||||||
// Constants.
|
// Constants.
|
||||||
|
|
||||||
// A test whose test case name or test name matches this filter is
|
// 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
|
// Iterates over a vector of TestCases, keeping a running sum of the
|
||||||
// results of calling a given int-returning method on each.
|
// results of calling a given int-returning method on each.
|
||||||
// Returns the sum.
|
// 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 (TestCase::*method)() const) {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (int i = 0; i < case_list.size(); i++) {
|
for (size_t i = 0; i < case_list.size(); i++) {
|
||||||
sum += (case_list.GetElement(i)->*method)();
|
sum += (case_list[i]->*method)();
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@ -673,12 +680,12 @@ void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
|
|||||||
|
|
||||||
// Gets the number of successful test cases.
|
// Gets the number of successful test cases.
|
||||||
int UnitTestImpl::successful_test_case_count() const {
|
int UnitTestImpl::successful_test_case_count() const {
|
||||||
return test_cases_.CountIf(TestCasePassed);
|
return CountIf(test_cases_, TestCasePassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the number of failed test cases.
|
// Gets the number of failed test cases.
|
||||||
int UnitTestImpl::failed_test_case_count() const {
|
int UnitTestImpl::failed_test_case_count() const {
|
||||||
return test_cases_.CountIf(TestCaseFailed);
|
return CountIf(test_cases_, TestCaseFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the number of all test cases.
|
// 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
|
// Gets the number of all test cases that contain at least one test
|
||||||
// that should run.
|
// that should run.
|
||||||
int UnitTestImpl::test_case_to_run_count() const {
|
int UnitTestImpl::test_case_to_run_count() const {
|
||||||
return test_cases_.CountIf(ShouldRunTestCase);
|
return CountIf(test_cases_, ShouldRunTestCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the number of successful tests.
|
// Gets the number of successful tests.
|
||||||
@ -1786,9 +1793,7 @@ String AppendUserMessage(const String& gtest_msg,
|
|||||||
|
|
||||||
// Creates an empty TestResult.
|
// Creates an empty TestResult.
|
||||||
TestResult::TestResult()
|
TestResult::TestResult()
|
||||||
: test_part_results_(new internal::Vector<TestPartResult>),
|
: death_test_count_(0),
|
||||||
test_properties_(new internal::Vector<TestProperty>),
|
|
||||||
death_test_count_(0),
|
|
||||||
elapsed_time_(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,
|
// range from 0 to total_part_count() - 1. If i is not in that range,
|
||||||
// aborts the program.
|
// aborts the program.
|
||||||
const TestPartResult& TestResult::GetTestPartResult(int i) const {
|
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
|
// 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
|
// test_property_count() - 1. If i is not in that range, aborts the
|
||||||
// program.
|
// program.
|
||||||
const TestProperty& TestResult::GetTestProperty(int i) const {
|
const TestProperty& TestResult::GetTestProperty(int i) const {
|
||||||
return test_properties_->GetElement(i);
|
return test_properties_.at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears the test part results.
|
// Clears the test part results.
|
||||||
void TestResult::ClearTestPartResults() {
|
void TestResult::ClearTestPartResults() {
|
||||||
test_part_results_->Clear();
|
test_part_results_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a test part result to the list.
|
// Adds a test part result to the list.
|
||||||
void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
|
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
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
internal::MutexLock lock(&test_properites_mutex_);
|
internal::MutexLock lock(&test_properites_mutex_);
|
||||||
TestProperty* const property_with_matching_key =
|
const std::vector<TestProperty>::iterator property_with_matching_key =
|
||||||
test_properties_->FindIf(
|
std::find_if(test_properties_.begin(), test_properties_.end(),
|
||||||
internal::TestPropertyKeyIs(test_property.key()));
|
internal::TestPropertyKeyIs(test_property.key()));
|
||||||
if (property_with_matching_key == NULL) {
|
if (property_with_matching_key == test_properties_.end()) {
|
||||||
test_properties_->PushBack(test_property);
|
test_properties_.push_back(test_property);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
property_with_matching_key->SetValue(test_property.value());
|
property_with_matching_key->SetValue(test_property.value());
|
||||||
@ -1855,8 +1860,8 @@ bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
|
|||||||
|
|
||||||
// Clears the object.
|
// Clears the object.
|
||||||
void TestResult::Clear() {
|
void TestResult::Clear() {
|
||||||
test_part_results_->Clear();
|
test_part_results_.clear();
|
||||||
test_properties_->Clear();
|
test_properties_.clear();
|
||||||
death_test_count_ = 0;
|
death_test_count_ = 0;
|
||||||
elapsed_time_ = 0;
|
elapsed_time_ = 0;
|
||||||
}
|
}
|
||||||
@ -1877,7 +1882,7 @@ static bool TestPartFatallyFailed(const TestPartResult& result) {
|
|||||||
|
|
||||||
// Returns true iff the test fatally failed.
|
// Returns true iff the test fatally failed.
|
||||||
bool TestResult::HasFatalFailure() const {
|
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.
|
// 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.
|
// Returns true iff the test has a non-fatal failure.
|
||||||
bool TestResult::HasNonfatalFailure() const {
|
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
|
// 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.
|
// of successful test parts and the number of failed test parts.
|
||||||
int TestResult::total_part_count() const {
|
int TestResult::total_part_count() const {
|
||||||
return test_part_results_->size();
|
return test_part_results_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of the test properties.
|
// Returns the number of the test properties.
|
||||||
int TestResult::test_property_count() const {
|
int TestResult::test_property_count() const {
|
||||||
return test_properties_->size();
|
return test_properties_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// class Test
|
// class Test
|
||||||
@ -1982,7 +1987,7 @@ bool Test::HasSameFixtureClass() {
|
|||||||
|
|
||||||
// Info about the first test in the current test case.
|
// Info about the first test in the current test case.
|
||||||
const internal::TestInfoImpl* const first_test_info =
|
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 internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
|
||||||
const char* const first_test_name = first_test_info->name();
|
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.
|
// Gets the number of successful tests in this test case.
|
||||||
int TestCase::successful_test_count() const {
|
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.
|
// Gets the number of failed tests in this test case.
|
||||||
int TestCase::failed_test_count() const {
|
int TestCase::failed_test_count() const {
|
||||||
return test_info_list_->CountIf(TestFailed);
|
return CountIf(test_info_list_, TestFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestCase::disabled_test_count() const {
|
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.
|
// Get the number of tests in this test case that should run.
|
||||||
int TestCase::test_to_run_count() const {
|
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.
|
// Gets the number of all tests.
|
||||||
int TestCase::total_test_count() const {
|
int TestCase::total_test_count() const {
|
||||||
return test_info_list_->size();
|
return test_info_list_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a TestCase with the given name.
|
// 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)
|
Test::TearDownTestCaseFunc tear_down_tc)
|
||||||
: name_(a_name),
|
: name_(a_name),
|
||||||
comment_(a_comment),
|
comment_(a_comment),
|
||||||
test_info_list_(new internal::Vector<TestInfo*>),
|
|
||||||
test_indices_(new internal::Vector<int>),
|
|
||||||
set_up_tc_(set_up_tc),
|
set_up_tc_(set_up_tc),
|
||||||
tear_down_tc_(tear_down_tc),
|
tear_down_tc_(tear_down_tc),
|
||||||
should_run_(false),
|
should_run_(false),
|
||||||
@ -2371,28 +2374,28 @@ TestCase::TestCase(const char* a_name, const char* a_comment,
|
|||||||
// Destructor of TestCase.
|
// Destructor of TestCase.
|
||||||
TestCase::~TestCase() {
|
TestCase::~TestCase() {
|
||||||
// Deletes every Test in the collection.
|
// 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
|
// 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.
|
// total_test_count() - 1. If i is not in that range, returns NULL.
|
||||||
const TestInfo* TestCase::GetTestInfo(int i) const {
|
const TestInfo* TestCase::GetTestInfo(int i) const {
|
||||||
const int index = test_indices_->GetElementOr(i, -1);
|
const int index = GetElementOr(test_indices_, i, -1);
|
||||||
return index < 0 ? NULL : test_info_list_->GetElement(index);
|
return index < 0 ? NULL : test_info_list_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the i-th test among all the tests. i can range from 0 to
|
// 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.
|
// total_test_count() - 1. If i is not in that range, returns NULL.
|
||||||
TestInfo* TestCase::GetMutableTestInfo(int i) {
|
TestInfo* TestCase::GetMutableTestInfo(int i) {
|
||||||
const int index = test_indices_->GetElementOr(i, -1);
|
const int index = GetElementOr(test_indices_, i, -1);
|
||||||
return index < 0 ? NULL : test_info_list_->GetElement(index);
|
return index < 0 ? NULL : test_info_list_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a test to this test case. Will delete the test upon
|
// Adds a test to this test case. Will delete the test upon
|
||||||
// destruction of the TestCase object.
|
// destruction of the TestCase object.
|
||||||
void TestCase::AddTestInfo(TestInfo * test_info) {
|
void TestCase::AddTestInfo(TestInfo * test_info) {
|
||||||
test_info_list_->PushBack(test_info);
|
test_info_list_.push_back(test_info);
|
||||||
test_indices_->PushBack(test_indices_->size());
|
test_indices_.push_back(test_indices_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs every test in this TestCase.
|
// Runs every test in this TestCase.
|
||||||
@ -2422,7 +2425,7 @@ void TestCase::Run() {
|
|||||||
|
|
||||||
// Clears the results of all tests in this test case.
|
// Clears the results of all tests in this test case.
|
||||||
void TestCase::ClearResult() {
|
void TestCase::ClearResult() {
|
||||||
test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult);
|
ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff test passed.
|
// Returns true iff test passed.
|
||||||
@ -2449,13 +2452,13 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
|
|||||||
|
|
||||||
// Shuffles the tests in this test case.
|
// Shuffles the tests in this test case.
|
||||||
void TestCase::ShuffleTests(internal::Random* random) {
|
void TestCase::ShuffleTests(internal::Random* random) {
|
||||||
test_indices_->Shuffle(random);
|
Shuffle(random, &test_indices_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restores the test order to before the first shuffle.
|
// Restores the test order to before the first shuffle.
|
||||||
void TestCase::UnshuffleTests() {
|
void TestCase::UnshuffleTests() {
|
||||||
for (int i = 0; i < test_indices_->size(); i++) {
|
for (size_t i = 0; i < test_indices_.size(); i++) {
|
||||||
test_indices_->GetMutableElement(i) = i;
|
test_indices_[i] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2902,26 +2905,24 @@ class TestEventRepeater : public TestEventListener {
|
|||||||
// in death test child processes.
|
// in death test child processes.
|
||||||
bool forwarding_enabled_;
|
bool forwarding_enabled_;
|
||||||
// The list of listeners that receive events.
|
// The list of listeners that receive events.
|
||||||
Vector<TestEventListener*> listeners_;
|
std::vector<TestEventListener*> listeners_;
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
|
||||||
};
|
};
|
||||||
|
|
||||||
TestEventRepeater::~TestEventRepeater() {
|
TestEventRepeater::~TestEventRepeater() {
|
||||||
for (int i = 0; i < listeners_.size(); i++) {
|
ForEach(listeners_, Delete<TestEventListener>);
|
||||||
delete listeners_.GetElement(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEventRepeater::Append(TestEventListener *listener) {
|
void TestEventRepeater::Append(TestEventListener *listener) {
|
||||||
listeners_.PushBack(listener);
|
listeners_.push_back(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
|
// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
|
||||||
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
|
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
|
||||||
for (int i = 0; i < listeners_.size(); ++i) {
|
for (size_t i = 0; i < listeners_.size(); ++i) {
|
||||||
if (listeners_.GetElement(i) == listener) {
|
if (listeners_[i] == listener) {
|
||||||
listeners_.Erase(i);
|
listeners_.erase(listeners_.begin() + i);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2934,8 +2935,8 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
|
|||||||
#define GTEST_REPEATER_METHOD_(Name, Type) \
|
#define GTEST_REPEATER_METHOD_(Name, Type) \
|
||||||
void TestEventRepeater::Name(const Type& parameter) { \
|
void TestEventRepeater::Name(const Type& parameter) { \
|
||||||
if (forwarding_enabled_) { \
|
if (forwarding_enabled_) { \
|
||||||
for (int i = 0; i < listeners_.size(); i++) { \
|
for (size_t i = 0; i < listeners_.size(); i++) { \
|
||||||
listeners_.GetElement(i)->Name(parameter); \
|
listeners_[i]->Name(parameter); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -2945,7 +2946,7 @@ void TestEventRepeater::Name(const Type& parameter) { \
|
|||||||
void TestEventRepeater::Name(const Type& parameter) { \
|
void TestEventRepeater::Name(const Type& parameter) { \
|
||||||
if (forwarding_enabled_) { \
|
if (forwarding_enabled_) { \
|
||||||
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
|
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,
|
void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
|
||||||
int iteration) {
|
int iteration) {
|
||||||
if (forwarding_enabled_) {
|
if (forwarding_enabled_) {
|
||||||
for (int i = 0; i < listeners_.size(); i++) {
|
for (size_t i = 0; i < listeners_.size(); i++) {
|
||||||
listeners_.GetElement(i)->OnTestIterationStart(unit_test, iteration);
|
listeners_[i]->OnTestIterationStart(unit_test, iteration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2978,7 +2979,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
int iteration) {
|
int iteration) {
|
||||||
if (forwarding_enabled_) {
|
if (forwarding_enabled_) {
|
||||||
for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_->environments()->PushBack(env);
|
impl_->environments().push_back(env);
|
||||||
impl_->environments_in_reverse_order()->PushFront(env);
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3564,12 +3564,11 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
|||||||
msg << message;
|
msg << message;
|
||||||
|
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
if (impl_->gtest_trace_stack()->size() > 0) {
|
if (impl_->gtest_trace_stack().size() > 0) {
|
||||||
msg << "\n" << GTEST_NAME_ << " trace:";
|
msg << "\n" << GTEST_NAME_ << " trace:";
|
||||||
|
|
||||||
for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
|
for (int i = impl_->gtest_trace_stack().size(); i > 0; --i) {
|
||||||
const internal::TraceInfo& trace =
|
const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
|
||||||
impl_->gtest_trace_stack()->GetElement(i);
|
|
||||||
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
|
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
|
||||||
<< " " << trace.message;
|
<< " " << trace.message;
|
||||||
}
|
}
|
||||||
@ -3734,14 +3733,14 @@ UnitTest::~UnitTest() {
|
|||||||
// L < mutex_
|
// L < mutex_
|
||||||
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
|
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
|
||||||
internal::MutexLock lock(&mutex_);
|
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.
|
// Pops a trace from the per-thread Google Test trace stack.
|
||||||
// L < mutex_
|
// L < mutex_
|
||||||
void UnitTest::PopGTestTrace() {
|
void UnitTest::PopGTestTrace() {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
impl_->gtest_trace_stack()->PopFront(NULL);
|
impl_->gtest_trace_stack().pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -3787,10 +3786,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
|||||||
|
|
||||||
UnitTestImpl::~UnitTestImpl() {
|
UnitTestImpl::~UnitTestImpl() {
|
||||||
// Deletes every TestCase.
|
// Deletes every TestCase.
|
||||||
test_cases_.ForEach(internal::Delete<TestCase>);
|
ForEach(test_cases_, internal::Delete<TestCase>);
|
||||||
|
|
||||||
// Deletes every Environment.
|
// Deletes every Environment.
|
||||||
environments_.ForEach(internal::Delete<Environment>);
|
ForEach(environments_, internal::Delete<Environment>);
|
||||||
|
|
||||||
delete os_stack_trace_getter_;
|
delete os_stack_trace_getter_;
|
||||||
}
|
}
|
||||||
@ -3882,9 +3881,11 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
|
|||||||
Test::SetUpTestCaseFunc set_up_tc,
|
Test::SetUpTestCaseFunc set_up_tc,
|
||||||
Test::TearDownTestCaseFunc tear_down_tc) {
|
Test::TearDownTestCaseFunc tear_down_tc) {
|
||||||
// Can we find a TestCase with the given name?
|
// 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;
|
return *test_case;
|
||||||
|
|
||||||
// No. Let's create one.
|
// 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
|
// defined so far. This only works when the test cases haven't
|
||||||
// been shuffled. Otherwise we may end up running a death test
|
// been shuffled. Otherwise we may end up running a death test
|
||||||
// after a non-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 {
|
} else {
|
||||||
// No. Appends to the end of the list.
|
// 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;
|
return new_test_case;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers for setting up / tearing down the given environment. They
|
// 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 SetUpEnvironment(Environment* env) { env->SetUp(); }
|
||||||
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
||||||
|
|
||||||
@ -4005,7 +4008,7 @@ int UnitTestImpl::RunAllTests() {
|
|||||||
if (has_tests_to_run) {
|
if (has_tests_to_run) {
|
||||||
// Sets up all environments beforehand.
|
// Sets up all environments beforehand.
|
||||||
repeater->OnEnvironmentsSetUpStart(*parent_);
|
repeater->OnEnvironmentsSetUpStart(*parent_);
|
||||||
environments_.ForEach(SetUpEnvironment);
|
ForEach(environments_, SetUpEnvironment);
|
||||||
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
||||||
|
|
||||||
// Runs the tests only if there was no fatal failure during global
|
// 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.
|
// Tears down all environments in reverse order afterwards.
|
||||||
repeater->OnEnvironmentsTearDownStart(*parent_);
|
repeater->OnEnvironmentsTearDownStart(*parent_);
|
||||||
environments_in_reverse_order_.ForEach(TearDownEnvironment);
|
std::for_each(environments_.rbegin(), environments_.rend(),
|
||||||
|
TearDownEnvironment);
|
||||||
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4165,13 +4169,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
// this shard.
|
// this shard.
|
||||||
int num_runnable_tests = 0;
|
int num_runnable_tests = 0;
|
||||||
int num_selected_tests = 0;
|
int num_selected_tests = 0;
|
||||||
for (int i = 0; i < test_cases_.size(); i++) {
|
for (size_t i = 0; i < test_cases_.size(); i++) {
|
||||||
TestCase* const test_case = test_cases_.GetElement(i);
|
TestCase* const test_case = test_cases_[i];
|
||||||
const String &test_case_name = test_case->name();
|
const String &test_case_name = test_case->name();
|
||||||
test_case->set_should_run(false);
|
test_case->set_should_run(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++) {
|
||||||
TestInfo* const test_info = test_case->test_info_list().GetElement(j);
|
TestInfo* const test_info = test_case->test_info_list()[j];
|
||||||
const String test_name(test_info->name());
|
const String test_name(test_info->name());
|
||||||
// A test is disabled if test case name or test name matches
|
// A test is disabled if test case name or test name matches
|
||||||
// kDisableTestFilter.
|
// kDisableTestFilter.
|
||||||
@ -4208,13 +4212,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
|
|
||||||
// Prints the names of the tests matching the user-specified filter flag.
|
// Prints the names of the tests matching the user-specified filter flag.
|
||||||
void UnitTestImpl::ListTestsMatchingFilter() {
|
void UnitTestImpl::ListTestsMatchingFilter() {
|
||||||
for (int i = 0; i < test_cases_.size(); i++) {
|
for (size_t i = 0; i < test_cases_.size(); i++) {
|
||||||
const TestCase* const test_case = test_cases_.GetElement(i);
|
const TestCase* const test_case = test_cases_[i];
|
||||||
bool printed_test_case_name = false;
|
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 =
|
const TestInfo* const test_info =
|
||||||
test_case->test_info_list().GetElement(j);
|
test_case->test_info_list()[j];
|
||||||
if (test_info->matches_filter()) {
|
if (test_info->matches_filter()) {
|
||||||
if (!printed_test_case_name) {
|
if (!printed_test_case_name) {
|
||||||
printed_test_case_name = true;
|
printed_test_case_name = true;
|
||||||
@ -4262,25 +4266,25 @@ TestResult* UnitTestImpl::current_test_result() {
|
|||||||
// making sure that death tests are still run first.
|
// making sure that death tests are still run first.
|
||||||
void UnitTestImpl::ShuffleTests() {
|
void UnitTestImpl::ShuffleTests() {
|
||||||
// Shuffles the death test cases.
|
// 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.
|
// Shuffles the non-death test cases.
|
||||||
test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1,
|
ShuffleRange(random(), last_death_test_case_ + 1,
|
||||||
test_cases_.size());
|
test_cases_.size(), &test_case_indices_);
|
||||||
|
|
||||||
// Shuffles the tests inside each test case.
|
// Shuffles the tests inside each test case.
|
||||||
for (int i = 0; i < test_cases_.size(); i++) {
|
for (size_t i = 0; i < test_cases_.size(); i++) {
|
||||||
test_cases_.GetElement(i)->ShuffleTests(random());
|
test_cases_[i]->ShuffleTests(random());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restores the test cases and tests to their order before the first shuffle.
|
// Restores the test cases and tests to their order before the first shuffle.
|
||||||
void UnitTestImpl::UnshuffleTests() {
|
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.
|
// Unshuffles the tests in each test case.
|
||||||
test_cases_.GetElement(i)->UnshuffleTests();
|
test_cases_[i]->UnshuffleTests();
|
||||||
// Resets the index of each test case.
|
// Resets the index of each test case.
|
||||||
test_case_indices_.GetMutableElement(i) = i;
|
test_case_indices_[i] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,15 +34,7 @@
|
|||||||
// right times.
|
// right times.
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
#include <vector>
|
||||||
// Indicates that this translation unit is part of Google Test's
|
|
||||||
// implementation. It must come before gtest-internal-inl.h is
|
|
||||||
// included, or there will be a compiler error. This trick is to
|
|
||||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
|
||||||
// his code.
|
|
||||||
#define GTEST_IMPLEMENTATION_ 1
|
|
||||||
#include "src/gtest-internal-inl.h" // For Vector.
|
|
||||||
#undef GTEST_IMPLEMENTATION_
|
|
||||||
|
|
||||||
using ::testing::AddGlobalTestEnvironment;
|
using ::testing::AddGlobalTestEnvironment;
|
||||||
using ::testing::Environment;
|
using ::testing::Environment;
|
||||||
@ -54,10 +46,9 @@ using ::testing::TestInfo;
|
|||||||
using ::testing::TestPartResult;
|
using ::testing::TestPartResult;
|
||||||
using ::testing::UnitTest;
|
using ::testing::UnitTest;
|
||||||
using ::testing::internal::String;
|
using ::testing::internal::String;
|
||||||
using ::testing::internal::Vector;
|
|
||||||
|
|
||||||
// Used by tests to register their events.
|
// Used by tests to register their events.
|
||||||
Vector<String>* g_events = NULL;
|
std::vector<String>* g_events = NULL;
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -68,7 +59,7 @@ class EventRecordingListener : public TestEventListener {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
|
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestProgramStart"));
|
g_events->push_back(GetFullMethodName("OnTestProgramStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
||||||
@ -76,43 +67,43 @@ class EventRecordingListener : public TestEventListener {
|
|||||||
Message message;
|
Message message;
|
||||||
message << GetFullMethodName("OnTestIterationStart")
|
message << GetFullMethodName("OnTestIterationStart")
|
||||||
<< "(" << iteration << ")";
|
<< "(" << iteration << ")";
|
||||||
g_events->PushBack(message.GetString());
|
g_events->push_back(message.GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {
|
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpStart"));
|
g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {
|
virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpEnd"));
|
g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {
|
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestCaseStart"));
|
g_events->push_back(GetFullMethodName("OnTestCaseStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestStart(const TestInfo& /*test_info*/) {
|
virtual void OnTestStart(const TestInfo& /*test_info*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestStart"));
|
g_events->push_back(GetFullMethodName("OnTestStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {
|
virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestPartResult"));
|
g_events->push_back(GetFullMethodName("OnTestPartResult"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestEnd(const TestInfo& /*test_info*/) {
|
virtual void OnTestEnd(const TestInfo& /*test_info*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestEnd"));
|
g_events->push_back(GetFullMethodName("OnTestEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {
|
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestCaseEnd"));
|
g_events->push_back(GetFullMethodName("OnTestCaseEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {
|
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownStart"));
|
g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {
|
virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownEnd"));
|
g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
||||||
@ -120,11 +111,11 @@ class EventRecordingListener : public TestEventListener {
|
|||||||
Message message;
|
Message message;
|
||||||
message << GetFullMethodName("OnTestIterationEnd")
|
message << GetFullMethodName("OnTestIterationEnd")
|
||||||
<< "(" << iteration << ")";
|
<< "(" << iteration << ")";
|
||||||
g_events->PushBack(message.GetString());
|
g_events->push_back(message.GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
|
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
|
||||||
g_events->PushBack(GetFullMethodName("OnTestProgramEnd"));
|
g_events->push_back(GetFullMethodName("OnTestProgramEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -140,42 +131,42 @@ class EventRecordingListener : public TestEventListener {
|
|||||||
class EnvironmentInvocationCatcher : public Environment {
|
class EnvironmentInvocationCatcher : public Environment {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
g_events->PushBack(String("Environment::SetUp"));
|
g_events->push_back(String("Environment::SetUp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
g_events->PushBack(String("Environment::TearDown"));
|
g_events->push_back(String("Environment::TearDown"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListenerTest : public Test {
|
class ListenerTest : public Test {
|
||||||
protected:
|
protected:
|
||||||
static void SetUpTestCase() {
|
static void SetUpTestCase() {
|
||||||
g_events->PushBack(String("ListenerTest::SetUpTestCase"));
|
g_events->push_back(String("ListenerTest::SetUpTestCase"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
static void TearDownTestCase() {
|
||||||
g_events->PushBack(String("ListenerTest::TearDownTestCase"));
|
g_events->push_back(String("ListenerTest::TearDownTestCase"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
g_events->PushBack(String("ListenerTest::SetUp"));
|
g_events->push_back(String("ListenerTest::SetUp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
g_events->PushBack(String("ListenerTest::TearDown"));
|
g_events->push_back(String("ListenerTest::TearDown"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ListenerTest, DoesFoo) {
|
TEST_F(ListenerTest, DoesFoo) {
|
||||||
// Test execution order within a test case is not guaranteed so we are not
|
// Test execution order within a test case is not guaranteed so we are not
|
||||||
// recording the test name.
|
// recording the test name.
|
||||||
g_events->PushBack(String("ListenerTest::* Test Body"));
|
g_events->push_back(String("ListenerTest::* Test Body"));
|
||||||
SUCCEED(); // Triggers OnTestPartResult.
|
SUCCEED(); // Triggers OnTestPartResult.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ListenerTest, DoesBar) {
|
TEST_F(ListenerTest, DoesBar) {
|
||||||
g_events->PushBack(String("ListenerTest::* Test Body"));
|
g_events->push_back(String("ListenerTest::* Test Body"));
|
||||||
SUCCEED(); // Triggers OnTestPartResult.
|
SUCCEED(); // Triggers OnTestPartResult.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +177,7 @@ TEST_F(ListenerTest, DoesBar) {
|
|||||||
using ::testing::internal::EnvironmentInvocationCatcher;
|
using ::testing::internal::EnvironmentInvocationCatcher;
|
||||||
using ::testing::internal::EventRecordingListener;
|
using ::testing::internal::EventRecordingListener;
|
||||||
|
|
||||||
void VerifyResults(const Vector<String>& data,
|
void VerifyResults(const std::vector<String>& data,
|
||||||
const char* const* expected_data,
|
const char* const* expected_data,
|
||||||
int expected_data_size) {
|
int expected_data_size) {
|
||||||
const int actual_size = data.size();
|
const int actual_size = data.size();
|
||||||
@ -199,18 +190,18 @@ void VerifyResults(const Vector<String>& data,
|
|||||||
expected_data_size : actual_size;
|
expected_data_size : actual_size;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < shorter_size; ++i) {
|
for (; i < shorter_size; ++i) {
|
||||||
ASSERT_STREQ(expected_data[i], data.GetElement(i).c_str())
|
ASSERT_STREQ(expected_data[i], data[i].c_str())
|
||||||
<< "at position " << i;
|
<< "at position " << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints extra elements in the actual data.
|
// Prints extra elements in the actual data.
|
||||||
for (; i < actual_size; ++i) {
|
for (; i < actual_size; ++i) {
|
||||||
printf(" Actual event #%d: %s\n", i, data.GetElement(i).c_str());
|
printf(" Actual event #%d: %s\n", i, data[i].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Vector<String> events;
|
std::vector<String> events;
|
||||||
g_events = &events;
|
g_events = &events;
|
||||||
InitGoogleTest(&argc, argv);
|
InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// We must define this macro in order to #include
|
// We must define this macro in order to #include
|
||||||
// gtest-internal-inl.h. This is how Google Test prevents a user from
|
// gtest-internal-inl.h. This is how Google Test prevents a user from
|
||||||
@ -51,7 +52,6 @@ namespace {
|
|||||||
using internal::scoped_ptr;
|
using internal::scoped_ptr;
|
||||||
using internal::String;
|
using internal::String;
|
||||||
using internal::TestPropertyKeyIs;
|
using internal::TestPropertyKeyIs;
|
||||||
using internal::Vector;
|
|
||||||
using internal::ThreadStartSemaphore;
|
using internal::ThreadStartSemaphore;
|
||||||
using internal::ThreadWithParam;
|
using internal::ThreadWithParam;
|
||||||
|
|
||||||
@ -75,12 +75,13 @@ String IdToString(int id) {
|
|||||||
return id_message.GetString();
|
return id_message.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
|
void ExpectKeyAndValueWereRecordedForId(
|
||||||
int id,
|
const std::vector<TestProperty>& properties,
|
||||||
const char* suffix) {
|
int id, const char* suffix) {
|
||||||
TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
|
TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
|
||||||
const TestProperty* property = properties.FindIf(matches_key);
|
const std::vector<TestProperty>::const_iterator property =
|
||||||
ASSERT_TRUE(property != NULL)
|
std::find_if(properties.begin(), properties.end(), matches_key);
|
||||||
|
ASSERT_TRUE(property != properties.end())
|
||||||
<< "expecting " << suffix << " value for id " << id;
|
<< "expecting " << suffix << " value for id " << id;
|
||||||
EXPECT_STREQ(IdToString(id).c_str(), property->value());
|
EXPECT_STREQ(IdToString(id).c_str(), property->value());
|
||||||
}
|
}
|
||||||
@ -143,11 +144,11 @@ TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
|
|||||||
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
|
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
|
||||||
const TestResult* const result = info->result();
|
const TestResult* const result = info->result();
|
||||||
|
|
||||||
Vector<TestProperty> properties;
|
std::vector<TestProperty> properties;
|
||||||
// We have no access to the TestResult's list of properties but we can
|
// We have no access to the TestResult's list of properties but we can
|
||||||
// copy them one by one.
|
// copy them one by one.
|
||||||
for (int i = 0; i < result->test_property_count(); ++i)
|
for (int i = 0; i < result->test_property_count(); ++i)
|
||||||
properties.PushBack(result->GetTestProperty(i));
|
properties.push_back(result->GetTestProperty(i));
|
||||||
|
|
||||||
EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
|
EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
|
||||||
<< "String and int values recorded on each thread, "
|
<< "String and int values recorded on each thread, "
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
// Google Test work.
|
// Google Test work.
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// Verifies that the command line flag variables can be accessed
|
// Verifies that the command line flag variables can be accessed
|
||||||
// in code once <gtest/gtest.h> has been #included.
|
// in code once <gtest/gtest.h> has been #included.
|
||||||
@ -154,11 +155,14 @@ using testing::internal::AlwaysFalse;
|
|||||||
using testing::internal::AlwaysTrue;
|
using testing::internal::AlwaysTrue;
|
||||||
using testing::internal::AppendUserMessage;
|
using testing::internal::AppendUserMessage;
|
||||||
using testing::internal::CodePointToUtf8;
|
using testing::internal::CodePointToUtf8;
|
||||||
|
using testing::internal::CountIf;
|
||||||
using testing::internal::EqFailure;
|
using testing::internal::EqFailure;
|
||||||
using testing::internal::FloatingPoint;
|
using testing::internal::FloatingPoint;
|
||||||
using testing::internal::FormatTimeInMillisAsSeconds;
|
using testing::internal::FormatTimeInMillisAsSeconds;
|
||||||
|
using testing::internal::ForEach;
|
||||||
using testing::internal::GTestFlagSaver;
|
using testing::internal::GTestFlagSaver;
|
||||||
using testing::internal::GetCurrentOsStackTraceExceptTop;
|
using testing::internal::GetCurrentOsStackTraceExceptTop;
|
||||||
|
using testing::internal::GetElementOr;
|
||||||
using testing::internal::GetNextRandomSeed;
|
using testing::internal::GetNextRandomSeed;
|
||||||
using testing::internal::GetRandomSeedFromFlag;
|
using testing::internal::GetRandomSeedFromFlag;
|
||||||
using testing::internal::GetTestTypeId;
|
using testing::internal::GetTestTypeId;
|
||||||
@ -170,12 +174,13 @@ using testing::internal::ParseInt32Flag;
|
|||||||
using testing::internal::ShouldRunTestOnShard;
|
using testing::internal::ShouldRunTestOnShard;
|
||||||
using testing::internal::ShouldShard;
|
using testing::internal::ShouldShard;
|
||||||
using testing::internal::ShouldUseColor;
|
using testing::internal::ShouldUseColor;
|
||||||
|
using testing::internal::Shuffle;
|
||||||
|
using testing::internal::ShuffleRange;
|
||||||
using testing::internal::StreamableToString;
|
using testing::internal::StreamableToString;
|
||||||
using testing::internal::String;
|
using testing::internal::String;
|
||||||
using testing::internal::TestEventListenersAccessor;
|
using testing::internal::TestEventListenersAccessor;
|
||||||
using testing::internal::TestResultAccessor;
|
using testing::internal::TestResultAccessor;
|
||||||
using testing::internal::UInt32;
|
using testing::internal::UInt32;
|
||||||
using testing::internal::Vector;
|
|
||||||
using testing::internal::WideStringToUtf8;
|
using testing::internal::WideStringToUtf8;
|
||||||
using testing::internal::kMaxRandomSeed;
|
using testing::internal::kMaxRandomSeed;
|
||||||
using testing::internal::kTestTypeIdInGoogleTest;
|
using testing::internal::kTestTypeIdInGoogleTest;
|
||||||
@ -186,14 +191,14 @@ using testing::internal::CaptureStdout;
|
|||||||
using testing::internal::GetCapturedStdout;
|
using testing::internal::GetCapturedStdout;
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION_
|
#endif // GTEST_HAS_STREAM_REDIRECTION_
|
||||||
|
|
||||||
class TestingVector : public Vector<int> {
|
class TestingVector : public std::vector<int> {
|
||||||
};
|
};
|
||||||
|
|
||||||
::std::ostream& operator<<(::std::ostream& os,
|
::std::ostream& operator<<(::std::ostream& os,
|
||||||
const TestingVector& vector) {
|
const TestingVector& vector) {
|
||||||
os << "{ ";
|
os << "{ ";
|
||||||
for (int i = 0; i < vector.size(); i++) {
|
for (size_t i = 0; i < vector.size(); i++) {
|
||||||
os << vector.GetElement(i) << " ";
|
os << vector[i] << " ";
|
||||||
}
|
}
|
||||||
os << "}";
|
os << "}";
|
||||||
return os;
|
return os;
|
||||||
@ -553,339 +558,80 @@ TEST(RandomTest, RepeatsWhenReseeded) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the Vector class template.
|
// Tests STL container utilities.
|
||||||
|
|
||||||
// Tests Vector::Clear().
|
// Tests CountIf().
|
||||||
TEST(VectorTest, Clear) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(1);
|
|
||||||
a.Clear();
|
|
||||||
EXPECT_EQ(0, a.size());
|
|
||||||
|
|
||||||
a.PushBack(2);
|
static bool IsPositive(int n) { return n > 0; }
|
||||||
a.PushBack(3);
|
|
||||||
a.Clear();
|
TEST(ContainerUtilityTest, CountIf) {
|
||||||
EXPECT_EQ(0, a.size());
|
std::vector<int> v;
|
||||||
|
EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container.
|
||||||
|
|
||||||
|
v.push_back(-1);
|
||||||
|
v.push_back(0);
|
||||||
|
EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies.
|
||||||
|
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(-10);
|
||||||
|
v.push_back(10);
|
||||||
|
EXPECT_EQ(2, CountIf(v, IsPositive));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests Vector::PushBack().
|
// Tests ForEach().
|
||||||
TEST(VectorTest, PushBack) {
|
|
||||||
Vector<char> a;
|
|
||||||
a.PushBack('a');
|
|
||||||
ASSERT_EQ(1, a.size());
|
|
||||||
EXPECT_EQ('a', a.GetElement(0));
|
|
||||||
|
|
||||||
a.PushBack('b');
|
static int g_sum = 0;
|
||||||
ASSERT_EQ(2, a.size());
|
static void Accumulate(int n) { g_sum += n; }
|
||||||
EXPECT_EQ('a', a.GetElement(0));
|
|
||||||
EXPECT_EQ('b', a.GetElement(1));
|
TEST(ContainerUtilityTest, ForEach) {
|
||||||
|
std::vector<int> v;
|
||||||
|
g_sum = 0;
|
||||||
|
ForEach(v, Accumulate);
|
||||||
|
EXPECT_EQ(0, g_sum); // Works for an empty container;
|
||||||
|
|
||||||
|
g_sum = 0;
|
||||||
|
v.push_back(1);
|
||||||
|
ForEach(v, Accumulate);
|
||||||
|
EXPECT_EQ(1, g_sum); // Works for a container with one element.
|
||||||
|
|
||||||
|
g_sum = 0;
|
||||||
|
v.push_back(20);
|
||||||
|
v.push_back(300);
|
||||||
|
ForEach(v, Accumulate);
|
||||||
|
EXPECT_EQ(321, g_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests Vector::PushFront().
|
// Tests GetElementOr().
|
||||||
TEST(VectorTest, PushFront) {
|
TEST(ContainerUtilityTest, GetElementOr) {
|
||||||
Vector<int> a;
|
std::vector<char> a;
|
||||||
ASSERT_EQ(0, a.size());
|
EXPECT_EQ('x', GetElementOr(a, 0, 'x'));
|
||||||
|
|
||||||
// Calls PushFront() on an empty Vector.
|
a.push_back('a');
|
||||||
a.PushFront(1);
|
a.push_back('b');
|
||||||
ASSERT_EQ(1, a.size());
|
EXPECT_EQ('a', GetElementOr(a, 0, 'x'));
|
||||||
EXPECT_EQ(1, a.GetElement(0));
|
EXPECT_EQ('b', GetElementOr(a, 1, 'x'));
|
||||||
|
EXPECT_EQ('x', GetElementOr(a, -2, 'x'));
|
||||||
// Calls PushFront() on a singleton Vector.
|
EXPECT_EQ('x', GetElementOr(a, 2, 'x'));
|
||||||
a.PushFront(2);
|
|
||||||
ASSERT_EQ(2, a.size());
|
|
||||||
EXPECT_EQ(2, a.GetElement(0));
|
|
||||||
EXPECT_EQ(1, a.GetElement(1));
|
|
||||||
|
|
||||||
// Calls PushFront() on a Vector with more than one elements.
|
|
||||||
a.PushFront(3);
|
|
||||||
ASSERT_EQ(3, a.size());
|
|
||||||
EXPECT_EQ(3, a.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a.GetElement(1));
|
|
||||||
EXPECT_EQ(1, a.GetElement(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests Vector::PopFront().
|
TEST(ContainerUtilityDeathTest, ShuffleRange) {
|
||||||
TEST(VectorTest, PopFront) {
|
std::vector<int> a;
|
||||||
Vector<int> a;
|
a.push_back(0);
|
||||||
|
a.push_back(1);
|
||||||
// Popping on an empty Vector should fail.
|
a.push_back(2);
|
||||||
EXPECT_FALSE(a.PopFront(NULL));
|
|
||||||
|
|
||||||
// Popping again on an empty Vector should fail, and the result element
|
|
||||||
// shouldn't be overwritten.
|
|
||||||
int element = 1;
|
|
||||||
EXPECT_FALSE(a.PopFront(&element));
|
|
||||||
EXPECT_EQ(1, element);
|
|
||||||
|
|
||||||
a.PushFront(2);
|
|
||||||
a.PushFront(3);
|
|
||||||
|
|
||||||
// PopFront() should pop the element in the front of the Vector.
|
|
||||||
EXPECT_TRUE(a.PopFront(&element));
|
|
||||||
EXPECT_EQ(3, element);
|
|
||||||
|
|
||||||
// After popping the last element, the Vector should be empty.
|
|
||||||
EXPECT_TRUE(a.PopFront(NULL));
|
|
||||||
EXPECT_EQ(0, a.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests inserting at the beginning using Vector::Insert().
|
|
||||||
TEST(VectorTest, InsertAtBeginning) {
|
|
||||||
Vector<int> a;
|
|
||||||
ASSERT_EQ(0, a.size());
|
|
||||||
|
|
||||||
// Inserts into an empty Vector.
|
|
||||||
a.Insert(1, 0);
|
|
||||||
ASSERT_EQ(1, a.size());
|
|
||||||
EXPECT_EQ(1, a.GetElement(0));
|
|
||||||
|
|
||||||
// Inserts at the beginning of a singleton Vector.
|
|
||||||
a.Insert(2, 0);
|
|
||||||
ASSERT_EQ(2, a.size());
|
|
||||||
EXPECT_EQ(2, a.GetElement(0));
|
|
||||||
EXPECT_EQ(1, a.GetElement(1));
|
|
||||||
|
|
||||||
// Inserts at the beginning of a Vector with more than one elements.
|
|
||||||
a.Insert(3, 0);
|
|
||||||
ASSERT_EQ(3, a.size());
|
|
||||||
EXPECT_EQ(3, a.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a.GetElement(1));
|
|
||||||
EXPECT_EQ(1, a.GetElement(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests inserting at a location other than the beginning using
|
|
||||||
// Vector::Insert().
|
|
||||||
TEST(VectorTest, InsertNotAtBeginning) {
|
|
||||||
// Prepares a singleton Vector.
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(1);
|
|
||||||
|
|
||||||
// Inserts at the end of a singleton Vector.
|
|
||||||
a.Insert(2, a.size());
|
|
||||||
ASSERT_EQ(2, a.size());
|
|
||||||
EXPECT_EQ(1, a.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a.GetElement(1));
|
|
||||||
|
|
||||||
// Inserts at the end of a Vector with more than one elements.
|
|
||||||
a.Insert(3, a.size());
|
|
||||||
ASSERT_EQ(3, a.size());
|
|
||||||
EXPECT_EQ(1, a.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a.GetElement(1));
|
|
||||||
EXPECT_EQ(3, a.GetElement(2));
|
|
||||||
|
|
||||||
// Inserts in the middle of a Vector.
|
|
||||||
a.Insert(4, 1);
|
|
||||||
ASSERT_EQ(4, a.size());
|
|
||||||
EXPECT_EQ(1, a.GetElement(0));
|
|
||||||
EXPECT_EQ(4, a.GetElement(1));
|
|
||||||
EXPECT_EQ(2, a.GetElement(2));
|
|
||||||
EXPECT_EQ(3, a.GetElement(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests Vector::GetElementOr().
|
|
||||||
TEST(VectorTest, GetElementOr) {
|
|
||||||
Vector<char> a;
|
|
||||||
EXPECT_EQ('x', a.GetElementOr(0, 'x'));
|
|
||||||
|
|
||||||
a.PushBack('a');
|
|
||||||
a.PushBack('b');
|
|
||||||
EXPECT_EQ('a', a.GetElementOr(0, 'x'));
|
|
||||||
EXPECT_EQ('b', a.GetElementOr(1, 'x'));
|
|
||||||
EXPECT_EQ('x', a.GetElementOr(-2, 'x'));
|
|
||||||
EXPECT_EQ('x', a.GetElementOr(2, 'x'));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VectorTest, Swap) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(0);
|
|
||||||
a.PushBack(1);
|
|
||||||
a.PushBack(2);
|
|
||||||
|
|
||||||
// Swaps an element with itself.
|
|
||||||
a.Swap(0, 0);
|
|
||||||
ASSERT_EQ(0, a.GetElement(0));
|
|
||||||
ASSERT_EQ(1, a.GetElement(1));
|
|
||||||
ASSERT_EQ(2, a.GetElement(2));
|
|
||||||
|
|
||||||
// Swaps two different elements where the indices go up.
|
|
||||||
a.Swap(0, 1);
|
|
||||||
ASSERT_EQ(1, a.GetElement(0));
|
|
||||||
ASSERT_EQ(0, a.GetElement(1));
|
|
||||||
ASSERT_EQ(2, a.GetElement(2));
|
|
||||||
|
|
||||||
// Swaps two different elements where the indices go down.
|
|
||||||
a.Swap(2, 0);
|
|
||||||
ASSERT_EQ(2, a.GetElement(0));
|
|
||||||
ASSERT_EQ(0, a.GetElement(1));
|
|
||||||
ASSERT_EQ(1, a.GetElement(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VectorTest, Clone) {
|
|
||||||
// Clones an empty Vector.
|
|
||||||
Vector<int> a;
|
|
||||||
scoped_ptr<Vector<int> > empty(a.Clone());
|
|
||||||
EXPECT_EQ(0, empty->size());
|
|
||||||
|
|
||||||
// Clones a singleton.
|
|
||||||
a.PushBack(42);
|
|
||||||
scoped_ptr<Vector<int> > singleton(a.Clone());
|
|
||||||
ASSERT_EQ(1, singleton->size());
|
|
||||||
EXPECT_EQ(42, singleton->GetElement(0));
|
|
||||||
|
|
||||||
// Clones a Vector with more elements.
|
|
||||||
a.PushBack(43);
|
|
||||||
a.PushBack(44);
|
|
||||||
scoped_ptr<Vector<int> > big(a.Clone());
|
|
||||||
ASSERT_EQ(3, big->size());
|
|
||||||
EXPECT_EQ(42, big->GetElement(0));
|
|
||||||
EXPECT_EQ(43, big->GetElement(1));
|
|
||||||
EXPECT_EQ(44, big->GetElement(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests Vector::Erase().
|
|
||||||
TEST(VectorDeathTest, Erase) {
|
|
||||||
Vector<int> a;
|
|
||||||
|
|
||||||
// Tests erasing from an empty vector.
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.Erase(0),
|
|
||||||
"Invalid Vector index 0: must be in range \\[0, -1\\]\\.");
|
|
||||||
|
|
||||||
// Tests erasing from a singleton vector.
|
|
||||||
a.PushBack(0);
|
|
||||||
|
|
||||||
a.Erase(0);
|
|
||||||
EXPECT_EQ(0, a.size());
|
|
||||||
|
|
||||||
// Tests Erase parameters beyond the bounds of the vector.
|
|
||||||
Vector<int> a1;
|
|
||||||
a1.PushBack(0);
|
|
||||||
a1.PushBack(1);
|
|
||||||
a1.PushBack(2);
|
|
||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a1.Erase(3),
|
|
||||||
"Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a1.Erase(-1),
|
|
||||||
"Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
|
|
||||||
|
|
||||||
// Tests erasing at the end of the vector.
|
|
||||||
Vector<int> a2;
|
|
||||||
a2.PushBack(0);
|
|
||||||
a2.PushBack(1);
|
|
||||||
a2.PushBack(2);
|
|
||||||
|
|
||||||
a2.Erase(2);
|
|
||||||
ASSERT_EQ(2, a2.size());
|
|
||||||
EXPECT_EQ(0, a2.GetElement(0));
|
|
||||||
EXPECT_EQ(1, a2.GetElement(1));
|
|
||||||
|
|
||||||
// Tests erasing in the middle of the vector.
|
|
||||||
Vector<int> a3;
|
|
||||||
a3.PushBack(0);
|
|
||||||
a3.PushBack(1);
|
|
||||||
a3.PushBack(2);
|
|
||||||
|
|
||||||
a3.Erase(1);
|
|
||||||
ASSERT_EQ(2, a3.size());
|
|
||||||
EXPECT_EQ(0, a3.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a3.GetElement(1));
|
|
||||||
|
|
||||||
// Tests erasing at the beginning of the vector.
|
|
||||||
Vector<int> a4;
|
|
||||||
a4.PushBack(0);
|
|
||||||
a4.PushBack(1);
|
|
||||||
a4.PushBack(2);
|
|
||||||
|
|
||||||
a4.Erase(0);
|
|
||||||
ASSERT_EQ(2, a4.size());
|
|
||||||
EXPECT_EQ(1, a4.GetElement(0));
|
|
||||||
EXPECT_EQ(2, a4.GetElement(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests the GetElement accessor.
|
|
||||||
TEST(VectorDeathTest, GetElement) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(0);
|
|
||||||
a.PushBack(1);
|
|
||||||
a.PushBack(2);
|
|
||||||
const Vector<int>& b = a;
|
|
||||||
|
|
||||||
EXPECT_EQ(0, b.GetElement(0));
|
|
||||||
EXPECT_EQ(1, b.GetElement(1));
|
|
||||||
EXPECT_EQ(2, b.GetElement(2));
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
b.GetElement(3),
|
|
||||||
"Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
b.GetElement(-1),
|
|
||||||
"Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests the GetMutableElement accessor.
|
|
||||||
TEST(VectorDeathTest, GetMutableElement) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(0);
|
|
||||||
a.PushBack(1);
|
|
||||||
a.PushBack(2);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, a.GetMutableElement(0));
|
|
||||||
EXPECT_EQ(1, a.GetMutableElement(1));
|
|
||||||
EXPECT_EQ(2, a.GetMutableElement(2));
|
|
||||||
|
|
||||||
a.GetMutableElement(0) = 42;
|
|
||||||
EXPECT_EQ(42, a.GetMutableElement(0));
|
|
||||||
EXPECT_EQ(1, a.GetMutableElement(1));
|
|
||||||
EXPECT_EQ(2, a.GetMutableElement(2));
|
|
||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.GetMutableElement(3),
|
|
||||||
"Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.GetMutableElement(-1),
|
|
||||||
"Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VectorDeathTest, Swap) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(0);
|
|
||||||
a.PushBack(1);
|
|
||||||
a.PushBack(2);
|
|
||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.Swap(-1, 1),
|
|
||||||
"Invalid first swap element -1: must be in range \\[0, 2\\]");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.Swap(3, 1),
|
|
||||||
"Invalid first swap element 3: must be in range \\[0, 2\\]");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.Swap(1, -1),
|
|
||||||
"Invalid second swap element -1: must be in range \\[0, 2\\]");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
a.Swap(1, 3),
|
|
||||||
"Invalid second swap element 3: must be in range \\[0, 2\\]");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VectorDeathTest, ShuffleRange) {
|
|
||||||
Vector<int> a;
|
|
||||||
a.PushBack(0);
|
|
||||||
a.PushBack(1);
|
|
||||||
a.PushBack(2);
|
|
||||||
testing::internal::Random random(1);
|
testing::internal::Random random(1);
|
||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
a.ShuffleRange(&random, -1, 1),
|
ShuffleRange(&random, -1, 1, &a),
|
||||||
"Invalid shuffle range start -1: must be in range \\[0, 3\\]");
|
"Invalid shuffle range start -1: must be in range \\[0, 3\\]");
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
a.ShuffleRange(&random, 4, 4),
|
ShuffleRange(&random, 4, 4, &a),
|
||||||
"Invalid shuffle range start 4: must be in range \\[0, 3\\]");
|
"Invalid shuffle range start 4: must be in range \\[0, 3\\]");
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
a.ShuffleRange(&random, 3, 2),
|
ShuffleRange(&random, 3, 2, &a),
|
||||||
"Invalid shuffle range finish 2: must be in range \\[3, 3\\]");
|
"Invalid shuffle range finish 2: must be in range \\[3, 3\\]");
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
a.ShuffleRange(&random, 3, 4),
|
ShuffleRange(&random, 3, 4, &a),
|
||||||
"Invalid shuffle range finish 4: must be in range \\[3, 3\\]");
|
"Invalid shuffle range finish 4: must be in range \\[3, 3\\]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,18 +641,18 @@ class VectorShuffleTest : public Test {
|
|||||||
|
|
||||||
VectorShuffleTest() : random_(1) {
|
VectorShuffleTest() : random_(1) {
|
||||||
for (int i = 0; i < kVectorSize; i++) {
|
for (int i = 0; i < kVectorSize; i++) {
|
||||||
vector_.PushBack(i);
|
vector_.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool VectorIsCorrupt(const TestingVector& vector) {
|
static bool VectorIsCorrupt(const TestingVector& vector) {
|
||||||
if (kVectorSize != vector.size()) {
|
if (kVectorSize != static_cast<int>(vector.size())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found_in_vector[kVectorSize] = { false };
|
bool found_in_vector[kVectorSize] = { false };
|
||||||
for (int i = 0; i < vector.size(); i++) {
|
for (size_t i = 0; i < vector.size(); i++) {
|
||||||
const int e = vector.GetElement(i);
|
const int e = vector[i];
|
||||||
if (e < 0 || e >= kVectorSize || found_in_vector[e]) {
|
if (e < 0 || e >= kVectorSize || found_in_vector[e]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -924,7 +670,7 @@ class VectorShuffleTest : public Test {
|
|||||||
|
|
||||||
static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) {
|
static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) {
|
||||||
for (int i = begin; i < end; i++) {
|
for (int i = begin; i < end; i++) {
|
||||||
if (i != vector.GetElement(i)) {
|
if (i != vector[i]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -952,39 +698,39 @@ const int VectorShuffleTest::kVectorSize;
|
|||||||
|
|
||||||
TEST_F(VectorShuffleTest, HandlesEmptyRange) {
|
TEST_F(VectorShuffleTest, HandlesEmptyRange) {
|
||||||
// Tests an empty range at the beginning...
|
// Tests an empty range at the beginning...
|
||||||
vector_.ShuffleRange(&random_, 0, 0);
|
ShuffleRange(&random_, 0, 0, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
|
|
||||||
// ...in the middle...
|
// ...in the middle...
|
||||||
vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2);
|
ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
|
|
||||||
// ...at the end...
|
// ...at the end...
|
||||||
vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1);
|
ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
|
|
||||||
// ...and past the end.
|
// ...and past the end.
|
||||||
vector_.ShuffleRange(&random_, kVectorSize, kVectorSize);
|
ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
|
TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
|
||||||
// Tests a size one range at the beginning...
|
// Tests a size one range at the beginning...
|
||||||
vector_.ShuffleRange(&random_, 0, 1);
|
ShuffleRange(&random_, 0, 1, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
|
|
||||||
// ...in the middle...
|
// ...in the middle...
|
||||||
vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1);
|
ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
|
|
||||||
// ...and at the end.
|
// ...and at the end.
|
||||||
vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize);
|
ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
ASSERT_PRED1(VectorIsUnshuffled, vector_);
|
||||||
}
|
}
|
||||||
@ -993,20 +739,20 @@ TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
|
|||||||
// we can guarantee that the following "random" tests will succeed.
|
// we can guarantee that the following "random" tests will succeed.
|
||||||
|
|
||||||
TEST_F(VectorShuffleTest, ShufflesEntireVector) {
|
TEST_F(VectorShuffleTest, ShufflesEntireVector) {
|
||||||
vector_.Shuffle(&random_);
|
Shuffle(&random_, &vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_;
|
EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_;
|
||||||
|
|
||||||
// Tests the first and last elements in particular to ensure that
|
// Tests the first and last elements in particular to ensure that
|
||||||
// there are no off-by-one problems in our shuffle algorithm.
|
// there are no off-by-one problems in our shuffle algorithm.
|
||||||
EXPECT_NE(0, vector_.GetElement(0));
|
EXPECT_NE(0, vector_[0]);
|
||||||
EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1));
|
EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
|
TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
|
||||||
const int kRangeSize = kVectorSize/2;
|
const int kRangeSize = kVectorSize/2;
|
||||||
|
|
||||||
vector_.ShuffleRange(&random_, 0, kRangeSize);
|
ShuffleRange(&random_, 0, kRangeSize, &vector_);
|
||||||
|
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize);
|
EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize);
|
||||||
@ -1015,7 +761,7 @@ TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
|
|||||||
|
|
||||||
TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
|
TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
|
||||||
const int kRangeSize = kVectorSize / 2;
|
const int kRangeSize = kVectorSize / 2;
|
||||||
vector_.ShuffleRange(&random_, kRangeSize, kVectorSize);
|
ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_);
|
||||||
|
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
|
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
|
||||||
@ -1024,7 +770,7 @@ TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
|
|||||||
|
|
||||||
TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
|
TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
|
||||||
int kRangeSize = kVectorSize/3;
|
int kRangeSize = kVectorSize/3;
|
||||||
vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize);
|
ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_);
|
||||||
|
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
|
EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
|
||||||
@ -1035,20 +781,19 @@ TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
|
|||||||
TEST_F(VectorShuffleTest, ShufflesRepeatably) {
|
TEST_F(VectorShuffleTest, ShufflesRepeatably) {
|
||||||
TestingVector vector2;
|
TestingVector vector2;
|
||||||
for (int i = 0; i < kVectorSize; i++) {
|
for (int i = 0; i < kVectorSize; i++) {
|
||||||
vector2.PushBack(i);
|
vector2.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
random_.Reseed(1234);
|
random_.Reseed(1234);
|
||||||
vector_.Shuffle(&random_);
|
Shuffle(&random_, &vector_);
|
||||||
random_.Reseed(1234);
|
random_.Reseed(1234);
|
||||||
vector2.Shuffle(&random_);
|
Shuffle(&random_, &vector2);
|
||||||
|
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector_);
|
||||||
ASSERT_PRED1(VectorIsNotCorrupt, vector2);
|
ASSERT_PRED1(VectorIsNotCorrupt, vector2);
|
||||||
|
|
||||||
for (int i = 0; i < kVectorSize; i++) {
|
for (int i = 0; i < kVectorSize; i++) {
|
||||||
EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i))
|
EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i;
|
||||||
<< " where i is " << i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1728,7 +1473,7 @@ TEST(TestPropertyTest, SetValue) {
|
|||||||
// The test fixture for testing TestResult.
|
// The test fixture for testing TestResult.
|
||||||
class TestResultTest : public Test {
|
class TestResultTest : public Test {
|
||||||
protected:
|
protected:
|
||||||
typedef Vector<TestPartResult> TPRVector;
|
typedef std::vector<TestPartResult> TPRVector;
|
||||||
|
|
||||||
// We make use of 2 TestPartResult objects,
|
// We make use of 2 TestPartResult objects,
|
||||||
TestPartResult * pr1, * pr2;
|
TestPartResult * pr1, * pr2;
|
||||||
@ -1755,23 +1500,23 @@ class TestResultTest : public Test {
|
|||||||
r2 = new TestResult();
|
r2 = new TestResult();
|
||||||
|
|
||||||
// In order to test TestResult, we need to modify its internal
|
// In order to test TestResult, we need to modify its internal
|
||||||
// state, in particular the TestPartResult Vector it holds.
|
// state, in particular the TestPartResult vector it holds.
|
||||||
// test_part_results() returns a const reference to this Vector.
|
// test_part_results() returns a const reference to this vector.
|
||||||
// We cast it to a non-const object s.t. it can be modified (yes,
|
// We cast it to a non-const object s.t. it can be modified (yes,
|
||||||
// this is a hack).
|
// this is a hack).
|
||||||
TPRVector* results1 = const_cast<Vector<TestPartResult> *>(
|
TPRVector* results1 = const_cast<TPRVector*>(
|
||||||
&TestResultAccessor::test_part_results(*r1));
|
&TestResultAccessor::test_part_results(*r1));
|
||||||
TPRVector* results2 = const_cast<Vector<TestPartResult> *>(
|
TPRVector* results2 = const_cast<TPRVector*>(
|
||||||
&TestResultAccessor::test_part_results(*r2));
|
&TestResultAccessor::test_part_results(*r2));
|
||||||
|
|
||||||
// r0 is an empty TestResult.
|
// r0 is an empty TestResult.
|
||||||
|
|
||||||
// r1 contains a single SUCCESS TestPartResult.
|
// r1 contains a single SUCCESS TestPartResult.
|
||||||
results1->PushBack(*pr1);
|
results1->push_back(*pr1);
|
||||||
|
|
||||||
// r2 contains a SUCCESS, and a FAILURE.
|
// r2 contains a SUCCESS, and a FAILURE.
|
||||||
results2->PushBack(*pr1);
|
results2->push_back(*pr1);
|
||||||
results2->PushBack(*pr2);
|
results2->push_back(*pr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
@ -1826,12 +1571,8 @@ typedef TestResultTest TestResultDeathTest;
|
|||||||
TEST_F(TestResultDeathTest, GetTestPartResult) {
|
TEST_F(TestResultDeathTest, GetTestPartResult) {
|
||||||
CompareTestPartResult(*pr1, r2->GetTestPartResult(0));
|
CompareTestPartResult(*pr1, r2->GetTestPartResult(0));
|
||||||
CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
|
CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), "");
|
||||||
r2->GetTestPartResult(2),
|
EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), "");
|
||||||
"Invalid Vector index 2: must be in range \\[0, 1\\]\\.");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
r2->GetTestPartResult(-1),
|
|
||||||
"Invalid Vector index -1: must be in range \\[0, 1\\]\\.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests TestResult has no properties when none are added.
|
// Tests TestResult has no properties when none are added.
|
||||||
@ -1913,12 +1654,8 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) {
|
|||||||
EXPECT_STREQ("key_3", fetched_property_3.key());
|
EXPECT_STREQ("key_3", fetched_property_3.key());
|
||||||
EXPECT_STREQ("3", fetched_property_3.value());
|
EXPECT_STREQ("3", fetched_property_3.value());
|
||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), "");
|
||||||
test_result.GetTestProperty(3),
|
EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), "");
|
||||||
"Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
|
||||||
test_result.GetTestProperty(-1),
|
|
||||||
"Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a property using a reserved key is supplied to this function, it tests
|
// When a property using a reserved key is supplied to this function, it tests
|
||||||
@ -2598,10 +2335,6 @@ TEST(PredTest, SingleEvaluationOnFailure) {
|
|||||||
// Some helper functions for testing using overloaded/template
|
// Some helper functions for testing using overloaded/template
|
||||||
// functions with ASSERT_PREDn and EXPECT_PREDn.
|
// functions with ASSERT_PREDn and EXPECT_PREDn.
|
||||||
|
|
||||||
bool IsPositive(int n) {
|
|
||||||
return n > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsPositive(double x) {
|
bool IsPositive(double x) {
|
||||||
return x > 0;
|
return x > 0;
|
||||||
}
|
}
|
||||||
@ -6747,26 +6480,26 @@ TEST(TestEventListenersTest, Append) {
|
|||||||
// order.
|
// order.
|
||||||
class SequenceTestingListener : public EmptyTestEventListener {
|
class SequenceTestingListener : public EmptyTestEventListener {
|
||||||
public:
|
public:
|
||||||
SequenceTestingListener(Vector<String>* vector, const char* id)
|
SequenceTestingListener(std::vector<String>* vector, const char* id)
|
||||||
: vector_(vector), id_(id) {}
|
: vector_(vector), id_(id) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
|
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
|
||||||
vector_->PushBack(GetEventDescription("OnTestProgramStart"));
|
vector_->push_back(GetEventDescription("OnTestProgramStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
|
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
|
||||||
vector_->PushBack(GetEventDescription("OnTestProgramEnd"));
|
vector_->push_back(GetEventDescription("OnTestProgramEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
||||||
int /*iteration*/) {
|
int /*iteration*/) {
|
||||||
vector_->PushBack(GetEventDescription("OnTestIterationStart"));
|
vector_->push_back(GetEventDescription("OnTestIterationStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
||||||
int /*iteration*/) {
|
int /*iteration*/) {
|
||||||
vector_->PushBack(GetEventDescription("OnTestIterationEnd"));
|
vector_->push_back(GetEventDescription("OnTestIterationEnd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -6776,14 +6509,14 @@ class SequenceTestingListener : public EmptyTestEventListener {
|
|||||||
return message.GetString();
|
return message.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String>* vector_;
|
std::vector<String>* vector_;
|
||||||
const char* const id_;
|
const char* const id_;
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener);
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(EventListenerTest, AppendKeepsOrder) {
|
TEST(EventListenerTest, AppendKeepsOrder) {
|
||||||
Vector<String> vec;
|
std::vector<String> vec;
|
||||||
TestEventListeners listeners;
|
TestEventListeners listeners;
|
||||||
listeners.Append(new SequenceTestingListener(&vec, "1st"));
|
listeners.Append(new SequenceTestingListener(&vec, "1st"));
|
||||||
listeners.Append(new SequenceTestingListener(&vec, "2nd"));
|
listeners.Append(new SequenceTestingListener(&vec, "2nd"));
|
||||||
@ -6791,34 +6524,34 @@ TEST(EventListenerTest, AppendKeepsOrder) {
|
|||||||
|
|
||||||
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
|
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
|
||||||
*UnitTest::GetInstance());
|
*UnitTest::GetInstance());
|
||||||
ASSERT_EQ(3, vec.size());
|
ASSERT_EQ(3U, vec.size());
|
||||||
EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str());
|
EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str());
|
||||||
EXPECT_STREQ("2nd.OnTestProgramStart", vec.GetElement(1).c_str());
|
EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str());
|
||||||
EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str());
|
EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str());
|
||||||
|
|
||||||
vec.Clear();
|
vec.clear();
|
||||||
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd(
|
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd(
|
||||||
*UnitTest::GetInstance());
|
*UnitTest::GetInstance());
|
||||||
ASSERT_EQ(3, vec.size());
|
ASSERT_EQ(3U, vec.size());
|
||||||
EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str());
|
EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str());
|
||||||
EXPECT_STREQ("2nd.OnTestProgramEnd", vec.GetElement(1).c_str());
|
EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str());
|
||||||
EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str());
|
EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str());
|
||||||
|
|
||||||
vec.Clear();
|
vec.clear();
|
||||||
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart(
|
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart(
|
||||||
*UnitTest::GetInstance(), 0);
|
*UnitTest::GetInstance(), 0);
|
||||||
ASSERT_EQ(3, vec.size());
|
ASSERT_EQ(3U, vec.size());
|
||||||
EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str());
|
EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str());
|
||||||
EXPECT_STREQ("2nd.OnTestIterationStart", vec.GetElement(1).c_str());
|
EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str());
|
||||||
EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str());
|
EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str());
|
||||||
|
|
||||||
vec.Clear();
|
vec.clear();
|
||||||
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd(
|
TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd(
|
||||||
*UnitTest::GetInstance(), 0);
|
*UnitTest::GetInstance(), 0);
|
||||||
ASSERT_EQ(3, vec.size());
|
ASSERT_EQ(3U, vec.size());
|
||||||
EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str());
|
EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str());
|
||||||
EXPECT_STREQ("2nd.OnTestIterationEnd", vec.GetElement(1).c_str());
|
EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str());
|
||||||
EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str());
|
EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a listener removed from a TestEventListeners list stops receiving
|
// Tests that a listener removed from a TestEventListeners list stops receiving
|
||||||
|
Loading…
x
Reference in New Issue
Block a user