34 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 35 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 44 #include "gtest/internal/gtest-internal.h" 45 #include "gtest/internal/gtest-linked_ptr.h" 46 #include "gtest/internal/gtest-port.h" 47 #include "gtest/gtest-printers.h" 49 #if GTEST_HAS_PARAM_TEST 63 const char * file,
int line);
65 template <
typename>
class ParamGeneratorInterface;
66 template <
typename>
class ParamGenerator;
71 class ParamIteratorInterface
78 virtual const ParamGeneratorInterface<T> *
BaseGenerator()
const = 0;
86 virtual ParamIteratorInterface *
Clone()
const = 0;
91 virtual const T *
Current()
const = 0;
95 virtual bool Equals(
const ParamIteratorInterface & other)
const = 0;
101 template <
typename T>
105 typedef T value_type;
106 typedef const T & reference;
107 typedef ptrdiff_t difference_type;
110 ParamIterator(
const ParamIterator & other) : impl_(other.impl_->
Clone()) {}
111 ParamIterator & operator=(
const ParamIterator & other)
114 { impl_.reset(other.impl_->Clone()); }
119 const T & operator*()
const {
return *impl_->Current(); }
120 const T * operator->()
const {
return impl_->Current(); }
122 ParamIterator & operator++()
128 ParamIterator operator++(
int )
130 ParamIteratorInterface<T> * clone = impl_->Clone();
132 return ParamIterator(clone);
134 bool operator==(
const ParamIterator & other)
const 136 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
138 bool operator!=(
const ParamIterator & other)
const 140 return !(*
this == other);
144 friend class ParamGenerator<T>;
145 explicit ParamIterator(ParamIteratorInterface<T> * impl) : impl_(impl) {}
146 scoped_ptr<ParamIteratorInterface<T> > impl_;
151 template <
typename T>
152 class ParamGeneratorInterface
157 virtual ~ParamGeneratorInterface() {}
160 virtual ParamIteratorInterface<T> * Begin()
const = 0;
161 virtual ParamIteratorInterface<T> * End()
const = 0;
173 typedef ParamIterator<T> iterator;
175 explicit ParamGenerator(ParamGeneratorInterface<T> * impl) : impl_(impl) {}
176 ParamGenerator(
const ParamGenerator & other) : impl_(other.impl_) {}
178 ParamGenerator & operator=(
const ParamGenerator & other)
184 iterator begin()
const {
return iterator(impl_->Begin()); }
185 iterator
end()
const {
return iterator(impl_->End()); }
188 linked_ptr<const ParamGeneratorInterface<T> > impl_;
195 template <
typename T,
typename IncrementT>
196 class RangeGenerator :
public ParamGeneratorInterface<T>
199 RangeGenerator(T begin, T
end, IncrementT step)
200 : begin_(begin), end_(end),
201 step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
202 virtual ~RangeGenerator() {}
204 virtual ParamIteratorInterface<T> * Begin()
const 206 return new Iterator(
this, begin_, 0, step_);
208 virtual ParamIteratorInterface<T> * End()
const 210 return new Iterator(
this, end_, end_index_, step_);
214 class Iterator :
public ParamIteratorInterface<T>
217 Iterator(
const ParamGeneratorInterface<T> * base, T value,
int index,
219 : base_(base), value_(value), index_(index), step_(step) {}
220 virtual ~Iterator() {}
222 virtual const ParamGeneratorInterface<T> *
BaseGenerator()
const 228 value_ = value_ + step_;
231 virtual ParamIteratorInterface<T> *
Clone()
const 233 return new Iterator(*
this);
235 virtual const T *
Current()
const {
return &value_; }
236 virtual bool Equals(
const ParamIteratorInterface<T> & other)
const 241 <<
"The program attempted to compare iterators " 242 <<
"from different generators." << std::endl;
243 const int other_index =
244 CheckedDowncastToActualType<const Iterator>(&other)->index_;
245 return index_ == other_index;
249 Iterator(
const Iterator & other)
250 : ParamIteratorInterface<T>(),
251 base_(other.base_), value_(other.value_), index_(other.index_),
252 step_(other.step_) {}
255 void operator=(
const Iterator & other);
257 const ParamGeneratorInterface<T> *
const base_;
260 const IncrementT step_;
263 static int CalculateEndIndex(
const T & begin,
265 const IncrementT & step)
269 for (T i = begin; i <
end; i = 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>
295 template <
typename ForwardIterator>
296 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator
end)
297 : container_(begin, end) {}
298 virtual ~ValuesInIteratorRangeGenerator() {}
300 virtual ParamIteratorInterface<T> * Begin()
const 302 return new Iterator(
this, container_.begin());
304 virtual ParamIteratorInterface<T> * End()
const 306 return new Iterator(
this, container_.end());
310 typedef typename ::std::vector<T> ContainerType;
312 class Iterator :
public ParamIteratorInterface<T>
315 Iterator(
const ParamGeneratorInterface<T> * base,
316 typename ContainerType::const_iterator iterator)
317 : base_(base), iterator_(iterator) {}
318 virtual ~Iterator() {}
320 virtual const ParamGeneratorInterface<T> *
BaseGenerator()
const 329 virtual ParamIteratorInterface<T> *
Clone()
const 331 return new Iterator(*
this);
340 virtual const T *
Current()
const 342 if (value_.get() == NULL)
343 { value_.reset(
new T(*iterator_)); }
347 virtual bool Equals(
const ParamIteratorInterface<T> & other)
const 352 <<
"The program attempted to compare iterators " 353 <<
"from different generators." << std::endl;
355 CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
359 Iterator(
const Iterator & other)
362 : ParamIteratorInterface<T>(),
364 iterator_(other.iterator_) {}
366 const ParamGeneratorInterface<T> *
const base_;
367 typename ContainerType::const_iterator iterator_;
373 mutable scoped_ptr<const T> value_;
377 void operator=(
const ValuesInIteratorRangeGenerator & other);
379 const ContainerType container_;
386 template <
class TestClass>
387 class ParameterizedTestFactory :
public TestFactoryBase
390 typedef typename TestClass::ParamType ParamType;
391 explicit ParameterizedTestFactory(ParamType parameter) :
392 parameter_(parameter) {}
393 virtual Test * CreateTest()
395 TestClass::SetParam(¶meter_);
396 return new TestClass();
400 const ParamType parameter_;
409 template <
class ParamType>
410 class TestMetaFactoryBase
413 virtual ~TestMetaFactoryBase() {}
415 virtual TestFactoryBase * CreateTestFactory(ParamType parameter) = 0;
426 template <
class TestCase>
427 class TestMetaFactory
428 :
public TestMetaFactoryBase<typename TestCase::ParamType>
431 typedef typename TestCase::ParamType ParamType;
435 virtual TestFactoryBase * CreateTestFactory(ParamType parameter)
437 return new ParameterizedTestFactory<TestCase>(parameter);
454 class ParameterizedTestCaseInfoBase
457 virtual ~ParameterizedTestCaseInfoBase() {}
460 virtual const string & GetTestCaseName()
const = 0;
462 virtual TypeId GetTestCaseTypeId()
const = 0;
467 virtual void RegisterTests() = 0;
470 ParameterizedTestCaseInfoBase() {}
483 template <
class TestCase>
484 class ParameterizedTestCaseInfo :
public ParameterizedTestCaseInfoBase
490 typedef typename TestCase::ParamType ParamType;
492 typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
494 explicit ParameterizedTestCaseInfo(
const char *
name)
495 : test_case_name_(name) {}
498 virtual const string & GetTestCaseName()
const {
return test_case_name_; }
500 virtual TypeId GetTestCaseTypeId()
const {
return GetTypeId<TestCase>(); }
507 void AddTestPattern(
const char * test_case_name,
508 const char * test_base_name,
509 TestMetaFactoryBase<ParamType> * meta_factory)
511 tests_.push_back(linked_ptr<TestInfo>(
new TestInfo(test_case_name,
517 int AddTestCaseInstantiation(
const string & instantiation_name,
518 GeneratorCreationFunc * func,
522 instantiations_.push_back(::std::make_pair(instantiation_name, func));
530 virtual void RegisterTests()
532 for (
typename TestInfoContainer::iterator test_it = tests_.begin();
533 test_it != tests_.end(); ++test_it)
535 linked_ptr<TestInfo> test_info = *test_it;
537 for (
typename InstantiationContainer::iterator gen_it =
538 instantiations_.begin(); gen_it != instantiations_.end();
541 const string & instantiation_name = gen_it->first;
542 ParamGenerator<ParamType> generator((*gen_it->second)());
544 string test_case_name;
546 if (!instantiation_name.empty())
547 { test_case_name = instantiation_name +
"/"; }
549 test_case_name += test_info->test_case_base_name;
555 param_it != generator.end(); ++param_it, ++i)
558 test_name_stream << test_info->test_base_name <<
"/" << i;
560 test_case_name.c_str(),
561 test_name_stream.GetString().c_str(),
565 TestCase::SetUpTestCase,
566 TestCase::TearDownTestCase,
567 test_info->test_meta_factory->CreateTestFactory(*param_it));
578 TestInfo(
const char * a_test_case_base_name,
579 const char * a_test_base_name,
580 TestMetaFactoryBase<ParamType> * a_test_meta_factory) :
581 test_case_base_name(a_test_case_base_name),
582 test_base_name(a_test_base_name),
583 test_meta_factory(a_test_meta_factory) {}
585 const string test_case_base_name;
586 const string test_base_name;
587 const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
589 typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
592 typedef ::std::vector<std::pair<string, GeneratorCreationFunc *> >
593 InstantiationContainer;
595 const string test_case_name_;
596 TestInfoContainer tests_;
597 InstantiationContainer instantiations_;
608 class ParameterizedTestCaseRegistry
611 ParameterizedTestCaseRegistry() {}
612 ~ParameterizedTestCaseRegistry()
614 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
615 it != test_case_infos_.end(); ++it)
623 template <
class TestCase>
624 ParameterizedTestCaseInfo<TestCase> * GetTestCasePatternHolder(
625 const char * test_case_name,
629 ParameterizedTestCaseInfo<TestCase> * typed_test_info = NULL;
631 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
632 it != test_case_infos_.end(); ++it)
634 if ((*it)->GetTestCaseName() == test_case_name)
636 if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>())
651 ParameterizedTestCaseInfo<TestCase> > (*it);
658 if (typed_test_info == NULL)
660 typed_test_info =
new ParameterizedTestCaseInfo<TestCase>(test_case_name);
661 test_case_infos_.push_back(typed_test_info);
664 return typed_test_info;
668 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
669 it != test_case_infos_.end(); ++it)
671 (*it)->RegisterTests();
676 typedef ::std::vector<ParameterizedTestCaseInfoBase *> TestCaseInfoContainer;
678 TestCaseInfoContainer test_case_infos_;
686 #endif // GTEST_HAS_PARAM_TEST 688 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
virtual ~ParamIteratorInterface()
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)
::std::string PrintToString(const T &value)
Derived * CheckedDowncastToActualType(Base *base)
virtual bool Equals(const ParamIteratorInterface &other) const =0
bool operator==(T *ptr, const linked_ptr< T > &x)
TestInfo * MakeAndRegisterTestInfo(const char *test_case_name, const char *name, const char *type_param, const char *value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase *factory)
void ReportInvalidTestCaseType(const char *test_case_name, const char *file, int line)
virtual const T * Current() const =0
ParamIterator< T > iterator
virtual const ParamGeneratorInterface< T > * BaseGenerator() const =0
virtual ParamIteratorInterface * Clone() const =0
bool operator!=(T *ptr, const linked_ptr< T > &x)
#define GTEST_CHECK_(condition)