1 // Copyright 2008 Google Inc.
2 // All Rights Reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
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
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.
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.
30 // Type and function utilities for implementing parameterized tests.
32 // IWYU pragma: private, include "gtest/gtest.h"
33 // IWYU pragma: friend gtest/.*
34 // IWYU pragma: friend gmock/.*
36 #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
37 #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
49 #include <type_traits>
53 #include "gtest/gtest-printers.h"
54 #include "gtest/gtest-test-part.h"
55 #include "gtest/internal/gtest-internal.h"
56 #include "gtest/internal/gtest-port.h"
59 // Input to a parameterized test name generator, describing a test parameter.
60 // Consists of the parameter value and the integer parameter index.
61 template <class ParamType
>
62 struct TestParamInfo
{
63 TestParamInfo(const ParamType
& a_param
, size_t an_index
)
64 : param(a_param
), index(an_index
) {}
69 // A builtin parameterized test name generator which returns the result of
70 // testing::PrintToString.
71 struct PrintToStringParamName
{
72 template <class ParamType
>
73 std::string
operator()(const TestParamInfo
<ParamType
>& info
) const {
74 return PrintToString(info
.param
);
80 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
83 // Outputs a message explaining invalid registration of different
84 // fixture class for the same test suite. This may happen when
85 // TEST_P macro is used to define two tests with the same name
86 // but in different namespaces.
87 GTEST_API_
void ReportInvalidTestSuiteType(const char* test_suite_name
,
88 CodeLocation code_location
);
91 class ParamGeneratorInterface
;
95 // Interface for iterating over elements provided by an implementation
96 // of ParamGeneratorInterface<T>.
98 class ParamIteratorInterface
{
100 virtual ~ParamIteratorInterface() = default;
101 // A pointer to the base generator instance.
102 // Used only for the purposes of iterator comparison
103 // to make sure that two iterators belong to the same generator.
104 virtual const ParamGeneratorInterface
<T
>* BaseGenerator() const = 0;
105 // Advances iterator to point to the next element
106 // provided by the generator. The caller is responsible
107 // for not calling Advance() on an iterator equal to
108 // BaseGenerator()->End().
109 virtual void Advance() = 0;
110 // Clones the iterator object. Used for implementing copy semantics
111 // of ParamIterator<T>.
112 virtual ParamIteratorInterface
* Clone() const = 0;
113 // Dereferences the current iterator and provides (read-only) access
114 // to the pointed value. It is the caller's responsibility not to call
115 // Current() on an iterator equal to BaseGenerator()->End().
116 // Used for implementing ParamGenerator<T>::operator*().
117 virtual const T
* Current() const = 0;
118 // Determines whether the given iterator and other point to the same
119 // element in the sequence generated by the generator.
120 // Used for implementing ParamGenerator<T>::operator==().
121 virtual bool Equals(const ParamIteratorInterface
& other
) const = 0;
124 // Class iterating over elements provided by an implementation of
125 // ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
126 // and implements the const forward iterator concept.
127 template <typename T
>
128 class ParamIterator
{
130 typedef T value_type
;
131 typedef const T
& reference
;
132 typedef ptrdiff_t difference_type
;
134 // ParamIterator assumes ownership of the impl_ pointer.
135 ParamIterator(const ParamIterator
& other
) : impl_(other
.impl_
->Clone()) {}
136 ParamIterator
& operator=(const ParamIterator
& other
) {
137 if (this != &other
) impl_
.reset(other
.impl_
->Clone());
141 const T
& operator*() const { return *impl_
->Current(); }
142 const T
* operator->() const { return impl_
->Current(); }
143 // Prefix version of operator++.
144 ParamIterator
& operator++() {
148 // Postfix version of operator++.
149 ParamIterator
operator++(int /*unused*/) {
150 ParamIteratorInterface
<T
>* clone
= impl_
->Clone();
152 return ParamIterator(clone
);
154 bool operator==(const ParamIterator
& other
) const {
155 return impl_
.get() == other
.impl_
.get() || impl_
->Equals(*other
.impl_
);
157 bool operator!=(const ParamIterator
& other
) const {
158 return !(*this == other
);
162 friend class ParamGenerator
<T
>;
163 explicit ParamIterator(ParamIteratorInterface
<T
>* impl
) : impl_(impl
) {}
164 std::unique_ptr
<ParamIteratorInterface
<T
>> impl_
;
167 // ParamGeneratorInterface<T> is the binary interface to access generators
168 // defined in other translation units.
169 template <typename T
>
170 class ParamGeneratorInterface
{
174 virtual ~ParamGeneratorInterface() = default;
176 // Generator interface definition
177 virtual ParamIteratorInterface
<T
>* Begin() const = 0;
178 virtual ParamIteratorInterface
<T
>* End() const = 0;
181 // Wraps ParamGeneratorInterface<T> and provides general generator syntax
182 // compatible with the STL Container concept.
183 // This class implements copy initialization semantics and the contained
184 // ParamGeneratorInterface<T> instance is shared among all copies
185 // of the original object. This is possible because that instance is immutable.
186 template <typename T
>
187 class ParamGenerator
{
189 typedef ParamIterator
<T
> iterator
;
191 explicit ParamGenerator(ParamGeneratorInterface
<T
>* impl
) : impl_(impl
) {}
192 ParamGenerator(const ParamGenerator
& other
) : impl_(other
.impl_
) {}
194 ParamGenerator
& operator=(const ParamGenerator
& other
) {
199 iterator
begin() const { return iterator(impl_
->Begin()); }
200 iterator
end() const { return iterator(impl_
->End()); }
203 std::shared_ptr
<const ParamGeneratorInterface
<T
>> impl_
;
206 // Generates values from a range of two comparable values. Can be used to
207 // generate sequences of user-defined types that implement operator+() and
209 // This class is used in the Range() function.
210 template <typename T
, typename IncrementT
>
211 class RangeGenerator
: public ParamGeneratorInterface
<T
> {
213 RangeGenerator(T begin
, T end
, IncrementT step
)
217 end_index_(CalculateEndIndex(begin
, end
, step
)) {}
218 ~RangeGenerator() override
= default;
220 ParamIteratorInterface
<T
>* Begin() const override
{
221 return new Iterator(this, begin_
, 0, step_
);
223 ParamIteratorInterface
<T
>* End() const override
{
224 return new Iterator(this, end_
, end_index_
, step_
);
228 class Iterator
: public ParamIteratorInterface
<T
> {
230 Iterator(const ParamGeneratorInterface
<T
>* base
, T value
, int index
,
232 : base_(base
), value_(value
), index_(index
), step_(step
) {}
233 ~Iterator() override
= default;
235 const ParamGeneratorInterface
<T
>* BaseGenerator() const override
{
238 void Advance() override
{
239 value_
= static_cast<T
>(value_
+ step_
);
242 ParamIteratorInterface
<T
>* Clone() const override
{
243 return new Iterator(*this);
245 const T
* Current() const override
{ return &value_
; }
246 bool Equals(const ParamIteratorInterface
<T
>& other
) const override
{
247 // Having the same base generator guarantees that the other
248 // iterator is of the same type and we can downcast.
249 GTEST_CHECK_(BaseGenerator() == other
.BaseGenerator())
250 << "The program attempted to compare iterators "
251 << "from different generators." << std::endl
;
252 const int other_index
=
253 CheckedDowncastToActualType
<const Iterator
>(&other
)->index_
;
254 return index_
== other_index
;
258 Iterator(const Iterator
& other
)
259 : ParamIteratorInterface
<T
>(),
261 value_(other
.value_
),
262 index_(other
.index_
),
263 step_(other
.step_
) {}
265 // No implementation - assignment is unsupported.
266 void operator=(const Iterator
& other
);
268 const ParamGeneratorInterface
<T
>* const base_
;
271 const IncrementT step_
;
272 }; // class RangeGenerator::Iterator
274 static int CalculateEndIndex(const T
& begin
, const T
& end
,
275 const IncrementT
& step
) {
277 for (T i
= begin
; i
< end
; i
= static_cast<T
>(i
+ step
)) end_index
++;
281 // No implementation - assignment is unsupported.
282 void operator=(const RangeGenerator
& other
);
286 const IncrementT step_
;
287 // The index for the end() iterator. All the elements in the generated
288 // sequence are indexed (0-based) to aid iterator comparison.
289 const int end_index_
;
290 }; // class RangeGenerator
292 // Generates values from a pair of STL-style iterators. Used in the
293 // ValuesIn() function. The elements are copied from the source range
294 // since the source can be located on the stack, and the generator
295 // is likely to persist beyond that stack frame.
296 template <typename T
>
297 class ValuesInIteratorRangeGenerator
: public ParamGeneratorInterface
<T
> {
299 template <typename ForwardIterator
>
300 ValuesInIteratorRangeGenerator(ForwardIterator begin
, ForwardIterator end
)
301 : container_(begin
, end
) {}
302 ~ValuesInIteratorRangeGenerator() override
= default;
304 ParamIteratorInterface
<T
>* Begin() const override
{
305 return new Iterator(this, container_
.begin());
307 ParamIteratorInterface
<T
>* End() const override
{
308 return new Iterator(this, container_
.end());
312 typedef typename ::std::vector
<T
> ContainerType
;
314 class Iterator
: public ParamIteratorInterface
<T
> {
316 Iterator(const ParamGeneratorInterface
<T
>* base
,
317 typename
ContainerType::const_iterator iterator
)
318 : base_(base
), iterator_(iterator
) {}
319 ~Iterator() override
= default;
321 const ParamGeneratorInterface
<T
>* BaseGenerator() const override
{
324 void Advance() override
{
328 ParamIteratorInterface
<T
>* Clone() const override
{
329 return new Iterator(*this);
331 // We need to use cached value referenced by iterator_ because *iterator_
332 // can return a temporary object (and of type other then T), so just
333 // having "return &*iterator_;" doesn't work.
334 // value_ is updated here and not in Advance() because Advance()
335 // can advance iterator_ beyond the end of the range, and we cannot
336 // detect that fact. The client code, on the other hand, is
337 // responsible for not calling Current() on an out-of-range iterator.
338 const T
* Current() const override
{
339 if (value_
.get() == nullptr) value_
.reset(new T(*iterator_
));
342 bool Equals(const ParamIteratorInterface
<T
>& other
) const override
{
343 // Having the same base generator guarantees that the other
344 // iterator is of the same type and we can downcast.
345 GTEST_CHECK_(BaseGenerator() == other
.BaseGenerator())
346 << "The program attempted to compare iterators "
347 << "from different generators." << std::endl
;
349 CheckedDowncastToActualType
<const Iterator
>(&other
)->iterator_
;
353 Iterator(const Iterator
& other
)
354 // The explicit constructor call suppresses a false warning
355 // emitted by gcc when supplied with the -Wextra option.
356 : ParamIteratorInterface
<T
>(),
358 iterator_(other
.iterator_
) {}
360 const ParamGeneratorInterface
<T
>* const base_
;
361 typename
ContainerType::const_iterator iterator_
;
362 // A cached value of *iterator_. We keep it here to allow access by
363 // pointer in the wrapping iterator's operator->().
364 // value_ needs to be mutable to be accessed in Current().
365 // Use of std::unique_ptr helps manage cached value's lifetime,
366 // which is bound by the lifespan of the iterator itself.
367 mutable std::unique_ptr
<const T
> value_
;
368 }; // class ValuesInIteratorRangeGenerator::Iterator
370 // No implementation - assignment is unsupported.
371 void operator=(const ValuesInIteratorRangeGenerator
& other
);
373 const ContainerType container_
;
374 }; // class ValuesInIteratorRangeGenerator
376 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
378 // Default parameterized test name generator, returns a string containing the
379 // integer test parameter index.
380 template <class ParamType
>
381 std::string
DefaultParamName(const TestParamInfo
<ParamType
>& info
) {
383 name_stream
<< info
.index
;
384 return name_stream
.GetString();
387 template <typename T
= int>
388 void TestNotEmpty() {
389 static_assert(sizeof(T
) == 0, "Empty arguments are not allowed.");
391 template <typename T
= int>
392 void TestNotEmpty(const T
&) {}
394 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
396 // Stores a parameter value and later creates tests parameterized with that
398 template <class TestClass
>
399 class ParameterizedTestFactory
: public TestFactoryBase
{
401 typedef typename
TestClass::ParamType ParamType
;
402 explicit ParameterizedTestFactory(ParamType parameter
)
403 : parameter_(parameter
) {}
404 Test
* CreateTest() override
{
405 TestClass::SetParam(¶meter_
);
406 return new TestClass();
410 const ParamType parameter_
;
412 ParameterizedTestFactory(const ParameterizedTestFactory
&) = delete;
413 ParameterizedTestFactory
& operator=(const ParameterizedTestFactory
&) = delete;
416 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
418 // TestMetaFactoryBase is a base class for meta-factories that create
419 // test factories for passing into MakeAndRegisterTestInfo function.
420 template <class ParamType
>
421 class TestMetaFactoryBase
{
423 virtual ~TestMetaFactoryBase() = default;
425 virtual TestFactoryBase
* CreateTestFactory(ParamType parameter
) = 0;
428 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
430 // TestMetaFactory creates test factories for passing into
431 // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
432 // ownership of test factory pointer, same factory object cannot be passed
433 // into that method twice. But ParameterizedTestSuiteInfo is going to call
434 // it for each Test/Parameter value combination. Thus it needs meta factory
436 template <class TestSuite
>
437 class TestMetaFactory
438 : public TestMetaFactoryBase
<typename
TestSuite::ParamType
> {
440 using ParamType
= typename
TestSuite::ParamType
;
442 TestMetaFactory() = default;
444 TestFactoryBase
* CreateTestFactory(ParamType parameter
) override
{
445 return new ParameterizedTestFactory
<TestSuite
>(parameter
);
449 TestMetaFactory(const TestMetaFactory
&) = delete;
450 TestMetaFactory
& operator=(const TestMetaFactory
&) = delete;
453 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
455 // ParameterizedTestSuiteInfoBase is a generic interface
456 // to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
457 // accumulates test information provided by TEST_P macro invocations
458 // and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
459 // and uses that information to register all resulting test instances
460 // in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
461 // a collection of pointers to the ParameterizedTestSuiteInfo objects
462 // and calls RegisterTests() on each of them when asked.
463 class ParameterizedTestSuiteInfoBase
{
465 virtual ~ParameterizedTestSuiteInfoBase() = default;
467 // Base part of test suite name for display purposes.
468 virtual const std::string
& GetTestSuiteName() const = 0;
469 // Test suite id to verify identity.
470 virtual TypeId
GetTestSuiteTypeId() const = 0;
471 // UnitTest class invokes this method to register tests in this
472 // test suite right before running them in RUN_ALL_TESTS macro.
473 // This method should not be called more than once on any single
474 // instance of a ParameterizedTestSuiteInfoBase derived class.
475 virtual void RegisterTests() = 0;
478 ParameterizedTestSuiteInfoBase() {}
481 ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase
&) =
483 ParameterizedTestSuiteInfoBase
& operator=(
484 const ParameterizedTestSuiteInfoBase
&) = delete;
487 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
489 // Report a the name of a test_suit as safe to ignore
490 // as the side effect of construction of this type.
491 struct GTEST_API_ MarkAsIgnored
{
492 explicit MarkAsIgnored(const char* test_suite
);
495 GTEST_API_
void InsertSyntheticTestCase(const std::string
& name
,
496 CodeLocation location
, bool has_test_p
);
498 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
500 // ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
501 // macro invocations for a particular test suite and generators
502 // obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
503 // test suite. It registers tests with all values generated by all
504 // generators when asked.
505 template <class TestSuite
>
506 class ParameterizedTestSuiteInfo
: public ParameterizedTestSuiteInfoBase
{
508 // ParamType and GeneratorCreationFunc are private types but are required
509 // for declarations of public methods AddTestPattern() and
510 // AddTestSuiteInstantiation().
511 using ParamType
= typename
TestSuite::ParamType
;
512 // A function that returns an instance of appropriate generator type.
513 typedef ParamGenerator
<ParamType
>(GeneratorCreationFunc
)();
514 using ParamNameGeneratorFunc
= std::string(const TestParamInfo
<ParamType
>&);
516 explicit ParameterizedTestSuiteInfo(const char* name
,
517 CodeLocation code_location
)
518 : test_suite_name_(name
), code_location_(code_location
) {}
520 // Test suite base name for display purposes.
521 const std::string
& GetTestSuiteName() const override
{
522 return test_suite_name_
;
524 // Test suite id to verify identity.
525 TypeId
GetTestSuiteTypeId() const override
{ return GetTypeId
<TestSuite
>(); }
526 // TEST_P macro uses AddTestPattern() to record information
527 // about a single test in a LocalTestInfo structure.
528 // test_suite_name is the base name of the test suite (without invocation
529 // prefix). test_base_name is the name of an individual test without
530 // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
531 // test suite base name and DoBar is test base name.
532 void AddTestPattern(const char* test_suite_name
, const char* test_base_name
,
533 TestMetaFactoryBase
<ParamType
>* meta_factory
,
534 CodeLocation code_location
) {
535 tests_
.push_back(std::shared_ptr
<TestInfo
>(new TestInfo(
536 test_suite_name
, test_base_name
, meta_factory
, code_location
)));
538 // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
539 // about a generator.
540 int AddTestSuiteInstantiation(const std::string
& instantiation_name
,
541 GeneratorCreationFunc
* func
,
542 ParamNameGeneratorFunc
* name_func
,
543 const char* file
, int line
) {
544 instantiations_
.push_back(
545 InstantiationInfo(instantiation_name
, func
, name_func
, file
, line
));
546 return 0; // Return value used only to run this method in namespace scope.
548 // UnitTest class invokes this method to register tests in this test suite
549 // right before running tests in RUN_ALL_TESTS macro.
550 // This method should not be called more than once on any single
551 // instance of a ParameterizedTestSuiteInfoBase derived class.
552 // UnitTest has a guard to prevent from calling this method more than once.
553 void RegisterTests() override
{
554 bool generated_instantiations
= false;
556 for (typename
TestInfoContainer::iterator test_it
= tests_
.begin();
557 test_it
!= tests_
.end(); ++test_it
) {
558 std::shared_ptr
<TestInfo
> test_info
= *test_it
;
559 for (typename
InstantiationContainer::iterator gen_it
=
560 instantiations_
.begin();
561 gen_it
!= instantiations_
.end(); ++gen_it
) {
562 const std::string
& instantiation_name
= gen_it
->name
;
563 ParamGenerator
<ParamType
> generator((*gen_it
->generator
)());
564 ParamNameGeneratorFunc
* name_func
= gen_it
->name_func
;
565 const char* file
= gen_it
->file
;
566 int line
= gen_it
->line
;
568 std::string test_suite_name
;
569 if (!instantiation_name
.empty())
570 test_suite_name
= instantiation_name
+ "/";
571 test_suite_name
+= test_info
->test_suite_base_name
;
574 std::set
<std::string
> test_param_names
;
575 for (typename ParamGenerator
<ParamType
>::iterator param_it
=
577 param_it
!= generator
.end(); ++param_it
, ++i
) {
578 generated_instantiations
= true;
580 Message test_name_stream
;
582 std::string param_name
=
583 name_func(TestParamInfo
<ParamType
>(*param_it
, i
));
585 GTEST_CHECK_(IsValidParamName(param_name
))
586 << "Parameterized test name '" << param_name
587 << "' is invalid, in " << file
<< " line " << line
<< std::endl
;
589 GTEST_CHECK_(test_param_names
.count(param_name
) == 0)
590 << "Duplicate parameterized test name '" << param_name
<< "', in "
591 << file
<< " line " << line
<< std::endl
;
593 test_param_names
.insert(param_name
);
595 if (!test_info
->test_base_name
.empty()) {
596 test_name_stream
<< test_info
->test_base_name
<< "/";
598 test_name_stream
<< param_name
;
599 MakeAndRegisterTestInfo(
600 test_suite_name
.c_str(), test_name_stream
.GetString().c_str(),
601 nullptr, // No type parameter.
602 PrintToString(*param_it
).c_str(), test_info
->code_location
,
603 GetTestSuiteTypeId(),
604 SuiteApiResolver
<TestSuite
>::GetSetUpCaseOrSuite(file
, line
),
605 SuiteApiResolver
<TestSuite
>::GetTearDownCaseOrSuite(file
, line
),
606 test_info
->test_meta_factory
->CreateTestFactory(*param_it
));
611 if (!generated_instantiations
) {
612 // There are no generaotrs, or they all generate nothing ...
613 InsertSyntheticTestCase(GetTestSuiteName(), code_location_
,
619 // LocalTestInfo structure keeps information about a single test registered
620 // with TEST_P macro.
622 TestInfo(const char* a_test_suite_base_name
, const char* a_test_base_name
,
623 TestMetaFactoryBase
<ParamType
>* a_test_meta_factory
,
624 CodeLocation a_code_location
)
625 : test_suite_base_name(a_test_suite_base_name
),
626 test_base_name(a_test_base_name
),
627 test_meta_factory(a_test_meta_factory
),
628 code_location(a_code_location
) {}
630 const std::string test_suite_base_name
;
631 const std::string test_base_name
;
632 const std::unique_ptr
<TestMetaFactoryBase
<ParamType
>> test_meta_factory
;
633 const CodeLocation code_location
;
635 using TestInfoContainer
= ::std::vector
<std::shared_ptr
<TestInfo
>>;
636 // Records data received from INSTANTIATE_TEST_SUITE_P macros:
637 // <Instantiation name, Sequence generator creation function,
638 // Name generator function, Source file, Source line>
639 struct InstantiationInfo
{
640 InstantiationInfo(const std::string
& name_in
,
641 GeneratorCreationFunc
* generator_in
,
642 ParamNameGeneratorFunc
* name_func_in
, const char* file_in
,
645 generator(generator_in
),
646 name_func(name_func_in
),
651 GeneratorCreationFunc
* generator
;
652 ParamNameGeneratorFunc
* name_func
;
656 typedef ::std::vector
<InstantiationInfo
> InstantiationContainer
;
658 static bool IsValidParamName(const std::string
& name
) {
659 // Check for empty string
660 if (name
.empty()) return false;
662 // Check for invalid characters
663 for (std::string::size_type index
= 0; index
< name
.size(); ++index
) {
664 if (!IsAlNum(name
[index
]) && name
[index
] != '_') return false;
670 const std::string test_suite_name_
;
671 CodeLocation code_location_
;
672 TestInfoContainer tests_
;
673 InstantiationContainer instantiations_
;
675 ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo
&) = delete;
676 ParameterizedTestSuiteInfo
& operator=(const ParameterizedTestSuiteInfo
&) =
678 }; // class ParameterizedTestSuiteInfo
680 // Legacy API is deprecated but still available
681 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
682 template <class TestCase
>
683 using ParameterizedTestCaseInfo
= ParameterizedTestSuiteInfo
<TestCase
>;
684 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
686 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
688 // ParameterizedTestSuiteRegistry contains a map of
689 // ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
690 // and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
691 // ParameterizedTestSuiteInfo descriptors.
692 class ParameterizedTestSuiteRegistry
{
694 ParameterizedTestSuiteRegistry() = default;
695 ~ParameterizedTestSuiteRegistry() {
696 for (auto& test_suite_info
: test_suite_infos_
) {
697 delete test_suite_info
;
701 // Looks up or creates and returns a structure containing information about
702 // tests and instantiations of a particular test suite.
703 template <class TestSuite
>
704 ParameterizedTestSuiteInfo
<TestSuite
>* GetTestSuitePatternHolder(
705 const char* test_suite_name
, CodeLocation code_location
) {
706 ParameterizedTestSuiteInfo
<TestSuite
>* typed_test_info
= nullptr;
707 for (auto& test_suite_info
: test_suite_infos_
) {
708 if (test_suite_info
->GetTestSuiteName() == test_suite_name
) {
709 if (test_suite_info
->GetTestSuiteTypeId() != GetTypeId
<TestSuite
>()) {
710 // Complain about incorrect usage of Google Test facilities
711 // and terminate the program since we cannot guaranty correct
712 // test suite setup and tear-down in this case.
713 ReportInvalidTestSuiteType(test_suite_name
, code_location
);
716 // At this point we are sure that the object we found is of the same
717 // type we are looking for, so we downcast it to that type
718 // without further checks.
719 typed_test_info
= CheckedDowncastToActualType
<
720 ParameterizedTestSuiteInfo
<TestSuite
>>(test_suite_info
);
725 if (typed_test_info
== nullptr) {
726 typed_test_info
= new ParameterizedTestSuiteInfo
<TestSuite
>(
727 test_suite_name
, code_location
);
728 test_suite_infos_
.push_back(typed_test_info
);
730 return typed_test_info
;
732 void RegisterTests() {
733 for (auto& test_suite_info
: test_suite_infos_
) {
734 test_suite_info
->RegisterTests();
737 // Legacy API is deprecated but still available
738 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
739 template <class TestCase
>
740 ParameterizedTestCaseInfo
<TestCase
>* GetTestCasePatternHolder(
741 const char* test_case_name
, CodeLocation code_location
) {
742 return GetTestSuitePatternHolder
<TestCase
>(test_case_name
, code_location
);
745 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
748 using TestSuiteInfoContainer
= ::std::vector
<ParameterizedTestSuiteInfoBase
*>;
750 TestSuiteInfoContainer test_suite_infos_
;
752 ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry
&) =
754 ParameterizedTestSuiteRegistry
& operator=(
755 const ParameterizedTestSuiteRegistry
&) = delete;
758 // Keep track of what type-parameterized test suite are defined and
759 // where as well as which are intatiated. This allows susequently
760 // identifying suits that are defined but never used.
761 class TypeParameterizedTestSuiteRegistry
{
763 // Add a suite definition
764 void RegisterTestSuite(const char* test_suite_name
,
765 CodeLocation code_location
);
767 // Add an instantiation of a suit.
768 void RegisterInstantiation(const char* test_suite_name
);
770 // For each suit repored as defined but not reported as instantiation,
771 // emit a test that reports that fact (configurably, as an error).
772 void CheckForInstantiations();
775 struct TypeParameterizedTestSuiteInfo
{
776 explicit TypeParameterizedTestSuiteInfo(CodeLocation c
)
777 : code_location(c
), instantiated(false) {}
779 CodeLocation code_location
;
783 std::map
<std::string
, TypeParameterizedTestSuiteInfo
> suites_
;
786 } // namespace internal
788 // Forward declarations of ValuesIn(), which is implemented in
789 // include/gtest/gtest-param-test.h.
790 template <class Container
>
791 internal::ParamGenerator
<typename
Container::value_type
> ValuesIn(
792 const Container
& container
);
795 // Used in the Values() function to provide polymorphic capabilities.
797 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
799 template <typename
... Ts
>
802 explicit ValueArray(Ts
... v
) : v_(FlatTupleConstructTag
{}, std::move(v
)...) {}
804 template <typename T
>
805 operator ParamGenerator
<T
>() const { // NOLINT
806 return ValuesIn(MakeVector
<T
>(MakeIndexSequence
<sizeof...(Ts
)>()));
810 template <typename T
, size_t... I
>
811 std::vector
<T
> MakeVector(IndexSequence
<I
...>) const {
812 return std::vector
<T
>{static_cast<T
>(v_
.template Get
<I
>())...};
818 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
820 template <typename
... T
>
821 class CartesianProductGenerator
822 : public ParamGeneratorInterface
<::std::tuple
<T
...>> {
824 typedef ::std::tuple
<T
...> ParamType
;
826 CartesianProductGenerator(const std::tuple
<ParamGenerator
<T
>...>& g
)
828 ~CartesianProductGenerator() override
= default;
830 ParamIteratorInterface
<ParamType
>* Begin() const override
{
831 return new Iterator(this, generators_
, false);
833 ParamIteratorInterface
<ParamType
>* End() const override
{
834 return new Iterator(this, generators_
, true);
840 template <size_t... I
>
841 class IteratorImpl
<IndexSequence
<I
...>>
842 : public ParamIteratorInterface
<ParamType
> {
844 IteratorImpl(const ParamGeneratorInterface
<ParamType
>* base
,
845 const std::tuple
<ParamGenerator
<T
>...>& generators
,
848 begin_(std::get
<I
>(generators
).begin()...),
849 end_(std::get
<I
>(generators
).end()...),
850 current_(is_end
? end_
: begin_
) {
851 ComputeCurrentValue();
853 ~IteratorImpl() override
= default;
855 const ParamGeneratorInterface
<ParamType
>* BaseGenerator() const override
{
858 // Advance should not be called on beyond-of-range iterators
859 // so no component iterators must be beyond end of range, either.
860 void Advance() override
{
862 // Advance the last iterator.
863 ++std::get
<sizeof...(T
) - 1>(current_
);
864 // if that reaches end, propagate that up.
865 AdvanceIfEnd
<sizeof...(T
) - 1>();
866 ComputeCurrentValue();
868 ParamIteratorInterface
<ParamType
>* Clone() const override
{
869 return new IteratorImpl(*this);
872 const ParamType
* Current() const override
{ return current_value_
.get(); }
874 bool Equals(const ParamIteratorInterface
<ParamType
>& other
) const override
{
875 // Having the same base generator guarantees that the other
876 // iterator is of the same type and we can downcast.
877 GTEST_CHECK_(BaseGenerator() == other
.BaseGenerator())
878 << "The program attempted to compare iterators "
879 << "from different generators." << std::endl
;
880 const IteratorImpl
* typed_other
=
881 CheckedDowncastToActualType
<const IteratorImpl
>(&other
);
883 // We must report iterators equal if they both point beyond their
884 // respective ranges. That can happen in a variety of fashions,
885 // so we have to consult AtEnd().
886 if (AtEnd() && typed_other
->AtEnd()) return true;
890 (same
= same
&& std::get
<I
>(current_
) ==
891 std::get
<I
>(typed_other
->current_
))...};
897 template <size_t ThisI
>
898 void AdvanceIfEnd() {
899 if (std::get
<ThisI
>(current_
) != std::get
<ThisI
>(end_
)) return;
901 bool last
= ThisI
== 0;
903 // We are done. Nothing else to propagate.
907 constexpr size_t NextI
= ThisI
- (ThisI
!= 0);
908 std::get
<ThisI
>(current_
) = std::get
<ThisI
>(begin_
);
909 ++std::get
<NextI
>(current_
);
910 AdvanceIfEnd
<NextI
>();
913 void ComputeCurrentValue() {
915 current_value_
= std::make_shared
<ParamType
>(*std::get
<I
>(current_
)...);
920 (at_end
= at_end
|| std::get
<I
>(current_
) == std::get
<I
>(end_
))...};
925 const ParamGeneratorInterface
<ParamType
>* const base_
;
926 std::tuple
<typename ParamGenerator
<T
>::iterator
...> begin_
;
927 std::tuple
<typename ParamGenerator
<T
>::iterator
...> end_
;
928 std::tuple
<typename ParamGenerator
<T
>::iterator
...> current_
;
929 std::shared_ptr
<ParamType
> current_value_
;
932 using Iterator
= IteratorImpl
<typename MakeIndexSequence
<sizeof...(T
)>::type
>;
934 std::tuple
<ParamGenerator
<T
>...> generators_
;
937 template <class... Gen
>
938 class CartesianProductHolder
{
940 CartesianProductHolder(const Gen
&... g
) : generators_(g
...) {}
941 template <typename
... T
>
942 operator ParamGenerator
<::std::tuple
<T
...>>() const {
943 return ParamGenerator
<::std::tuple
<T
...>>(
944 new CartesianProductGenerator
<T
...>(generators_
));
948 std::tuple
<Gen
...> generators_
;
951 template <typename From
, typename To
>
952 class ParamGeneratorConverter
: public ParamGeneratorInterface
<To
> {
954 ParamGeneratorConverter(ParamGenerator
<From
> gen
) // NOLINT
955 : generator_(std::move(gen
)) {}
957 ParamIteratorInterface
<To
>* Begin() const override
{
958 return new Iterator(this, generator_
.begin(), generator_
.end());
960 ParamIteratorInterface
<To
>* End() const override
{
961 return new Iterator(this, generator_
.end(), generator_
.end());
965 class Iterator
: public ParamIteratorInterface
<To
> {
967 Iterator(const ParamGeneratorInterface
<To
>* base
, ParamIterator
<From
> it
,
968 ParamIterator
<From
> end
)
969 : base_(base
), it_(it
), end_(end
) {
970 if (it_
!= end_
) value_
= std::make_shared
<To
>(static_cast<To
>(*it_
));
972 ~Iterator() override
= default;
974 const ParamGeneratorInterface
<To
>* BaseGenerator() const override
{
977 void Advance() override
{
979 if (it_
!= end_
) value_
= std::make_shared
<To
>(static_cast<To
>(*it_
));
981 ParamIteratorInterface
<To
>* Clone() const override
{
982 return new Iterator(*this);
984 const To
* Current() const override
{ return value_
.get(); }
985 bool Equals(const ParamIteratorInterface
<To
>& other
) const override
{
986 // Having the same base generator guarantees that the other
987 // iterator is of the same type and we can downcast.
988 GTEST_CHECK_(BaseGenerator() == other
.BaseGenerator())
989 << "The program attempted to compare iterators "
990 << "from different generators." << std::endl
;
991 const ParamIterator
<From
> other_it
=
992 CheckedDowncastToActualType
<const Iterator
>(&other
)->it_
;
993 return it_
== other_it
;
997 Iterator(const Iterator
& other
) = default;
999 const ParamGeneratorInterface
<To
>* const base_
;
1000 ParamIterator
<From
> it_
;
1001 ParamIterator
<From
> end_
;
1002 std::shared_ptr
<To
> value_
;
1003 }; // class ParamGeneratorConverter::Iterator
1005 ParamGenerator
<From
> generator_
;
1006 }; // class ParamGeneratorConverter
1008 template <class Gen
>
1009 class ParamConverterGenerator
{
1011 ParamConverterGenerator(ParamGenerator
<Gen
> g
) // NOLINT
1012 : generator_(std::move(g
)) {}
1014 template <typename T
>
1015 operator ParamGenerator
<T
>() const { // NOLINT
1016 return ParamGenerator
<T
>(new ParamGeneratorConverter
<Gen
, T
>(generator_
));
1020 ParamGenerator
<Gen
> generator_
;
1023 } // namespace internal
1024 } // namespace testing
1026 #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_