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