Adds color support for TERM=linux (by Alexander Demin); renames List to Vector (by Zhanyong Wan); implements Vector::Erase (by Vlad Losev).

This commit is contained in:
zhanyong.wan 2009-07-13 19:25:02 +00:00
parent 600105ee3a
commit 89080477ae
10 changed files with 208 additions and 132 deletions

View File

@ -193,7 +193,7 @@ class Message {
// decide between class template specializations for T and T*, so a // decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that. // tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T> template <typename T>
inline void StreamHelper(internal::true_type dummy, T* pointer) { inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
if (pointer == NULL) { if (pointer == NULL) {
*ss_ << "(null)"; *ss_ << "(null)";
} else { } else {
@ -201,7 +201,7 @@ class Message {
} }
} }
template <typename T> template <typename T>
inline void StreamHelper(internal::false_type dummy, const T& value) { inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
::GTestStreamToHelper(ss_, value); ::GTestStreamToHelper(ss_, value);
} }
#endif // GTEST_OS_SYMBIAN #endif // GTEST_OS_SYMBIAN

View File

@ -136,9 +136,8 @@ 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 list to simulate the array. Yes, this means // Internally we use a Vector to implement the array.
// that random access is O(N) in time, but it's OK for its purpose. internal::Vector<TestPartResult>* const array_;
internal::List<TestPartResult>* const list_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
}; };

View File

@ -453,13 +453,13 @@ class TestResult {
friend class testing::TestInfo; friend class testing::TestInfo;
friend class testing::UnitTest; friend class testing::UnitTest;
// Gets the list of TestPartResults. // Gets the vector of TestPartResults.
const internal::List<TestPartResult>& test_part_results() const { const internal::Vector<TestPartResult>& test_part_results() const {
return *test_part_results_; return *test_part_results_;
} }
// Gets the list of TestProperties. // Gets the vector of TestProperties.
const internal::List<internal::TestProperty>& test_properties() const { const internal::Vector<internal::TestProperty>& test_properties() const {
return *test_properties_; return *test_properties_;
} }
@ -493,14 +493,15 @@ class TestResult {
// Clears the object. // Clears the object.
void Clear(); void Clear();
// Protects mutable state of the property list and of owned properties, whose // Protects mutable state of the property vector and of owned
// values may be updated. // properties, whose values may be updated.
internal::Mutex test_properites_mutex_; internal::Mutex test_properites_mutex_;
// The list of TestPartResults // The vector of TestPartResults
scoped_ptr<internal::List<TestPartResult> > test_part_results_; internal::scoped_ptr<internal::Vector<TestPartResult> > test_part_results_;
// The list of TestProperties // The vector of TestProperties
scoped_ptr<internal::List<internal::TestProperty> > test_properties_; internal::scoped_ptr<internal::Vector<internal::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.
@ -604,7 +605,7 @@ class TestInfo {
namespace internal { namespace internal {
// A test case, which consists of a list of TestInfos. // A test case, which consists of a vector of TestInfos.
// //
// TestCase is not copyable. // TestCase is not copyable.
class TestCase { class TestCase {
@ -667,11 +668,11 @@ class TestCase {
friend class testing::Test; friend class testing::Test;
friend class UnitTestImpl; friend class UnitTestImpl;
// Gets the (mutable) list of TestInfos in this TestCase. // Gets the (mutable) vector of TestInfos in this TestCase.
internal::List<TestInfo*>& test_info_list() { return *test_info_list_; } internal::Vector<TestInfo*>& test_info_list() { return *test_info_list_; }
// Gets the (immutable) list of TestInfos in this TestCase. // Gets the (immutable) vector of TestInfos in this TestCase.
const internal::List<TestInfo *> & test_info_list() const { const internal::Vector<TestInfo *> & test_info_list() const {
return *test_info_list_; return *test_info_list_;
} }
@ -712,8 +713,8 @@ class TestCase {
internal::String name_; internal::String name_;
// Comment on the test case. // Comment on the test case.
internal::String comment_; internal::String comment_;
// List of TestInfos. // Vector of TestInfos.
internal::List<TestInfo*>* test_info_list_; internal::Vector<TestInfo*>* test_info_list_;
// 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.
@ -760,7 +761,7 @@ class Environment {
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
}; };
// A UnitTest consists of a list of TestCases. // A UnitTest consists of a vector of TestCases.
// //
// This is a singleton class. The only instance of UnitTest is // This is a singleton class. The only instance of UnitTest is
// created when UnitTest::GetInstance() is first called. This // created when UnitTest::GetInstance() is first called. This

View File

@ -116,7 +116,7 @@ class ScopedTrace; // Implements scoped trace.
class TestInfoImpl; // Opaque implementation of TestInfo class TestInfoImpl; // Opaque implementation of TestInfo
class TestResult; // Result of a single Test. class TestResult; // Result of a single Test.
class UnitTestImpl; // Opaque implementation of UnitTest class UnitTestImpl; // Opaque implementation of UnitTest
template <typename E> class List; // A generic list. 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;
@ -208,13 +208,13 @@ String StreamableToString(const T& streamable);
// This overload makes sure that all pointers (including // This overload makes sure that all pointers (including
// those to char or wchar_t) are printed as raw pointers. // those to char or wchar_t) are printed as raw pointers.
template <typename T> template <typename T>
inline String FormatValueForFailureMessage(internal::true_type dummy, inline String FormatValueForFailureMessage(internal::true_type /*dummy*/,
T* pointer) { T* pointer) {
return StreamableToString(static_cast<const void*>(pointer)); return StreamableToString(static_cast<const void*>(pointer));
} }
template <typename T> template <typename T>
inline String FormatValueForFailureMessage(internal::false_type dummy, inline String FormatValueForFailureMessage(internal::false_type /*dummy*/,
const T& value) { const T& value) {
return StreamableToString(value); return StreamableToString(value);
} }

View File

@ -199,7 +199,7 @@ 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);
// List is an ordered container that supports random access to the // Vector is an ordered container that supports random access to the
// elements. // elements.
// //
// We cannot use std::vector, as Visual C++ 7.1's implementation of // We cannot use std::vector, as Visual C++ 7.1's implementation of
@ -209,15 +209,15 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id);
// //
// The element type must support copy constructor and operator=. // The element type must support copy constructor and operator=.
template <typename E> // E is the element type. template <typename E> // E is the element type.
class List { class Vector {
public: public:
// Creates an empty list. // Creates an empty Vector.
List() : elements_(NULL), capacity_(0), size_(0) {} Vector() : elements_(NULL), capacity_(0), size_(0) {}
// D'tor. // D'tor.
virtual ~List() { Clear(); } virtual ~Vector() { Clear(); }
// Clears the list. // Clears the Vector.
void Clear() { void Clear() {
if (elements_ != NULL) { if (elements_ != NULL) {
for (int i = 0; i < size_; i++) { for (int i = 0; i < size_; i++) {
@ -233,29 +233,27 @@ class List {
// Gets the number of elements. // Gets the number of elements.
int size() const { return size_; } int size() const { return size_; }
// Adds an element to the end of the list. A copy of the element is // Adds an element to the end of the Vector. A copy of the element
// created using the copy constructor, and then stored in the list. // is created using the copy constructor, and then stored in the
// Changes made to the element in the list doesn't affect the source // Vector. Changes made to the element in the Vector doesn't affect
// object, and vice versa. // the source object, and vice versa.
void PushBack(const E & element) { Insert(element, size_); } void PushBack(const E & element) { Insert(element, size_); }
// Adds an element to the beginning of this list. // Adds an element to the beginning of this Vector.
void PushFront(const E& element) { Insert(element, 0); } void PushFront(const E& element) { Insert(element, 0); }
// Removes an element from the beginning of this list. If the // Removes an element from the beginning of this Vector. If the
// result argument is not NULL, the removed element is stored in the // result argument is not NULL, the removed element is stored in the
// memory it points to. Otherwise the element is thrown away. // memory it points to. Otherwise the element is thrown away.
// Returns true iff the list wasn't empty before the operation. // Returns true iff the vector wasn't empty before the operation.
bool PopFront(E* result) { bool PopFront(E* result) {
if (size_ == 0) if (size_ == 0)
return false; return false;
if (result != NULL) if (result != NULL)
*result = *(elements_[0]); *result = GetElement(0);
delete elements_[0]; Erase(0);
size_--;
MoveElements(1, size_, 0);
return true; return true;
} }
@ -269,6 +267,18 @@ class List {
size_++; 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. // Returns the number of elements that satisfy a given predicate.
// The parameter 'predicate' is a Boolean function or functor that // The parameter 'predicate' is a Boolean function or functor that
// accepts a 'const E &', where E is the element type. // accepts a 'const E &', where E is the element type.
@ -284,7 +294,7 @@ class List {
return count; return count;
} }
// Applies a function/functor to each element in the list. The // Applies a function/functor to each element in the Vector. The
// parameter 'functor' is a function/functor that accepts a 'const // parameter 'functor' is a function/functor that accepts a 'const
// E &', where E is the element type. This method does not change // E &', where E is the element type. This method does not change
// the elements. // the elements.
@ -323,7 +333,7 @@ class List {
// is not in range [0, size()). // is not in range [0, size()).
const E& GetElement(int i) const { const E& GetElement(int i) const {
GTEST_CHECK_(0 <= i && i < size_) GTEST_CHECK_(0 <= i && i < size_)
<< "Invalid list index " << i << ": must be in range [0, " << "Invalid Vector index " << i << ": must be in range [0, "
<< (size_ - 1) << "]."; << (size_ - 1) << "].";
return *(elements_[i]); return *(elements_[i]);
@ -346,13 +356,13 @@ class List {
// no more than 1/3 of the slots are wasted. // no more than 1/3 of the slots are wasted.
const int new_capacity = 3*(capacity_/2 + 1); const int new_capacity = 3*(capacity_/2 + 1);
GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow? GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow?
<< "Cannot grow a list with " << capacity_ << " elements already."; << "Cannot grow a Vector with " << capacity_ << " elements already.";
capacity_ = new_capacity; capacity_ = new_capacity;
elements_ = static_cast<E**>( elements_ = static_cast<E**>(
realloc(elements_, capacity_*sizeof(elements_[0]))); realloc(elements_, capacity_*sizeof(elements_[0])));
} }
// Moves the give consecutive elements to a new index in the list. // Moves the give consecutive elements to a new index in the Vector.
void MoveElements(int source, int count, int dest) { void MoveElements(int source, int count, int dest) {
memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0])); memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0]));
} }
@ -361,9 +371,9 @@ class List {
int capacity_; // The number of elements allocated for elements_. int capacity_; // The number of elements allocated for elements_.
int size_; // The number of elements; in the range [0, capacity_]. int size_; // The number of elements; in the range [0, capacity_].
// We disallow copying List. // We disallow copying Vector.
GTEST_DISALLOW_COPY_AND_ASSIGN_(List); GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector);
}; // class List }; // 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.
@ -840,21 +850,21 @@ class UnitTestImpl {
TestInfo* current_test_info() { return current_test_info_; } TestInfo* current_test_info() { return current_test_info_; }
const TestInfo* current_test_info() const { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; }
// Returns the list 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::List<Environment*>* environments() { return &environments_; } internal::Vector<Environment*>* environments() { return &environments_; }
internal::List<Environment*>* environments_in_reverse_order() { internal::Vector<Environment*>* environments_in_reverse_order() {
return &environments_in_reverse_order_; return &environments_in_reverse_order_;
} }
internal::List<TestCase*>* test_cases() { return &test_cases_; } internal::Vector<TestCase*>* test_cases() { return &test_cases_; }
const internal::List<TestCase*>* test_cases() const { return &test_cases_; } const internal::Vector<TestCase*>* test_cases() const { return &test_cases_; }
// Getters for the per-thread Google Test trace stack. // Getters for the per-thread Google Test trace stack.
internal::List<TraceInfo>* gtest_trace_stack() { internal::Vector<TraceInfo>* gtest_trace_stack() {
return gtest_trace_stack_.pointer(); return gtest_trace_stack_.pointer();
} }
const internal::List<TraceInfo>* gtest_trace_stack() const { const internal::Vector<TraceInfo>* gtest_trace_stack() const {
return gtest_trace_stack_.pointer(); return gtest_trace_stack_.pointer();
} }
@ -899,13 +909,13 @@ class UnitTestImpl {
internal::ThreadLocal<TestPartResultReporterInterface*> internal::ThreadLocal<TestPartResultReporterInterface*>
per_thread_test_part_result_reporter_; per_thread_test_part_result_reporter_;
// The list 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. environments_in_reverse_order_
// simply mirrors environments_ in reverse order. // simply mirrors environments_ in reverse order.
internal::List<Environment*> environments_; internal::Vector<Environment*> environments_;
internal::List<Environment*> environments_in_reverse_order_; internal::Vector<Environment*> environments_in_reverse_order_;
internal::List<TestCase*> test_cases_; // The list of TestCases. internal::Vector<TestCase*> test_cases_; // The vector of TestCases.
#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized // ParameterizedTestRegistry object used to register value-parameterized
@ -964,7 +974,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::List<TraceInfo> > gtest_trace_stack_; internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
}; // class UnitTestImpl }; // class UnitTestImpl

View File

@ -66,17 +66,17 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
// Constructs an empty TestPartResultArray. // Constructs an empty TestPartResultArray.
TestPartResultArray::TestPartResultArray() TestPartResultArray::TestPartResultArray()
: list_(new internal::List<TestPartResult>) { : array_(new internal::Vector<TestPartResult>) {
} }
// Destructs a TestPartResultArray. // Destructs a TestPartResultArray.
TestPartResultArray::~TestPartResultArray() { TestPartResultArray::~TestPartResultArray() {
delete list_; 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) {
list_->PushBack(result); array_->PushBack(result);
} }
// Returns the TestPartResult at the given index (0-based). // Returns the TestPartResult at the given index (0-based).
@ -86,12 +86,12 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
internal::posix::Abort(); internal::posix::Abort();
} }
return list_->GetElement(index); return array_->GetElement(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 list_->size(); return array_->size();
} }
namespace internal { namespace internal {

View File

@ -185,7 +185,7 @@ GTEST_DEFINE_string_(
"Whether to use colors in the output. Valid values: yes, no, " "Whether to use colors in the output. Valid values: yes, no, "
"and auto. 'auto' means to use colors if the output is " "and auto. 'auto' means to use colors if the output is "
"being sent to a terminal and the TERM environment variable " "being sent to a terminal and the TERM environment variable "
"is set to xterm, xterm-color, xterm-256color or cygwin."); "is set to xterm, xterm-color, xterm-256color, linux or cygwin.");
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
filter, filter,
@ -258,10 +258,10 @@ static bool g_help_flag = false;
int g_init_gtest_count = 0; int g_init_gtest_count = 0;
static bool GTestIsInitialized() { return g_init_gtest_count != 0; } static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
// Iterates over a list 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::List<TestCase*>& case_list, static int SumOverTestCaseList(const internal::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 (int i = 0; i < case_list.size(); i++) {
@ -1818,8 +1818,8 @@ String AppendUserMessage(const String& gtest_msg,
// Creates an empty TestResult. // Creates an empty TestResult.
TestResult::TestResult() TestResult::TestResult()
: test_part_results_(new List<TestPartResult>), : test_part_results_(new Vector<TestPartResult>),
test_properties_(new List<TestProperty>), test_properties_(new Vector<TestProperty>),
death_test_count_(0), death_test_count_(0),
elapsed_time_(0) { elapsed_time_(0) {
} }
@ -2407,7 +2407,7 @@ TestCase::TestCase(const char* name, const char* comment,
tear_down_tc_(tear_down_tc), tear_down_tc_(tear_down_tc),
should_run_(false), should_run_(false),
elapsed_time_(0) { elapsed_time_(0) {
test_info_list_ = new internal::List<TestInfo *>; test_info_list_ = new internal::Vector<TestInfo *>;
} }
// Destructor of TestCase. // Destructor of TestCase.
@ -2603,6 +2603,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "xterm-256color") ||
String::CStringEquals(term, "linux") ||
String::CStringEquals(term, "cygwin"); String::CStringEquals(term, "cygwin");
return stdout_is_tty && term_supports_color; return stdout_is_tty && term_supports_color;
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
@ -2881,7 +2882,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
// This class forwards events to other event listeners. // This class forwards events to other event listeners.
class UnitTestEventsRepeater : public UnitTestEventListenerInterface { class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
public: public:
typedef internal::List<UnitTestEventListenerInterface *> Listeners; typedef internal::Vector<UnitTestEventListenerInterface *> Listeners;
UnitTestEventsRepeater() {} UnitTestEventsRepeater() {}
virtual ~UnitTestEventsRepeater(); virtual ~UnitTestEventsRepeater();
void AddListener(UnitTestEventListenerInterface *listener); void AddListener(UnitTestEventListenerInterface *listener);
@ -3685,7 +3686,7 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
} }
// 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 List::ForEach() method. // are for use in the Vector::ForEach() method.
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(); }
@ -3739,7 +3740,7 @@ int UnitTestImpl::RunAllTests() {
? HONOR_SHARDING_PROTOCOL ? HONOR_SHARDING_PROTOCOL
: IGNORE_SHARDING_PROTOCOL) > 0; : IGNORE_SHARDING_PROTOCOL) > 0;
// List the tests and exit if the --gtest_list_tests flag was specified. // Lists the tests and exits if the --gtest_list_tests flag was specified.
if (GTEST_FLAG(list_tests)) { if (GTEST_FLAG(list_tests)) {
// This must be called *after* FilterTests() has been called. // This must be called *after* FilterTests() has been called.
ListTestsMatchingFilter(); ListTestsMatchingFilter();

View File

@ -77,6 +77,7 @@ class GTestColorTest(gtest_test_utils.TestCase):
self.assert_(not UsesColor('xterm-mono', None, None)) self.assert_(not UsesColor('xterm-mono', None, None))
self.assert_(not UsesColor('unknown', None, None)) self.assert_(not UsesColor('unknown', None, None))
self.assert_(not UsesColor(None, None, None)) self.assert_(not UsesColor(None, None, None))
self.assert_(UsesColor('linux', None, None))
self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('cygwin', None, None))
self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm', None, None))
self.assert_(UsesColor('xterm-color', None, None)) self.assert_(UsesColor('xterm-color', None, None))

View File

@ -45,10 +45,10 @@
namespace testing { namespace testing {
namespace { namespace {
using internal::List;
using internal::String; using internal::String;
using internal::TestProperty; using internal::TestProperty;
using internal::TestPropertyKeyIs; using internal::TestPropertyKeyIs;
using internal::Vector;
// How many threads to create? // How many threads to create?
const int kThreadCount = 50; const int kThreadCount = 50;
@ -65,7 +65,7 @@ String IdToString(int id) {
return id_message.GetString(); return id_message.GetString();
} }
void ExpectKeyAndValueWereRecordedForId(const List<TestProperty>& properties, void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
int id, int id,
const char* suffix) { const char* suffix) {
TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());

View File

@ -106,7 +106,7 @@ class TestResultAccessor {
test_result->ClearTestPartResults(); test_result->ClearTestPartResults();
} }
static const List<testing::TestPartResult>& test_part_results( static const 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();
} }
@ -171,7 +171,6 @@ using testing::internal::GetUnitTestImpl;
using testing::internal::GTestFlagSaver; using testing::internal::GTestFlagSaver;
using testing::internal::Int32; using testing::internal::Int32;
using testing::internal::Int32FromEnvOrDie; using testing::internal::Int32FromEnvOrDie;
using testing::internal::List;
using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldRunTestOnShard;
using testing::internal::ShouldShard; using testing::internal::ShouldShard;
using testing::internal::ShouldUseColor; using testing::internal::ShouldUseColor;
@ -182,6 +181,7 @@ using testing::internal::TestProperty;
using testing::internal::TestResult; using testing::internal::TestResult;
using testing::internal::TestResultAccessor; using testing::internal::TestResultAccessor;
using testing::internal::ThreadLocal; using testing::internal::ThreadLocal;
using testing::internal::Vector;
using testing::internal::WideStringToUtf8; using testing::internal::WideStringToUtf8;
// This line tests that we can define tests in an unnamed namespace. // This line tests that we can define tests in an unnamed namespace.
@ -458,11 +458,11 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) {
} }
#endif // !GTEST_WIDE_STRING_USES_UTF16_ #endif // !GTEST_WIDE_STRING_USES_UTF16_
// Tests the List class template. // Tests the Vector class template.
// Tests List::Clear(). // Tests Vector::Clear().
TEST(ListTest, Clear) { TEST(VectorTest, Clear) {
List<int> a; Vector<int> a;
a.PushBack(1); a.PushBack(1);
a.Clear(); a.Clear();
EXPECT_EQ(0, a.size()); EXPECT_EQ(0, a.size());
@ -473,9 +473,9 @@ TEST(ListTest, Clear) {
EXPECT_EQ(0, a.size()); EXPECT_EQ(0, a.size());
} }
// Tests List::PushBack(). // Tests Vector::PushBack().
TEST(ListTest, PushBack) { TEST(VectorTest, PushBack) {
List<char> a; Vector<char> a;
a.PushBack('a'); a.PushBack('a');
ASSERT_EQ(1, a.size()); ASSERT_EQ(1, a.size());
EXPECT_EQ('a', a.GetElement(0)); EXPECT_EQ('a', a.GetElement(0));
@ -486,23 +486,23 @@ TEST(ListTest, PushBack) {
EXPECT_EQ('b', a.GetElement(1)); EXPECT_EQ('b', a.GetElement(1));
} }
// Tests List::PushFront(). // Tests Vector::PushFront().
TEST(ListTest, PushFront) { TEST(VectorTest, PushFront) {
List<int> a; Vector<int> a;
ASSERT_EQ(0, a.size()); ASSERT_EQ(0, a.size());
// Calls PushFront() on an empty list. // Calls PushFront() on an empty Vector.
a.PushFront(1); a.PushFront(1);
ASSERT_EQ(1, a.size()); ASSERT_EQ(1, a.size());
EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(0));
// Calls PushFront() on a singleton list. // Calls PushFront() on a singleton Vector.
a.PushFront(2); a.PushFront(2);
ASSERT_EQ(2, a.size()); ASSERT_EQ(2, a.size());
EXPECT_EQ(2, a.GetElement(0)); EXPECT_EQ(2, a.GetElement(0));
EXPECT_EQ(1, a.GetElement(1)); EXPECT_EQ(1, a.GetElement(1));
// Calls PushFront() on a list with more than one elements. // Calls PushFront() on a Vector with more than one elements.
a.PushFront(3); a.PushFront(3);
ASSERT_EQ(3, a.size()); ASSERT_EQ(3, a.size());
EXPECT_EQ(3, a.GetElement(0)); EXPECT_EQ(3, a.GetElement(0));
@ -510,14 +510,14 @@ TEST(ListTest, PushFront) {
EXPECT_EQ(1, a.GetElement(2)); EXPECT_EQ(1, a.GetElement(2));
} }
// Tests List::PopFront(). // Tests Vector::PopFront().
TEST(ListTest, PopFront) { TEST(VectorTest, PopFront) {
List<int> a; Vector<int> a;
// Popping on an empty list should fail. // Popping on an empty Vector should fail.
EXPECT_FALSE(a.PopFront(NULL)); EXPECT_FALSE(a.PopFront(NULL));
// Popping again on an empty list should fail, and the result element // Popping again on an empty Vector should fail, and the result element
// shouldn't be overwritten. // shouldn't be overwritten.
int element = 1; int element = 1;
EXPECT_FALSE(a.PopFront(&element)); EXPECT_FALSE(a.PopFront(&element));
@ -526,32 +526,32 @@ TEST(ListTest, PopFront) {
a.PushFront(2); a.PushFront(2);
a.PushFront(3); a.PushFront(3);
// PopFront() should pop the element in the front of the list. // PopFront() should pop the element in the front of the Vector.
EXPECT_TRUE(a.PopFront(&element)); EXPECT_TRUE(a.PopFront(&element));
EXPECT_EQ(3, element); EXPECT_EQ(3, element);
// After popping the last element, the list should be empty. // After popping the last element, the Vector should be empty.
EXPECT_TRUE(a.PopFront(NULL)); EXPECT_TRUE(a.PopFront(NULL));
EXPECT_EQ(0, a.size()); EXPECT_EQ(0, a.size());
} }
// Tests inserting at the beginning using List::Insert(). // Tests inserting at the beginning using Vector::Insert().
TEST(ListTest, InsertAtBeginning) { TEST(VectorTest, InsertAtBeginning) {
List<int> a; Vector<int> a;
ASSERT_EQ(0, a.size()); ASSERT_EQ(0, a.size());
// Inserts into an empty list. // Inserts into an empty Vector.
a.Insert(1, 0); a.Insert(1, 0);
ASSERT_EQ(1, a.size()); ASSERT_EQ(1, a.size());
EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(0));
// Inserts at the beginning of a singleton list. // Inserts at the beginning of a singleton Vector.
a.Insert(2, 0); a.Insert(2, 0);
ASSERT_EQ(2, a.size()); ASSERT_EQ(2, a.size());
EXPECT_EQ(2, a.GetElement(0)); EXPECT_EQ(2, a.GetElement(0));
EXPECT_EQ(1, a.GetElement(1)); EXPECT_EQ(1, a.GetElement(1));
// Inserts at the beginning of a list with more than one elements. // Inserts at the beginning of a Vector with more than one elements.
a.Insert(3, 0); a.Insert(3, 0);
ASSERT_EQ(3, a.size()); ASSERT_EQ(3, a.size());
EXPECT_EQ(3, a.GetElement(0)); EXPECT_EQ(3, a.GetElement(0));
@ -560,26 +560,26 @@ TEST(ListTest, InsertAtBeginning) {
} }
// Tests inserting at a location other than the beginning using // Tests inserting at a location other than the beginning using
// List::Insert(). // Vector::Insert().
TEST(ListTest, InsertNotAtBeginning) { TEST(VectorTest, InsertNotAtBeginning) {
// Prepares a singleton list. // Prepares a singleton Vector.
List<int> a; Vector<int> a;
a.PushBack(1); a.PushBack(1);
// Inserts at the end of a singleton list. // Inserts at the end of a singleton Vector.
a.Insert(2, a.size()); a.Insert(2, a.size());
ASSERT_EQ(2, a.size()); ASSERT_EQ(2, a.size());
EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(0));
EXPECT_EQ(2, a.GetElement(1)); EXPECT_EQ(2, a.GetElement(1));
// Inserts at the end of a list with more than one elements. // Inserts at the end of a Vector with more than one elements.
a.Insert(3, a.size()); a.Insert(3, a.size());
ASSERT_EQ(3, a.size()); ASSERT_EQ(3, a.size());
EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(0));
EXPECT_EQ(2, a.GetElement(1)); EXPECT_EQ(2, a.GetElement(1));
EXPECT_EQ(3, a.GetElement(2)); EXPECT_EQ(3, a.GetElement(2));
// Inserts in the middle of a list. // Inserts in the middle of a Vector.
a.Insert(4, 1); a.Insert(4, 1);
ASSERT_EQ(4, a.size()); ASSERT_EQ(4, a.size());
EXPECT_EQ(1, a.GetElement(0)); EXPECT_EQ(1, a.GetElement(0));
@ -588,9 +588,9 @@ TEST(ListTest, InsertNotAtBeginning) {
EXPECT_EQ(3, a.GetElement(3)); EXPECT_EQ(3, a.GetElement(3));
} }
// Tests List::GetElementOr(). // Tests Vector::GetElementOr().
TEST(ListTest, GetElementOr) { TEST(VectorTest, GetElementOr) {
List<char> a; Vector<char> a;
EXPECT_EQ('x', a.GetElementOr(0, 'x')); EXPECT_EQ('x', a.GetElementOr(0, 'x'));
a.PushBack('a'); a.PushBack('a');
@ -601,9 +601,71 @@ TEST(ListTest, GetElementOr) {
EXPECT_EQ('x', a.GetElementOr(2, 'x')); EXPECT_EQ('x', a.GetElementOr(2, 'x'));
} }
// Tests Vector::Erase().
TEST(VectorDeathTest, Erase) {
Vector<int> a;
// Tests erasing from an empty vector.
GTEST_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);
GTEST_EXPECT_DEATH_IF_SUPPORTED_(
a1.Erase(3),
"Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
GTEST_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. // Tests the GetElement accessor.
TEST(ListDeathTest, GetElement) { TEST(ListDeathTest, GetElement) {
List<int> a; Vector<int> a;
a.PushBack(0); a.PushBack(0);
a.PushBack(1); a.PushBack(1);
a.PushBack(2); a.PushBack(2);
@ -613,10 +675,10 @@ TEST(ListDeathTest, GetElement) {
EXPECT_EQ(2, a.GetElement(2)); EXPECT_EQ(2, a.GetElement(2));
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
a.GetElement(3), a.GetElement(3),
"Invalid list index 3: must be in range \\[0, 2\\]\\."); "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
a.GetElement(-1), a.GetElement(-1),
"Invalid list index -1: must be in range \\[0, 2\\]\\."); "Invalid Vector index -1: must be in range \\[0, 2\\]\\.");
} }
// Tests the String class. // Tests the String class.
@ -1126,7 +1188,7 @@ TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) {
// The test fixture for testing TestResult. // The test fixture for testing TestResult.
class TestResultTest : public Test { class TestResultTest : public Test {
protected: protected:
typedef List<TestPartResult> TPRList; typedef Vector<TestPartResult> TPRVector;
// We make use of 2 TestPartResult objects, // We make use of 2 TestPartResult objects,
TestPartResult * pr1, * pr2; TestPartResult * pr1, * pr2;
@ -1149,24 +1211,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 list it holds. // state, in particular the TestPartResult Vector it holds.
// test_part_results() returns a const reference to this list. // 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).
TPRList * list1, * list2; TPRVector* results1 = const_cast<Vector<TestPartResult> *>(
list1 = const_cast<List<TestPartResult> *>(
&TestResultAccessor::test_part_results(*r1)); &TestResultAccessor::test_part_results(*r1));
list2 = const_cast<List<TestPartResult> *>( TPRVector* results2 = const_cast<Vector<TestPartResult> *>(
&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.
list1->PushBack(*pr1); results1->PushBack(*pr1);
// r2 contains a SUCCESS, and a FAILURE. // r2 contains a SUCCESS, and a FAILURE.
list2->PushBack(*pr1); results2->PushBack(*pr1);
list2->PushBack(*pr2); results2->PushBack(*pr2);
} }
virtual void TearDown() { virtual void TearDown() {
@ -1251,10 +1312,10 @@ TEST_F(TestResultDeathTest, GetTestPartResult) {
CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
r2->GetTestPartResult(2), r2->GetTestPartResult(2),
"Invalid list index 2: must be in range \\[0, 1\\]\\."); "Invalid Vector index 2: must be in range \\[0, 1\\]\\.");
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
r2->GetTestPartResult(-1), r2->GetTestPartResult(-1),
"Invalid list index -1: must be in range \\[0, 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.
@ -1338,10 +1399,10 @@ TEST(TestResultPropertyDeathTest, GetTestProperty) {
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
test_result.GetTestProperty(3), test_result.GetTestProperty(3),
"Invalid list index 3: must be in range \\[0, 2\\]\\."); "Invalid Vector index 3: must be in range \\[0, 2\\]\\.");
GTEST_EXPECT_DEATH_IF_SUPPORTED_( GTEST_EXPECT_DEATH_IF_SUPPORTED_(
test_result.GetTestProperty(-1), test_result.GetTestProperty(-1),
"Invalid list index -1: must be in range \\[0, 2\\]\\."); "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
@ -5684,6 +5745,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
SetEnv("TERM", "xterm-color"); // TERM supports colors. SetEnv("TERM", "xterm-color"); // TERM supports colors.
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
SetEnv("TERM", "linux"); // TERM supports colors.
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
} }