📄 gtest-param-util.h
字号:
// having "return &*iterator_;" doesn't work. // value_ is updated here and not in Advance() because Advance() // can advance iterator_ beyond the end of the range, and we cannot // detect that fact. The client code, on the other hand, is // responsible for not calling Current() on an out-of-range iterator. 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 { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. 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) // The explicit constructor call suppresses a false warning // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface<T>(), base_(other.base_), iterator_(other.iterator_) {} const ParamGeneratorInterface<T>* const base_; typename ContainerType::const_iterator iterator_; // A cached value of *iterator_. We keep it here to allow access by // pointer in the wrapping iterator's operator->(). // value_ needs to be mutable to be accessed in Current(). // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr<const T> value_; }; const ContainerType container_;}; // class ValuesInIteratorRangeGenerator// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// Stores a parameter value and later creates tests parameterized with that// value.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);};// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// TestMetaFactoryBase is a base class for meta-factories that create// test factories for passing into MakeAndRegisterTestInfo function.template <class ParamType>class TestMetaFactoryBase { public: virtual ~TestMetaFactoryBase() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;};// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// TestMetaFactory creates test factories for passing into// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives// ownership of test factory pointer, same factory object cannot be passed// into that method twice. But ParameterizedTestCaseInfo is going to call// it for each Test/Parameter value combination. Thus it needs meta factory// creator class.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);};// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// ParameterizedTestCaseInfoBase is a generic interface// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase// accumulates test information provided by TEST_P macro invocations// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations// and uses that information to register all resulting test instances// in RegisterTests method. The ParameterizeTestCaseRegistry class holds// a collection of pointers to the ParameterizedTestCaseInfo objects// and calls RegisterTests() on each of them when asked.class ParameterizedTestCaseInfoBase { public: virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. virtual const String& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this // test case right before running them in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. virtual void RegisterTests() = 0; protected: ParameterizedTestCaseInfoBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);};// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P// macro invocations for a particular test case and generators// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that// test case. It registers tests with all values generated by all// generators when asked.template <class TestCase>class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { public: // ParamType and GeneratorCreationFunc are private types but are required // for declarations of public methods AddTestPattern() and // AddTestCaseInstantiation(). typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); explicit ParameterizedTestCaseInfo(const char* name) : test_case_name_(name) {} // Test case base name for display purposes. virtual const String& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } // TEST_P macro uses AddTestPattern() to record information // about a single test in a LocalTestInfo structure. // test_case_name is the base name of the test case (without invocation // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test case base name and DoBar is test base name. 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))); } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. int AddTestCaseInstantiation(const char* instantiation_name, GeneratorCreationFunc* func, const char* file, int line) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test case // test cases right before running tests in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. // UnitTest has a guard to prevent from calling this method more then once. 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->first; ParamGenerator<ParamType> generator((*gen_it->second)()); Message test_case_name_stream; if ( !instantiation_name.empty() ) test_case_name_stream << instantiation_name.c_str() << "/"; test_case_name_stream << test_info->test_case_base_name.c_str(); int i = 0; for (typename ParamGenerator<ParamType>::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; test_name_stream << test_info->test_base_name.c_str() << "/" << i; ::testing::internal::MakeAndRegisterTestInfo( test_case_name_stream.GetString().c_str(), test_name_stream.GetString().c_str(), "", // test_case_comment "", // comment; TODO(vladl@google.com): provide parameter value // representation. GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it } // for gen_it } // for test_it } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { TestInfo(const char* test_case_base_name, const char* test_base_name, TestMetaFactoryBase<ParamType>* test_meta_factory) : test_case_base_name(test_case_base_name), test_base_name(test_base_name), test_meta_factory(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; // Keeps pairs of <Instantiation name, Sequence generator creation function> // received from INSTANTIATE_TEST_CASE_P macros. typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> > InstantiationContainer; const String test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);}; // class ParameterizedTestCaseInfo// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.//// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P// macros use it to locate their corresponding ParameterizedTestCaseInfo// descriptors.class ParameterizedTestCaseRegistry { public: ParameterizedTestCaseRegistry() {} ~ParameterizedTestCaseRegistry() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { delete *it; } } // Looks up or creates and returns a structure containing information about // tests and instantiations of a particular test case. template <class TestCase> ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( const char* test_case_name, const char* file, int line) { 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>()) { // Complain about incorrect usage of Google Test facilities // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< ParameterizedTestCaseInfo<TestCase> >(*it); } break; } } if (typed_test_info == NULL) { typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); 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);};} // namespace internal} // namespace testing#endif // GTEST_HAS_PARAM_TEST#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -