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