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