Qucs-core  0.0.19
gtest-param-util.h
Go to the documentation of this file.
00001 // Copyright 2008 Google Inc.
00002 // All Rights Reserved.
00003 //
00004 // Redistribution and use in source and binary forms, with or without
00005 // modification, are permitted provided that the following conditions are
00006 // met:
00007 //
00008 //     * Redistributions of source code must retain the above copyright
00009 // notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above
00011 // copyright notice, this list of conditions and the following disclaimer
00012 // in the documentation and/or other materials provided with the
00013 // distribution.
00014 //     * Neither the name of Google Inc. nor the names of its
00015 // contributors may be used to endorse or promote products derived from
00016 // this software without specific prior written permission.
00017 //
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // Author: vladl@google.com (Vlad Losev)
00031 
00032 // Type and function utilities for implementing parameterized tests.
00033 
00034 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
00035 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
00036 
00037 #include <iterator>
00038 #include <utility>
00039 #include <vector>
00040 
00041 // scripts/fuse_gtest.py depends on gtest's own header being #included
00042 // *unconditionally*.  Therefore these #includes cannot be moved
00043 // inside #if GTEST_HAS_PARAM_TEST.
00044 #include "gtest/internal/gtest-internal.h"
00045 #include "gtest/internal/gtest-linked_ptr.h"
00046 #include "gtest/internal/gtest-port.h"
00047 #include "gtest/gtest-printers.h"
00048 
00049 #if GTEST_HAS_PARAM_TEST
00050 
00051 namespace testing {
00052 namespace internal {
00053 
00054 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00055 //
00056 // Outputs a message explaining invalid registration of different
00057 // fixture class for the same test case. This may happen when
00058 // TEST_P macro is used to define two tests with the same name
00059 // but in different namespaces.
00060 GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
00061                                           const char* file, int line);
00062 
00063 template <typename> class ParamGeneratorInterface;
00064 template <typename> class ParamGenerator;
00065 
00066 // Interface for iterating over elements provided by an implementation
00067 // of ParamGeneratorInterface<T>.
00068 template <typename T>
00069 class ParamIteratorInterface {
00070  public:
00071   virtual ~ParamIteratorInterface() {}
00072   // A pointer to the base generator instance.
00073   // Used only for the purposes of iterator comparison
00074   // to make sure that two iterators belong to the same generator.
00075   virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
00076   // Advances iterator to point to the next element
00077   // provided by the generator. The caller is responsible
00078   // for not calling Advance() on an iterator equal to
00079   // BaseGenerator()->End().
00080   virtual void Advance() = 0;
00081   // Clones the iterator object. Used for implementing copy semantics
00082   // of ParamIterator<T>.
00083   virtual ParamIteratorInterface* Clone() const = 0;
00084   // Dereferences the current iterator and provides (read-only) access
00085   // to the pointed value. It is the caller's responsibility not to call
00086   // Current() on an iterator equal to BaseGenerator()->End().
00087   // Used for implementing ParamGenerator<T>::operator*().
00088   virtual const T* Current() const = 0;
00089   // Determines whether the given iterator and other point to the same
00090   // element in the sequence generated by the generator.
00091   // Used for implementing ParamGenerator<T>::operator==().
00092   virtual bool Equals(const ParamIteratorInterface& other) const = 0;
00093 };
00094 
00095 // Class iterating over elements provided by an implementation of
00096 // ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
00097 // and implements the const forward iterator concept.
00098 template <typename T>
00099 class ParamIterator {
00100  public:
00101   typedef T value_type;
00102   typedef const T& reference;
00103   typedef ptrdiff_t difference_type;
00104 
00105   // ParamIterator assumes ownership of the impl_ pointer.
00106   ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
00107   ParamIterator& operator=(const ParamIterator& other) {
00108     if (this != &other)
00109       impl_.reset(other.impl_->Clone());
00110     return *this;
00111   }
00112 
00113   const T& operator*() const { return *impl_->Current(); }
00114   const T* operator->() const { return impl_->Current(); }
00115   // Prefix version of operator++.
00116   ParamIterator& operator++() {
00117     impl_->Advance();
00118     return *this;
00119   }
00120   // Postfix version of operator++.
00121   ParamIterator operator++(int /*unused*/) {
00122     ParamIteratorInterface<T>* clone = impl_->Clone();
00123     impl_->Advance();
00124     return ParamIterator(clone);
00125   }
00126   bool operator==(const ParamIterator& other) const {
00127     return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
00128   }
00129   bool operator!=(const ParamIterator& other) const {
00130     return !(*this == other);
00131   }
00132 
00133  private:
00134   friend class ParamGenerator<T>;
00135   explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
00136   scoped_ptr<ParamIteratorInterface<T> > impl_;
00137 };
00138 
00139 // ParamGeneratorInterface<T> is the binary interface to access generators
00140 // defined in other translation units.
00141 template <typename T>
00142 class ParamGeneratorInterface {
00143  public:
00144   typedef T ParamType;
00145 
00146   virtual ~ParamGeneratorInterface() {}
00147 
00148   // Generator interface definition
00149   virtual ParamIteratorInterface<T>* Begin() const = 0;
00150   virtual ParamIteratorInterface<T>* End() const = 0;
00151 };
00152 
00153 // Wraps ParamGeneratorInterface<T> and provides general generator syntax
00154 // compatible with the STL Container concept.
00155 // This class implements copy initialization semantics and the contained
00156 // ParamGeneratorInterface<T> instance is shared among all copies
00157 // of the original object. This is possible because that instance is immutable.
00158 template<typename T>
00159 class ParamGenerator {
00160  public:
00161   typedef ParamIterator<T> iterator;
00162 
00163   explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
00164   ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
00165 
00166   ParamGenerator& operator=(const ParamGenerator& other) {
00167     impl_ = other.impl_;
00168     return *this;
00169   }
00170 
00171   iterator begin() const { return iterator(impl_->Begin()); }
00172   iterator end() const { return iterator(impl_->End()); }
00173 
00174  private:
00175   linked_ptr<const ParamGeneratorInterface<T> > impl_;
00176 };
00177 
00178 // Generates values from a range of two comparable values. Can be used to
00179 // generate sequences of user-defined types that implement operator+() and
00180 // operator<().
00181 // This class is used in the Range() function.
00182 template <typename T, typename IncrementT>
00183 class RangeGenerator : public ParamGeneratorInterface<T> {
00184  public:
00185   RangeGenerator(T begin, T end, IncrementT step)
00186       : begin_(begin), end_(end),
00187         step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
00188   virtual ~RangeGenerator() {}
00189 
00190   virtual ParamIteratorInterface<T>* Begin() const {
00191     return new Iterator(this, begin_, 0, step_);
00192   }
00193   virtual ParamIteratorInterface<T>* End() const {
00194     return new Iterator(this, end_, end_index_, step_);
00195   }
00196 
00197  private:
00198   class Iterator : public ParamIteratorInterface<T> {
00199    public:
00200     Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
00201              IncrementT step)
00202         : base_(base), value_(value), index_(index), step_(step) {}
00203     virtual ~Iterator() {}
00204 
00205     virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
00206       return base_;
00207     }
00208     virtual void Advance() {
00209       value_ = value_ + step_;
00210       index_++;
00211     }
00212     virtual ParamIteratorInterface<T>* Clone() const {
00213       return new Iterator(*this);
00214     }
00215     virtual const T* Current() const { return &value_; }
00216     virtual bool Equals(const ParamIteratorInterface<T>& other) const {
00217       // Having the same base generator guarantees that the other
00218       // iterator is of the same type and we can downcast.
00219       GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
00220           << "The program attempted to compare iterators "
00221           << "from different generators." << std::endl;
00222       const int other_index =
00223           CheckedDowncastToActualType<const Iterator>(&other)->index_;
00224       return index_ == other_index;
00225     }
00226 
00227    private:
00228     Iterator(const Iterator& other)
00229         : ParamIteratorInterface<T>(),
00230           base_(other.base_), value_(other.value_), index_(other.index_),
00231           step_(other.step_) {}
00232 
00233     // No implementation - assignment is unsupported.
00234     void operator=(const Iterator& other);
00235 
00236     const ParamGeneratorInterface<T>* const base_;
00237     T value_;
00238     int index_;
00239     const IncrementT step_;
00240   };  // class RangeGenerator::Iterator
00241 
00242   static int CalculateEndIndex(const T& begin,
00243                                const T& end,
00244                                const IncrementT& step) {
00245     int end_index = 0;
00246     for (T i = begin; i < end; i = i + step)
00247       end_index++;
00248     return end_index;
00249   }
00250 
00251   // No implementation - assignment is unsupported.
00252   void operator=(const RangeGenerator& other);
00253 
00254   const T begin_;
00255   const T end_;
00256   const IncrementT step_;
00257   // The index for the end() iterator. All the elements in the generated
00258   // sequence are indexed (0-based) to aid iterator comparison.
00259   const int end_index_;
00260 };  // class RangeGenerator
00261 
00262 
00263 // Generates values from a pair of STL-style iterators. Used in the
00264 // ValuesIn() function. The elements are copied from the source range
00265 // since the source can be located on the stack, and the generator
00266 // is likely to persist beyond that stack frame.
00267 template <typename T>
00268 class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
00269  public:
00270   template <typename ForwardIterator>
00271   ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
00272       : container_(begin, end) {}
00273   virtual ~ValuesInIteratorRangeGenerator() {}
00274 
00275   virtual ParamIteratorInterface<T>* Begin() const {
00276     return new Iterator(this, container_.begin());
00277   }
00278   virtual ParamIteratorInterface<T>* End() const {
00279     return new Iterator(this, container_.end());
00280   }
00281 
00282  private:
00283   typedef typename ::std::vector<T> ContainerType;
00284 
00285   class Iterator : public ParamIteratorInterface<T> {
00286    public:
00287     Iterator(const ParamGeneratorInterface<T>* base,
00288              typename ContainerType::const_iterator iterator)
00289         : base_(base), iterator_(iterator) {}
00290     virtual ~Iterator() {}
00291 
00292     virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
00293       return base_;
00294     }
00295     virtual void Advance() {
00296       ++iterator_;
00297       value_.reset();
00298     }
00299     virtual ParamIteratorInterface<T>* Clone() const {
00300       return new Iterator(*this);
00301     }
00302     // We need to use cached value referenced by iterator_ because *iterator_
00303     // can return a temporary object (and of type other then T), so just
00304     // having "return &*iterator_;" doesn't work.
00305     // value_ is updated here and not in Advance() because Advance()
00306     // can advance iterator_ beyond the end of the range, and we cannot
00307     // detect that fact. The client code, on the other hand, is
00308     // responsible for not calling Current() on an out-of-range iterator.
00309     virtual const T* Current() const {
00310       if (value_.get() == NULL)
00311         value_.reset(new T(*iterator_));
00312       return value_.get();
00313     }
00314     virtual bool Equals(const ParamIteratorInterface<T>& other) const {
00315       // Having the same base generator guarantees that the other
00316       // iterator is of the same type and we can downcast.
00317       GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
00318           << "The program attempted to compare iterators "
00319           << "from different generators." << std::endl;
00320       return iterator_ ==
00321           CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
00322     }
00323 
00324    private:
00325     Iterator(const Iterator& other)
00326           // The explicit constructor call suppresses a false warning
00327           // emitted by gcc when supplied with the -Wextra option.
00328         : ParamIteratorInterface<T>(),
00329           base_(other.base_),
00330           iterator_(other.iterator_) {}
00331 
00332     const ParamGeneratorInterface<T>* const base_;
00333     typename ContainerType::const_iterator iterator_;
00334     // A cached value of *iterator_. We keep it here to allow access by
00335     // pointer in the wrapping iterator's operator->().
00336     // value_ needs to be mutable to be accessed in Current().
00337     // Use of scoped_ptr helps manage cached value's lifetime,
00338     // which is bound by the lifespan of the iterator itself.
00339     mutable scoped_ptr<const T> value_;
00340   };  // class ValuesInIteratorRangeGenerator::Iterator
00341 
00342   // No implementation - assignment is unsupported.
00343   void operator=(const ValuesInIteratorRangeGenerator& other);
00344 
00345   const ContainerType container_;
00346 };  // class ValuesInIteratorRangeGenerator
00347 
00348 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00349 //
00350 // Stores a parameter value and later creates tests parameterized with that
00351 // value.
00352 template <class TestClass>
00353 class ParameterizedTestFactory : public TestFactoryBase {
00354  public:
00355   typedef typename TestClass::ParamType ParamType;
00356   explicit ParameterizedTestFactory(ParamType parameter) :
00357       parameter_(parameter) {}
00358   virtual Test* CreateTest() {
00359     TestClass::SetParam(&parameter_);
00360     return new TestClass();
00361   }
00362 
00363  private:
00364   const ParamType parameter_;
00365 
00366   GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
00367 };
00368 
00369 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00370 //
00371 // TestMetaFactoryBase is a base class for meta-factories that create
00372 // test factories for passing into MakeAndRegisterTestInfo function.
00373 template <class ParamType>
00374 class TestMetaFactoryBase {
00375  public:
00376   virtual ~TestMetaFactoryBase() {}
00377 
00378   virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
00379 };
00380 
00381 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00382 //
00383 // TestMetaFactory creates test factories for passing into
00384 // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
00385 // ownership of test factory pointer, same factory object cannot be passed
00386 // into that method twice. But ParameterizedTestCaseInfo is going to call
00387 // it for each Test/Parameter value combination. Thus it needs meta factory
00388 // creator class.
00389 template <class TestCase>
00390 class TestMetaFactory
00391     : public TestMetaFactoryBase<typename TestCase::ParamType> {
00392  public:
00393   typedef typename TestCase::ParamType ParamType;
00394 
00395   TestMetaFactory() {}
00396 
00397   virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
00398     return new ParameterizedTestFactory<TestCase>(parameter);
00399   }
00400 
00401  private:
00402   GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
00403 };
00404 
00405 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00406 //
00407 // ParameterizedTestCaseInfoBase is a generic interface
00408 // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
00409 // accumulates test information provided by TEST_P macro invocations
00410 // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
00411 // and uses that information to register all resulting test instances
00412 // in RegisterTests method. The ParameterizeTestCaseRegistry class holds
00413 // a collection of pointers to the ParameterizedTestCaseInfo objects
00414 // and calls RegisterTests() on each of them when asked.
00415 class ParameterizedTestCaseInfoBase {
00416  public:
00417   virtual ~ParameterizedTestCaseInfoBase() {}
00418 
00419   // Base part of test case name for display purposes.
00420   virtual const string& GetTestCaseName() const = 0;
00421   // Test case id to verify identity.
00422   virtual TypeId GetTestCaseTypeId() const = 0;
00423   // UnitTest class invokes this method to register tests in this
00424   // test case right before running them in RUN_ALL_TESTS macro.
00425   // This method should not be called more then once on any single
00426   // instance of a ParameterizedTestCaseInfoBase derived class.
00427   virtual void RegisterTests() = 0;
00428 
00429  protected:
00430   ParameterizedTestCaseInfoBase() {}
00431 
00432  private:
00433   GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
00434 };
00435 
00436 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00437 //
00438 // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
00439 // macro invocations for a particular test case and generators
00440 // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
00441 // test case. It registers tests with all values generated by all
00442 // generators when asked.
00443 template <class TestCase>
00444 class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
00445  public:
00446   // ParamType and GeneratorCreationFunc are private types but are required
00447   // for declarations of public methods AddTestPattern() and
00448   // AddTestCaseInstantiation().
00449   typedef typename TestCase::ParamType ParamType;
00450   // A function that returns an instance of appropriate generator type.
00451   typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
00452 
00453   explicit ParameterizedTestCaseInfo(const char* name)
00454       : test_case_name_(name) {}
00455 
00456   // Test case base name for display purposes.
00457   virtual const string& GetTestCaseName() const { return test_case_name_; }
00458   // Test case id to verify identity.
00459   virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
00460   // TEST_P macro uses AddTestPattern() to record information
00461   // about a single test in a LocalTestInfo structure.
00462   // test_case_name is the base name of the test case (without invocation
00463   // prefix). test_base_name is the name of an individual test without
00464   // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
00465   // test case base name and DoBar is test base name.
00466   void AddTestPattern(const char* test_case_name,
00467                       const char* test_base_name,
00468                       TestMetaFactoryBase<ParamType>* meta_factory) {
00469     tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
00470                                                        test_base_name,
00471                                                        meta_factory)));
00472   }
00473   // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
00474   // about a generator.
00475   int AddTestCaseInstantiation(const string& instantiation_name,
00476                                GeneratorCreationFunc* func,
00477                                const char* /* file */,
00478                                int /* line */) {
00479     instantiations_.push_back(::std::make_pair(instantiation_name, func));
00480     return 0;  // Return value used only to run this method in namespace scope.
00481   }
00482   // UnitTest class invokes this method to register tests in this test case
00483   // test cases right before running tests in RUN_ALL_TESTS macro.
00484   // This method should not be called more then once on any single
00485   // instance of a ParameterizedTestCaseInfoBase derived class.
00486   // UnitTest has a guard to prevent from calling this method more then once.
00487   virtual void RegisterTests() {
00488     for (typename TestInfoContainer::iterator test_it = tests_.begin();
00489          test_it != tests_.end(); ++test_it) {
00490       linked_ptr<TestInfo> test_info = *test_it;
00491       for (typename InstantiationContainer::iterator gen_it =
00492                instantiations_.begin(); gen_it != instantiations_.end();
00493                ++gen_it) {
00494         const string& instantiation_name = gen_it->first;
00495         ParamGenerator<ParamType> generator((*gen_it->second)());
00496 
00497         string test_case_name;
00498         if ( !instantiation_name.empty() )
00499           test_case_name = instantiation_name + "/";
00500         test_case_name += test_info->test_case_base_name;
00501 
00502         int i = 0;
00503         for (typename ParamGenerator<ParamType>::iterator param_it =
00504                  generator.begin();
00505              param_it != generator.end(); ++param_it, ++i) {
00506           Message test_name_stream;
00507           test_name_stream << test_info->test_base_name << "/" << i;
00508           MakeAndRegisterTestInfo(
00509               test_case_name.c_str(),
00510               test_name_stream.GetString().c_str(),
00511               NULL,  // No type parameter.
00512               PrintToString(*param_it).c_str(),
00513               GetTestCaseTypeId(),
00514               TestCase::SetUpTestCase,
00515               TestCase::TearDownTestCase,
00516               test_info->test_meta_factory->CreateTestFactory(*param_it));
00517         }  // for param_it
00518       }  // for gen_it
00519     }  // for test_it
00520   }  // RegisterTests
00521 
00522  private:
00523   // LocalTestInfo structure keeps information about a single test registered
00524   // with TEST_P macro.
00525   struct TestInfo {
00526     TestInfo(const char* a_test_case_base_name,
00527              const char* a_test_base_name,
00528              TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
00529         test_case_base_name(a_test_case_base_name),
00530         test_base_name(a_test_base_name),
00531         test_meta_factory(a_test_meta_factory) {}
00532 
00533     const string test_case_base_name;
00534     const string test_base_name;
00535     const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
00536   };
00537   typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
00538   // Keeps pairs of <Instantiation name, Sequence generator creation function>
00539   // received from INSTANTIATE_TEST_CASE_P macros.
00540   typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >
00541       InstantiationContainer;
00542 
00543   const string test_case_name_;
00544   TestInfoContainer tests_;
00545   InstantiationContainer instantiations_;
00546 
00547   GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
00548 };  // class ParameterizedTestCaseInfo
00549 
00550 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
00551 //
00552 // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
00553 // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
00554 // macros use it to locate their corresponding ParameterizedTestCaseInfo
00555 // descriptors.
00556 class ParameterizedTestCaseRegistry {
00557  public:
00558   ParameterizedTestCaseRegistry() {}
00559   ~ParameterizedTestCaseRegistry() {
00560     for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
00561          it != test_case_infos_.end(); ++it) {
00562       delete *it;
00563     }
00564   }
00565 
00566   // Looks up or creates and returns a structure containing information about
00567   // tests and instantiations of a particular test case.
00568   template <class TestCase>
00569   ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
00570       const char* test_case_name,
00571       const char* file,
00572       int line) {
00573     ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
00574     for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
00575          it != test_case_infos_.end(); ++it) {
00576       if ((*it)->GetTestCaseName() == test_case_name) {
00577         if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
00578           // Complain about incorrect usage of Google Test facilities
00579           // and terminate the program since we cannot guaranty correct
00580           // test case setup and tear-down in this case.
00581           ReportInvalidTestCaseType(test_case_name,  file, line);
00582           posix::Abort();
00583         } else {
00584           // At this point we are sure that the object we found is of the same
00585           // type we are looking for, so we downcast it to that type
00586           // without further checks.
00587           typed_test_info = CheckedDowncastToActualType<
00588               ParameterizedTestCaseInfo<TestCase> >(*it);
00589         }
00590         break;
00591       }
00592     }
00593     if (typed_test_info == NULL) {
00594       typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
00595       test_case_infos_.push_back(typed_test_info);
00596     }
00597     return typed_test_info;
00598   }
00599   void RegisterTests() {
00600     for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
00601          it != test_case_infos_.end(); ++it) {
00602       (*it)->RegisterTests();
00603     }
00604   }
00605 
00606  private:
00607   typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
00608 
00609   TestCaseInfoContainer test_case_infos_;
00610 
00611   GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
00612 };
00613 
00614 }  // namespace internal
00615 }  // namespace testing
00616 
00617 #endif  //  GTEST_HAS_PARAM_TEST
00618 
00619 #endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_