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