1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright 2008 Google Inc. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// All Rights Reserved. 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Redistribution and use in source and binary forms, with or without 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// modification, are permitted provided that the following conditions are 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// met: 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Redistributions of source code must retain the above copyright 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notice, this list of conditions and the following disclaimer. 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Redistributions in binary form must reproduce the above 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// copyright notice, this list of conditions and the following disclaimer 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the documentation and/or other materials provided with the 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// distribution. 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Neither the name of Google Inc. nor the names of its 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// contributors may be used to endorse or promote products derived from 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this software without specific prior written permission. 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Author: vladl@google.com (Vlad Losev) 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Type and function utilities for implementing parameterized tests. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <iterator> 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <utility> 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// scripts/fuse_gtest.py depends on gtest's own header being #included 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// *unconditionally*. Therefore these #includes cannot be moved 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// inside #if GTEST_HAS_PARAM_TEST. 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "gtest/internal/gtest-internal.h" 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "gtest/internal/gtest-linked_ptr.h" 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "gtest/internal/gtest-port.h" 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "gtest/gtest-printers.h" 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if GTEST_HAS_PARAM_TEST 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace testing { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace internal { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Outputs a message explaining invalid registration of different 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// fixture class for the same test case. This may happen when 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TEST_P macro is used to define two tests with the same name 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// but in different namespaces. 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* file, int line); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename> class ParamGeneratorInterface; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename> class ParamGenerator; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Interface for iterating over elements provided by an implementation 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of ParamGeneratorInterface<T>. 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename T> 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParamIteratorInterface { 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~ParamIteratorInterface() {} 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A pointer to the base generator instance. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Used only for the purposes of iterator comparison 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to make sure that two iterators belong to the same generator. 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Advances iterator to point to the next element 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // provided by the generator. The caller is responsible 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for not calling Advance() on an iterator equal to 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // BaseGenerator()->End(). 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Advance() = 0; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Clones the iterator object. Used for implementing copy semantics 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of ParamIterator<T>. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface* Clone() const = 0; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Dereferences the current iterator and provides (read-only) access 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to the pointed value. It is the caller's responsibility not to call 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Current() on an iterator equal to BaseGenerator()->End(). 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Used for implementing ParamGenerator<T>::operator*(). 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const T* Current() const = 0; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Determines whether the given iterator and other point to the same 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // element in the sequence generated by the generator. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Used for implementing ParamGenerator<T>::operator==(). 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Equals(const ParamIteratorInterface& other) const = 0; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Class iterating over elements provided by an implementation of 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and implements the const forward iterator concept. 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename T> 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParamIterator { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef T value_type; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef const T& reference; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ptrdiff_t difference_type; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ParamIterator assumes ownership of the impl_ pointer. 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamIterator& operator=(const ParamIterator& other) { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (this != &other) 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch impl_.reset(other.impl_->Clone()); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *this; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const T& operator*() const { return *impl_->Current(); } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const T* operator->() const { return impl_->Current(); } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Prefix version of operator++. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamIterator& operator++() { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch impl_->Advance(); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *this; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Postfix version of operator++. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamIterator operator++(int /*unused*/) { 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamIteratorInterface<T>* clone = impl_->Clone(); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch impl_->Advance(); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ParamIterator(clone); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool operator==(const ParamIterator& other) const { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool operator!=(const ParamIterator& other) const { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !(*this == other); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class ParamGenerator<T>; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ParamIteratorInterface<T> > impl_; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParamGeneratorInterface<T> is the binary interface to access generators 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// defined in other translation units. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename T> 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParamGeneratorInterface { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef T ParamType; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~ParamGeneratorInterface() {} 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Generator interface definition 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* Begin() const = 0; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* End() const = 0; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Wraps ParamGeneratorInterface<T> and provides general generator syntax 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// compatible with the STL Container concept. 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class implements copy initialization semantics and the contained 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParamGeneratorInterface<T> instance is shared among all copies 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the original object. This is possible because that instance is immutable. 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<typename T> 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParamGenerator { 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ParamIterator<T> iterator; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamGenerator& operator=(const ParamGenerator& other) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch impl_ = other.impl_; 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *this; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator begin() const { return iterator(impl_->Begin()); } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator end() const { return iterator(impl_->End()); } 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick linked_ptr<const ParamGeneratorInterface<T> > impl_; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Generates values from a range of two comparable values. Can be used to 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// generate sequences of user-defined types that implement operator+() and 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// operator<(). 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class is used in the Range() function. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename T, typename IncrementT> 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass RangeGenerator : public ParamGeneratorInterface<T> { 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RangeGenerator(T begin, T end, IncrementT step) 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : begin_(begin), end_(end), 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~RangeGenerator() {} 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* Begin() const { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(this, begin_, 0, step_); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* End() const { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(this, end_, end_index_, step_); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Iterator : public ParamIteratorInterface<T> { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Iterator(const ParamGeneratorInterface<T>* base, T value, int index, 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IncrementT step) 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : base_(base), value_(value), index_(index), step_(step) {} 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~Iterator() {} 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const ParamGeneratorInterface<T>* BaseGenerator() const { 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return base_; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Advance() { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_ = value_ + step_; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index_++; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* Clone() const { 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(*this); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const T* Current() const { return &value_; } 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Equals(const ParamIteratorInterface<T>& other) const { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Having the same base generator guarantees that the other 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // iterator is of the same type and we can downcast. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "The program attempted to compare iterators " 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "from different generators." << std::endl; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int other_index = 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckedDowncastToActualType<const Iterator>(&other)->index_; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return index_ == other_index; 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Iterator(const Iterator& other) 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ParamIteratorInterface<T>(), 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_(other.base_), value_(other.value_), index_(other.index_), 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch step_(other.step_) {} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No implementation - assignment is unsupported. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void operator=(const Iterator& other); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ParamGeneratorInterface<T>* const base_; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T value_; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index_; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const IncrementT step_; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; // class RangeGenerator::Iterator 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static int CalculateEndIndex(const T& begin, 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const T& end, 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const IncrementT& step) { 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int end_index = 0; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (T i = begin; i < end; i = i + step) 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch end_index++; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return end_index; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No implementation - assignment is unsupported. 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void operator=(const RangeGenerator& other); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const T begin_; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const T end_; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const IncrementT step_; 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The index for the end() iterator. All the elements in the generated 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sequence are indexed (0-based) to aid iterator comparison. 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int end_index_; 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // class RangeGenerator 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Generates values from a pair of STL-style iterators. Used in the 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ValuesIn() function. The elements are copied from the source range 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// since the source can be located on the stack, and the generator 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is likely to persist beyond that stack frame. 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename T> 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename ForwardIterator> 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : container_(begin, end) {} 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~ValuesInIteratorRangeGenerator() {} 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* Begin() const { 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(this, container_.begin()); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* End() const { 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(this, container_.end()); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef typename ::std::vector<T> ContainerType; 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Iterator : public ParamIteratorInterface<T> { 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Iterator(const ParamGeneratorInterface<T>* base, 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typename ContainerType::const_iterator iterator) 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : base_(base), iterator_(iterator) {} 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~Iterator() {} 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const ParamGeneratorInterface<T>* BaseGenerator() const { 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return base_; 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Advance() { 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator_; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_.reset(); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ParamIteratorInterface<T>* Clone() const { 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new Iterator(*this); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We need to use cached value referenced by iterator_ because *iterator_ 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // can return a temporary object (and of type other then T), so just 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // having "return &*iterator_;" doesn't work. 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value_ is updated here and not in Advance() because Advance() 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // can advance iterator_ beyond the end of the range, and we cannot 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // detect that fact. The client code, on the other hand, is 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // responsible for not calling Current() on an out-of-range iterator. 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const T* Current() const { 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (value_.get() == NULL) 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_.reset(new T(*iterator_)); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return value_.get(); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool Equals(const ParamIteratorInterface<T>& other) const { 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Having the same base generator guarantees that the other 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // iterator is of the same type and we can downcast. 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "The program attempted to compare iterators " 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "from different generators." << std::endl; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return iterator_ == 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckedDowncastToActualType<const Iterator>(&other)->iterator_; 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Iterator(const Iterator& other) 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The explicit constructor call suppresses a false warning 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // emitted by gcc when supplied with the -Wextra option. 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ParamIteratorInterface<T>(), 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base_(other.base_), 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iterator_(other.iterator_) {} 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ParamGeneratorInterface<T>* const base_; 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typename ContainerType::const_iterator iterator_; 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A cached value of *iterator_. We keep it here to allow access by 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pointer in the wrapping iterator's operator->(). 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value_ needs to be mutable to be accessed in Current(). 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use of scoped_ptr helps manage cached value's lifetime, 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which is bound by the lifespan of the iterator itself. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable scoped_ptr<const T> value_; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; // class ValuesInIteratorRangeGenerator::Iterator 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No implementation - assignment is unsupported. 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void operator=(const ValuesInIteratorRangeGenerator& other); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ContainerType container_; 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // class ValuesInIteratorRangeGenerator 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Stores a parameter value and later creates tests parameterized with that 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// value. 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class TestClass> 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParameterizedTestFactory : public TestFactoryBase { 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef typename TestClass::ParamType ParamType; 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit ParameterizedTestFactory(ParamType parameter) : 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parameter_(parameter) {} 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual Test* CreateTest() { 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestClass::SetParam(¶meter_); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new TestClass(); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ParamType parameter_; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TestMetaFactoryBase is a base class for meta-factories that create 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// test factories for passing into MakeAndRegisterTestInfo function. 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class ParamType> 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestMetaFactoryBase { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~TestMetaFactoryBase() {} 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TestMetaFactory creates test factories for passing into 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ownership of test factory pointer, same factory object cannot be passed 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// into that method twice. But ParameterizedTestCaseInfo is going to call 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// it for each Test/Parameter value combination. Thus it needs meta factory 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creator class. 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class TestCase> 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestMetaFactory 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public TestMetaFactoryBase<typename TestCase::ParamType> { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef typename TestCase::ParamType ParamType; 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestMetaFactory() {} 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new ParameterizedTestFactory<TestCase>(parameter); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParameterizedTestCaseInfoBase is a generic interface 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// accumulates test information provided by TEST_P macro invocations 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and uses that information to register all resulting test instances 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in RegisterTests method. The ParameterizeTestCaseRegistry class holds 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a collection of pointers to the ParameterizedTestCaseInfo objects 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and calls RegisterTests() on each of them when asked. 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParameterizedTestCaseInfoBase { 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~ParameterizedTestCaseInfoBase() {} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Base part of test case name for display purposes. 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const String& GetTestCaseName() const = 0; 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test case id to verify identity. 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual TypeId GetTestCaseTypeId() const = 0; 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // UnitTest class invokes this method to register tests in this 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test case right before running them in RUN_ALL_TESTS macro. 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This method should not be called more then once on any single 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // instance of a ParameterizedTestCaseInfoBase derived class. 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RegisterTests() = 0; 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParameterizedTestCaseInfoBase() {} 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// macro invocations for a particular test case and generators 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// test case. It registers tests with all values generated by all 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// generators when asked. 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class TestCase> 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ParamType and GeneratorCreationFunc are private types but are required 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for declarations of public methods AddTestPattern() and 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // AddTestCaseInstantiation(). 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef typename TestCase::ParamType ParamType; 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A function that returns an instance of appropriate generator type. 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit ParameterizedTestCaseInfo(const char* name) 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : test_case_name_(name) {} 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test case base name for display purposes. 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const String& GetTestCaseName() const { return test_case_name_; } 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test case id to verify identity. 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TEST_P macro uses AddTestPattern() to record information 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // about a single test in a LocalTestInfo structure. 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test_case_name is the base name of the test case (without invocation 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // prefix). test_base_name is the name of an individual test without 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test case base name and DoBar is test base name. 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddTestPattern(const char* test_case_name, 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* test_base_name, 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestMetaFactoryBase<ParamType>* meta_factory) { 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_base_name, 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch meta_factory))); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // about a generator. 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int AddTestCaseInstantiation(const char* instantiation_name, 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GeneratorCreationFunc* func, 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* /* file */, 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int /* line */) { 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch instantiations_.push_back(::std::make_pair(instantiation_name, func)); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; // Return value used only to run this method in namespace scope. 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // UnitTest class invokes this method to register tests in this test case 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test cases right before running tests in RUN_ALL_TESTS macro. 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This method should not be called more then once on any single 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // instance of a ParameterizedTestCaseInfoBase derived class. 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // UnitTest has a guard to prevent from calling this method more then once. 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RegisterTests() { 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (typename TestInfoContainer::iterator test_it = tests_.begin(); 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_it != tests_.end(); ++test_it) { 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch linked_ptr<TestInfo> test_info = *test_it; 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (typename InstantiationContainer::iterator gen_it = 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch instantiations_.begin(); gen_it != instantiations_.end(); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++gen_it) { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const String& instantiation_name = gen_it->first; 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParamGenerator<ParamType> generator((*gen_it->second)()); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Message test_case_name_stream; 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ( !instantiation_name.empty() ) 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case_name_stream << instantiation_name.c_str() << "/"; 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case_name_stream << test_info->test_case_base_name.c_str(); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int i = 0; 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (typename ParamGenerator<ParamType>::iterator param_it = 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch generator.begin(); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch param_it != generator.end(); ++param_it, ++i) { 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Message test_name_stream; 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_name_stream << test_info->test_base_name.c_str() << "/" << i; 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MakeAndRegisterTestInfo( 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case_name_stream.GetString().c_str(), 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_name_stream.GetString().c_str(), 511dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NULL, // No type parameter. 512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintToString(*param_it).c_str(), 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetTestCaseTypeId(), 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCase::SetUpTestCase, 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCase::TearDownTestCase, 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_info->test_meta_factory->CreateTestFactory(*param_it)); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // for param_it 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // for gen_it 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // for test_it 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } // RegisterTests 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // LocalTestInfo structure keeps information about a single test registered 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with TEST_P macro. 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestInfo { 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestInfo(const char* a_test_case_base_name, 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* a_test_base_name, 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestMetaFactoryBase<ParamType>* a_test_meta_factory) : 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case_base_name(a_test_case_base_name), 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_base_name(a_test_base_name), 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_meta_factory(a_test_meta_factory) {} 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const String test_case_base_name; 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const String test_base_name; 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Keeps pairs of <Instantiation name, Sequence generator creation function> 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // received from INSTANTIATE_TEST_CASE_P macros. 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> > 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InstantiationContainer; 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const String test_case_name_; 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestInfoContainer tests_; 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InstantiationContainer instantiations_; 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // class ParameterizedTestCaseInfo 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// macros use it to locate their corresponding ParameterizedTestCaseInfo 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// descriptors. 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ParameterizedTestCaseRegistry { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParameterizedTestCaseRegistry() {} 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~ParameterizedTestCaseRegistry() { 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != test_case_infos_.end(); ++it) { 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete *it; 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Looks up or creates and returns a structure containing information about 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // tests and instantiations of a particular test case. 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <class TestCase> 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* test_case_name, 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* file, 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int line) { 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != test_case_infos_.end(); ++it) { 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*it)->GetTestCaseName() == test_case_name) { 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Complain about incorrect usage of Google Test facilities 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and terminate the program since we cannot guaranty correct 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test case setup and tear-down in this case. 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReportInvalidTestCaseType(test_case_name, file, line); 582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen posix::Abort(); 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // At this point we are sure that the object we found is of the same 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // type we are looking for, so we downcast it to that type 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // without further checks. 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_test_info = CheckedDowncastToActualType< 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParameterizedTestCaseInfo<TestCase> >(*it); 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (typed_test_info == NULL) { 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_case_infos_.push_back(typed_test_info); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return typed_test_info; 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RegisterTests() { 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != test_case_infos_.end(); ++it) { 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*it)->RegisterTests(); 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCaseInfoContainer test_case_infos_; 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace internal 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace testing 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // GTEST_HAS_PARAM_TEST 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 620