34 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 35 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 52 #if GTEST_HAS_PARAM_TEST 58 template <
class ParamType>
59 struct TestParamInfo {
60 TestParamInfo(
const ParamType& a_param,
size_t an_index) :
69 struct PrintToStringParamName {
70 template <
class ParamType>
71 std::string operator()(
const TestParamInfo<ParamType>& info)
const {
84 GTEST_API_ void ReportInvalidTestCaseType(
const char* test_case_name,
85 CodeLocation code_location);
87 template <
typename>
class ParamGeneratorInterface;
88 template <
typename>
class ParamGenerator;
93 class ParamIteratorInterface {
95 virtual ~ParamIteratorInterface() {}
99 virtual const ParamGeneratorInterface<T>* BaseGenerator()
const = 0;
104 virtual void Advance() = 0;
107 virtual ParamIteratorInterface* Clone()
const = 0;
112 virtual const T* Current()
const = 0;
116 virtual bool Equals(
const ParamIteratorInterface& other)
const = 0;
122 template <
typename T>
123 class ParamIterator {
125 typedef T value_type;
126 typedef const T& reference;
127 typedef ptrdiff_t difference_type;
130 ParamIterator(
const ParamIterator& other) : impl_(other.impl_->Clone()) {}
131 ParamIterator& operator=(
const ParamIterator& other) {
133 impl_.reset(other.impl_->Clone());
137 const T& operator*()
const {
return *impl_->Current(); }
138 const T* operator->()
const {
return impl_->Current(); }
140 ParamIterator& operator++() {
145 ParamIterator operator++(
int ) {
146 ParamIteratorInterface<T>* clone = impl_->Clone();
148 return ParamIterator(clone);
150 bool operator==(
const ParamIterator& other)
const {
151 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
153 bool operator!=(
const ParamIterator& other)
const {
154 return !(*
this == other);
158 friend class ParamGenerator<T>;
159 explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
160 scoped_ptr<ParamIteratorInterface<T> > impl_;
165 template <
typename T>
166 class ParamGeneratorInterface {
170 virtual ~ParamGeneratorInterface() {}
173 virtual ParamIteratorInterface<T>* Begin()
const = 0;
174 virtual ParamIteratorInterface<T>* End()
const = 0;
183 class ParamGenerator {
185 typedef ParamIterator<T> iterator;
187 explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
188 ParamGenerator(
const ParamGenerator& other) : impl_(other.impl_) {}
190 ParamGenerator& operator=(
const ParamGenerator& other) {
195 iterator begin()
const {
return iterator(impl_->Begin()); }
196 iterator end()
const {
return iterator(impl_->End()); }
199 linked_ptr<const ParamGeneratorInterface<T> > impl_;
206 template <
typename T,
typename IncrementT>
207 class RangeGenerator :
public ParamGeneratorInterface<T> {
209 RangeGenerator(T begin, T end, IncrementT step)
210 : begin_(begin), end_(end),
211 step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
212 virtual ~RangeGenerator() {}
214 virtual ParamIteratorInterface<T>* Begin()
const {
215 return new Iterator(
this, begin_, 0, step_);
217 virtual ParamIteratorInterface<T>* End()
const {
218 return new Iterator(
this, end_, end_index_, step_);
222 class Iterator :
public ParamIteratorInterface<T> {
224 Iterator(
const ParamGeneratorInterface<T>* base, T value,
int index,
226 : base_(base), value_(value), index_(index), step_(step) {}
227 virtual ~Iterator() {}
229 virtual const ParamGeneratorInterface<T>* BaseGenerator()
const {
232 virtual void Advance() {
233 value_ =
static_cast<T
>(value_ + step_);
236 virtual ParamIteratorInterface<T>* Clone()
const {
237 return new Iterator(*
this);
239 virtual const T* Current()
const {
return &value_; }
240 virtual bool Equals(
const ParamIteratorInterface<T>& other)
const {
244 <<
"The program attempted to compare iterators " 245 <<
"from different generators." << std::endl;
246 const int other_index =
247 CheckedDowncastToActualType<const Iterator>(&other)->index_;
248 return index_ == other_index;
252 Iterator(
const Iterator& other)
253 : ParamIteratorInterface<T>(),
254 base_(other.base_), value_(other.value_), index_(other.index_),
255 step_(other.step_) {}
258 void operator=(
const Iterator& other);
260 const ParamGeneratorInterface<T>*
const base_;
263 const IncrementT step_;
266 static int CalculateEndIndex(
const T& begin,
268 const IncrementT& step) {
270 for (T i = begin; i < end; i = static_cast<T>(i + step))
276 void operator=(
const RangeGenerator& other);
280 const IncrementT step_;
283 const int end_index_;
291 template <
typename T>
292 class ValuesInIteratorRangeGenerator :
public ParamGeneratorInterface<T> {
294 template <
typename ForwardIterator>
295 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
296 : container_(begin, end) {}
297 virtual ~ValuesInIteratorRangeGenerator() {}
299 virtual ParamIteratorInterface<T>* Begin()
const {
300 return new Iterator(
this, container_.begin());
302 virtual ParamIteratorInterface<T>* End()
const {
303 return new Iterator(
this, container_.end());
307 typedef typename ::std::vector<T> ContainerType;
309 class Iterator :
public ParamIteratorInterface<T> {
311 Iterator(
const ParamGeneratorInterface<T>* base,
312 typename ContainerType::const_iterator iterator)
313 : base_(base), iterator_(iterator) {}
314 virtual ~Iterator() {}
316 virtual const ParamGeneratorInterface<T>* BaseGenerator()
const {
319 virtual void Advance() {
323 virtual ParamIteratorInterface<T>* Clone()
const {
324 return new Iterator(*
this);
333 virtual const T* Current()
const {
334 if (value_.get() == NULL)
335 value_.reset(
new T(*iterator_));
338 virtual bool Equals(
const ParamIteratorInterface<T>& other)
const {
342 <<
"The program attempted to compare iterators " 343 <<
"from different generators." << std::endl;
345 CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
349 Iterator(
const Iterator& other)
352 : ParamIteratorInterface<T>(),
354 iterator_(other.iterator_) {}
356 const ParamGeneratorInterface<T>*
const base_;
357 typename ContainerType::const_iterator iterator_;
363 mutable scoped_ptr<const T> value_;
367 void operator=(
const ValuesInIteratorRangeGenerator& other);
369 const ContainerType container_;
376 template <
class ParamType>
377 std::string DefaultParamName(
const TestParamInfo<ParamType>& info) {
379 name_stream << info.index;
380 return name_stream.GetString();
388 template <
class ParamType,
class ParamNameGenFunctor>
389 ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
393 template <
class ParamType>
394 struct ParamNameGenFunc {
398 template <
class ParamType>
400 return DefaultParamName;
407 template <
class TestClass>
408 class ParameterizedTestFactory :
public TestFactoryBase {
410 typedef typename TestClass::ParamType ParamType;
411 explicit ParameterizedTestFactory(ParamType parameter) :
412 parameter_(parameter) {}
413 virtual Test* CreateTest() {
414 TestClass::SetParam(¶meter_);
415 return new TestClass();
419 const ParamType parameter_;
428 template <
class ParamType>
429 class TestMetaFactoryBase {
431 virtual ~TestMetaFactoryBase() {}
433 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
444 template <
class TestCase>
445 class TestMetaFactory
446 :
public TestMetaFactoryBase<typename TestCase::ParamType> {
448 typedef typename TestCase::ParamType ParamType;
452 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
453 return new ParameterizedTestFactory<TestCase>(parameter);
470 class ParameterizedTestCaseInfoBase {
472 virtual ~ParameterizedTestCaseInfoBase() {}
475 virtual const string& GetTestCaseName()
const = 0;
477 virtual TypeId GetTestCaseTypeId()
const = 0;
482 virtual void RegisterTests() = 0;
485 ParameterizedTestCaseInfoBase() {}
498 template <
class TestCase>
499 class ParameterizedTestCaseInfo :
public ParameterizedTestCaseInfoBase {
504 typedef typename TestCase::ParamType ParamType;
506 typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
509 explicit ParameterizedTestCaseInfo(
510 const char* name, CodeLocation code_location)
511 : test_case_name_(name), code_location_(code_location) {}
514 virtual const string& GetTestCaseName()
const {
return test_case_name_; }
516 virtual TypeId GetTestCaseTypeId()
const {
return GetTypeId<TestCase>(); }
523 void AddTestPattern(
const char* test_case_name,
524 const char* test_base_name,
525 TestMetaFactoryBase<ParamType>* meta_factory) {
526 tests_.push_back(linked_ptr<TestInfo>(
new TestInfo(test_case_name,
532 int AddTestCaseInstantiation(
const string& instantiation_name,
533 GeneratorCreationFunc* func,
534 ParamNameGeneratorFunc* name_func,
537 instantiations_.push_back(
538 InstantiationInfo(instantiation_name, func, name_func, file, line));
546 virtual void RegisterTests() {
547 for (
typename TestInfoContainer::iterator test_it = tests_.begin();
548 test_it != tests_.end(); ++test_it) {
549 linked_ptr<TestInfo> test_info = *test_it;
550 for (
typename InstantiationContainer::iterator gen_it =
551 instantiations_.begin(); gen_it != instantiations_.end();
553 const string& instantiation_name = gen_it->name;
554 ParamGenerator<ParamType> generator((*gen_it->generator)());
555 ParamNameGeneratorFunc* name_func = gen_it->name_func;
556 const char* file = gen_it->file;
557 int line = gen_it->line;
559 string test_case_name;
560 if ( !instantiation_name.empty() )
561 test_case_name = instantiation_name +
"/";
562 test_case_name += test_info->test_case_base_name;
565 std::set<std::string> test_param_names;
566 for (
typename ParamGenerator<ParamType>::iterator param_it =
568 param_it != generator.end(); ++param_it, ++i) {
569 Message test_name_stream;
572 TestParamInfo<ParamType>(*param_it, i));
575 <<
"Parameterized test name '" << param_name
576 <<
"' is invalid, in " << file
577 <<
" line " << line << std::endl;
580 <<
"Duplicate parameterized test name '" << param_name
581 <<
"', in " << file <<
" line " << line << std::endl;
583 test_param_names.insert(param_name);
585 test_name_stream << test_info->test_base_name <<
"/" << param_name;
587 test_case_name.c_str(),
588 test_name_stream.GetString().c_str(),
593 TestCase::SetUpTestCase,
594 TestCase::TearDownTestCase,
595 test_info->test_meta_factory->CreateTestFactory(*param_it));
605 TestInfo(
const char* a_test_case_base_name,
606 const char* a_test_base_name,
607 TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
608 test_case_base_name(a_test_case_base_name),
609 test_base_name(a_test_base_name),
610 test_meta_factory(a_test_meta_factory) {}
612 const string test_case_base_name;
613 const string test_base_name;
614 const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
616 typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
620 struct InstantiationInfo {
622 GeneratorCreationFunc* generator_in,
623 ParamNameGeneratorFunc* name_func_in,
627 generator(generator_in),
628 name_func(name_func_in),
633 GeneratorCreationFunc* generator;
634 ParamNameGeneratorFunc* name_func;
638 typedef ::std::vector<InstantiationInfo> InstantiationContainer;
640 static bool IsValidParamName(
const std::string& name) {
647 if (!isalnum(name[
index]) && name[
index] !=
'_')
654 const string test_case_name_;
655 CodeLocation code_location_;
656 TestInfoContainer tests_;
657 InstantiationContainer instantiations_;
668 class ParameterizedTestCaseRegistry {
670 ParameterizedTestCaseRegistry() {}
671 ~ParameterizedTestCaseRegistry() {
672 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
673 it != test_case_infos_.end(); ++it) {
680 template <
class TestCase>
681 ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
682 const char* test_case_name,
683 CodeLocation code_location) {
684 ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
685 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
686 it != test_case_infos_.end(); ++it) {
687 if ((*it)->GetTestCaseName() == test_case_name) {
688 if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
692 ReportInvalidTestCaseType(test_case_name, code_location);
699 ParameterizedTestCaseInfo<TestCase> >(*it);
704 if (typed_test_info == NULL) {
705 typed_test_info =
new ParameterizedTestCaseInfo<TestCase>(
706 test_case_name, code_location);
707 test_case_infos_.push_back(typed_test_info);
709 return typed_test_info;
711 void RegisterTests() {
712 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
713 it != test_case_infos_.end(); ++it) {
714 (*it)->RegisterTests();
719 typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
721 TestCaseInfoContainer test_case_infos_;
729 #endif // GTEST_HAS_PARAM_TEST 731 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
GTEST_API_ TestInfo * MakeAndRegisterTestInfo(const char *test_case_name, const char *name, const char *type_param, const char *value_param, CodeLocation code_location, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase *factory)
Definition: gmock-actions.h:53
::std::string PrintToString(const T &value)
Definition: gtest-printers.h:980
::std::string string
Definition: gtest-port.h:1097
bool operator==(const BlockingPolicy &lhs, const BlockingPolicy &rhs)
#define GTEST_API_
Definition: gtest-port.h:934
bool operator!=(const BlockingPolicy &lhs, const BlockingPolicy &rhs)
const void * TypeId
Definition: gtest-internal.h:429
#define GTEST_CHECK_(condition)
Definition: gtest-port.h:1295
void Abort()
Definition: gtest-port.h:2410
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)
Definition: gtest-port.h:874
Type
Definition: Type.h:26
Derived * CheckedDowncastToActualType(Base *base)
Definition: gtest-port.h:1392