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// Type and function utilities for implementing parameterized tests. 31 32// IWYU pragma: private, include "gtest/gtest.h" 33// IWYU pragma: friend gtest/.* 34// IWYU pragma: friend gmock/.* 35 36#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 37#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 38 39#include <ctype.h> 40 41#include <cassert> 42#include <iterator> 43#include <map> 44#include <memory> 45#include <ostream> 46#include <set> 47#include <string> 48#include <tuple> 49#include <type_traits> 50#include <utility> 51#include <vector> 52 53#include "gtest/gtest-printers.h" 54#include "gtest/gtest-test-part.h" 55#include "gtest/internal/gtest-internal.h" 56#include "gtest/internal/gtest-port.h" 57 58namespace testing { 59// Input to a parameterized test name generator, describing a test parameter. 60// Consists of the parameter value and the integer parameter index. 61template <class ParamType> 62struct TestParamInfo { 63 TestParamInfo(const ParamType& a_param, size_t an_index) 64 : param(a_param), index(an_index) {} 65 ParamType param; 66 size_t index; 67}; 68 69// A builtin parameterized test name generator which returns the result of 70// testing::PrintToString. 71struct PrintToStringParamName { 72 template <class ParamType> 73 std::string operator()(const TestParamInfo<ParamType>& info) const { 74 return PrintToString(info.param); 75 } 76}; 77 78namespace internal { 79 80// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 81// Utility Functions 82 83// Outputs a message explaining invalid registration of different 84// fixture class for the same test suite. This may happen when 85// TEST_P macro is used to define two tests with the same name 86// but in different namespaces. 87GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, 88 CodeLocation code_location); 89 90template <typename> 91class ParamGeneratorInterface; 92template <typename> 93class ParamGenerator; 94 95// Interface for iterating over elements provided by an implementation 96// of ParamGeneratorInterface<T>. 97template <typename T> 98class ParamIteratorInterface { 99 public: 100 virtual ~ParamIteratorInterface() = default; 101 // A pointer to the base generator instance. 102 // Used only for the purposes of iterator comparison 103 // to make sure that two iterators belong to the same generator. 104 virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; 105 // Advances iterator to point to the next element 106 // provided by the generator. The caller is responsible 107 // for not calling Advance() on an iterator equal to 108 // BaseGenerator()->End(). 109 virtual void Advance() = 0; 110 // Clones the iterator object. Used for implementing copy semantics 111 // of ParamIterator<T>. 112 virtual ParamIteratorInterface* Clone() const = 0; 113 // Dereferences the current iterator and provides (read-only) access 114 // to the pointed value. It is the caller's responsibility not to call 115 // Current() on an iterator equal to BaseGenerator()->End(). 116 // Used for implementing ParamGenerator<T>::operator*(). 117 virtual const T* Current() const = 0; 118 // Determines whether the given iterator and other point to the same 119 // element in the sequence generated by the generator. 120 // Used for implementing ParamGenerator<T>::operator==(). 121 virtual bool Equals(const ParamIteratorInterface& other) const = 0; 122}; 123 124// Class iterating over elements provided by an implementation of 125// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> 126// and implements the const forward iterator concept. 127template <typename T> 128class ParamIterator { 129 public: 130 typedef T value_type; 131 typedef const T& reference; 132 typedef ptrdiff_t difference_type; 133 134 // ParamIterator assumes ownership of the impl_ pointer. 135 ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} 136 ParamIterator& operator=(const ParamIterator& other) { 137 if (this != &other) impl_.reset(other.impl_->Clone()); 138 return *this; 139 } 140 141 const T& operator*() const { return *impl_->Current(); } 142 const T* operator->() const { return impl_->Current(); } 143 // Prefix version of operator++. 144 ParamIterator& operator++() { 145 impl_->Advance(); 146 return *this; 147 } 148 // Postfix version of operator++. 149 ParamIterator operator++(int /*unused*/) { 150 ParamIteratorInterface<T>* clone = impl_->Clone(); 151 impl_->Advance(); 152 return ParamIterator(clone); 153 } 154 bool operator==(const ParamIterator& other) const { 155 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); 156 } 157 bool operator!=(const ParamIterator& other) const { 158 return !(*this == other); 159 } 160 161 private: 162 friend class ParamGenerator<T>; 163 explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} 164 std::unique_ptr<ParamIteratorInterface<T>> impl_; 165}; 166 167// ParamGeneratorInterface<T> is the binary interface to access generators 168// defined in other translation units. 169template <typename T> 170class ParamGeneratorInterface { 171 public: 172 typedef T ParamType; 173 174 virtual ~ParamGeneratorInterface() = default; 175 176 // Generator interface definition 177 virtual ParamIteratorInterface<T>* Begin() const = 0; 178 virtual ParamIteratorInterface<T>* End() const = 0; 179}; 180 181// Wraps ParamGeneratorInterface<T> and provides general generator syntax 182// compatible with the STL Container concept. 183// This class implements copy initialization semantics and the contained 184// ParamGeneratorInterface<T> instance is shared among all copies 185// of the original object. This is possible because that instance is immutable. 186template <typename T> 187class ParamGenerator { 188 public: 189 typedef ParamIterator<T> iterator; 190 191 explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} 192 ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} 193 194 ParamGenerator& operator=(const ParamGenerator& other) { 195 impl_ = other.impl_; 196 return *this; 197 } 198 199 iterator begin() const { return iterator(impl_->Begin()); } 200 iterator end() const { return iterator(impl_->End()); } 201 202 private: 203 std::shared_ptr<const ParamGeneratorInterface<T>> impl_; 204}; 205 206// Generates values from a range of two comparable values. Can be used to 207// generate sequences of user-defined types that implement operator+() and 208// operator<(). 209// This class is used in the Range() function. 210template <typename T, typename IncrementT> 211class RangeGenerator : public ParamGeneratorInterface<T> { 212 public: 213 RangeGenerator(T begin, T end, IncrementT step) 214 : begin_(begin), 215 end_(end), 216 step_(step), 217 end_index_(CalculateEndIndex(begin, end, step)) {} 218 ~RangeGenerator() override = default; 219 220 ParamIteratorInterface<T>* Begin() const override { 221 return new Iterator(this, begin_, 0, step_); 222 } 223 ParamIteratorInterface<T>* End() const override { 224 return new Iterator(this, end_, end_index_, step_); 225 } 226 227 private: 228 class Iterator : public ParamIteratorInterface<T> { 229 public: 230 Iterator(const ParamGeneratorInterface<T>* base, T value, int index, 231 IncrementT step) 232 : base_(base), value_(value), index_(index), step_(step) {} 233 ~Iterator() override = default; 234 235 const ParamGeneratorInterface<T>* BaseGenerator() const override { 236 return base_; 237 } 238 void Advance() override { 239 value_ = static_cast<T>(value_ + step_); 240 index_++; 241 } 242 ParamIteratorInterface<T>* Clone() const override { 243 return new Iterator(*this); 244 } 245 const T* Current() const override { return &value_; } 246 bool Equals(const ParamIteratorInterface<T>& other) const override { 247 // Having the same base generator guarantees that the other 248 // iterator is of the same type and we can downcast. 249 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 250 << "The program attempted to compare iterators " 251 << "from different generators." << std::endl; 252 const int other_index = 253 CheckedDowncastToActualType<const Iterator>(&other)->index_; 254 return index_ == other_index; 255 } 256 257 private: 258 Iterator(const Iterator& other) 259 : ParamIteratorInterface<T>(), 260 base_(other.base_), 261 value_(other.value_), 262 index_(other.index_), 263 step_(other.step_) {} 264 265 // No implementation - assignment is unsupported. 266 void operator=(const Iterator& other); 267 268 const ParamGeneratorInterface<T>* const base_; 269 T value_; 270 int index_; 271 const IncrementT step_; 272 }; // class RangeGenerator::Iterator 273 274 static int CalculateEndIndex(const T& begin, const T& end, 275 const IncrementT& step) { 276 int end_index = 0; 277 for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++; 278 return end_index; 279 } 280 281 // No implementation - assignment is unsupported. 282 void operator=(const RangeGenerator& other); 283 284 const T begin_; 285 const T end_; 286 const IncrementT step_; 287 // The index for the end() iterator. All the elements in the generated 288 // sequence are indexed (0-based) to aid iterator comparison. 289 const int end_index_; 290}; // class RangeGenerator 291 292// Generates values from a pair of STL-style iterators. Used in the 293// ValuesIn() function. The elements are copied from the source range 294// since the source can be located on the stack, and the generator 295// is likely to persist beyond that stack frame. 296template <typename T> 297class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { 298 public: 299 template <typename ForwardIterator> 300 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) 301 : container_(begin, end) {} 302 ~ValuesInIteratorRangeGenerator() override = default; 303 304 ParamIteratorInterface<T>* Begin() const override { 305 return new Iterator(this, container_.begin()); 306 } 307 ParamIteratorInterface<T>* End() const override { 308 return new Iterator(this, container_.end()); 309 } 310 311 private: 312 typedef typename ::std::vector<T> ContainerType; 313 314 class Iterator : public ParamIteratorInterface<T> { 315 public: 316 Iterator(const ParamGeneratorInterface<T>* base, 317 typename ContainerType::const_iterator iterator) 318 : base_(base), iterator_(iterator) {} 319 ~Iterator() override = default; 320 321 const ParamGeneratorInterface<T>* BaseGenerator() const override { 322 return base_; 323 } 324 void Advance() override { 325 ++iterator_; 326 value_.reset(); 327 } 328 ParamIteratorInterface<T>* Clone() const override { 329 return new Iterator(*this); 330 } 331 // We need to use cached value referenced by iterator_ because *iterator_ 332 // can return a temporary object (and of type other then T), so just 333 // having "return &*iterator_;" doesn't work. 334 // value_ is updated here and not in Advance() because Advance() 335 // can advance iterator_ beyond the end of the range, and we cannot 336 // detect that fact. The client code, on the other hand, is 337 // responsible for not calling Current() on an out-of-range iterator. 338 const T* Current() const override { 339 if (value_.get() == nullptr) value_.reset(new T(*iterator_)); 340 return value_.get(); 341 } 342 bool Equals(const ParamIteratorInterface<T>& other) const override { 343 // Having the same base generator guarantees that the other 344 // iterator is of the same type and we can downcast. 345 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 346 << "The program attempted to compare iterators " 347 << "from different generators." << std::endl; 348 return iterator_ == 349 CheckedDowncastToActualType<const Iterator>(&other)->iterator_; 350 } 351 352 private: 353 Iterator(const Iterator& other) 354 // The explicit constructor call suppresses a false warning 355 // emitted by gcc when supplied with the -Wextra option. 356 : ParamIteratorInterface<T>(), 357 base_(other.base_), 358 iterator_(other.iterator_) {} 359 360 const ParamGeneratorInterface<T>* const base_; 361 typename ContainerType::const_iterator iterator_; 362 // A cached value of *iterator_. We keep it here to allow access by 363 // pointer in the wrapping iterator's operator->(). 364 // value_ needs to be mutable to be accessed in Current(). 365 // Use of std::unique_ptr helps manage cached value's lifetime, 366 // which is bound by the lifespan of the iterator itself. 367 mutable std::unique_ptr<const T> value_; 368 }; // class ValuesInIteratorRangeGenerator::Iterator 369 370 // No implementation - assignment is unsupported. 371 void operator=(const ValuesInIteratorRangeGenerator& other); 372 373 const ContainerType container_; 374}; // class ValuesInIteratorRangeGenerator 375 376// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 377// 378// Default parameterized test name generator, returns a string containing the 379// integer test parameter index. 380template <class ParamType> 381std::string DefaultParamName(const TestParamInfo<ParamType>& info) { 382 Message name_stream; 383 name_stream << info.index; 384 return name_stream.GetString(); 385} 386 387template <typename T = int> 388void TestNotEmpty() { 389 static_assert(sizeof(T) == 0, "Empty arguments are not allowed."); 390} 391template <typename T = int> 392void TestNotEmpty(const T&) {} 393 394// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 395// 396// Stores a parameter value and later creates tests parameterized with that 397// value. 398template <class TestClass> 399class ParameterizedTestFactory : public TestFactoryBase { 400 public: 401 typedef typename TestClass::ParamType ParamType; 402 explicit ParameterizedTestFactory(ParamType parameter) 403 : parameter_(parameter) {} 404 Test* CreateTest() override { 405 TestClass::SetParam(¶meter_); 406 return new TestClass(); 407 } 408 409 private: 410 const ParamType parameter_; 411 412 ParameterizedTestFactory(const ParameterizedTestFactory&) = delete; 413 ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete; 414}; 415 416// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 417// 418// TestMetaFactoryBase is a base class for meta-factories that create 419// test factories for passing into MakeAndRegisterTestInfo function. 420template <class ParamType> 421class TestMetaFactoryBase { 422 public: 423 virtual ~TestMetaFactoryBase() = default; 424 425 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; 426}; 427 428// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 429// 430// TestMetaFactory creates test factories for passing into 431// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives 432// ownership of test factory pointer, same factory object cannot be passed 433// into that method twice. But ParameterizedTestSuiteInfo is going to call 434// it for each Test/Parameter value combination. Thus it needs meta factory 435// creator class. 436template <class TestSuite> 437class TestMetaFactory 438 : public TestMetaFactoryBase<typename TestSuite::ParamType> { 439 public: 440 using ParamType = typename TestSuite::ParamType; 441 442 TestMetaFactory() = default; 443 444 TestFactoryBase* CreateTestFactory(ParamType parameter) override { 445 return new ParameterizedTestFactory<TestSuite>(parameter); 446 } 447 448 private: 449 TestMetaFactory(const TestMetaFactory&) = delete; 450 TestMetaFactory& operator=(const TestMetaFactory&) = delete; 451}; 452 453// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 454// 455// ParameterizedTestSuiteInfoBase is a generic interface 456// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase 457// accumulates test information provided by TEST_P macro invocations 458// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations 459// and uses that information to register all resulting test instances 460// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds 461// a collection of pointers to the ParameterizedTestSuiteInfo objects 462// and calls RegisterTests() on each of them when asked. 463class ParameterizedTestSuiteInfoBase { 464 public: 465 virtual ~ParameterizedTestSuiteInfoBase() = default; 466 467 // Base part of test suite name for display purposes. 468 virtual const std::string& GetTestSuiteName() const = 0; 469 // Test suite id to verify identity. 470 virtual TypeId GetTestSuiteTypeId() const = 0; 471 // UnitTest class invokes this method to register tests in this 472 // test suite right before running them in RUN_ALL_TESTS macro. 473 // This method should not be called more than once on any single 474 // instance of a ParameterizedTestSuiteInfoBase derived class. 475 virtual void RegisterTests() = 0; 476 477 protected: 478 ParameterizedTestSuiteInfoBase() {} 479 480 private: 481 ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) = 482 delete; 483 ParameterizedTestSuiteInfoBase& operator=( 484 const ParameterizedTestSuiteInfoBase&) = delete; 485}; 486 487// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 488// 489// Report a the name of a test_suit as safe to ignore 490// as the side effect of construction of this type. 491struct GTEST_API_ MarkAsIgnored { 492 explicit MarkAsIgnored(const char* test_suite); 493}; 494 495GTEST_API_ void InsertSyntheticTestCase(const std::string& name, 496 CodeLocation location, bool has_test_p); 497 498// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 499// 500// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P 501// macro invocations for a particular test suite and generators 502// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that 503// test suite. It registers tests with all values generated by all 504// generators when asked. 505template <class TestSuite> 506class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { 507 public: 508 // ParamType and GeneratorCreationFunc are private types but are required 509 // for declarations of public methods AddTestPattern() and 510 // AddTestSuiteInstantiation(). 511 using ParamType = typename TestSuite::ParamType; 512 // A function that returns an instance of appropriate generator type. 513 typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); 514 using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&); 515 516 explicit ParameterizedTestSuiteInfo(const char* name, 517 CodeLocation code_location) 518 : test_suite_name_(name), code_location_(code_location) {} 519 520 // Test suite base name for display purposes. 521 const std::string& GetTestSuiteName() const override { 522 return test_suite_name_; 523 } 524 // Test suite id to verify identity. 525 TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); } 526 // TEST_P macro uses AddTestPattern() to record information 527 // about a single test in a LocalTestInfo structure. 528 // test_suite_name is the base name of the test suite (without invocation 529 // prefix). test_base_name is the name of an individual test without 530 // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is 531 // test suite base name and DoBar is test base name. 532 void AddTestPattern(const char* test_suite_name, const char* test_base_name, 533 TestMetaFactoryBase<ParamType>* meta_factory, 534 CodeLocation code_location) { 535 tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo( 536 test_suite_name, test_base_name, meta_factory, code_location))); 537 } 538 // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information 539 // about a generator. 540 int AddTestSuiteInstantiation(const std::string& instantiation_name, 541 GeneratorCreationFunc* func, 542 ParamNameGeneratorFunc* name_func, 543 const char* file, int line) { 544 instantiations_.push_back( 545 InstantiationInfo(instantiation_name, func, name_func, file, line)); 546 return 0; // Return value used only to run this method in namespace scope. 547 } 548 // UnitTest class invokes this method to register tests in this test suite 549 // right before running tests in RUN_ALL_TESTS macro. 550 // This method should not be called more than once on any single 551 // instance of a ParameterizedTestSuiteInfoBase derived class. 552 // UnitTest has a guard to prevent from calling this method more than once. 553 void RegisterTests() override { 554 bool generated_instantiations = false; 555 556 for (typename TestInfoContainer::iterator test_it = tests_.begin(); 557 test_it != tests_.end(); ++test_it) { 558 std::shared_ptr<TestInfo> test_info = *test_it; 559 for (typename InstantiationContainer::iterator gen_it = 560 instantiations_.begin(); 561 gen_it != instantiations_.end(); ++gen_it) { 562 const std::string& instantiation_name = gen_it->name; 563 ParamGenerator<ParamType> generator((*gen_it->generator)()); 564 ParamNameGeneratorFunc* name_func = gen_it->name_func; 565 const char* file = gen_it->file; 566 int line = gen_it->line; 567 568 std::string test_suite_name; 569 if (!instantiation_name.empty()) 570 test_suite_name = instantiation_name + "/"; 571 test_suite_name += test_info->test_suite_base_name; 572 573 size_t i = 0; 574 std::set<std::string> test_param_names; 575 for (typename ParamGenerator<ParamType>::iterator param_it = 576 generator.begin(); 577 param_it != generator.end(); ++param_it, ++i) { 578 generated_instantiations = true; 579 580 Message test_name_stream; 581 582 std::string param_name = 583 name_func(TestParamInfo<ParamType>(*param_it, i)); 584 585 GTEST_CHECK_(IsValidParamName(param_name)) 586 << "Parameterized test name '" << param_name 587 << "' is invalid (contains spaces, dashes, underscores, or " 588 "non-alphanumeric characters), in " 589 << file << " line " << line << "" << std::endl; 590 591 GTEST_CHECK_(test_param_names.count(param_name) == 0) 592 << "Duplicate parameterized test name '" << param_name << "', in " 593 << file << " line " << line << std::endl; 594 595 test_param_names.insert(param_name); 596 597 if (!test_info->test_base_name.empty()) { 598 test_name_stream << test_info->test_base_name << "/"; 599 } 600 test_name_stream << param_name; 601 MakeAndRegisterTestInfo( 602 test_suite_name.c_str(), test_name_stream.GetString().c_str(), 603 nullptr, // No type parameter. 604 PrintToString(*param_it).c_str(), test_info->code_location, 605 GetTestSuiteTypeId(), 606 SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line), 607 SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line), 608 test_info->test_meta_factory->CreateTestFactory(*param_it)); 609 } // for param_it 610 } // for gen_it 611 } // for test_it 612 613 if (!generated_instantiations) { 614 // There are no generaotrs, or they all generate nothing ... 615 InsertSyntheticTestCase(GetTestSuiteName(), code_location_, 616 !tests_.empty()); 617 } 618 } // RegisterTests 619 620 private: 621 // LocalTestInfo structure keeps information about a single test registered 622 // with TEST_P macro. 623 struct TestInfo { 624 TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name, 625 TestMetaFactoryBase<ParamType>* a_test_meta_factory, 626 CodeLocation a_code_location) 627 : test_suite_base_name(a_test_suite_base_name), 628 test_base_name(a_test_base_name), 629 test_meta_factory(a_test_meta_factory), 630 code_location(a_code_location) {} 631 632 const std::string test_suite_base_name; 633 const std::string test_base_name; 634 const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory; 635 const CodeLocation code_location; 636 }; 637 using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>; 638 // Records data received from INSTANTIATE_TEST_SUITE_P macros: 639 // <Instantiation name, Sequence generator creation function, 640 // Name generator function, Source file, Source line> 641 struct InstantiationInfo { 642 InstantiationInfo(const std::string& name_in, 643 GeneratorCreationFunc* generator_in, 644 ParamNameGeneratorFunc* name_func_in, const char* file_in, 645 int line_in) 646 : name(name_in), 647 generator(generator_in), 648 name_func(name_func_in), 649 file(file_in), 650 line(line_in) {} 651 652 std::string name; 653 GeneratorCreationFunc* generator; 654 ParamNameGeneratorFunc* name_func; 655 const char* file; 656 int line; 657 }; 658 typedef ::std::vector<InstantiationInfo> InstantiationContainer; 659 660 static bool IsValidParamName(const std::string& name) { 661 // Check for empty string 662 if (name.empty()) return false; 663 664 // Check for invalid characters 665 for (std::string::size_type index = 0; index < name.size(); ++index) { 666 if (!IsAlNum(name[index]) && name[index] != '_') return false; 667 } 668 669 return true; 670 } 671 672 const std::string test_suite_name_; 673 CodeLocation code_location_; 674 TestInfoContainer tests_; 675 InstantiationContainer instantiations_; 676 677 ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete; 678 ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) = 679 delete; 680}; // class ParameterizedTestSuiteInfo 681 682// Legacy API is deprecated but still available 683#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 684template <class TestCase> 685using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>; 686#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 687 688// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 689// 690// ParameterizedTestSuiteRegistry contains a map of 691// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P 692// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding 693// ParameterizedTestSuiteInfo descriptors. 694class ParameterizedTestSuiteRegistry { 695 public: 696 ParameterizedTestSuiteRegistry() = default; 697 ~ParameterizedTestSuiteRegistry() { 698 for (auto& test_suite_info : test_suite_infos_) { 699 delete test_suite_info; 700 } 701 } 702 703 // Looks up or creates and returns a structure containing information about 704 // tests and instantiations of a particular test suite. 705 template <class TestSuite> 706 ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder( 707 const char* test_suite_name, CodeLocation code_location) { 708 ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr; 709 for (auto& test_suite_info : test_suite_infos_) { 710 if (test_suite_info->GetTestSuiteName() == test_suite_name) { 711 if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) { 712 // Complain about incorrect usage of Google Test facilities 713 // and terminate the program since we cannot guaranty correct 714 // test suite setup and tear-down in this case. 715 ReportInvalidTestSuiteType(test_suite_name, code_location); 716 posix::Abort(); 717 } else { 718 // At this point we are sure that the object we found is of the same 719 // type we are looking for, so we downcast it to that type 720 // without further checks. 721 typed_test_info = CheckedDowncastToActualType< 722 ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info); 723 } 724 break; 725 } 726 } 727 if (typed_test_info == nullptr) { 728 typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>( 729 test_suite_name, code_location); 730 test_suite_infos_.push_back(typed_test_info); 731 } 732 return typed_test_info; 733 } 734 void RegisterTests() { 735 for (auto& test_suite_info : test_suite_infos_) { 736 test_suite_info->RegisterTests(); 737 } 738 } 739// Legacy API is deprecated but still available 740#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 741 template <class TestCase> 742 ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( 743 const char* test_case_name, CodeLocation code_location) { 744 return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location); 745 } 746 747#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 748 749 private: 750 using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>; 751 752 TestSuiteInfoContainer test_suite_infos_; 753 754 ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) = 755 delete; 756 ParameterizedTestSuiteRegistry& operator=( 757 const ParameterizedTestSuiteRegistry&) = delete; 758}; 759 760// Keep track of what type-parameterized test suite are defined and 761// where as well as which are intatiated. This allows susequently 762// identifying suits that are defined but never used. 763class TypeParameterizedTestSuiteRegistry { 764 public: 765 // Add a suite definition 766 void RegisterTestSuite(const char* test_suite_name, 767 CodeLocation code_location); 768 769 // Add an instantiation of a suit. 770 void RegisterInstantiation(const char* test_suite_name); 771 772 // For each suit repored as defined but not reported as instantiation, 773 // emit a test that reports that fact (configurably, as an error). 774 void CheckForInstantiations(); 775 776 private: 777 struct TypeParameterizedTestSuiteInfo { 778 explicit TypeParameterizedTestSuiteInfo(CodeLocation c) 779 : code_location(c), instantiated(false) {} 780 781 CodeLocation code_location; 782 bool instantiated; 783 }; 784 785 std::map<std::string, TypeParameterizedTestSuiteInfo> suites_; 786}; 787 788} // namespace internal 789 790// Forward declarations of ValuesIn(), which is implemented in 791// include/gtest/gtest-param-test.h. 792template <class Container> 793internal::ParamGenerator<typename Container::value_type> ValuesIn( 794 const Container& container); 795 796namespace internal { 797// Used in the Values() function to provide polymorphic capabilities. 798 799GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) 800 801template <typename... Ts> 802class ValueArray { 803 public: 804 explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {} 805 806 template <typename T> 807 operator ParamGenerator<T>() const { // NOLINT 808 return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>())); 809 } 810 811 private: 812 template <typename T, size_t... I> 813 std::vector<T> MakeVector(IndexSequence<I...>) const { 814 return std::vector<T>{static_cast<T>(v_.template Get<I>())...}; 815 } 816 817 FlatTuple<Ts...> v_; 818}; 819 820GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 821 822template <typename... T> 823class CartesianProductGenerator 824 : public ParamGeneratorInterface<::std::tuple<T...>> { 825 public: 826 typedef ::std::tuple<T...> ParamType; 827 828 CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g) 829 : generators_(g) {} 830 ~CartesianProductGenerator() override = default; 831 832 ParamIteratorInterface<ParamType>* Begin() const override { 833 return new Iterator(this, generators_, false); 834 } 835 ParamIteratorInterface<ParamType>* End() const override { 836 return new Iterator(this, generators_, true); 837 } 838 839 private: 840 template <class I> 841 class IteratorImpl; 842 template <size_t... I> 843 class IteratorImpl<IndexSequence<I...>> 844 : public ParamIteratorInterface<ParamType> { 845 public: 846 IteratorImpl(const ParamGeneratorInterface<ParamType>* base, 847 const std::tuple<ParamGenerator<T>...>& generators, 848 bool is_end) 849 : base_(base), 850 begin_(std::get<I>(generators).begin()...), 851 end_(std::get<I>(generators).end()...), 852 current_(is_end ? end_ : begin_) { 853 ComputeCurrentValue(); 854 } 855 ~IteratorImpl() override = default; 856 857 const ParamGeneratorInterface<ParamType>* BaseGenerator() const override { 858 return base_; 859 } 860 // Advance should not be called on beyond-of-range iterators 861 // so no component iterators must be beyond end of range, either. 862 void Advance() override { 863 assert(!AtEnd()); 864 // Advance the last iterator. 865 ++std::get<sizeof...(T) - 1>(current_); 866 // if that reaches end, propagate that up. 867 AdvanceIfEnd<sizeof...(T) - 1>(); 868 ComputeCurrentValue(); 869 } 870 ParamIteratorInterface<ParamType>* Clone() const override { 871 return new IteratorImpl(*this); 872 } 873 874 const ParamType* Current() const override { return current_value_.get(); } 875 876 bool Equals(const ParamIteratorInterface<ParamType>& other) const override { 877 // Having the same base generator guarantees that the other 878 // iterator is of the same type and we can downcast. 879 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 880 << "The program attempted to compare iterators " 881 << "from different generators." << std::endl; 882 const IteratorImpl* typed_other = 883 CheckedDowncastToActualType<const IteratorImpl>(&other); 884 885 // We must report iterators equal if they both point beyond their 886 // respective ranges. That can happen in a variety of fashions, 887 // so we have to consult AtEnd(). 888 if (AtEnd() && typed_other->AtEnd()) return true; 889 890 bool same = true; 891 bool dummy[] = { 892 (same = same && std::get<I>(current_) == 893 std::get<I>(typed_other->current_))...}; 894 (void)dummy; 895 return same; 896 } 897 898 private: 899 template <size_t ThisI> 900 void AdvanceIfEnd() { 901 if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return; 902 903 bool last = ThisI == 0; 904 if (last) { 905 // We are done. Nothing else to propagate. 906 return; 907 } 908 909 constexpr size_t NextI = ThisI - (ThisI != 0); 910 std::get<ThisI>(current_) = std::get<ThisI>(begin_); 911 ++std::get<NextI>(current_); 912 AdvanceIfEnd<NextI>(); 913 } 914 915 void ComputeCurrentValue() { 916 if (!AtEnd()) 917 current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...); 918 } 919 bool AtEnd() const { 920 bool at_end = false; 921 bool dummy[] = { 922 (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...}; 923 (void)dummy; 924 return at_end; 925 } 926 927 const ParamGeneratorInterface<ParamType>* const base_; 928 std::tuple<typename ParamGenerator<T>::iterator...> begin_; 929 std::tuple<typename ParamGenerator<T>::iterator...> end_; 930 std::tuple<typename ParamGenerator<T>::iterator...> current_; 931 std::shared_ptr<ParamType> current_value_; 932 }; 933 934 using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>; 935 936 std::tuple<ParamGenerator<T>...> generators_; 937}; 938 939template <class... Gen> 940class CartesianProductHolder { 941 public: 942 CartesianProductHolder(const Gen&... g) : generators_(g...) {} 943 template <typename... T> 944 operator ParamGenerator<::std::tuple<T...>>() const { 945 return ParamGenerator<::std::tuple<T...>>( 946 new CartesianProductGenerator<T...>(generators_)); 947 } 948 949 private: 950 std::tuple<Gen...> generators_; 951}; 952 953template <typename From, typename To> 954class ParamGeneratorConverter : public ParamGeneratorInterface<To> { 955 public: 956 ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT 957 : generator_(std::move(gen)) {} 958 959 ParamIteratorInterface<To>* Begin() const override { 960 return new Iterator(this, generator_.begin(), generator_.end()); 961 } 962 ParamIteratorInterface<To>* End() const override { 963 return new Iterator(this, generator_.end(), generator_.end()); 964 } 965 966 private: 967 class Iterator : public ParamIteratorInterface<To> { 968 public: 969 Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it, 970 ParamIterator<From> end) 971 : base_(base), it_(it), end_(end) { 972 if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_)); 973 } 974 ~Iterator() override = default; 975 976 const ParamGeneratorInterface<To>* BaseGenerator() const override { 977 return base_; 978 } 979 void Advance() override { 980 ++it_; 981 if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_)); 982 } 983 ParamIteratorInterface<To>* Clone() const override { 984 return new Iterator(*this); 985 } 986 const To* Current() const override { return value_.get(); } 987 bool Equals(const ParamIteratorInterface<To>& other) const override { 988 // Having the same base generator guarantees that the other 989 // iterator is of the same type and we can downcast. 990 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 991 << "The program attempted to compare iterators " 992 << "from different generators." << std::endl; 993 const ParamIterator<From> other_it = 994 CheckedDowncastToActualType<const Iterator>(&other)->it_; 995 return it_ == other_it; 996 } 997 998 private: 999 Iterator(const Iterator& other) = default; 1000 1001 const ParamGeneratorInterface<To>* const base_; 1002 ParamIterator<From> it_; 1003 ParamIterator<From> end_; 1004 std::shared_ptr<To> value_; 1005 }; // class ParamGeneratorConverter::Iterator 1006 1007 ParamGenerator<From> generator_; 1008}; // class ParamGeneratorConverter 1009 1010template <class Gen> 1011class ParamConverterGenerator { 1012 public: 1013 ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT 1014 : generator_(std::move(g)) {} 1015 1016 template <typename T> 1017 operator ParamGenerator<T>() const { // NOLINT 1018 return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_)); 1019 } 1020 1021 private: 1022 ParamGenerator<Gen> generator_; 1023}; 1024 1025} // namespace internal 1026} // namespace testing 1027 1028#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 1029