Makes List a random-access data structure. This simplifies the implementation and makes it easier to implement test shuffling.
This commit is contained in:
		@@ -434,13 +434,14 @@ class TestResult {
 | 
				
			|||||||
  TimeInMillis elapsed_time() const { return elapsed_time_; }
 | 
					  TimeInMillis elapsed_time() const { return elapsed_time_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns the i-th test part result among all the results. i can range
 | 
					  // Returns the i-th test part result among all the results. i can range
 | 
				
			||||||
  // from 0 to test_property_count() - 1. If i is not in that range, returns
 | 
					  // from 0 to test_property_count() - 1. If i is not in that range, aborts
 | 
				
			||||||
  // NULL.
 | 
					  // the program.
 | 
				
			||||||
  const TestPartResult* GetTestPartResult(int i) const;
 | 
					  const TestPartResult& GetTestPartResult(int i) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 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, returns NULL.
 | 
					  // test_property_count() - 1. If i is not in that range, aborts the
 | 
				
			||||||
  const TestProperty* GetTestProperty(int i) const;
 | 
					  // program.
 | 
				
			||||||
 | 
					  const TestProperty& GetTestProperty(int i) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  friend class DefaultGlobalTestPartResultReporter;
 | 
					  friend class DefaultGlobalTestPartResultReporter;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -116,9 +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 List;      // A generic list.
 | 
				
			||||||
template <typename E> class ListNode;  // A node in a generic list.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,8 @@
 | 
				
			|||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#endif  // !_WIN32_WCE
 | 
					#endif  // !_WIN32_WCE
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <stdlib.h>   // For strtoll/_strtoul64.
 | 
					#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
 | 
				
			||||||
 | 
					#include <string.h>  // For memmove.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,199 +199,74 @@ 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 a simple singly-linked list container.
 | 
					// List is an ordered container that supports random access to the
 | 
				
			||||||
 | 
					// elements.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// We cannot use std::list as Microsoft's implementation of STL has
 | 
					// We cannot use std::vector, as Visual C++ 7.1's implementation of
 | 
				
			||||||
// problems when exception is disabled.  There is a hack to work
 | 
					// STL has problems compiling when exceptions are disabled.  There is
 | 
				
			||||||
// around this, but we've seen cases where the hack fails to work.
 | 
					// a hack to work around the problems, but we've seen cases where the
 | 
				
			||||||
 | 
					// hack fails to work.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// TODO(wan): switch to std::list when we have a reliable fix for the
 | 
					// The element type must support copy constructor and operator=.
 | 
				
			||||||
// STL problem, e.g. when we upgrade to the next version of Visual
 | 
					 | 
				
			||||||
// C++, or (more likely) switch to STLport.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The element type must support copy constructor.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Forward declare List
 | 
					 | 
				
			||||||
template <typename E>  // E is the element type.
 | 
					 | 
				
			||||||
class List;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListNode is a node in a singly-linked list.  It consists of an
 | 
					 | 
				
			||||||
// element and a pointer to the next node.  The last node in the list
 | 
					 | 
				
			||||||
// has a NULL value for its next pointer.
 | 
					 | 
				
			||||||
template <typename E>  // E is the element type.
 | 
					 | 
				
			||||||
class ListNode {
 | 
					 | 
				
			||||||
  friend class List<E>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  E element_;
 | 
					 | 
				
			||||||
  ListNode * next_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // The c'tor is private s.t. only in the ListNode class and in its
 | 
					 | 
				
			||||||
  // friend class List we can create a ListNode object.
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // Creates a node with a given element value.  The next pointer is
 | 
					 | 
				
			||||||
  // set to NULL.
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // ListNode does NOT have a default constructor.  Always use this
 | 
					 | 
				
			||||||
  // constructor (with parameter) to create a ListNode object.
 | 
					 | 
				
			||||||
  explicit ListNode(const E & element) : element_(element), next_(NULL) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // We disallow copying ListNode
 | 
					 | 
				
			||||||
  GTEST_DISALLOW_COPY_AND_ASSIGN_(ListNode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Gets the element in this node.
 | 
					 | 
				
			||||||
  E & element() { return element_; }
 | 
					 | 
				
			||||||
  const E & element() const { return element_; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Gets the next node in the list.
 | 
					 | 
				
			||||||
  ListNode * next() { return next_; }
 | 
					 | 
				
			||||||
  const ListNode * next() const { return next_; }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// List is a simple singly-linked list container.
 | 
					 | 
				
			||||||
template <typename E>  // E is the element type.
 | 
					template <typename E>  // E is the element type.
 | 
				
			||||||
class List {
 | 
					class List {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Creates an empty list.
 | 
					  // Creates an empty list.
 | 
				
			||||||
  List() : head_(NULL), last_(NULL), size_(0),
 | 
					  List() : elements_(NULL), capacity_(0), size_(0) {}
 | 
				
			||||||
           last_read_index_(-1), last_read_(NULL) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // D'tor.
 | 
					  // D'tor.
 | 
				
			||||||
  virtual ~List();
 | 
					  virtual ~List() { Clear(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Clears the list.
 | 
					  // Clears the list.
 | 
				
			||||||
  void Clear() {
 | 
					  void Clear() {
 | 
				
			||||||
    if ( size_ > 0 ) {
 | 
					    if (elements_ != NULL) {
 | 
				
			||||||
      // 1. Deletes every node.
 | 
					      for (int i = 0; i < size_; i++) {
 | 
				
			||||||
      ListNode<E> * node = head_;
 | 
					        delete elements_[i];
 | 
				
			||||||
      ListNode<E> * next = node->next();
 | 
					 | 
				
			||||||
      for ( ; ; ) {
 | 
					 | 
				
			||||||
        delete node;
 | 
					 | 
				
			||||||
        node = next;
 | 
					 | 
				
			||||||
        if ( node == NULL ) break;
 | 
					 | 
				
			||||||
        next = node->next();
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // 2. Resets the member variables.
 | 
					      free(elements_);
 | 
				
			||||||
      last_read_ = head_ = last_ = NULL;
 | 
					      elements_ = NULL;
 | 
				
			||||||
      size_ = 0;
 | 
					      capacity_ = size_ = 0;
 | 
				
			||||||
      last_read_index_ = -1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Gets the number of elements.
 | 
					  // Gets the number of elements.
 | 
				
			||||||
  int size() const { return size_; }
 | 
					  int size() const { return size_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns true if the list is empty.
 | 
					 | 
				
			||||||
  bool IsEmpty() const { return size() == 0; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Gets the first element of the list, or NULL if the list is empty.
 | 
					 | 
				
			||||||
  ListNode<E> * Head() { return head_; }
 | 
					 | 
				
			||||||
  const ListNode<E> * Head() const { return head_; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Gets the last element of the list, or NULL if the list is empty.
 | 
					 | 
				
			||||||
  ListNode<E> * Last() { return last_; }
 | 
					 | 
				
			||||||
  const ListNode<E> * Last() const { return last_; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Adds an element to the end of the list.  A copy of the element is
 | 
					  // Adds an element to the end of the list.  A copy of the element is
 | 
				
			||||||
  // created using the copy constructor, and then stored in the list.
 | 
					  // created using the copy constructor, and then stored in the list.
 | 
				
			||||||
  // Changes made to the element in the list doesn't affect the source
 | 
					  // Changes made to the element in the list doesn't affect the source
 | 
				
			||||||
  // object, and vice versa.  This does not affect the "last read"
 | 
					  // object, and vice versa.
 | 
				
			||||||
  // index.
 | 
					  void PushBack(const E & element) { Insert(element, size_); }
 | 
				
			||||||
  void PushBack(const E & element) {
 | 
					 | 
				
			||||||
    ListNode<E> * new_node = new ListNode<E>(element);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( size_ == 0 ) {
 | 
					  // Adds an element to the beginning of this list.
 | 
				
			||||||
      head_ = last_ = new_node;
 | 
					  void PushFront(const E& element) { Insert(element, 0); }
 | 
				
			||||||
      size_ = 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      last_->next_ = new_node;
 | 
					 | 
				
			||||||
      last_ = new_node;
 | 
					 | 
				
			||||||
      size_++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Adds an element to the beginning of this list.  The "last read"
 | 
					 | 
				
			||||||
  // index is adjusted accordingly.
 | 
					 | 
				
			||||||
  void PushFront(const E& element) {
 | 
					 | 
				
			||||||
    ListNode<E>* const new_node = new ListNode<E>(element);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( size_ == 0 ) {
 | 
					 | 
				
			||||||
      head_ = last_ = new_node;
 | 
					 | 
				
			||||||
      size_ = 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      new_node->next_ = head_;
 | 
					 | 
				
			||||||
      head_ = new_node;
 | 
					 | 
				
			||||||
      size_++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (last_read_index_ >= 0) {
 | 
					 | 
				
			||||||
      // A new element at the head bumps up an existing index by 1.
 | 
					 | 
				
			||||||
      last_read_index_++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Removes an element from the beginning of this list.  If the
 | 
					  // Removes an element from the beginning of this list.  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.  The
 | 
					  // Returns true iff the list wasn't empty before the operation.
 | 
				
			||||||
  // "last read" index is adjusted accordingly.
 | 
					 | 
				
			||||||
  bool PopFront(E* result) {
 | 
					  bool PopFront(E* result) {
 | 
				
			||||||
    if (size_ == 0) return false;
 | 
					    if (size_ == 0)
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (result != NULL) {
 | 
					    if (result != NULL)
 | 
				
			||||||
      *result = head_->element_;
 | 
					      *result = *(elements_[0]);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ListNode<E>* const old_head = head_;
 | 
					    delete elements_[0];
 | 
				
			||||||
    size_--;
 | 
					    size_--;
 | 
				
			||||||
    if (size_ == 0) {
 | 
					    MoveElements(1, size_, 0);
 | 
				
			||||||
      head_ = last_ = NULL;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      head_ = head_->next_;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    delete old_head;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (last_read_index_ > 0) {
 | 
					 | 
				
			||||||
      last_read_index_--;
 | 
					 | 
				
			||||||
    } else if (last_read_index_ == 0) {
 | 
					 | 
				
			||||||
      last_read_index_ = -1;
 | 
					 | 
				
			||||||
      last_read_ = NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts an element after a given node in the list.  It's the
 | 
					  // Inserts an element at the given index.  It's the caller's
 | 
				
			||||||
  // caller's responsibility to ensure that the given node is in the
 | 
					  // responsibility to ensure that the given index is in the range [0,
 | 
				
			||||||
  // list.  If the given node is NULL, inserts the element at the
 | 
					  // size()].
 | 
				
			||||||
  // front of the list.  The "last read" index is adjusted
 | 
					  void Insert(const E& element, int index) {
 | 
				
			||||||
  // accordingly.
 | 
					    GrowIfNeeded();
 | 
				
			||||||
  ListNode<E>* InsertAfter(ListNode<E>* node, const E& element) {
 | 
					    MoveElements(index, size_ - index, index + 1);
 | 
				
			||||||
    if (node == NULL) {
 | 
					    elements_[index] = new E(element);
 | 
				
			||||||
      PushFront(element);
 | 
					 | 
				
			||||||
      return Head();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ListNode<E>* const new_node = new ListNode<E>(element);
 | 
					 | 
				
			||||||
    new_node->next_ = node->next_;
 | 
					 | 
				
			||||||
    node->next_ = new_node;
 | 
					 | 
				
			||||||
    size_++;
 | 
					    size_++;
 | 
				
			||||||
    if (node == last_) {
 | 
					 | 
				
			||||||
      last_ = new_node;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // We aren't sure whether this insertion will affect the last read
 | 
					 | 
				
			||||||
    // index, so we invalidate it to be safe.
 | 
					 | 
				
			||||||
    last_read_index_ = -1;
 | 
					 | 
				
			||||||
    last_read_ = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return new_node;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns the number of elements that satisfy a given predicate.
 | 
					  // Returns the number of elements that satisfy a given predicate.
 | 
				
			||||||
@@ -399,10 +275,8 @@ class List {
 | 
				
			|||||||
  template <typename P>  // P is the type of the predicate function/functor
 | 
					  template <typename P>  // P is the type of the predicate function/functor
 | 
				
			||||||
  int CountIf(P predicate) const {
 | 
					  int CountIf(P predicate) const {
 | 
				
			||||||
    int count = 0;
 | 
					    int count = 0;
 | 
				
			||||||
    for ( const ListNode<E> * node = Head();
 | 
					    for (int i = 0; i < size_; i++) {
 | 
				
			||||||
          node != NULL;
 | 
					      if (predicate(*(elements_[i]))) {
 | 
				
			||||||
          node = node->next() ) {
 | 
					 | 
				
			||||||
      if ( predicate(node->element()) ) {
 | 
					 | 
				
			||||||
        count++;
 | 
					        count++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -416,10 +290,8 @@ class List {
 | 
				
			|||||||
  // the elements.
 | 
					  // the elements.
 | 
				
			||||||
  template <typename F>  // F is the type of the function/functor
 | 
					  template <typename F>  // F is the type of the function/functor
 | 
				
			||||||
  void ForEach(F functor) const {
 | 
					  void ForEach(F functor) const {
 | 
				
			||||||
    for ( const ListNode<E> * node = Head();
 | 
					    for (int i = 0; i < size_; i++) {
 | 
				
			||||||
          node != NULL;
 | 
					      functor(*(elements_[i]));
 | 
				
			||||||
          node = node->next() ) {
 | 
					 | 
				
			||||||
      functor(node->element());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -428,81 +300,70 @@ class List {
 | 
				
			|||||||
  // function/functor that accepts a 'const E &', where E is the
 | 
					  // function/functor that accepts a 'const E &', where E is the
 | 
				
			||||||
  // element type.  This method does not change the elements.
 | 
					  // element type.  This method does not change the elements.
 | 
				
			||||||
  template <typename P>  // P is the type of the predicate function/functor.
 | 
					  template <typename P>  // P is the type of the predicate function/functor.
 | 
				
			||||||
  const ListNode<E> * FindIf(P predicate) const {
 | 
					  const E* FindIf(P predicate) const {
 | 
				
			||||||
    for ( const ListNode<E> * node = Head();
 | 
					    for (int i = 0; i < size_; i++) {
 | 
				
			||||||
          node != NULL;
 | 
					      if (predicate(*elements_[i])) {
 | 
				
			||||||
          node = node->next() ) {
 | 
					        return elements_[i];
 | 
				
			||||||
      if ( predicate(node->element()) ) {
 | 
					 | 
				
			||||||
        return node;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename P>
 | 
					  template <typename P>
 | 
				
			||||||
  ListNode<E> * FindIf(P predicate) {
 | 
					  E* FindIf(P predicate) {
 | 
				
			||||||
    for ( ListNode<E> * node = Head();
 | 
					    for (int i = 0; i < size_; i++) {
 | 
				
			||||||
          node != NULL;
 | 
					      if (predicate(*elements_[i])) {
 | 
				
			||||||
          node = node->next() ) {
 | 
					        return elements_[i];
 | 
				
			||||||
      if ( predicate(node->element() ) ) {
 | 
					 | 
				
			||||||
        return node;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns a pointer to the i-th element of the list, or NULL if i is not
 | 
					  // Returns the i-th element of the list, or aborts the program if i
 | 
				
			||||||
  // in range [0, size()).  The "last read" index is adjusted accordingly.
 | 
					  // is not in range [0, size()).
 | 
				
			||||||
  const E* GetElement(int i) const {
 | 
					  const E& GetElement(int i) const {
 | 
				
			||||||
    if (i < 0 || i >= size())
 | 
					    GTEST_CHECK_(0 <= i && i < size_)
 | 
				
			||||||
      return NULL;
 | 
					        << "Invalid list index " << i << ": must be in range [0, "
 | 
				
			||||||
 | 
					        << (size_ - 1) << "].";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (last_read_index_ < 0 || last_read_index_ > i) {
 | 
					    return *(elements_[i]);
 | 
				
			||||||
      // We have to count from the start.
 | 
					 | 
				
			||||||
      last_read_index_ = 0;
 | 
					 | 
				
			||||||
      last_read_ = Head();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (last_read_index_ < i) {
 | 
					 | 
				
			||||||
      last_read_ = last_read_->next();
 | 
					 | 
				
			||||||
      last_read_index_++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return &(last_read_->element());
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns the i-th element of the list, or default_value if i is not
 | 
					  // Returns the i-th element of the list, or default_value if i is not
 | 
				
			||||||
  // in range [0, size()).  The "last read" index is adjusted accordingly.
 | 
					  // in range [0, size()).
 | 
				
			||||||
  E GetElementOr(int i, E default_value) const {
 | 
					  E GetElementOr(int i, E default_value) const {
 | 
				
			||||||
    const E* element = GetElement(i);
 | 
					    return (i < 0 || i >= size_) ? default_value : *(elements_[i]);
 | 
				
			||||||
    return element ? *element : default_value;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  ListNode<E>* head_;  // The first node of the list.
 | 
					  // Grows the buffer if it is not big enough to hold one more element.
 | 
				
			||||||
  ListNode<E>* last_;  // The last node of the list.
 | 
					  void GrowIfNeeded() {
 | 
				
			||||||
  int size_;           // The number of elements in the list.
 | 
					    if (size_ < capacity_)
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // These fields point to the last element read via GetElement(i) or
 | 
					    // Exponential bump-up is necessary to ensure that inserting N
 | 
				
			||||||
  // GetElementOr(i).  They are used to speed up list traversal as
 | 
					    // elements is O(N) instead of O(N^2).  The factor 3/2 means that
 | 
				
			||||||
  // often they allow us to find the wanted element by looking from
 | 
					    // no more than 1/3 of the slots are wasted.
 | 
				
			||||||
  // the last visited one instead of the list head.  This means a
 | 
					    const int new_capacity = 3*(capacity_/2 + 1);
 | 
				
			||||||
  // sequential traversal of the list can be done in O(N) time instead
 | 
					    GTEST_CHECK_(new_capacity > capacity_)  // Does the new capacity overflow?
 | 
				
			||||||
  // of O(N^2).
 | 
					        << "Cannot grow a list with " << capacity_ << " elements already.";
 | 
				
			||||||
  mutable int last_read_index_;
 | 
					    capacity_ = new_capacity;
 | 
				
			||||||
  mutable const ListNode<E>* last_read_;
 | 
					    elements_ = static_cast<E**>(
 | 
				
			||||||
 | 
					        realloc(elements_, capacity_*sizeof(elements_[0])));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Moves the give consecutive elements to a new index in the list.
 | 
				
			||||||
 | 
					  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 List.
 | 
					  // We disallow copying List.
 | 
				
			||||||
  GTEST_DISALLOW_COPY_AND_ASSIGN_(List);
 | 
					  GTEST_DISALLOW_COPY_AND_ASSIGN_(List);
 | 
				
			||||||
};
 | 
					};  // class List
 | 
				
			||||||
 | 
					 | 
				
			||||||
// The virtual destructor of List.
 | 
					 | 
				
			||||||
template <typename E>
 | 
					 | 
				
			||||||
List<E>::~List() {
 | 
					 | 
				
			||||||
  Clear();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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.
 | 
				
			||||||
@@ -907,10 +768,8 @@ class UnitTestImpl {
 | 
				
			|||||||
    // before main() is reached.
 | 
					    // before main() is reached.
 | 
				
			||||||
    if (original_working_dir_.IsEmpty()) {
 | 
					    if (original_working_dir_.IsEmpty()) {
 | 
				
			||||||
      original_working_dir_.Set(FilePath::GetCurrentDir());
 | 
					      original_working_dir_.Set(FilePath::GetCurrentDir());
 | 
				
			||||||
      if (original_working_dir_.IsEmpty()) {
 | 
					      GTEST_CHECK_(!original_working_dir_.IsEmpty())
 | 
				
			||||||
        printf("%s\n", "Failed to get the current working directory.");
 | 
					          << "Failed to get the current working directory.";
 | 
				
			||||||
        posix::Abort();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GetTestCase(test_info->test_case_name(),
 | 
					    GetTestCase(test_info->test_case_name(),
 | 
				
			||||||
@@ -1057,8 +916,8 @@ class UnitTestImpl {
 | 
				
			|||||||
  bool parameterized_tests_registered_;
 | 
					  bool parameterized_tests_registered_;
 | 
				
			||||||
#endif  // GTEST_HAS_PARAM_TEST
 | 
					#endif  // GTEST_HAS_PARAM_TEST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Points to the last death test case registered.  Initially NULL.
 | 
					  // Index of the last death test case registered.  Initially -1.
 | 
				
			||||||
  internal::ListNode<TestCase*>* last_death_test_case_;
 | 
					  int last_death_test_case_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // This points to the TestCase for the currently running test.  It
 | 
					  // This points to the TestCase for the currently running test.  It
 | 
				
			||||||
  // changes as Google Test goes through one test case after another.
 | 
					  // changes as Google Test goes through one test case after another.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,12 +86,7 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
 | 
				
			|||||||
    internal::posix::Abort();
 | 
					    internal::posix::Abort();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const internal::ListNode<TestPartResult>* p = list_->Head();
 | 
					  return list_->GetElement(index);
 | 
				
			||||||
  for (int i = 0; i < index; i++) {
 | 
					 | 
				
			||||||
    p = p->next();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return p->element();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns the number of TestPartResult objects in the array.
 | 
					// Returns the number of TestPartResult objects in the array.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										118
									
								
								src/gtest.cc
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								src/gtest.cc
									
									
									
									
									
								
							@@ -264,10 +264,8 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
 | 
				
			|||||||
static int SumOverTestCaseList(const internal::List<TestCase*>& case_list,
 | 
					static int SumOverTestCaseList(const internal::List<TestCase*>& case_list,
 | 
				
			||||||
                               int (TestCase::*method)() const) {
 | 
					                               int (TestCase::*method)() const) {
 | 
				
			||||||
  int sum = 0;
 | 
					  int sum = 0;
 | 
				
			||||||
  for (const internal::ListNode<TestCase*>* node = case_list.Head();
 | 
					  for (int i = 0; i < case_list.size(); i++) {
 | 
				
			||||||
       node != NULL;
 | 
					    sum += (case_list.GetElement(i)->*method)();
 | 
				
			||||||
       node = node->next()) {
 | 
					 | 
				
			||||||
    sum += (node->element()->*method)();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return sum;
 | 
					  return sum;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1830,16 +1828,17 @@ TestResult::TestResult()
 | 
				
			|||||||
TestResult::~TestResult() {
 | 
					TestResult::~TestResult() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns the i-th test part result among all the results. i can range
 | 
					// Returns the i-th test part result among all the results. i can
 | 
				
			||||||
// from 0 to total_part_count() - 1. If i is not in that range, returns
 | 
					// range from 0 to total_part_count() - 1. If i is not in that range,
 | 
				
			||||||
// NULL.
 | 
					// 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_->GetElement(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, returns NULL.
 | 
					// test_property_count() - 1. If i is not in that range, aborts the
 | 
				
			||||||
const TestProperty* TestResult::GetTestProperty(int i) const {
 | 
					// program.
 | 
				
			||||||
 | 
					const TestProperty& TestResult::GetTestProperty(int i) const {
 | 
				
			||||||
  return test_properties_->GetElement(i);
 | 
					  return test_properties_->GetElement(i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1861,14 +1860,13 @@ void TestResult::RecordProperty(const TestProperty& test_property) {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  MutexLock lock(&test_properites_mutex_);
 | 
					  MutexLock lock(&test_properites_mutex_);
 | 
				
			||||||
  ListNode<TestProperty>* const node_with_matching_key =
 | 
					  TestProperty* const property_with_matching_key =
 | 
				
			||||||
      test_properties_->FindIf(TestPropertyKeyIs(test_property.key()));
 | 
					      test_properties_->FindIf(TestPropertyKeyIs(test_property.key()));
 | 
				
			||||||
  if (node_with_matching_key == NULL) {
 | 
					  if (property_with_matching_key == NULL) {
 | 
				
			||||||
    test_properties_->PushBack(test_property);
 | 
					    test_properties_->PushBack(test_property);
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  TestProperty& property_with_matching_key = node_with_matching_key->element();
 | 
					  property_with_matching_key->SetValue(test_property.value());
 | 
				
			||||||
  property_with_matching_key.SetValue(test_property.value());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Adds a failure if the key is a reserved attribute of Google Test
 | 
					// Adds a failure if the key is a reserved attribute of Google Test
 | 
				
			||||||
@@ -2028,7 +2026,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().Head()->element()->impl();
 | 
					      test_case->test_info_list().GetElement(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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2884,7 +2882,6 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
 | 
				
			|||||||
class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
 | 
					class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  typedef internal::List<UnitTestEventListenerInterface *> Listeners;
 | 
					  typedef internal::List<UnitTestEventListenerInterface *> Listeners;
 | 
				
			||||||
  typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode;
 | 
					 | 
				
			||||||
  UnitTestEventsRepeater() {}
 | 
					  UnitTestEventsRepeater() {}
 | 
				
			||||||
  virtual ~UnitTestEventsRepeater();
 | 
					  virtual ~UnitTestEventsRepeater();
 | 
				
			||||||
  void AddListener(UnitTestEventListenerInterface *listener);
 | 
					  void AddListener(UnitTestEventListenerInterface *listener);
 | 
				
			||||||
@@ -2908,10 +2905,8 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
UnitTestEventsRepeater::~UnitTestEventsRepeater() {
 | 
					UnitTestEventsRepeater::~UnitTestEventsRepeater() {
 | 
				
			||||||
  for (ListenersNode* listener = listeners_.Head();
 | 
					  for (int i = 0; i < listeners_.size(); i++) {
 | 
				
			||||||
       listener != NULL;
 | 
					    delete listeners_.GetElement(i);
 | 
				
			||||||
       listener = listener->next()) {
 | 
					 | 
				
			||||||
    delete listener->element();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2924,10 +2919,8 @@ void UnitTestEventsRepeater::AddListener(
 | 
				
			|||||||
// This defines a member that repeats the call to all listeners.
 | 
					// This defines a member that repeats the call to all listeners.
 | 
				
			||||||
#define GTEST_REPEATER_METHOD_(Name, Type) \
 | 
					#define GTEST_REPEATER_METHOD_(Name, Type) \
 | 
				
			||||||
void UnitTestEventsRepeater::Name(const Type& parameter) { \
 | 
					void UnitTestEventsRepeater::Name(const Type& parameter) { \
 | 
				
			||||||
  for (ListenersNode* listener = listeners_.Head(); \
 | 
					  for (int i = 0; i < listeners_.size(); i++) { \
 | 
				
			||||||
       listener != NULL; \
 | 
					    listeners_.GetElement(i)->Name(parameter); \
 | 
				
			||||||
       listener = listener->next()) { \
 | 
					 | 
				
			||||||
    listener->element()->Name(parameter); \
 | 
					 | 
				
			||||||
  } \
 | 
					  } \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3150,7 +3143,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  int failures = 0;
 | 
					  int failures = 0;
 | 
				
			||||||
  for (int i = 0; i < result.total_part_count(); ++i) {
 | 
					  for (int i = 0; i < result.total_part_count(); ++i) {
 | 
				
			||||||
    const TestPartResult& part = *result.GetTestPartResult(i);
 | 
					    const TestPartResult& part = result.GetTestPartResult(i);
 | 
				
			||||||
    if (part.failed()) {
 | 
					    if (part.failed()) {
 | 
				
			||||||
      const internal::String message =
 | 
					      const internal::String message =
 | 
				
			||||||
          internal::String::Format("%s:%d\n%s", part.file_name(),
 | 
					          internal::String::Format("%s:%d\n%s", part.file_name(),
 | 
				
			||||||
@@ -3212,7 +3205,7 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
 | 
				
			|||||||
  using internal::TestProperty;
 | 
					  using internal::TestProperty;
 | 
				
			||||||
  Message attributes;
 | 
					  Message attributes;
 | 
				
			||||||
  for (int i = 0; i < result.test_property_count(); ++i) {
 | 
					  for (int i = 0; i < result.test_property_count(); ++i) {
 | 
				
			||||||
    const TestProperty& property = *result.GetTestProperty(i);
 | 
					    const TestProperty& property = result.GetTestProperty(i);
 | 
				
			||||||
    attributes << " " << property.key() << "="
 | 
					    attributes << " " << property.key() << "="
 | 
				
			||||||
        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
 | 
					        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -3407,11 +3400,9 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type,
 | 
				
			|||||||
  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 (internal::ListNode<internal::TraceInfo>* node =
 | 
					    for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
 | 
				
			||||||
         impl_->gtest_trace_stack()->Head();
 | 
					      const internal::TraceInfo& trace =
 | 
				
			||||||
         node != NULL;
 | 
					          impl_->gtest_trace_stack()->GetElement(i);
 | 
				
			||||||
         node = node->next()) {
 | 
					 | 
				
			||||||
      const internal::TraceInfo& trace = node->element();
 | 
					 | 
				
			||||||
      msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message;
 | 
					      msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -3606,7 +3597,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
 | 
				
			|||||||
      parameterized_test_registry_(),
 | 
					      parameterized_test_registry_(),
 | 
				
			||||||
      parameterized_tests_registered_(false),
 | 
					      parameterized_tests_registered_(false),
 | 
				
			||||||
#endif  // GTEST_HAS_PARAM_TEST
 | 
					#endif  // GTEST_HAS_PARAM_TEST
 | 
				
			||||||
      last_death_test_case_(NULL),
 | 
					      last_death_test_case_(-1),
 | 
				
			||||||
      current_test_case_(NULL),
 | 
					      current_test_case_(NULL),
 | 
				
			||||||
      current_test_info_(NULL),
 | 
					      current_test_info_(NULL),
 | 
				
			||||||
      ad_hoc_test_result_(),
 | 
					      ad_hoc_test_result_(),
 | 
				
			||||||
@@ -3670,30 +3661,27 @@ 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?
 | 
				
			||||||
  internal::ListNode<TestCase*>* node = test_cases_.FindIf(
 | 
					  TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name));
 | 
				
			||||||
      TestCaseNameIs(test_case_name));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node == NULL) {
 | 
					  if (test_case != NULL)
 | 
				
			||||||
    // No.  Let's create one.
 | 
					    return *test_case;
 | 
				
			||||||
    TestCase* const test_case =
 | 
					
 | 
				
			||||||
 | 
					  // No.  Let's create one.
 | 
				
			||||||
 | 
					  TestCase* const new_test_case =
 | 
				
			||||||
      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
 | 
					      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Is this a death test case?
 | 
					  // Is this a death test case?
 | 
				
			||||||
    if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
 | 
					  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
 | 
				
			||||||
                                                 kDeathTestCaseFilter)) {
 | 
					                                               kDeathTestCaseFilter)) {
 | 
				
			||||||
      // Yes.  Inserts the test case after the last death test case
 | 
					    // Yes.  Inserts the test case after the last death test case
 | 
				
			||||||
      // defined so far.
 | 
					    // defined so far.
 | 
				
			||||||
      node = test_cases_.InsertAfter(last_death_test_case_, test_case);
 | 
					    test_cases_.Insert(new_test_case, ++last_death_test_case_);
 | 
				
			||||||
      last_death_test_case_ = node;
 | 
					  } 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_.PushBack(test_case);
 | 
					 | 
				
			||||||
      node = test_cases_.Last();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Returns the TestCase found.
 | 
					  return new_test_case;
 | 
				
			||||||
  return node->element();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helpers for setting up / tearing down the given environment.  They
 | 
					// Helpers for setting up / tearing down the given environment.  They
 | 
				
			||||||
@@ -3925,19 +3913,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 (const internal::ListNode<TestCase *> *test_case_node =
 | 
					  for (int i = 0; i < test_cases_.size(); i++) {
 | 
				
			||||||
           test_cases_.Head();
 | 
					    TestCase* const test_case = test_cases_.GetElement(i);
 | 
				
			||||||
       test_case_node != NULL;
 | 
					 | 
				
			||||||
       test_case_node = test_case_node->next()) {
 | 
					 | 
				
			||||||
    TestCase * const test_case = test_case_node->element();
 | 
					 | 
				
			||||||
    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 (const internal::ListNode<TestInfo *> *test_info_node =
 | 
					    for (int j = 0; j < test_case->test_info_list().size(); j++) {
 | 
				
			||||||
             test_case->test_info_list().Head();
 | 
					      TestInfo* const test_info = test_case->test_info_list().GetElement(j);
 | 
				
			||||||
         test_info_node != NULL;
 | 
					 | 
				
			||||||
         test_info_node = test_info_node->next()) {
 | 
					 | 
				
			||||||
      TestInfo * const test_info = test_info_node->element();
 | 
					 | 
				
			||||||
      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.
 | 
				
			||||||
@@ -3974,17 +3956,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 (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head();
 | 
					  for (int i = 0; i < test_cases_.size(); i++) {
 | 
				
			||||||
       test_case_node != NULL;
 | 
					    const TestCase* const test_case = test_cases_.GetElement(i);
 | 
				
			||||||
       test_case_node = test_case_node->next()) {
 | 
					 | 
				
			||||||
    const TestCase* const test_case = test_case_node->element();
 | 
					 | 
				
			||||||
    bool printed_test_case_name = false;
 | 
					    bool printed_test_case_name = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const internal::ListNode<TestInfo*>* test_info_node =
 | 
					    for (int j = 0; j < test_case->test_info_list().size(); j++) {
 | 
				
			||||||
         test_case->test_info_list().Head();
 | 
					      const TestInfo* const test_info =
 | 
				
			||||||
         test_info_node != NULL;
 | 
					          test_case->test_info_list().GetElement(j);
 | 
				
			||||||
         test_info_node = test_info_node->next()) {
 | 
					 | 
				
			||||||
      const TestInfo* const test_info = test_info_node->element();
 | 
					 | 
				
			||||||
      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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,6 @@ namespace testing {
 | 
				
			|||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using internal::List;
 | 
					using internal::List;
 | 
				
			||||||
using internal::ListNode;
 | 
					 | 
				
			||||||
using internal::String;
 | 
					using internal::String;
 | 
				
			||||||
using internal::TestProperty;
 | 
					using internal::TestProperty;
 | 
				
			||||||
using internal::TestPropertyKeyIs;
 | 
					using internal::TestPropertyKeyIs;
 | 
				
			||||||
@@ -70,9 +69,10 @@ void ExpectKeyAndValueWereRecordedForId(const List<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());
 | 
				
			||||||
  const ListNode<TestProperty>* node = properties.FindIf(matches_key);
 | 
					  const TestProperty* property = properties.FindIf(matches_key);
 | 
				
			||||||
  EXPECT_TRUE(node != NULL) << "expecting " << suffix << " node for id " << id;
 | 
					  ASSERT_TRUE(property != NULL)
 | 
				
			||||||
  EXPECT_STREQ(IdToString(id).c_str(), node->element().value());
 | 
					      << "expecting " << suffix << " value for id " << id;
 | 
				
			||||||
 | 
					  EXPECT_STREQ(IdToString(id).c_str(), property->value());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Calls a large number of Google Test assertions, where exactly one of them
 | 
					// Calls a large number of Google Test assertions, where exactly one of them
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,16 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
 | 
				
			|||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) expands to a
 | 
				
			||||||
 | 
					// real death test if death tests are supported; otherwise it expands
 | 
				
			||||||
 | 
					// to empty.
 | 
				
			||||||
 | 
					#if GTEST_HAS_DEATH_TEST
 | 
				
			||||||
 | 
					#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex) \
 | 
				
			||||||
 | 
					    EXPECT_DEATH(statement, regex)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define GTEST_EXPECT_DEATH_IF_SUPPORTED_(statement, regex)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace testing {
 | 
					namespace testing {
 | 
				
			||||||
namespace internal {
 | 
					namespace internal {
 | 
				
			||||||
const char* FormatTimeInMillisAsSeconds(TimeInMillis ms);
 | 
					const char* FormatTimeInMillisAsSeconds(TimeInMillis ms);
 | 
				
			||||||
@@ -448,31 +458,56 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif  // !GTEST_WIDE_STRING_USES_UTF16_
 | 
					#endif  // !GTEST_WIDE_STRING_USES_UTF16_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests the List template class.
 | 
					// Tests the List class template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests List::Clear().
 | 
				
			||||||
 | 
					TEST(ListTest, Clear) {
 | 
				
			||||||
 | 
					  List<int> a;
 | 
				
			||||||
 | 
					  a.PushBack(1);
 | 
				
			||||||
 | 
					  a.Clear();
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, a.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  a.PushBack(2);
 | 
				
			||||||
 | 
					  a.PushBack(3);
 | 
				
			||||||
 | 
					  a.Clear();
 | 
				
			||||||
 | 
					  EXPECT_EQ(0, a.size());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests List::PushBack().
 | 
				
			||||||
 | 
					TEST(ListTest, PushBack) {
 | 
				
			||||||
 | 
					  List<char> a;
 | 
				
			||||||
 | 
					  a.PushBack('a');
 | 
				
			||||||
 | 
					  ASSERT_EQ(1, a.size());
 | 
				
			||||||
 | 
					  EXPECT_EQ('a', a.GetElement(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  a.PushBack('b');
 | 
				
			||||||
 | 
					  ASSERT_EQ(2, a.size());
 | 
				
			||||||
 | 
					  EXPECT_EQ('a', a.GetElement(0));
 | 
				
			||||||
 | 
					  EXPECT_EQ('b', a.GetElement(1));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests List::PushFront().
 | 
					// Tests List::PushFront().
 | 
				
			||||||
TEST(ListTest, PushFront) {
 | 
					TEST(ListTest, PushFront) {
 | 
				
			||||||
  List<int> a;
 | 
					  List<int> a;
 | 
				
			||||||
  ASSERT_EQ(0u, a.size());
 | 
					  ASSERT_EQ(0, a.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Calls PushFront() on an empty list.
 | 
					  // Calls PushFront() on an empty list.
 | 
				
			||||||
  a.PushFront(1);
 | 
					  a.PushFront(1);
 | 
				
			||||||
  ASSERT_EQ(1u, a.size());
 | 
					  ASSERT_EQ(1, a.size());
 | 
				
			||||||
  EXPECT_EQ(1, a.Head()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(0));
 | 
				
			||||||
  ASSERT_EQ(a.Head(), a.Last());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Calls PushFront() on a singleton list.
 | 
					  // Calls PushFront() on a singleton list.
 | 
				
			||||||
  a.PushFront(2);
 | 
					  a.PushFront(2);
 | 
				
			||||||
  ASSERT_EQ(2u, a.size());
 | 
					  ASSERT_EQ(2, a.size());
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(1, a.Last()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Calls PushFront() on a list with more than one elements.
 | 
					  // Calls PushFront() on a list with more than one elements.
 | 
				
			||||||
  a.PushFront(3);
 | 
					  a.PushFront(3);
 | 
				
			||||||
  ASSERT_EQ(3u, a.size());
 | 
					  ASSERT_EQ(3, a.size());
 | 
				
			||||||
  EXPECT_EQ(3, a.Head()->element());
 | 
					  EXPECT_EQ(3, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->next()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(1));
 | 
				
			||||||
  EXPECT_EQ(1, a.Last()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests List::PopFront().
 | 
					// Tests List::PopFront().
 | 
				
			||||||
@@ -497,75 +532,91 @@ TEST(ListTest, PopFront) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // After popping the last element, the list should be empty.
 | 
					  // After popping the last element, the list should be empty.
 | 
				
			||||||
  EXPECT_TRUE(a.PopFront(NULL));
 | 
					  EXPECT_TRUE(a.PopFront(NULL));
 | 
				
			||||||
  EXPECT_EQ(0u, a.size());
 | 
					  EXPECT_EQ(0, a.size());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests inserting at the beginning using List::InsertAfter().
 | 
					// Tests inserting at the beginning using List::Insert().
 | 
				
			||||||
TEST(ListTest, InsertAfterAtBeginning) {
 | 
					TEST(ListTest, InsertAtBeginning) {
 | 
				
			||||||
  List<int> a;
 | 
					  List<int> a;
 | 
				
			||||||
  ASSERT_EQ(0u, a.size());
 | 
					  ASSERT_EQ(0, a.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts into an empty list.
 | 
					  // Inserts into an empty list.
 | 
				
			||||||
  a.InsertAfter(NULL, 1);
 | 
					  a.Insert(1, 0);
 | 
				
			||||||
  ASSERT_EQ(1u, a.size());
 | 
					  ASSERT_EQ(1, a.size());
 | 
				
			||||||
  EXPECT_EQ(1, a.Head()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(0));
 | 
				
			||||||
  ASSERT_EQ(a.Head(), a.Last());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts at the beginning of a singleton list.
 | 
					  // Inserts at the beginning of a singleton list.
 | 
				
			||||||
  a.InsertAfter(NULL, 2);
 | 
					  a.Insert(2, 0);
 | 
				
			||||||
  ASSERT_EQ(2u, a.size());
 | 
					  ASSERT_EQ(2, a.size());
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(1, a.Last()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts at the beginning of a list with more than one elements.
 | 
					  // Inserts at the beginning of a list with more than one elements.
 | 
				
			||||||
  a.InsertAfter(NULL, 3);
 | 
					  a.Insert(3, 0);
 | 
				
			||||||
  ASSERT_EQ(3u, a.size());
 | 
					  ASSERT_EQ(3, a.size());
 | 
				
			||||||
  EXPECT_EQ(3, a.Head()->element());
 | 
					  EXPECT_EQ(3, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->next()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(1));
 | 
				
			||||||
  EXPECT_EQ(1, a.Last()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests inserting at a location other than the beginning using
 | 
					// Tests inserting at a location other than the beginning using
 | 
				
			||||||
// List::InsertAfter().
 | 
					// List::Insert().
 | 
				
			||||||
TEST(ListTest, InsertAfterNotAtBeginning) {
 | 
					TEST(ListTest, InsertNotAtBeginning) {
 | 
				
			||||||
  // Prepares a singleton list.
 | 
					  // Prepares a singleton list.
 | 
				
			||||||
  List<int> a;
 | 
					  List<int> a;
 | 
				
			||||||
  a.PushBack(1);
 | 
					  a.PushBack(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts at the end of a singleton list.
 | 
					  // Inserts at the end of a singleton list.
 | 
				
			||||||
  a.InsertAfter(a.Last(), 2);
 | 
					  a.Insert(2, a.size());
 | 
				
			||||||
  ASSERT_EQ(2u, a.size());
 | 
					  ASSERT_EQ(2, a.size());
 | 
				
			||||||
  EXPECT_EQ(1, a.Head()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(2, a.Last()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts at the end of a list with more than one elements.
 | 
					  // Inserts at the end of a list with more than one elements.
 | 
				
			||||||
  a.InsertAfter(a.Last(), 3);
 | 
					  a.Insert(3, a.size());
 | 
				
			||||||
  ASSERT_EQ(3u, a.size());
 | 
					  ASSERT_EQ(3, a.size());
 | 
				
			||||||
  EXPECT_EQ(1, a.Head()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->next()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(1));
 | 
				
			||||||
  EXPECT_EQ(3, a.Last()->element());
 | 
					  EXPECT_EQ(3, a.GetElement(2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Inserts in the middle of a list.
 | 
					  // Inserts in the middle of a list.
 | 
				
			||||||
  a.InsertAfter(a.Head(), 4);
 | 
					  a.Insert(4, 1);
 | 
				
			||||||
  ASSERT_EQ(4u, a.size());
 | 
					  ASSERT_EQ(4, a.size());
 | 
				
			||||||
  EXPECT_EQ(1, a.Head()->element());
 | 
					  EXPECT_EQ(1, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(4, a.Head()->next()->element());
 | 
					  EXPECT_EQ(4, a.GetElement(1));
 | 
				
			||||||
  EXPECT_EQ(2, a.Head()->next()->next()->element());
 | 
					  EXPECT_EQ(2, a.GetElement(2));
 | 
				
			||||||
  EXPECT_EQ(3, a.Last()->element());
 | 
					  EXPECT_EQ(3, a.GetElement(3));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests List::GetElementOr().
 | 
				
			||||||
 | 
					TEST(ListTest, GetElementOr) {
 | 
				
			||||||
 | 
					  List<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'));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests the GetElement accessor.
 | 
					// Tests the GetElement accessor.
 | 
				
			||||||
TEST(ListTest, GetElement) {
 | 
					TEST(ListDeathTest, GetElement) {
 | 
				
			||||||
  List<int> a;
 | 
					  List<int> a;
 | 
				
			||||||
  a.PushBack(0);
 | 
					  a.PushBack(0);
 | 
				
			||||||
  a.PushBack(1);
 | 
					  a.PushBack(1);
 | 
				
			||||||
  a.PushBack(2);
 | 
					  a.PushBack(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  EXPECT_EQ(&(a.Head()->element()), a.GetElement(0));
 | 
					  EXPECT_EQ(0, a.GetElement(0));
 | 
				
			||||||
  EXPECT_EQ(&(a.Head()->next()->element()), a.GetElement(1));
 | 
					  EXPECT_EQ(1, a.GetElement(1));
 | 
				
			||||||
  EXPECT_EQ(&(a.Head()->next()->next()->element()), a.GetElement(2));
 | 
					  EXPECT_EQ(2, a.GetElement(2));
 | 
				
			||||||
  EXPECT_TRUE(a.GetElement(3) == NULL);
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
  EXPECT_TRUE(a.GetElement(-1) == NULL);
 | 
					      a.GetElement(3),
 | 
				
			||||||
 | 
					      "Invalid list index 3: must be in range \\[0, 2\\]\\.");
 | 
				
			||||||
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
 | 
					      a.GetElement(-1),
 | 
				
			||||||
 | 
					      "Invalid list index -1: must be in range \\[0, 2\\]\\.");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests the String class.
 | 
					// Tests the String class.
 | 
				
			||||||
@@ -1128,18 +1179,17 @@ class TestResultTest : public Test {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Helper that compares two two TestPartResults.
 | 
					  // Helper that compares two two TestPartResults.
 | 
				
			||||||
  static void CompareTestPartResult(const TestPartResult* expected,
 | 
					  static void CompareTestPartResult(const TestPartResult& expected,
 | 
				
			||||||
                                    const TestPartResult* actual) {
 | 
					                                    const TestPartResult& actual) {
 | 
				
			||||||
    ASSERT_TRUE(actual != NULL);
 | 
					    EXPECT_EQ(expected.type(), actual.type());
 | 
				
			||||||
    EXPECT_EQ(expected->type(), actual->type());
 | 
					    EXPECT_STREQ(expected.file_name(), actual.file_name());
 | 
				
			||||||
    EXPECT_STREQ(expected->file_name(), actual->file_name());
 | 
					    EXPECT_EQ(expected.line_number(), actual.line_number());
 | 
				
			||||||
    EXPECT_EQ(expected->line_number(), actual->line_number());
 | 
					    EXPECT_STREQ(expected.summary(), actual.summary());
 | 
				
			||||||
    EXPECT_STREQ(expected->summary(), actual->summary());
 | 
					    EXPECT_STREQ(expected.message(), actual.message());
 | 
				
			||||||
    EXPECT_STREQ(expected->message(), actual->message());
 | 
					    EXPECT_EQ(expected.passed(), actual.passed());
 | 
				
			||||||
    EXPECT_EQ(expected->passed(), actual->passed());
 | 
					    EXPECT_EQ(expected.failed(), actual.failed());
 | 
				
			||||||
    EXPECT_EQ(expected->failed(), actual->failed());
 | 
					    EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed());
 | 
				
			||||||
    EXPECT_EQ(expected->nonfatally_failed(), actual->nonfatally_failed());
 | 
					    EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed());
 | 
				
			||||||
    EXPECT_EQ(expected->fatally_failed(), actual->fatally_failed());
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1193,11 +1243,18 @@ TEST_F(TestResultTest, Failed) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests TestResult::GetTestPartResult().
 | 
					// Tests TestResult::GetTestPartResult().
 | 
				
			||||||
TEST_F(TestResultTest, GetTestPartResult) {
 | 
					
 | 
				
			||||||
  CompareTestPartResult(pr1, r2->GetTestPartResult(0));
 | 
					typedef TestResultTest TestResultDeathTest;
 | 
				
			||||||
  CompareTestPartResult(pr2, r2->GetTestPartResult(1));
 | 
					
 | 
				
			||||||
  EXPECT_TRUE(r2->GetTestPartResult(2) == NULL);
 | 
					TEST_F(TestResultDeathTest, GetTestPartResult) {
 | 
				
			||||||
  EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL);
 | 
					  CompareTestPartResult(*pr1, r2->GetTestPartResult(0));
 | 
				
			||||||
 | 
					  CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
 | 
				
			||||||
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
 | 
					      r2->GetTestPartResult(2),
 | 
				
			||||||
 | 
					      "Invalid list index 2: must be in range \\[0, 1\\]\\.");
 | 
				
			||||||
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
 | 
					      r2->GetTestPartResult(-1),
 | 
				
			||||||
 | 
					      "Invalid list 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.
 | 
				
			||||||
@@ -1212,9 +1269,9 @@ TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) {
 | 
				
			|||||||
  TestProperty property("key_1", "1");
 | 
					  TestProperty property("key_1", "1");
 | 
				
			||||||
  TestResultAccessor::RecordProperty(&test_result, property);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property);
 | 
				
			||||||
  ASSERT_EQ(1, test_result.test_property_count());
 | 
					  ASSERT_EQ(1, test_result.test_property_count());
 | 
				
			||||||
  const TestProperty* actual_property = test_result.GetTestProperty(0);
 | 
					  const TestProperty& actual_property = test_result.GetTestProperty(0);
 | 
				
			||||||
  EXPECT_STREQ("key_1", actual_property->key());
 | 
					  EXPECT_STREQ("key_1", actual_property.key());
 | 
				
			||||||
  EXPECT_STREQ("1", actual_property->value());
 | 
					  EXPECT_STREQ("1", actual_property.value());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests TestResult has multiple properties when added.
 | 
					// Tests TestResult has multiple properties when added.
 | 
				
			||||||
@@ -1225,13 +1282,13 @@ TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) {
 | 
				
			|||||||
  TestResultAccessor::RecordProperty(&test_result, property_1);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property_1);
 | 
				
			||||||
  TestResultAccessor::RecordProperty(&test_result, property_2);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property_2);
 | 
				
			||||||
  ASSERT_EQ(2, test_result.test_property_count());
 | 
					  ASSERT_EQ(2, test_result.test_property_count());
 | 
				
			||||||
  const TestProperty* actual_property_1 = test_result.GetTestProperty(0);
 | 
					  const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
 | 
				
			||||||
  EXPECT_STREQ("key_1", actual_property_1->key());
 | 
					  EXPECT_STREQ("key_1", actual_property_1.key());
 | 
				
			||||||
  EXPECT_STREQ("1", actual_property_1->value());
 | 
					  EXPECT_STREQ("1", actual_property_1.value());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const TestProperty* actual_property_2 = test_result.GetTestProperty(1);
 | 
					  const TestProperty& actual_property_2 = test_result.GetTestProperty(1);
 | 
				
			||||||
  EXPECT_STREQ("key_2", actual_property_2->key());
 | 
					  EXPECT_STREQ("key_2", actual_property_2.key());
 | 
				
			||||||
  EXPECT_STREQ("2", actual_property_2->value());
 | 
					  EXPECT_STREQ("2", actual_property_2.value());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests TestResult::RecordProperty() overrides values for duplicate keys.
 | 
					// Tests TestResult::RecordProperty() overrides values for duplicate keys.
 | 
				
			||||||
@@ -1247,17 +1304,17 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) {
 | 
				
			|||||||
  TestResultAccessor::RecordProperty(&test_result, property_2_2);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property_2_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ASSERT_EQ(2, test_result.test_property_count());
 | 
					  ASSERT_EQ(2, test_result.test_property_count());
 | 
				
			||||||
  const TestProperty* actual_property_1 = test_result.GetTestProperty(0);
 | 
					  const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
 | 
				
			||||||
  EXPECT_STREQ("key_1", actual_property_1->key());
 | 
					  EXPECT_STREQ("key_1", actual_property_1.key());
 | 
				
			||||||
  EXPECT_STREQ("12", actual_property_1->value());
 | 
					  EXPECT_STREQ("12", actual_property_1.value());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const TestProperty* actual_property_2 = test_result.GetTestProperty(1);
 | 
					  const TestProperty& actual_property_2 = test_result.GetTestProperty(1);
 | 
				
			||||||
  EXPECT_STREQ("key_2", actual_property_2->key());
 | 
					  EXPECT_STREQ("key_2", actual_property_2.key());
 | 
				
			||||||
  EXPECT_STREQ("22", actual_property_2->value());
 | 
					  EXPECT_STREQ("22", actual_property_2.value());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests TestResult::GetTestProperty().
 | 
					// Tests TestResult::GetTestProperty().
 | 
				
			||||||
TEST(TestResultPropertyTest, GetTestProperty) {
 | 
					TEST(TestResultPropertyDeathTest, GetTestProperty) {
 | 
				
			||||||
  TestResult test_result;
 | 
					  TestResult test_result;
 | 
				
			||||||
  TestProperty property_1("key_1", "1");
 | 
					  TestProperty property_1("key_1", "1");
 | 
				
			||||||
  TestProperty property_2("key_2", "2");
 | 
					  TestProperty property_2("key_2", "2");
 | 
				
			||||||
@@ -1266,24 +1323,25 @@ TEST(TestResultPropertyTest, GetTestProperty) {
 | 
				
			|||||||
  TestResultAccessor::RecordProperty(&test_result, property_2);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property_2);
 | 
				
			||||||
  TestResultAccessor::RecordProperty(&test_result, property_3);
 | 
					  TestResultAccessor::RecordProperty(&test_result, property_3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const TestProperty* fetched_property_1 = test_result.GetTestProperty(0);
 | 
					  const TestProperty& fetched_property_1 = test_result.GetTestProperty(0);
 | 
				
			||||||
  const TestProperty* fetched_property_2 = test_result.GetTestProperty(1);
 | 
					  const TestProperty& fetched_property_2 = test_result.GetTestProperty(1);
 | 
				
			||||||
  const TestProperty* fetched_property_3 = test_result.GetTestProperty(2);
 | 
					  const TestProperty& fetched_property_3 = test_result.GetTestProperty(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ASSERT_TRUE(fetched_property_1 != NULL);
 | 
					  EXPECT_STREQ("key_1", fetched_property_1.key());
 | 
				
			||||||
  EXPECT_STREQ("key_1", fetched_property_1->key());
 | 
					  EXPECT_STREQ("1", fetched_property_1.value());
 | 
				
			||||||
  EXPECT_STREQ("1", fetched_property_1->value());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ASSERT_TRUE(fetched_property_2 != NULL);
 | 
					  EXPECT_STREQ("key_2", fetched_property_2.key());
 | 
				
			||||||
  EXPECT_STREQ("key_2", fetched_property_2->key());
 | 
					  EXPECT_STREQ("2", fetched_property_2.value());
 | 
				
			||||||
  EXPECT_STREQ("2", fetched_property_2->value());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ASSERT_TRUE(fetched_property_3 != NULL);
 | 
					  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());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ASSERT_TRUE(test_result.GetTestProperty(3) == NULL);
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
  ASSERT_TRUE(test_result.GetTestProperty(-1) == NULL);
 | 
					      test_result.GetTestProperty(3),
 | 
				
			||||||
 | 
					      "Invalid list index 3: must be in range \\[0, 2\\]\\.");
 | 
				
			||||||
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
 | 
					      test_result.GetTestProperty(-1),
 | 
				
			||||||
 | 
					      "Invalid list 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
 | 
				
			||||||
@@ -1548,29 +1606,26 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) {
 | 
				
			|||||||
  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123");
 | 
					  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123");
 | 
				
			||||||
  EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333));
 | 
					  EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif // _WIN32_WCE
 | 
					#endif  // _WIN32_WCE
 | 
				
			||||||
 | 
					 | 
				
			||||||
#if GTEST_HAS_DEATH_TEST
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Int32FromEnvOrDie() aborts with an error message
 | 
					// Tests that Int32FromEnvOrDie() aborts with an error message
 | 
				
			||||||
// if the variable is not an Int32.
 | 
					// if the variable is not an Int32.
 | 
				
			||||||
TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) {
 | 
					TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) {
 | 
				
			||||||
  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx");
 | 
					  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx");
 | 
				
			||||||
  EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
               ".*");
 | 
					      Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123),
 | 
				
			||||||
 | 
					      ".*");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Int32FromEnvOrDie() aborts with an error message
 | 
					// Tests that Int32FromEnvOrDie() aborts with an error message
 | 
				
			||||||
// if the variable cannot be represnted by an Int32.
 | 
					// if the variable cannot be represnted by an Int32.
 | 
				
			||||||
TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) {
 | 
					TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) {
 | 
				
			||||||
  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234");
 | 
					  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234");
 | 
				
			||||||
  EXPECT_DEATH({Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(
 | 
				
			||||||
               ".*");
 | 
					      Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123),
 | 
				
			||||||
 | 
					      ".*");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // GTEST_HAS_DEATH_TEST
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tests that ShouldRunTestOnShard() selects all tests
 | 
					// Tests that ShouldRunTestOnShard() selects all tests
 | 
				
			||||||
// where there is 1 shard.
 | 
					// where there is 1 shard.
 | 
				
			||||||
TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) {
 | 
					TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) {
 | 
				
			||||||
@@ -1635,35 +1690,34 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) {
 | 
				
			|||||||
  EXPECT_TRUE(ShouldShard(total_var_, index_var_, false));
 | 
					  EXPECT_TRUE(ShouldShard(total_var_, index_var_, false));
 | 
				
			||||||
  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
 | 
					  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif // _WIN32_WCE
 | 
					#endif  // _WIN32_WCE
 | 
				
			||||||
 | 
					 | 
				
			||||||
#if GTEST_HAS_DEATH_TEST
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that we exit in error if the sharding values are not valid.
 | 
					// Tests that we exit in error if the sharding values are not valid.
 | 
				
			||||||
TEST_F(ShouldShardTest, AbortsWhenShardingEnvVarsAreInvalid) {
 | 
					
 | 
				
			||||||
 | 
					typedef ShouldShardTest ShouldShardDeathTest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) {
 | 
				
			||||||
  SetEnv(index_var_, "4");
 | 
					  SetEnv(index_var_, "4");
 | 
				
			||||||
  SetEnv(total_var_, "4");
 | 
					  SetEnv(total_var_, "4");
 | 
				
			||||||
  EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false),
 | 
				
			||||||
               ".*");
 | 
					                                   ".*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SetEnv(index_var_, "4");
 | 
					  SetEnv(index_var_, "4");
 | 
				
			||||||
  SetEnv(total_var_, "-2");
 | 
					  SetEnv(total_var_, "-2");
 | 
				
			||||||
  EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false),
 | 
				
			||||||
               ".*");
 | 
					                                   ".*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SetEnv(index_var_, "5");
 | 
					  SetEnv(index_var_, "5");
 | 
				
			||||||
  SetEnv(total_var_, "");
 | 
					  SetEnv(total_var_, "");
 | 
				
			||||||
  EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false),
 | 
				
			||||||
               ".*");
 | 
					                                   ".*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SetEnv(index_var_, "");
 | 
					  SetEnv(index_var_, "");
 | 
				
			||||||
  SetEnv(total_var_, "5");
 | 
					  SetEnv(total_var_, "5");
 | 
				
			||||||
  EXPECT_DEATH({ShouldShard(total_var_, index_var_, false);},
 | 
					  GTEST_EXPECT_DEATH_IF_SUPPORTED_(ShouldShard(total_var_, index_var_, false),
 | 
				
			||||||
               ".*");
 | 
					                                   ".*");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // GTEST_HAS_DEATH_TEST
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tests that ShouldRunTestOnShard is a partition when 5
 | 
					// Tests that ShouldRunTestOnShard is a partition when 5
 | 
				
			||||||
// shards are used.
 | 
					// shards are used.
 | 
				
			||||||
TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) {
 | 
					TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) {
 | 
				
			||||||
@@ -3624,31 +3678,31 @@ namespace testing {
 | 
				
			|||||||
TEST(SuccessfulAssertionTest, SUCCEED) {
 | 
					TEST(SuccessfulAssertionTest, SUCCEED) {
 | 
				
			||||||
  SUCCEED();
 | 
					  SUCCEED();
 | 
				
			||||||
  SUCCEED() << "OK";
 | 
					  SUCCEED() << "OK";
 | 
				
			||||||
  EXPECT_EQ(2u, GetSuccessfulPartCount());
 | 
					  EXPECT_EQ(2, GetSuccessfulPartCount());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Google Test doesn't track successful EXPECT_*.
 | 
					// Tests that Google Test doesn't track successful EXPECT_*.
 | 
				
			||||||
TEST(SuccessfulAssertionTest, EXPECT) {
 | 
					TEST(SuccessfulAssertionTest, EXPECT) {
 | 
				
			||||||
  EXPECT_TRUE(true);
 | 
					  EXPECT_TRUE(true);
 | 
				
			||||||
  EXPECT_EQ(0u, GetSuccessfulPartCount());
 | 
					  EXPECT_EQ(0, GetSuccessfulPartCount());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Google Test doesn't track successful EXPECT_STR*.
 | 
					// Tests that Google Test doesn't track successful EXPECT_STR*.
 | 
				
			||||||
TEST(SuccessfulAssertionTest, EXPECT_STR) {
 | 
					TEST(SuccessfulAssertionTest, EXPECT_STR) {
 | 
				
			||||||
  EXPECT_STREQ("", "");
 | 
					  EXPECT_STREQ("", "");
 | 
				
			||||||
  EXPECT_EQ(0u, GetSuccessfulPartCount());
 | 
					  EXPECT_EQ(0, GetSuccessfulPartCount());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Google Test doesn't track successful ASSERT_*.
 | 
					// Tests that Google Test doesn't track successful ASSERT_*.
 | 
				
			||||||
TEST(SuccessfulAssertionTest, ASSERT) {
 | 
					TEST(SuccessfulAssertionTest, ASSERT) {
 | 
				
			||||||
  ASSERT_TRUE(true);
 | 
					  ASSERT_TRUE(true);
 | 
				
			||||||
  EXPECT_EQ(0u, GetSuccessfulPartCount());
 | 
					  EXPECT_EQ(0, GetSuccessfulPartCount());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Tests that Google Test doesn't track successful ASSERT_STR*.
 | 
					// Tests that Google Test doesn't track successful ASSERT_STR*.
 | 
				
			||||||
TEST(SuccessfulAssertionTest, ASSERT_STR) {
 | 
					TEST(SuccessfulAssertionTest, ASSERT_STR) {
 | 
				
			||||||
  ASSERT_STREQ("", "");
 | 
					  ASSERT_STREQ("", "");
 | 
				
			||||||
  EXPECT_EQ(0u, GetSuccessfulPartCount());
 | 
					  EXPECT_EQ(0, GetSuccessfulPartCount());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace testing
 | 
					}  // namespace testing
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user