LCOV - code coverage report
Current view: top level - third_party/googletest/include/gtest/internal - gtest-param-util.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 100 114 87.7 %
Date: 2015-10-10 Functions: 287 513 55.9 %

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

Generated by: LCOV version 1.10