/Unittests/googletest/include/gtest/internal/gtest-param-util.h

http://unladen-swallow.googlecode.com/ · C++ Header · 638 lines · 380 code · 74 blank · 184 comment · 32 complexity · 6cb50bcd9105e7f9cbed906a65d943ac MD5 · raw file

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