aboutsummaryrefslogtreecommitdiffstats
path: root/googletest/src
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2019-12-19 12:36:47 -0500
committerAndy Soffer <asoffer@google.com>2020-01-02 16:48:59 -0500
commita13a0626188b4e7d22d63a4c9fcfe9f441c81e4a (patch)
tree29e7ba132b7ec3acf8943cf3195cadb5c287a703 /googletest/src
parent008629ae2163035dabd428d581379fa5aac4b7bb (diff)
downloadgoogletest-a13a0626188b4e7d22d63a4c9fcfe9f441c81e4a.tar.gz
googletest-a13a0626188b4e7d22d63a4c9fcfe9f441c81e4a.tar.bz2
googletest-a13a0626188b4e7d22d63a4c9fcfe9f441c81e4a.zip
Googletest export
Add option (default to disabled) to make C++ type parameterized tests (TYPED_TEST_P) fail when they're not instantiated. When an un-instantiated TYPED_TEST_P is found, a new test will be inserted that emits a suitable message. For now, that is just a notice, but the hope it to flip the bit to make it fail by default. PiperOrigin-RevId: 286408038
Diffstat (limited to 'googletest/src')
-rw-r--r--googletest/src/gtest-internal-inl.h9
-rw-r--r--googletest/src/gtest-typed-test.cc5
-rw-r--r--googletest/src/gtest.cc59
3 files changed, 72 insertions, 1 deletions
diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h
index c3575ee3..d0ebe0c5 100644
--- a/googletest/src/gtest-internal-inl.h
+++ b/googletest/src/gtest-internal-inl.h
@@ -698,6 +698,13 @@ class GTEST_API_ UnitTestImpl {
return parameterized_test_registry_;
}
+ // Returns TypeParameterizedTestSuiteRegistry object used to keep track of
+ // type-parameterized tests and instantiations of them.
+ internal::TypeParameterizedTestSuiteRegistry&
+ type_parameterized_test_registry() {
+ return type_parameterized_test_registry_;
+ }
+
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
@@ -874,6 +881,8 @@ class GTEST_API_ UnitTestImpl {
// ParameterizedTestRegistry object used to register value-parameterized
// tests.
internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;
+ internal::TypeParameterizedTestSuiteRegistry
+ type_parameterized_test_registry_;
// Indicates whether RegisterParameterizedTests() has been called already.
bool parameterized_tests_registered_;
diff --git a/googletest/src/gtest-typed-test.cc b/googletest/src/gtest-typed-test.cc
index 8677caf7..1b1cfb0d 100644
--- a/googletest/src/gtest-typed-test.cc
+++ b/googletest/src/gtest-typed-test.cc
@@ -58,7 +58,10 @@ static std::vector<std::string> SplitIntoTestNames(const char* src) {
// registered_tests_; returns registered_tests if successful, or
// aborts the program otherwise.
const char* TypedTestSuitePState::VerifyRegisteredTestNames(
- const char* file, int line, const char* registered_tests) {
+ const char* test_suite_name, const char* file, int line,
+ const char* registered_tests) {
+ RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));
+
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
registered_ = true;
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index f6466b92..07015cba 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -415,6 +415,7 @@ namespace {
//
// This configuration bit will likely be removed at some point.
constexpr bool kErrorOnUninstantiatedParameterizedTest = false;
+constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = false;
// A test that fails at a given file/line location with a given message.
class FailureTest : public Test {
@@ -467,6 +468,63 @@ void InsertSyntheticTestCase(const std::string &name, CodeLocation location) {
});
}
+void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
+ CodeLocation code_location) {
+ GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
+ test_suite_name, code_location);
+}
+
+void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
+ GetUnitTestImpl()
+ ->type_parameterized_test_registry()
+ .RegisterInstantiation(case_name);
+}
+
+void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
+ const char* test_suite_name, CodeLocation code_location) {
+ suites_.emplace(std::string(test_suite_name),
+ TypeParameterizedTestSuiteInfo(code_location));
+}
+
+void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
+ const char* test_suite_name) {
+ auto it = suites_.find(std::string(test_suite_name));
+ if (it != suites_.end()) {
+ it->second.instantiated = true;
+ } else {
+ GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '"
+ << test_suite_name << "'";
+ }
+}
+
+void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {
+ for (const auto& testcase : suites_) {
+ if (testcase.second.instantiated) continue;
+
+ std::string message =
+ "Type paramaterized test suite " + testcase.first +
+ " is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated "
+ "via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run."
+ "\n\n"
+ "Ideally, TYPED_TEST_P definitions should only ever be included as "
+ "part of binaries that intend to use them. (As opposed to, for "
+ "example, being placed in a library that may be linked in to get other "
+ "utilities.)";
+
+ std::string full_name =
+ "UninstantiatedTypeParamaterizedTestSuite<" + testcase.first + ">";
+ RegisterTest( //
+ "GoogleTestVerification", full_name.c_str(),
+ nullptr, // No type parameter.
+ nullptr, // No value parameter.
+ testcase.second.code_location.file.c_str(),
+ testcase.second.code_location.line, [message, testcase] {
+ return new FailureTest(testcase.second.code_location, message,
+ kErrorOnUninstantiatedTypeParameterizedTest);
+ });
+ }
+}
+
// A copy of all command line arguments. Set by InitGoogleTest().
static ::std::vector<std::string> g_argvs;
@@ -2710,6 +2768,7 @@ namespace internal {
void UnitTestImpl::RegisterParameterizedTests() {
if (!parameterized_tests_registered_) {
parameterized_test_registry_.RegisterTests();
+ type_parameterized_test_registry_.CheckForInstantiations();
parameterized_tests_registered_ = true;
}
}