You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

619 lines
24 KiB

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