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
52 namespace testing {
53 // Input to a parameterized test name generator, describing a test parameter.
54 // Consists of the parameter value and the integer parameter index.
55 template <class ParamType>
56 struct TestParamInfo {
TestParamInfoTestParamInfo57 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.
66 struct PrintToStringParamName {
67 template <class ParamType>
operatorPrintToStringParamName68 std::string operator()(const TestParamInfo<ParamType>& info) const {
69 return PrintToString(info.param);
70 }
71 };
72
73 namespace 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.
82 GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
83 CodeLocation code_location);
84
85 template <typename> class ParamGeneratorInterface;
86 template <typename> class ParamGenerator;
87
88 // Interface for iterating over elements provided by an implementation
89 // of ParamGeneratorInterface<T>.
90 template <typename T>
91 class ParamIteratorInterface {
92 public:
~ParamIteratorInterface()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.
120 template <typename T>
121 class 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.
ParamIterator(const ParamIterator & other)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>;
ParamIterator(ParamIteratorInterface<T> * impl)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.
163 template <typename T>
164 class ParamGeneratorInterface {
165 public:
166 typedef T ParamType;
167
~ParamGeneratorInterface()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.
180 template<typename T>
181 class ParamGenerator {
182 public:
183 typedef ParamIterator<T> iterator;
184
ParamGenerator(ParamGeneratorInterface<T> * impl)185 explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
ParamGenerator(const ParamGenerator & other)186 ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
187
188 ParamGenerator& operator=(const ParamGenerator& other) {
189 impl_ = other.impl_;
190 return *this;
191 }
192
begin()193 iterator begin() const { return iterator(impl_->Begin()); }
end()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.
204 template <typename T, typename IncrementT>
205 class RangeGenerator : public ParamGeneratorInterface<T> {
206 public:
RangeGenerator(T begin,T end,IncrementT step)207 RangeGenerator(T begin, T end, IncrementT step)
208 : begin_(begin), end_(end),
209 step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
~RangeGenerator()210 ~RangeGenerator() override {}
211
Begin()212 ParamIteratorInterface<T>* Begin() const override {
213 return new Iterator(this, begin_, 0, step_);
214 }
End()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:
Iterator(const ParamGeneratorInterface<T> * base,T value,int index,IncrementT step)222 Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
223 IncrementT step)
224 : base_(base), value_(value), index_(index), step_(step) {}
~Iterator()225 ~Iterator() override {}
226
BaseGenerator()227 const ParamGeneratorInterface<T>* BaseGenerator() const override {
228 return base_;
229 }
Advance()230 void Advance() override {
231 value_ = static_cast<T>(value_ + step_);
232 index_++;
233 }
Clone()234 ParamIteratorInterface<T>* Clone() const override {
235 return new Iterator(*this);
236 }
Current()237 const T* Current() const override { return &value_; }
Equals(const ParamIteratorInterface<T> & other)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:
Iterator(const Iterator & other)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
CalculateEndIndex(const T & begin,const T & end,const IncrementT & step)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.
289 template <typename T>
290 class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
291 public:
292 template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin,ForwardIterator end)293 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
294 : container_(begin, end) {}
~ValuesInIteratorRangeGenerator()295 ~ValuesInIteratorRangeGenerator() override {}
296
Begin()297 ParamIteratorInterface<T>* Begin() const override {
298 return new Iterator(this, container_.begin());
299 }
End()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:
Iterator(const ParamGeneratorInterface<T> * base,typename ContainerType::const_iterator iterator)309 Iterator(const ParamGeneratorInterface<T>* base,
310 typename ContainerType::const_iterator iterator)
311 : base_(base), iterator_(iterator) {}
~Iterator()312 ~Iterator() override {}
313
BaseGenerator()314 const ParamGeneratorInterface<T>* BaseGenerator() const override {
315 return base_;
316 }
Advance()317 void Advance() override {
318 ++iterator_;
319 value_.reset();
320 }
Clone()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.
Current()331 const T* Current() const override {
332 if (value_.get() == nullptr) value_.reset(new T(*iterator_));
333 return value_.get();
334 }
Equals(const ParamIteratorInterface<T> & other)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:
Iterator(const Iterator & other)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.
373 template <class ParamType>
DefaultParamName(const TestParamInfo<ParamType> & info)374 std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
375 Message name_stream;
376 name_stream << info.index;
377 return name_stream.GetString();
378 }
379
380 template <typename T = int>
TestNotEmpty()381 void TestNotEmpty() {
382 static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
383 }
384 template <typename T = int>
TestNotEmpty(const T &)385 void 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.
391 template <class TestClass>
392 class ParameterizedTestFactory : public TestFactoryBase {
393 public:
394 typedef typename TestClass::ParamType ParamType;
ParameterizedTestFactory(ParamType parameter)395 explicit ParameterizedTestFactory(ParamType parameter) :
396 parameter_(parameter) {}
CreateTest()397 Test* CreateTest() override {
398 TestClass::SetParam(¶meter_);
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.
412 template <class ParamType>
413 class TestMetaFactoryBase {
414 public:
~TestMetaFactoryBase()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.
428 template <class TestSuite>
429 class TestMetaFactory
430 : public TestMetaFactoryBase<typename TestSuite::ParamType> {
431 public:
432 using ParamType = typename TestSuite::ParamType;
433
TestMetaFactory()434 TestMetaFactory() {}
435
CreateTestFactory(ParamType parameter)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.
454 class ParameterizedTestSuiteInfoBase {
455 public:
~ParameterizedTestSuiteInfoBase()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 then once on any single
465 // instance of a ParameterizedTestSuiteInfoBase derived class.
466 virtual void RegisterTests() = 0;
467
468 protected:
ParameterizedTestSuiteInfoBase()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.
482 template <class TestSuite>
483 class 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
ParameterizedTestSuiteInfo(const char * name,CodeLocation code_location)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.
GetTestSuiteName()498 const std::string& GetTestSuiteName() const override {
499 return test_suite_name_;
500 }
501 // Test case id to verify identity.
GetTestSuiteTypeId()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.
AddTestPattern(const char * test_suite_name,const char * test_base_name,TestMetaFactoryBase<ParamType> * meta_factory)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.
AddTestSuiteInstantiation(const std::string & instantiation_name,GeneratorCreationFunc * func,ParamNameGeneratorFunc * name_func,const char * file,int line)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 then once on any single
527 // instance of a ParameterizedTestSuiteInfoBase derived class.
528 // UnitTest has a guard to prevent from calling this method more then once.
RegisterTests()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(),
575 SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(),
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 {
TestInfoTestInfo586 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 {
InstantiationInfoInstantiationInfo601 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
IsValidParamName(const std::string & name)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_
644 template <class TestCase>
645 using 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.
654 class ParameterizedTestSuiteRegistry {
655 public:
ParameterizedTestSuiteRegistry()656 ParameterizedTestSuiteRegistry() {}
~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>
GetTestSuitePatternHolder(const char * test_suite_name,CodeLocation code_location)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 }
RegisterTests()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>
GetTestCasePatternHolder(const char * test_case_name,CodeLocation code_location)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.
721 template <class Container>
722 internal::ParamGenerator<typename Container::value_type> ValuesIn(
723 const Container& container);
724
725 namespace internal {
726 // Used in the Values() function to provide polymorphic capabilities.
727
728 template <typename... Ts>
729 class ValueArray {
730 public:
ValueArray(Ts...v)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>
MakeVector(IndexSequence<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
747 template <typename... T>
748 class CartesianProductGenerator
749 : public ParamGeneratorInterface<::std::tuple<T...>> {
750 public:
751 typedef ::std::tuple<T...> ParamType;
752
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...> & g)753 CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
754 : generators_(g) {}
~CartesianProductGenerator()755 ~CartesianProductGenerator() override {}
756
Begin()757 ParamIteratorInterface<ParamType>* Begin() const override {
758 return new Iterator(this, generators_, false);
759 }
End()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:
IteratorImpl(const ParamGeneratorInterface<ParamType> * base,const std::tuple<ParamGenerator<T>...> & generators,bool is_end)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 }
~IteratorImpl()779 ~IteratorImpl() override {}
780
BaseGenerator()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.
Advance()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 }
Clone()794 ParamIteratorInterface<ParamType>* Clone() const override {
795 return new IteratorImpl(*this);
796 }
797
Current()798 const ParamType* Current() const override { return current_value_.get(); }
799
Equals(const ParamIteratorInterface<ParamType> & other)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>
AdvanceIfEnd()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
ComputeCurrentValue()839 void ComputeCurrentValue() {
840 if (!AtEnd())
841 current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
842 }
AtEnd()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
863 template <class... Gen>
864 class CartesianProductHolder {
865 public:
CartesianProductHolder(const Gen &...g)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