summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925>2008-08-06 21:44:19 +0000
committershiqian <shiqian@861a406c-534a-0410-8894-cb66d6ee9925>2008-08-06 21:44:19 +0000
commit4834581321d60c17997d65a2360c7674f15f9bbc (patch)
treefae369ee214062805989e6506d40f297c85b22c9
parent760af5c16f8af7d34b7ef75a0e4d0b18f023f3f3 (diff)
downloadgtest-4834581321d60c17997d65a2360c7674f15f9bbc.tar.gz
gtest-4834581321d60c17997d65a2360c7674f15f9bbc.tar.bz2
gtest-4834581321d60c17997d65a2360c7674f15f9bbc.tar.xz
Changes test creation functions to factories. By Vlad Losev.
git-svn-id: http://googletest.googlecode.com/svn/trunk@78 861a406c-534a-0410-8894-cb66d6ee9925
-rw-r--r--CONTRIBUTORS1
-rw-r--r--include/gtest/gtest.h17
-rw-r--r--include/gtest/internal/gtest-internal.h44
-rw-r--r--src/gtest-internal-inl.h5
-rw-r--r--src/gtest.cc26
5 files changed, 61 insertions, 32 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index d6fa9bd..ffc2341 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -24,4 +24,5 @@ Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com>
Tracy Bialik <tracy@pentad.com>
+Vlad Losev <vladl@google.com>
Zhanyong Wan <wan@google.com>
diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h
index 2464f72..1f5d764 100644
--- a/include/gtest/gtest.h
+++ b/include/gtest/gtest.h
@@ -310,11 +310,6 @@ class Test {
};
-// Defines the type of a function pointer that creates a Test object
-// when invoked.
-typedef Test* (*TestMaker)();
-
-
// A TestInfo object stores the following information about a test:
//
// Test case name
@@ -342,7 +337,9 @@ class TestInfo {
// fixture_class_id: ID of the test fixture class
// 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
- // maker: pointer to the function that creates a test object
+ // factory: Pointer to the factory that creates a test object.
+ // The newly created TestInfo instance will assume
+ // ownershi pof the factory object.
//
// This is public only because it's needed by the TEST and TEST_F macros.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
@@ -352,7 +349,7 @@ class TestInfo {
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
- TestMaker maker);
+ internal::TestFactoryBase* factory);
// Returns the test case name.
const char* test_case_name() const;
@@ -395,9 +392,11 @@ class TestInfo {
internal::TestInfoImpl* impl() { return impl_; }
const internal::TestInfoImpl* impl() const { return impl_; }
- // Constructs a TestInfo object.
+ // Constructs a TestInfo object. The newly constructed instance assumes
+ // ownership of the factory object.
TestInfo(const char* test_case_name, const char* name,
- internal::TypeId fixture_class_id, TestMaker maker);
+ internal::TypeId fixture_class_id,
+ internal::TestFactoryBase* factory);
// An opaque implementation object.
internal::TestInfoImpl* impl_;
diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h
index 2eefc7b..dc6154b 100644
--- a/include/gtest/internal/gtest-internal.h
+++ b/include/gtest/internal/gtest-internal.h
@@ -98,6 +98,7 @@ namespace testing {
// Forward declaration of classes.
class Message; // Represents a failure message.
+class Test; // Represents a test.
class TestCase; // A collection of related tests.
class TestPartResult; // Result of a test part.
class TestInfo; // Information about a test.
@@ -484,6 +485,31 @@ inline TypeId GetTypeId() {
return &dummy;
}
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+ virtual ~TestFactoryBase() {}
+
+ // Creates a test instance to run. The instance is both created and destroyed
+ // within TestInfoImpl::Run()
+ virtual Test* CreateTest() = 0;
+
+ protected:
+ TestFactoryBase() {}
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+ virtual Test* CreateTest() { return new TestClass; }
+};
+
#ifdef GTEST_OS_WINDOWS
// Predicate-formatters for implementing the HRESULT checking macros
@@ -523,9 +549,6 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT
class test_case_name##_##test_name##_Test : public parent_class {\
public:\
test_case_name##_##test_name##_Test() {}\
- static ::testing::Test* NewTest() {\
- return new test_case_name##_##test_name##_Test;\
- }\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_;\
@@ -533,13 +556,14 @@ class test_case_name##_##test_name##_Test : public parent_class {\
};\
\
::testing::TestInfo* const test_case_name##_##test_name##_Test::test_info_ =\
- ::testing::TestInfo::MakeAndRegisterInstance(\
- #test_case_name, \
- #test_name, \
- ::testing::internal::GetTypeId< parent_class >(), \
- parent_class::SetUpTestCase, \
- parent_class::TearDownTestCase, \
- test_case_name##_##test_name##_Test::NewTest);\
+ ::testing::TestInfo::MakeAndRegisterInstance(\
+ #test_case_name, \
+ #test_name, \
+ ::testing::internal::GetTypeId< parent_class >(), \
+ parent_class::SetUpTestCase, \
+ parent_class::TearDownTestCase, \
+ new ::testing::internal::TestFactoryImpl<\
+ test_case_name##_##test_name##_Test>);\
void test_case_name##_##test_name##_Test::TestBody()
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h
index 5546a77..7757191 100644
--- a/src/gtest-internal-inl.h
+++ b/src/gtest-internal-inl.h
@@ -542,7 +542,7 @@ class TestInfoImpl {
public:
TestInfoImpl(TestInfo* parent, const char* test_case_name,
const char* name, TypeId fixture_class_id,
- TestMaker maker);
+ internal::TestFactoryBase* factory);
~TestInfoImpl();
// Returns true if this test should run.
@@ -595,7 +595,8 @@ class TestInfoImpl {
const TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled
- const TestMaker maker_; // The function that creates the test object
+ internal::TestFactoryBase* const factory_; // The factory that creates
+ // the test object
// This field is mutable and needs to be reset before running the
// test for the second time.
diff --git a/src/gtest.cc b/src/gtest.cc
index 720341b..a0a0520 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -1882,13 +1882,14 @@ bool Test::HasFatalFailure() {
// class TestInfo
-// Constructs a TestInfo object.
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object via impl_.
TestInfo::TestInfo(const char* test_case_name,
const char* name,
internal::TypeId fixture_class_id,
- TestMaker maker) {
+ internal::TestFactoryBase* factory) {
impl_ = new internal::TestInfoImpl(this, test_case_name, name,
- fixture_class_id, maker);
+ fixture_class_id, factory);
}
// Destructs a TestInfo object.
@@ -1905,16 +1906,17 @@ TestInfo::~TestInfo() {
// name: name of the test
// 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
-// maker: pointer to the function that creates a test object
+// factory factory object that creates a test object. The new
+// TestInfo instance assumes ownership of the factory object.
TestInfo* TestInfo::MakeAndRegisterInstance(
const char* test_case_name,
const char* name,
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
- TestMaker maker) {
+ internal::TestFactoryBase* factory) {
TestInfo* const test_info =
- new TestInfo(test_case_name, name, fixture_class_id, maker);
+ new TestInfo(test_case_name, name, fixture_class_id, factory);
internal::GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
@@ -2007,7 +2009,7 @@ void TestInfoImpl::Run() {
__try {
// Creates the test object.
- test = (*maker_)();
+ test = factory_->CreateTest();
} __except(internal::UnitTestOptions::GTestShouldProcessSEH(
GetExceptionCode())) {
AddExceptionThrownFailure(GetExceptionCode(),
@@ -2022,7 +2024,7 @@ void TestInfoImpl::Run() {
// exception-safe.
// Creates the test object.
- Test* test = (*maker_)();
+ Test* test = factory_->CreateTest();
#endif // GTEST_OS_WINDOWS
// Runs the test only if the constructor of the test fixture didn't
@@ -3417,23 +3419,25 @@ internal::TestResult* UnitTestImpl::current_test_result() {
current_test_info_->impl()->result() : &ad_hoc_test_result_;
}
-// TestInfoImpl constructor.
+// TestInfoImpl constructor. The new instance assumes ownership of the test
+// factory opbject.
TestInfoImpl::TestInfoImpl(TestInfo* parent,
const char* test_case_name,
const char* name,
TypeId fixture_class_id,
- TestMaker maker) :
+ internal::TestFactoryBase* factory) :
parent_(parent),
test_case_name_(String(test_case_name)),
name_(String(name)),
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),
- maker_(maker) {
+ factory_(factory) {
}
// TestInfoImpl destructor.
TestInfoImpl::~TestInfoImpl() {
+ delete factory_;
}
} // namespace internal