123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
- #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
- #include <ctype.h>
- #include <iterator>
- #include <set>
- #include <utility>
- #include <vector>
- #include "gtest/internal/gtest-internal.h"
- #include "gtest/internal/gtest-linked_ptr.h"
- #include "gtest/internal/gtest-port.h"
- #include "gtest/gtest-printers.h"
- #if GTEST_HAS_PARAM_TEST
- namespace testing {
- template <class ParamType>
- struct TestParamInfo {
- TestParamInfo(const ParamType& a_param, size_t an_index) :
- param(a_param),
- index(an_index) {}
- ParamType param;
- size_t index;
- };
- struct PrintToStringParamName {
- template <class ParamType>
- std::string operator()(const TestParamInfo<ParamType>& info) const {
- return PrintToString(info.param);
- }
- };
- namespace internal {
- GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
- CodeLocation code_location);
- template <typename> class ParamGeneratorInterface;
- template <typename> class ParamGenerator;
- template <typename T>
- class ParamIteratorInterface {
- public:
- virtual ~ParamIteratorInterface() {}
-
-
-
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
-
-
-
-
- virtual void Advance() = 0;
-
-
- virtual ParamIteratorInterface* Clone() const = 0;
-
-
-
-
- virtual const T* Current() const = 0;
-
-
-
- virtual bool Equals(const ParamIteratorInterface& other) const = 0;
- };
- template <typename T>
- class ParamIterator {
- public:
- typedef T value_type;
- typedef const T& reference;
- typedef ptrdiff_t difference_type;
-
- ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
- ParamIterator& operator=(const ParamIterator& other) {
- if (this != &other)
- impl_.reset(other.impl_->Clone());
- return *this;
- }
- const T& operator*() const { return *impl_->Current(); }
- const T* operator->() const { return impl_->Current(); }
-
- ParamIterator& operator++() {
- impl_->Advance();
- return *this;
- }
-
- ParamIterator operator++(int ) {
- ParamIteratorInterface<T>* clone = impl_->Clone();
- impl_->Advance();
- return ParamIterator(clone);
- }
- bool operator==(const ParamIterator& other) const {
- return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
- }
- bool operator!=(const ParamIterator& other) const {
- return !(*this == other);
- }
- private:
- friend class ParamGenerator<T>;
- explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
- scoped_ptr<ParamIteratorInterface<T> > impl_;
- };
- template <typename T>
- class ParamGeneratorInterface {
- public:
- typedef T ParamType;
- virtual ~ParamGeneratorInterface() {}
-
- virtual ParamIteratorInterface<T>* Begin() const = 0;
- virtual ParamIteratorInterface<T>* End() const = 0;
- };
- template<typename T>
- class ParamGenerator {
- public:
- typedef ParamIterator<T> iterator;
- explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
- ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
- ParamGenerator& operator=(const ParamGenerator& other) {
- impl_ = other.impl_;
- return *this;
- }
- iterator begin() const { return iterator(impl_->Begin()); }
- iterator end() const { return iterator(impl_->End()); }
- private:
- linked_ptr<const ParamGeneratorInterface<T> > impl_;
- };
- template <typename T, typename IncrementT>
- class RangeGenerator : public ParamGeneratorInterface<T> {
- public:
- RangeGenerator(T begin, T end, IncrementT step)
- : begin_(begin), end_(end),
- step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
- virtual ~RangeGenerator() {}
- virtual ParamIteratorInterface<T>* Begin() const {
- return new Iterator(this, begin_, 0, step_);
- }
- virtual ParamIteratorInterface<T>* End() const {
- return new Iterator(this, end_, end_index_, step_);
- }
- private:
- class Iterator : public ParamIteratorInterface<T> {
- public:
- Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
- IncrementT step)
- : base_(base), value_(value), index_(index), step_(step) {}
- virtual ~Iterator() {}
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
- return base_;
- }
- virtual void Advance() {
- value_ = static_cast<T>(value_ + step_);
- index_++;
- }
- virtual ParamIteratorInterface<T>* Clone() const {
- return new Iterator(*this);
- }
- virtual const T* Current() const { return &value_; }
- virtual bool Equals(const ParamIteratorInterface<T>& other) const {
-
-
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const int other_index =
- CheckedDowncastToActualType<const Iterator>(&other)->index_;
- return index_ == other_index;
- }
- private:
- Iterator(const Iterator& other)
- : ParamIteratorInterface<T>(),
- base_(other.base_), value_(other.value_), index_(other.index_),
- step_(other.step_) {}
-
- void operator=(const Iterator& other);
- const ParamGeneratorInterface<T>* const base_;
- T value_;
- int index_;
- const IncrementT step_;
- };
- static int CalculateEndIndex(const T& begin,
- const T& end,
- const IncrementT& step) {
- int end_index = 0;
- for (T i = begin; i < end; i = static_cast<T>(i + step))
- end_index++;
- return end_index;
- }
-
- void operator=(const RangeGenerator& other);
- const T begin_;
- const T end_;
- const IncrementT step_;
-
-
- const int end_index_;
- };
- template <typename T>
- class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
- public:
- template <typename ForwardIterator>
- ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
- : container_(begin, end) {}
- virtual ~ValuesInIteratorRangeGenerator() {}
- virtual ParamIteratorInterface<T>* Begin() const {
- return new Iterator(this, container_.begin());
- }
- virtual ParamIteratorInterface<T>* End() const {
- return new Iterator(this, container_.end());
- }
- private:
- typedef typename ::std::vector<T> ContainerType;
- class Iterator : public ParamIteratorInterface<T> {
- public:
- Iterator(const ParamGeneratorInterface<T>* base,
- typename ContainerType::const_iterator iterator)
- : base_(base), iterator_(iterator) {}
- virtual ~Iterator() {}
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
- return base_;
- }
- virtual void Advance() {
- ++iterator_;
- value_.reset();
- }
- virtual ParamIteratorInterface<T>* Clone() const {
- return new Iterator(*this);
- }
-
-
-
-
-
-
-
- virtual const T* Current() const {
- if (value_.get() == NULL)
- value_.reset(new T(*iterator_));
- return value_.get();
- }
- virtual bool Equals(const ParamIteratorInterface<T>& other) const {
-
-
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- return iterator_ ==
- CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
- }
- private:
- Iterator(const Iterator& other)
-
-
- : ParamIteratorInterface<T>(),
- base_(other.base_),
- iterator_(other.iterator_) {}
- const ParamGeneratorInterface<T>* const base_;
- typename ContainerType::const_iterator iterator_;
-
-
-
-
-
- mutable scoped_ptr<const T> value_;
- };
-
- void operator=(const ValuesInIteratorRangeGenerator& other);
- const ContainerType container_;
- };
- template <class ParamType>
- std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
- Message name_stream;
- name_stream << info.index;
- return name_stream.GetString();
- }
- template <class ParamType, class ParamNameGenFunctor>
- ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
- return func;
- }
- template <class ParamType>
- struct ParamNameGenFunc {
- typedef std::string Type(const TestParamInfo<ParamType>&);
- };
- template <class ParamType>
- typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
- return DefaultParamName;
- }
- template <class TestClass>
- class ParameterizedTestFactory : public TestFactoryBase {
- public:
- typedef typename TestClass::ParamType ParamType;
- explicit ParameterizedTestFactory(ParamType parameter) :
- parameter_(parameter) {}
- virtual Test* CreateTest() {
- TestClass::SetParam(¶meter_);
- return new TestClass();
- }
- private:
- const ParamType parameter_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
- };
- template <class ParamType>
- class TestMetaFactoryBase {
- public:
- virtual ~TestMetaFactoryBase() {}
- virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
- };
- template <class TestCase>
- class TestMetaFactory
- : public TestMetaFactoryBase<typename TestCase::ParamType> {
- public:
- typedef typename TestCase::ParamType ParamType;
- TestMetaFactory() {}
- virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
- return new ParameterizedTestFactory<TestCase>(parameter);
- }
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
- };
- class ParameterizedTestCaseInfoBase {
- public:
- virtual ~ParameterizedTestCaseInfoBase() {}
-
- virtual const string& GetTestCaseName() const = 0;
-
- virtual TypeId GetTestCaseTypeId() const = 0;
-
-
-
-
- virtual void RegisterTests() = 0;
- protected:
- ParameterizedTestCaseInfoBase() {}
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
- };
- template <class TestCase>
- class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
- public:
-
-
-
- typedef typename TestCase::ParamType ParamType;
-
- typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
- typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
- explicit ParameterizedTestCaseInfo(
- const char* name, CodeLocation code_location)
- : test_case_name_(name), code_location_(code_location) {}
-
- virtual const string& GetTestCaseName() const { return test_case_name_; }
-
- virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
-
-
-
-
-
-
- void AddTestPattern(const char* test_case_name,
- const char* test_base_name,
- TestMetaFactoryBase<ParamType>* meta_factory) {
- tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
- test_base_name,
- meta_factory)));
- }
-
-
- int AddTestCaseInstantiation(const string& instantiation_name,
- GeneratorCreationFunc* func,
- ParamNameGeneratorFunc* name_func,
- const char* file,
- int line) {
- instantiations_.push_back(
- InstantiationInfo(instantiation_name, func, name_func, file, line));
- return 0;
- }
-
-
-
-
-
- virtual void RegisterTests() {
- for (typename TestInfoContainer::iterator test_it = tests_.begin();
- test_it != tests_.end(); ++test_it) {
- linked_ptr<TestInfo> test_info = *test_it;
- for (typename InstantiationContainer::iterator gen_it =
- instantiations_.begin(); gen_it != instantiations_.end();
- ++gen_it) {
- const string& instantiation_name = gen_it->name;
- ParamGenerator<ParamType> generator((*gen_it->generator)());
- ParamNameGeneratorFunc* name_func = gen_it->name_func;
- const char* file = gen_it->file;
- int line = gen_it->line;
- string test_case_name;
- if ( !instantiation_name.empty() )
- test_case_name = instantiation_name + "/";
- test_case_name += test_info->test_case_base_name;
- size_t i = 0;
- std::set<std::string> test_param_names;
- for (typename ParamGenerator<ParamType>::iterator param_it =
- generator.begin();
- param_it != generator.end(); ++param_it, ++i) {
- Message test_name_stream;
- std::string param_name = name_func(
- TestParamInfo<ParamType>(*param_it, i));
- GTEST_CHECK_(IsValidParamName(param_name))
- << "Parameterized test name '" << param_name
- << "' is invalid, in " << file
- << " line " << line << std::endl;
- GTEST_CHECK_(test_param_names.count(param_name) == 0)
- << "Duplicate parameterized test name '" << param_name
- << "', in " << file << " line " << line << std::endl;
- test_param_names.insert(param_name);
- test_name_stream << test_info->test_base_name << "/" << param_name;
- MakeAndRegisterTestInfo(
- test_case_name.c_str(),
- test_name_stream.GetString().c_str(),
- NULL,
- PrintToString(*param_it).c_str(),
- code_location_,
- GetTestCaseTypeId(),
- TestCase::SetUpTestCase,
- TestCase::TearDownTestCase,
- test_info->test_meta_factory->CreateTestFactory(*param_it));
- }
- }
- }
- }
- private:
-
-
- struct TestInfo {
- TestInfo(const char* a_test_case_base_name,
- const char* a_test_base_name,
- TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
- test_case_base_name(a_test_case_base_name),
- test_base_name(a_test_base_name),
- test_meta_factory(a_test_meta_factory) {}
- const string test_case_base_name;
- const string test_base_name;
- const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
- };
- typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
-
-
-
- struct InstantiationInfo {
- InstantiationInfo(const std::string &name_in,
- GeneratorCreationFunc* generator_in,
- ParamNameGeneratorFunc* name_func_in,
- const char* file_in,
- int line_in)
- : name(name_in),
- generator(generator_in),
- name_func(name_func_in),
- file(file_in),
- line(line_in) {}
- std::string name;
- GeneratorCreationFunc* generator;
- ParamNameGeneratorFunc* name_func;
- const char* file;
- int line;
- };
- typedef ::std::vector<InstantiationInfo> InstantiationContainer;
- static bool IsValidParamName(const std::string& name) {
-
- if (name.empty())
- return false;
-
- for (std::string::size_type index = 0; index < name.size(); ++index) {
- if (!isalnum(name[index]) && name[index] != '_')
- return false;
- }
- return true;
- }
- const string test_case_name_;
- CodeLocation code_location_;
- TestInfoContainer tests_;
- InstantiationContainer instantiations_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
- };
- class ParameterizedTestCaseRegistry {
- public:
- ParameterizedTestCaseRegistry() {}
- ~ParameterizedTestCaseRegistry() {
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- delete *it;
- }
- }
-
-
- template <class TestCase>
- ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
- const char* test_case_name,
- CodeLocation code_location) {
- ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- if ((*it)->GetTestCaseName() == test_case_name) {
- if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
-
-
-
- ReportInvalidTestCaseType(test_case_name, code_location);
- posix::Abort();
- } else {
-
-
-
- typed_test_info = CheckedDowncastToActualType<
- ParameterizedTestCaseInfo<TestCase> >(*it);
- }
- break;
- }
- }
- if (typed_test_info == NULL) {
- typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
- test_case_name, code_location);
- test_case_infos_.push_back(typed_test_info);
- }
- return typed_test_info;
- }
- void RegisterTests() {
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- (*it)->RegisterTests();
- }
- }
- private:
- typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
- TestCaseInfoContainer test_case_infos_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
- };
- }
- }
- #endif
- #endif
|