Value-parameterized tests and many bugfixes
This commit is contained in:
@@ -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_;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
85
src/gtest.cc
85
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
|
||||
|
||||
Reference in New Issue
Block a user