|
|
|
@ -34,7 +34,10 @@ |
|
|
|
|
#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> |
|
|
|
|
|
|
|
|
@ -49,6 +52,27 @@ |
|
|
|
|
#if GTEST_HAS_PARAM_TEST |
|
|
|
|
|
|
|
|
|
namespace testing { |
|
|
|
|
|
|
|
|
|
// Input to a parameterized test name generator, describing a test parameter.
|
|
|
|
|
// Consists of the parameter value and the integer parameter index.
|
|
|
|
|
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; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// A builtin parameterized test name generator which returns the result of
|
|
|
|
|
// testing::PrintToString.
|
|
|
|
|
struct PrintToStringParamName { |
|
|
|
|
template <class ParamType> |
|
|
|
|
std::string operator()(const TestParamInfo<ParamType>& info) const { |
|
|
|
|
return PrintToString(info.param); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
namespace internal { |
|
|
|
|
|
|
|
|
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
|
|
@ -345,6 +369,37 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { |
|
|
|
|
const ContainerType container_; |
|
|
|
|
}; // class ValuesInIteratorRangeGenerator
|
|
|
|
|
|
|
|
|
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
|
|
|
//
|
|
|
|
|
// Default parameterized test name generator, returns a string containing the
|
|
|
|
|
// integer test parameter index.
|
|
|
|
|
template <class ParamType> |
|
|
|
|
std::string DefaultParamName(const TestParamInfo<ParamType>& info) { |
|
|
|
|
Message name_stream; |
|
|
|
|
name_stream << info.index; |
|
|
|
|
return name_stream.GetString(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
|
|
|
//
|
|
|
|
|
// Parameterized test name overload helpers, which help the
|
|
|
|
|
// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
|
|
|
|
|
// test name generator and user param name generator.
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
|
|
|
//
|
|
|
|
|
// Stores a parameter value and later creates tests parameterized with that
|
|
|
|
@ -449,6 +504,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { |
|
|
|
|
typedef typename TestCase::ParamType ParamType; |
|
|
|
|
// A function that returns an instance of appropriate generator type.
|
|
|
|
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); |
|
|
|
|
typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc; |
|
|
|
|
|
|
|
|
|
explicit ParameterizedTestCaseInfo( |
|
|
|
|
const char* name, CodeLocation code_location) |
|
|
|
@ -475,9 +531,11 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { |
|
|
|
|
// about a generator.
|
|
|
|
|
int AddTestCaseInstantiation(const string& instantiation_name, |
|
|
|
|
GeneratorCreationFunc* func, |
|
|
|
|
const char* /* file */, |
|
|
|
|
int /* line */) { |
|
|
|
|
instantiations_.push_back(::std::make_pair(instantiation_name, func)); |
|
|
|
|
ParamNameGeneratorFunc* name_func, |
|
|
|
|
const char* file, |
|
|
|
|
int line) { |
|
|
|
|
instantiations_.push_back( |
|
|
|
|
InstantiationInfo(instantiation_name, func, name_func, file, line)); |
|
|
|
|
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
|
|
|
|
@ -492,20 +550,39 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { |
|
|
|
|
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)()); |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
int i = 0; |
|
|
|
|
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; |
|
|
|
|
test_name_stream << test_info->test_base_name << "/" << i; |
|
|
|
|
|
|
|
|
|
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(), |
|
|
|
@ -537,10 +614,42 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { |
|
|
|
|
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; |
|
|
|
|
// Records data received from INSTANTIATE_TEST_CASE_P macros:
|
|
|
|
|
// <Instantiation name, Sequence generator creation function,
|
|
|
|
|
// Name generator function, Source file, Source line>
|
|
|
|
|
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) { |
|
|
|
|
// Check for empty string
|
|
|
|
|
if (name.empty()) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// Check for invalid characters
|
|
|
|
|
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_; |
|
|
|
|