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