diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest-internal-inl.h | 28 | ||||
-rw-r--r-- | src/gtest-port.cc | 32 | ||||
-rw-r--r-- | src/gtest.cc | 85 |
3 files changed, 132 insertions, 13 deletions
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index ce1d0f4f..0f2bcfba 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -53,7 +53,6 @@ #include <windows.h> // NOLINT #endif // GTEST_OS_WINDOWS -#include <ostream> // NOLINT #include <gtest/gtest.h> #include <gtest/gtest-spi.h> @@ -846,7 +845,7 @@ class OsStackTraceGetterInterface { GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; -// A working implemenation of the OsStackTraceGetterInterface interface. +// A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() {} @@ -1063,6 +1062,14 @@ class UnitTestImpl { tear_down_tc)->AddTestInfo(test_info); } +#ifdef GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + // Sets the TestCase object for the test that's currently running. void set_current_test_case(TestCase* current_test_case) { current_test_case_ = current_test_case; @@ -1075,6 +1082,14 @@ class UnitTestImpl { current_test_info_ = current_test_info; } + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has + // guards protecting from registering the tests more then once. + // If value-parameterized tests are disabled, RegisterParameterizedTests + // is present but does nothing. + void RegisterParameterizedTests(); + // Runs all tests in this UnitTest object, prints the result, and // returns 0 if all tests are successful, or 1 otherwise. If any // exception is thrown during a test on Windows, this test is @@ -1169,6 +1184,15 @@ class UnitTestImpl { internal::List<TestCase*> test_cases_; // The list of TestCases. +#ifdef GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + // Points to the last death test case registered. Initially NULL. internal::ListNode<TestCase*>* last_death_test_case_; diff --git a/src/gtest-port.cc b/src/gtest-port.cc index 000a4ab1..9878cae0 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -56,25 +56,49 @@ namespace internal { // Implements RE. Currently only needed for death tests. RE::~RE() { - regfree(®ex_); + regfree(&partial_regex_); + regfree(&full_regex_); free(const_cast<char*>(pattern_)); } -// Returns true iff str contains regular expression re. +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; - return regexec(&re.regex_, str, 1, &match, 0) == 0; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = strdup(regex); - is_valid_ = regcomp(®ex_, regex, REG_EXTENDED) == 0; + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_; EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; } #endif // GTEST_HAS_DEATH_TEST diff --git a/src/gtest.cc b/src/gtest.cc index b5c3d077..83708300 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -277,6 +277,9 @@ void AssertHelper::operator=(const Message& message) const { ); // NOLINT } +// Mutex for linked pointers. +Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); + // Application pathname gotten in InitGoogleTest. String g_executable_path; @@ -830,7 +833,7 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len, // several other places). for (size_t i = 0; i != len; ) { // NOLINT if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, len - i); + *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i)); while (i != len && wstr[i] != L'\0') i++; } else { @@ -1453,7 +1456,7 @@ inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, // will be encoded as individual Unicode characters from Basic Normal Plane. String WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) - num_chars = wcslen(str); + num_chars = static_cast<int>(wcslen(str)); StrStream stream; for (int i = 0; i < num_chars; ++i) { @@ -2080,6 +2083,25 @@ TestInfo* MakeAndRegisterTestInfo( return test_info; } +#ifdef GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + } // namespace internal // Returns the test case name. @@ -2156,6 +2178,18 @@ TestInfo * TestCase::GetTestInfo(const char* test_name) { namespace internal { +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#ifdef GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + // Creates the test object, runs it, records its result, and then // deletes it. void TestInfoImpl::Run() { @@ -3269,6 +3303,16 @@ const TestInfo* UnitTest::current_test_info() const { return impl_->current_test_info(); } +#ifdef GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + // Creates an empty UnitTest. UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); @@ -3314,6 +3358,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), test_cases_(), +#ifdef GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST last_death_test_case_(NULL), current_test_case_(NULL), current_test_info_(NULL), @@ -3415,6 +3463,10 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } // considered to be failed, but the rest of the tests will still be // run. (We disable exceptions on Linux and Mac OS X, so the issue // doesn't apply there.) +// When parameterized tests are enabled, it explands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. int UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { @@ -3424,6 +3476,8 @@ int UnitTestImpl::RunAllTests() { return 1; } + RegisterParameterizedTests(); + // Lists all the tests and exits if the --gtest_list_tests // flag was specified. if (GTEST_FLAG(list_tests)) { @@ -3639,7 +3693,7 @@ internal::TestResult* UnitTestImpl::current_test_result() { } // TestInfoImpl constructor. The new instance assumes ownership of the test -// factory opbject. +// factory object. TestInfoImpl::TestInfoImpl(TestInfo* parent, const char* test_case_name, const char* name, @@ -3663,10 +3717,6 @@ TestInfoImpl::~TestInfoImpl() { delete factory_; } -} // namespace internal - -namespace internal { - // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. @@ -3814,6 +3864,27 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { } } +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return unit_test->impl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Returns the number of failed test parts in the given test result object. +int GetFailedPartCount(const TestResult* result) { + return result->failed_part_count(); +} + } // namespace internal // Initializes Google Test. This must be called before calling |