|
|
|
@ -606,6 +606,37 @@ inline std::string GetPrefixUntilComma(const char* str) { |
|
|
|
|
void SplitString(const ::std::string& str, char delimiter, |
|
|
|
|
::std::vector< ::std::string>* dest); |
|
|
|
|
|
|
|
|
|
// The default argument to the template below for the case when the user does
|
|
|
|
|
// not provide a name generator.
|
|
|
|
|
struct DefaultNameGenerator { |
|
|
|
|
template <typename T> |
|
|
|
|
static std::string GetName(int i) { |
|
|
|
|
return StreamableToString(i); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template <typename Provided = DefaultNameGenerator> |
|
|
|
|
struct NameGeneratorSelector { |
|
|
|
|
typedef Provided type; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template <typename NameGenerator> |
|
|
|
|
void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {} |
|
|
|
|
|
|
|
|
|
template <typename NameGenerator, typename Types> |
|
|
|
|
void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) { |
|
|
|
|
result->push_back(NameGenerator::template GetName<typename Types::Head>(i)); |
|
|
|
|
GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result, |
|
|
|
|
i + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename NameGenerator, typename Types> |
|
|
|
|
std::vector<std::string> GenerateNames() { |
|
|
|
|
std::vector<std::string> result; |
|
|
|
|
GenerateNamesRecursively<NameGenerator>(Types(), &result, 0); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
|
|
|
|
|
// registers a list of type-parameterized tests with Google Test. The
|
|
|
|
|
// return value is insignificant - we just need to return something
|
|
|
|
@ -620,10 +651,10 @@ class TypeParameterizedTest { |
|
|
|
|
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
|
|
|
|
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
|
|
|
|
// length of Types.
|
|
|
|
|
static bool Register(const char* prefix, |
|
|
|
|
const CodeLocation& code_location, |
|
|
|
|
const char* case_name, const char* test_names, |
|
|
|
|
int index) { |
|
|
|
|
static bool Register(const char* prefix, const CodeLocation& code_location, |
|
|
|
|
const char* case_name, const char* test_names, int index, |
|
|
|
|
const std::vector<std::string>& type_names = |
|
|
|
|
GenerateNames<DefaultNameGenerator, Types>()) { |
|
|
|
|
typedef typename Types::Head Type; |
|
|
|
|
typedef Fixture<Type> FixtureClass; |
|
|
|
|
typedef typename GTEST_BIND_(TestSel, Type) TestClass; |
|
|
|
@ -631,20 +662,23 @@ class TypeParameterizedTest { |
|
|
|
|
// First, registers the first type-parameterized test in the type
|
|
|
|
|
// list.
|
|
|
|
|
MakeAndRegisterTestInfo( |
|
|
|
|
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" |
|
|
|
|
+ StreamableToString(index)).c_str(), |
|
|
|
|
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + |
|
|
|
|
"/" + type_names[index]) |
|
|
|
|
.c_str(), |
|
|
|
|
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), |
|
|
|
|
GetTypeName<Type>().c_str(), |
|
|
|
|
NULL, // No value parameter.
|
|
|
|
|
code_location, |
|
|
|
|
GetTypeId<FixtureClass>(), |
|
|
|
|
TestClass::SetUpTestCase, |
|
|
|
|
TestClass::TearDownTestCase, |
|
|
|
|
new TestFactoryImpl<TestClass>); |
|
|
|
|
code_location, GetTypeId<FixtureClass>(), TestClass::SetUpTestCase, |
|
|
|
|
TestClass::TearDownTestCase, new TestFactoryImpl<TestClass>); |
|
|
|
|
|
|
|
|
|
// Next, recurses (at compile time) with the tail of the type list.
|
|
|
|
|
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail> |
|
|
|
|
::Register(prefix, code_location, case_name, test_names, index + 1); |
|
|
|
|
return TypeParameterizedTest<Fixture, TestSel, |
|
|
|
|
typename Types::Tail>::Register(prefix, |
|
|
|
|
code_location, |
|
|
|
|
case_name, |
|
|
|
|
test_names, |
|
|
|
|
index + 1, |
|
|
|
|
type_names); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -654,7 +688,9 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> { |
|
|
|
|
public: |
|
|
|
|
static bool Register(const char* /*prefix*/, const CodeLocation&, |
|
|
|
|
const char* /*case_name*/, const char* /*test_names*/, |
|
|
|
|
int /*index*/) { |
|
|
|
|
int /*index*/, |
|
|
|
|
const std::vector<std::string>& = |
|
|
|
|
std::vector<std::string>() /*type_names*/) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -667,8 +703,10 @@ template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> |
|
|
|
|
class TypeParameterizedTestCase { |
|
|
|
|
public: |
|
|
|
|
static bool Register(const char* prefix, CodeLocation code_location, |
|
|
|
|
const TypedTestCasePState* state, |
|
|
|
|
const char* case_name, const char* test_names) { |
|
|
|
|
const TypedTestCasePState* state, const char* case_name, |
|
|
|
|
const char* test_names, |
|
|
|
|
const std::vector<std::string>& type_names = |
|
|
|
|
GenerateNames<DefaultNameGenerator, Types>()) { |
|
|
|
|
std::string test_name = StripTrailingSpaces( |
|
|
|
|
GetPrefixUntilComma(test_names)); |
|
|
|
|
if (!state->TestExists(test_name)) { |
|
|
|
@ -685,12 +723,14 @@ class TypeParameterizedTestCase { |
|
|
|
|
|
|
|
|
|
// First, register the first test in 'Test' for each type in 'Types'.
|
|
|
|
|
TypeParameterizedTest<Fixture, Head, Types>::Register( |
|
|
|
|
prefix, test_location, case_name, test_names, 0); |
|
|
|
|
prefix, test_location, case_name, test_names, 0, type_names); |
|
|
|
|
|
|
|
|
|
// Next, recurses (at compile time) with the tail of the test list.
|
|
|
|
|
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types> |
|
|
|
|
::Register(prefix, code_location, state, |
|
|
|
|
case_name, SkipComma(test_names)); |
|
|
|
|
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, |
|
|
|
|
Types>::Register(prefix, code_location, |
|
|
|
|
state, case_name, |
|
|
|
|
SkipComma(test_names), |
|
|
|
|
type_names); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -700,7 +740,9 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> { |
|
|
|
|
public: |
|
|
|
|
static bool Register(const char* /*prefix*/, const CodeLocation&, |
|
|
|
|
const TypedTestCasePState* /*state*/, |
|
|
|
|
const char* /*case_name*/, const char* /*test_names*/) { |
|
|
|
|
const char* /*case_name*/, const char* /*test_names*/, |
|
|
|
|
const std::vector<std::string>& = |
|
|
|
|
std::vector<std::string>() /*type_names*/) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|