Add support for --gtest_flagfile.

This commit is contained in:
kosak 2015-07-17 22:11:58 +00:00
parent 195610d30c
commit 4f8dc917eb
9 changed files with 182 additions and 53 deletions

View File

@ -1387,11 +1387,14 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
static int AddToRegistry() { \ static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\ GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \
#test_case_name, \ ::testing::internal::CodeLocation(\
#test_name, \ __FILE__, __LINE__))->AddTestPattern(\
new ::testing::internal::TestMetaFactory< \ #test_case_name, \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ #test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(\
test_case_name, test_name)>()); \
return 0; \ return 0; \
} \ } \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
@ -1409,10 +1412,12 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \ int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\ GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #test_case_name, \
#prefix, \ ::testing::internal::CodeLocation(\
&gtest_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__))->AddTestCaseInstantiation(\
__FILE__, __LINE__) #prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing } // namespace testing

View File

@ -453,11 +453,14 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
static int AddToRegistry() { \ static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\ GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \
#test_case_name, \ ::testing::internal::CodeLocation(\
#test_name, \ __FILE__, __LINE__))->AddTestPattern(\
new ::testing::internal::TestMetaFactory< \ #test_case_name, \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ #test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(\
test_case_name, test_name)>()); \
return 0; \ return 0; \
} \ } \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
@ -475,10 +478,12 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \ int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\ GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #test_case_name, \
#prefix, \ ::testing::internal::CodeLocation(\
&gtest_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__))->AddTestCaseInstantiation(\
__FILE__, __LINE__) #prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing } // namespace testing

View File

@ -181,7 +181,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
::testing::internal::TemplateSel< \ ::testing::internal::TemplateSel< \
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
GTEST_TYPE_PARAMS_(CaseName)>::Register(\ GTEST_TYPE_PARAMS_(CaseName)>::Register(\
"", #CaseName, #TestName, 0); \ "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
#CaseName, #TestName, 0); \
template <typename gtest_TypeParam_> \ template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
@ -252,7 +253,10 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
::testing::internal::TypeParameterizedTestCase<CaseName, \ ::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
::testing::internal::TypeList< Types >::type>::Register(\ ::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #Prefix, \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \
#CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST_P

View File

@ -669,6 +669,12 @@ class GTEST_API_ TestInfo {
return NULL; return NULL;
} }
// Returns the file name where this test is defined.
const char* file() const { return location_.file.c_str(); }
// Returns the line where this test is defined.
int line() const { return location_.line; }
// Returns true if this test should run, that is if the test is not // Returns true if this test should run, that is if the test is not
// disabled (or it is disabled but the also_run_disabled_tests flag has // disabled (or it is disabled but the also_run_disabled_tests flag has
// been specified) and its full name matches the user-specified filter. // been specified) and its full name matches the user-specified filter.
@ -711,6 +717,7 @@ class GTEST_API_ TestInfo {
const char* name, const char* name,
const char* type_param, const char* type_param,
const char* value_param, const char* value_param,
internal::CodeLocation code_location,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc, Test::TearDownTestCaseFunc tear_down_tc,
@ -722,6 +729,7 @@ class GTEST_API_ TestInfo {
const std::string& name, const std::string& name,
const char* a_type_param, // NULL if not a type-parameterized test const char* a_type_param, // NULL if not a type-parameterized test
const char* a_value_param, // NULL if not a value-parameterized test const char* a_value_param, // NULL if not a value-parameterized test
internal::CodeLocation a_code_location,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory); internal::TestFactoryBase* factory);
@ -748,6 +756,7 @@ class GTEST_API_ TestInfo {
// Text representation of the value parameter, or NULL if this is not a // Text representation of the value parameter, or NULL if this is not a
// value-parameterized test. // value-parameterized test.
const internal::scoped_ptr<const ::std::string> value_param_; const internal::scoped_ptr<const ::std::string> value_param_;
internal::CodeLocation location_;
const internal::TypeId fixture_class_id_; // ID of the test fixture class const internal::TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled bool is_disabled_; // True iff this test is disabled

View File

@ -55,6 +55,7 @@
#include <string.h> #include <string.h>
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
#include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
@ -503,6 +504,13 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
typedef void (*SetUpTestCaseFunc)(); typedef void (*SetUpTestCaseFunc)();
typedef void (*TearDownTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)();
struct CodeLocation {
CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {}
string file;
int line;
};
// Creates a new TestInfo object and registers it with Google Test; // Creates a new TestInfo object and registers it with Google Test;
// returns the created object. // returns the created object.
// //
@ -514,6 +522,7 @@ typedef void (*TearDownTestCaseFunc)();
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// value_param text representation of the test's value parameter, // value_param text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test. // or NULL if this is not a type-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
@ -525,6 +534,7 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* name, const char* name,
const char* type_param, const char* type_param,
const char* value_param, const char* value_param,
CodeLocation code_location,
TypeId fixture_class_id, TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc, SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc, TearDownTestCaseFunc tear_down_tc,
@ -554,10 +564,21 @@ class GTEST_API_ TypedTestCasePState {
fflush(stderr); fflush(stderr);
posix::Abort(); posix::Abort();
} }
defined_test_names_.insert(test_name); registered_tests_.insert(
::std::make_pair(test_name, CodeLocation(file, line)));
return true; return true;
} }
bool TestExists(const std::string& test_name) const {
return registered_tests_.count(test_name) > 0;
}
const CodeLocation& GetCodeLocation(const std::string& test_name) const {
RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
GTEST_CHECK_(it != registered_tests_.end());
return it->second;
}
// Verifies that registered_tests match the test names in // Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or // defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise. // aborts the program otherwise.
@ -565,8 +586,10 @@ class GTEST_API_ TypedTestCasePState {
const char* file, int line, const char* registered_tests); const char* file, int line, const char* registered_tests);
private: private:
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
bool registered_; bool registered_;
::std::set<const char*> defined_test_names_; RegisteredTestsMap registered_tests_;
}; };
// Skips to the first non-space char after the first comma in 'str'; // Skips to the first non-space char after the first comma in 'str';
@ -606,8 +629,10 @@ class TypeParameterizedTest {
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
// Types). Valid values for 'index' are [0, N - 1] where N is the // Types). Valid values for 'index' are [0, N - 1] where N is the
// length of Types. // length of Types.
static bool Register(const char* prefix, const char* case_name, static bool Register(const char* prefix,
const char* test_names, int index) { CodeLocation code_location,
const char* case_name, const char* test_names,
int index) {
typedef typename Types::Head Type; typedef typename Types::Head Type;
typedef Fixture<Type> FixtureClass; typedef Fixture<Type> FixtureClass;
typedef typename GTEST_BIND_(TestSel, Type) TestClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass;
@ -620,6 +645,7 @@ class TypeParameterizedTest {
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
GetTypeName<Type>().c_str(), GetTypeName<Type>().c_str(),
NULL, // No value parameter. NULL, // No value parameter.
code_location,
GetTypeId<FixtureClass>(), GetTypeId<FixtureClass>(),
TestClass::SetUpTestCase, TestClass::SetUpTestCase,
TestClass::TearDownTestCase, TestClass::TearDownTestCase,
@ -627,7 +653,7 @@ class TypeParameterizedTest {
// Next, recurses (at compile time) with the tail of the type list. // Next, recurses (at compile time) with the tail of the type list.
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail> return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
::Register(prefix, case_name, test_names, index + 1); ::Register(prefix, code_location, case_name, test_names, index + 1);
} }
}; };
@ -635,8 +661,9 @@ class TypeParameterizedTest {
template <GTEST_TEMPLATE_ Fixture, class TestSel> template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> { class TypeParameterizedTest<Fixture, TestSel, Types0> {
public: public:
static bool Register(const char* /*prefix*/, const char* /*case_name*/, static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*test_names*/, int /*index*/) { const char* /*case_name*/, const char* /*test_names*/,
int /*index*/) {
return true; return true;
} }
}; };
@ -648,17 +675,31 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> {
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
class TypeParameterizedTestCase { class TypeParameterizedTestCase {
public: public:
static bool Register(const char* prefix, const char* case_name, static bool Register(const char* prefix, CodeLocation code_location,
const char* test_names) { const TypedTestCasePState* state,
const char* case_name, const char* test_names) {
std::string test_name = StripTrailingSpaces(
GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) {
fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
case_name, test_name.c_str(),
FormatFileLocation(code_location.file.c_str(),
code_location.line).c_str());
fflush(stderr);
posix::Abort();
}
const CodeLocation& test_location = state->GetCodeLocation(test_name);
typedef typename Tests::Head Head; typedef typename Tests::Head Head;
// First, register the first test in 'Test' for each type in 'Types'. // First, register the first test in 'Test' for each type in 'Types'.
TypeParameterizedTest<Fixture, Head, Types>::Register( TypeParameterizedTest<Fixture, Head, Types>::Register(
prefix, case_name, test_names, 0); prefix, test_location, case_name, test_names, 0);
// Next, recurses (at compile time) with the tail of the test list. // Next, recurses (at compile time) with the tail of the test list.
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types> return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
::Register(prefix, case_name, SkipComma(test_names)); ::Register(prefix, code_location, state,
case_name, SkipComma(test_names));
} }
}; };
@ -666,8 +707,9 @@ class TypeParameterizedTestCase {
template <GTEST_TEMPLATE_ Fixture, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestCase<Fixture, Templates0, Types> { class TypeParameterizedTestCase<Fixture, Templates0, Types> {
public: public:
static bool Register(const char* /*prefix*/, const char* /*case_name*/, static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*test_names*/) { const TypedTestCasePState* /*state*/,
const char* /*case_name*/, const char* /*test_names*/) {
return true; return true;
} }
}; };
@ -1187,6 +1229,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
::test_info_ =\ ::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\ ::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, NULL, NULL, \ #test_case_name, #test_name, NULL, NULL, \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
(parent_id), \ (parent_id), \
parent_class::SetUpTestCase, \ parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \ parent_class::TearDownTestCase, \

View File

@ -58,7 +58,7 @@ namespace internal {
// TEST_P macro is used to define two tests with the same name // TEST_P macro is used to define two tests with the same name
// but in different namespaces. // but in different namespaces.
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line); CodeLocation code_location);
template <typename> class ParamGeneratorInterface; template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator; template <typename> class ParamGenerator;
@ -450,8 +450,9 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
// A function that returns an instance of appropriate generator type. // A function that returns an instance of appropriate generator type.
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
explicit ParameterizedTestCaseInfo(const char* name) explicit ParameterizedTestCaseInfo(
: test_case_name_(name) {} const char* name, CodeLocation code_location)
: test_case_name_(name), code_location_(code_location) {}
// Test case base name for display purposes. // Test case base name for display purposes.
virtual const string& GetTestCaseName() const { return test_case_name_; } virtual const string& GetTestCaseName() const { return test_case_name_; }
@ -510,6 +511,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
test_name_stream.GetString().c_str(), test_name_stream.GetString().c_str(),
NULL, // No type parameter. NULL, // No type parameter.
PrintToString(*param_it).c_str(), PrintToString(*param_it).c_str(),
code_location_,
GetTestCaseTypeId(), GetTestCaseTypeId(),
TestCase::SetUpTestCase, TestCase::SetUpTestCase,
TestCase::TearDownTestCase, TestCase::TearDownTestCase,
@ -541,6 +543,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
InstantiationContainer; InstantiationContainer;
const string test_case_name_; const string test_case_name_;
CodeLocation code_location_;
TestInfoContainer tests_; TestInfoContainer tests_;
InstantiationContainer instantiations_; InstantiationContainer instantiations_;
@ -568,8 +571,7 @@ class ParameterizedTestCaseRegistry {
template <class TestCase> template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name, const char* test_case_name,
const char* file, CodeLocation code_location) {
int line) {
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) { it != test_case_infos_.end(); ++it) {
@ -578,7 +580,7 @@ class ParameterizedTestCaseRegistry {
// Complain about incorrect usage of Google Test facilities // Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct // and terminate the program since we cannot guaranty correct
// test case setup and tear-down in this case. // test case setup and tear-down in this case.
ReportInvalidTestCaseType(test_case_name, file, line); ReportInvalidTestCaseType(test_case_name, code_location);
posix::Abort(); posix::Abort();
} else { } else {
// At this point we are sure that the object we found is of the same // At this point we are sure that the object we found is of the same
@ -591,7 +593,8 @@ class ParameterizedTestCaseRegistry {
} }
} }
if (typed_test_info == NULL) { if (typed_test_info == NULL) {
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
test_case_name, code_location);
test_case_infos_.push_back(typed_test_info); test_case_infos_.push_back(typed_test_info);
} }
return typed_test_info; return typed_test_info;

View File

@ -55,11 +55,11 @@ static std::vector<std::string> SplitIntoTestNames(const char* src) {
} }
// Verifies that registered_tests match the test names in // Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or // registered_tests_; returns registered_tests if successful, or
// aborts the program otherwise. // aborts the program otherwise.
const char* TypedTestCasePState::VerifyRegisteredTestNames( const char* TypedTestCasePState::VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests) { const char* file, int line, const char* registered_tests) {
typedef ::std::set<const char*>::const_iterator DefinedTestIter; typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
registered_ = true; registered_ = true;
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests); std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
@ -76,10 +76,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
} }
bool found = false; bool found = false;
for (DefinedTestIter it = defined_test_names_.begin(); for (RegisteredTestIter it = registered_tests_.begin();
it != defined_test_names_.end(); it != registered_tests_.end();
++it) { ++it) {
if (name == *it) { if (name == it->first) {
found = true; found = true;
break; break;
} }
@ -93,11 +93,11 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
} }
} }
for (DefinedTestIter it = defined_test_names_.begin(); for (RegisteredTestIter it = registered_tests_.begin();
it != defined_test_names_.end(); it != registered_tests_.end();
++it) { ++it) {
if (tests.count(*it) == 0) { if (tests.count(it->first) == 0) {
errors << "You forgot to list test " << *it << ".\n"; errors << "You forgot to list test " << it->first << ".\n";
} }
} }

View File

@ -2493,12 +2493,14 @@ TestInfo::TestInfo(const std::string& a_test_case_name,
const std::string& a_name, const std::string& a_name,
const char* a_type_param, const char* a_type_param,
const char* a_value_param, const char* a_value_param,
internal::CodeLocation a_code_location,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory) internal::TestFactoryBase* factory)
: test_case_name_(a_test_case_name), : test_case_name_(a_test_case_name),
name_(a_name), name_(a_name),
type_param_(a_type_param ? new std::string(a_type_param) : NULL), type_param_(a_type_param ? new std::string(a_type_param) : NULL),
value_param_(a_value_param ? new std::string(a_value_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL),
location_(a_code_location),
fixture_class_id_(fixture_class_id), fixture_class_id_(fixture_class_id),
should_run_(false), should_run_(false),
is_disabled_(false), is_disabled_(false),
@ -2522,6 +2524,7 @@ namespace internal {
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// value_param: text representation of the test's value parameter, // value_param: text representation of the test's value parameter,
// or NULL if this is not a value-parameterized test. // or NULL if this is not a value-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
@ -2533,20 +2536,21 @@ TestInfo* MakeAndRegisterTestInfo(
const char* name, const char* name,
const char* type_param, const char* type_param,
const char* value_param, const char* value_param,
CodeLocation code_location,
TypeId fixture_class_id, TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc, SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc, TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory) { TestFactoryBase* factory) {
TestInfo* const test_info = TestInfo* const test_info =
new TestInfo(test_case_name, name, type_param, value_param, new TestInfo(test_case_name, name, type_param, value_param,
fixture_class_id, factory); code_location, fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info; return test_info;
} }
#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_PARAM_TEST
void ReportInvalidTestCaseType(const char* test_case_name, void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line) { CodeLocation code_location) {
Message errors; Message errors;
errors errors
<< "Attempted redefinition of test case " << test_case_name << ".\n" << "Attempted redefinition of test case " << test_case_name << ".\n"
@ -2558,7 +2562,9 @@ void ReportInvalidTestCaseType(const char* test_case_name,
<< "probably rename one of the classes to put the tests into different\n" << "probably rename one of the classes to put the tests into different\n"
<< "test cases."; << "test cases.";
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), fprintf(stderr, "%s %s",
FormatFileLocation(code_location.file.c_str(),
code_location.line).c_str(),
errors.GetString().c_str()); errors.GetString().c_str());
} }
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST

View File

@ -94,7 +94,8 @@ class StreamingListenerTest : public Test {
StreamingListenerTest() StreamingListenerTest()
: fake_sock_writer_(new FakeSocketWriter), : fake_sock_writer_(new FakeSocketWriter),
streamer_(fake_sock_writer_), streamer_(fake_sock_writer_),
test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} test_info_obj_("FooTest", "Bar", NULL, NULL,
CodeLocation(__FILE__, __LINE__), 0, NULL) {}
protected: protected:
string* output() { return &(fake_sock_writer_->output_); } string* output() { return &(fake_sock_writer_->output_); }
@ -5328,6 +5329,59 @@ TEST_F(TestInfoTest, result) {
ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); ASSERT_EQ(0, GetTestResult(test_info)->total_part_count());
} }
#define VERIFY_CODE_LOCATION \
const int expected_line = __LINE__ - 1; \
const TestInfo* const test_info = GetUnitTestImpl()->current_test_info(); \
ASSERT_TRUE(test_info); \
EXPECT_STREQ(__FILE__, test_info->file()); \
EXPECT_EQ(expected_line, test_info->line())
TEST(CodeLocationForTEST, Verify) {
VERIFY_CODE_LOCATION;
}
class CodeLocationForTESTF : public Test {
};
TEST_F(CodeLocationForTESTF, Verify) {
VERIFY_CODE_LOCATION;
}
class CodeLocationForTESTP : public TestWithParam<int> {
};
TEST_P(CodeLocationForTESTP, Verify) {
VERIFY_CODE_LOCATION;
}
INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, Values(0));
template <typename T>
class CodeLocationForTYPEDTEST : public Test {
};
TYPED_TEST_CASE(CodeLocationForTYPEDTEST, int);
TYPED_TEST(CodeLocationForTYPEDTEST, Verify) {
VERIFY_CODE_LOCATION;
}
template <typename T>
class CodeLocationForTYPEDTESTP : public Test {
};
TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP);
TYPED_TEST_P(CodeLocationForTYPEDTESTP, Verify) {
VERIFY_CODE_LOCATION;
}
REGISTER_TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP, Verify);
INSTANTIATE_TYPED_TEST_CASE_P(My, CodeLocationForTYPEDTESTP, int);
#undef VERIFY_CODE_LOCATION
// Tests setting up and tearing down a test case. // Tests setting up and tearing down a test case.
class SetUpTestCaseTest : public Test { class SetUpTestCaseTest : public Test {